Changeset: 5389bf9e901d for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5389bf9e901d
Modified Files:
        gdk/gdk_logger.c
        gdk/gdk_string.c
        sql/server/rel_optimizer.c
        sql/server/rel_rel.c
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-query.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-view.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-2join-query.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-2join-view.stable.out
        
sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-prologue.stable.out
Branch: Oct2020
Log Message:

Merged with Jun2020


diffs (truncated from 725 to 300 lines):

diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c
--- a/gdk/gdk_logger.c
+++ b/gdk/gdk_logger.c
@@ -2898,7 +2898,7 @@ log_delta(logger *lg, BAT *uid, BAT *uva
                        fprintf(stderr, "#Logged %s " LLFMT " inserts\n", name, 
l.nr);
        }
        if (ok != GDK_SUCCEED)
-               TRC_CRITICAL(GDK, "write failed\n");
+               TRC_CRITICAL(GDK, "write failed for %s\n", name);
        return ok;
 }
 
@@ -2946,7 +2946,7 @@ log_bat(logger *lg, BAT *b, const char *
        }
 
        if (ok != GDK_SUCCEED)
-               TRC_CRITICAL(GDK, "write failed\n");
+               TRC_CRITICAL(GDK, "write failed for %s\n", name);
        return ok;
 }
 
diff --git a/gdk/gdk_string.c b/gdk/gdk_string.c
--- a/gdk/gdk_string.c
+++ b/gdk/gdk_string.c
@@ -176,6 +176,46 @@ strLocate(Heap *h, const char *v)
        return 0;
 }
 
+static inline gdk_return
+checkUTF8(const char *v)
+{
+       if (v[0] != '\200' || v[1] != '\0') {
+               /* check that string is correctly encoded UTF-8; there
+                * was no need to do this earlier: if the string was
+                * found above, it must have gone through here in the
+                * past */
+               int nutf8 = 0;
+               int m = 0;
+               for (size_t i = 0; v[i]; i++) {
+                       if (nutf8 > 0) {
+                               if ((v[i] & 0xC0) != 0x80 ||
+                                   (m != 0 && (v[i] & m) == 0))
+                                       goto badutf8;
+                               m = 0;
+                               nutf8--;
+                       } else if ((v[i] & 0xE0) == 0xC0) {
+                               nutf8 = 1;
+                               if ((v[i] & 0x1E) == 0)
+                                       goto badutf8;
+                       } else if ((v[i] & 0xF0) == 0xE0) {
+                               nutf8 = 2;
+                               if ((v[i] & 0x0F) == 0)
+                                       m = 0x20;
+                       } else if ((v[i] & 0xF8) == 0xF0) {
+                               nutf8 = 3;
+                               if ((v[i] & 0x07) == 0)
+                                       m = 0x30;
+                       } else if ((v[i] & 0x80) != 0) {
+                               goto badutf8;
+                       }
+               }
+       }
+       return GDK_SUCCEED;
+
+  badutf8:
+       return GDK_FAIL;
+}
+
 var_t
 strPut(Heap *h, var_t *dst, const char *v)
 {
@@ -219,39 +259,9 @@ strPut(Heap *h, var_t *dst, const char *
        }
        /* the string was not found in the heap, we need to enter it */
 
-       if (v[0] != '\200' || v[1] != '\0') {
-               /* check that string is correctly encoded UTF-8; there
-                * was no need to do this earlier: if the string was
-                * found above, it must have gone through here in the
-                * past */
-               int nutf8 = 0;
-               int m = 0;
-               for (size_t i = 0; v[i]; i++) {
-                       if (nutf8 > 0) {
-                               if ((v[i] & 0xC0) != 0x80 ||
-                                   (m != 0 && (v[i] & m) == 0)) {
-                                 badutf8:
-                                       GDKerror("incorrectly encoded UTF-8");
-                                       return 0;
-                               }
-                               m = 0;
-                               nutf8--;
-                       } else if ((v[i] & 0xE0) == 0xC0) {
-                               nutf8 = 1;
-                               if ((v[i] & 0x1E) == 0)
-                                       goto badutf8;
-                       } else if ((v[i] & 0xF0) == 0xE0) {
-                               nutf8 = 2;
-                               if ((v[i] & 0x0F) == 0)
-                                       m = 0x20;
-                       } else if ((v[i] & 0xF8) == 0xF0) {
-                               nutf8 = 3;
-                               if ((v[i] & 0x07) == 0)
-                                       m = 0x30;
-                       } else if ((v[i] & 0x80) != 0) {
-                               goto badutf8;
-                       }
-               }
+       if (checkUTF8(v) != GDK_SUCCEED) {
+               GDKerror("incorrectly encoded UTF-8\n");
+               return 0;
        }
 
        pad = GDK_VARALIGN - (h->free & (GDK_VARALIGN - 1));
@@ -780,6 +790,10 @@ strWrite(const char *a, stream *s, size_
 
        (void) cnt;
        assert(cnt == 1);
+       if (checkUTF8(a) != GDK_SUCCEED) {
+               GDKerror("incorrectly encoded UTF-8\n");
+               return GDK_FAIL;
+       }
        if (mnstr_writeInt(s, (int) len) && mnstr_write(s, a, len, 1) == 1)
                return GDK_SUCCEED;
        else
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -1680,12 +1680,12 @@ rel_simplify_project_fk_join(mvc *sql, s
 {
        sql_rel *rl = r->l;
        sql_rel *rr = r->r;
-       sql_exp *je;
+       sql_exp *je, *le, *nje, *re;
        node *n;
        int fk_left = 1;
 
        /* check for foreign key join */
-       if (!r->exps || list_length(r->exps) != 1)
+       if (list_length(r->exps) != 1)
                return r;
        je = r->exps->h->data;
        if (je && !find_prop(je->p, PROP_JOINIDX))
@@ -1729,11 +1729,24 @@ rel_simplify_project_fk_join(mvc *sql, s
                        return r;
        }
 
+       /* rewrite, ie remove pkey side if possible */
+       le = (sql_exp*)je->l, re = (sql_exp*)je->l;
+
+       /* both have NULL and there are semantics, the join cannot be removed */
+       if (is_semantics(je) && has_nil(le) && has_nil(re))
+               return r;
+
        (*changes)++;
-       /* rewrite, ie remove pkey side */
-       if (fk_left)
-               return r->l;
-       return r->r;
+       /* if the foreign key column doesn't have NULL values, then return it */
+       if (!has_nil(le) || is_full(r->op) || (fk_left && is_left(r->op)) || 
(!fk_left && is_right(r->op)))
+               return fk_left ? r->l : r->r;
+
+       /* remove NULL values, ie generate a select not null */
+       nje = exp_compare(sql->sa, exp_ref(sql, le), exp_atom(sql->sa, 
atom_general(sql->sa, exp_subtype(le), NULL)), cmp_equal);
+       set_anti(nje);
+       set_has_no_nil(nje);
+       set_semantics(nje);
+       return rel_select(sql->sa, fk_left ? r->l : r->r, nje);
 }
 
 static sql_rel *
@@ -1741,11 +1754,11 @@ rel_simplify_count_fk_join(mvc *sql, sql
 {
        sql_rel *rl = r->l;
        sql_rel *rr = r->r;
-       sql_exp *oce, *je;
+       sql_exp *je, *le, *nje, *re, *oce;
        int fk_left = 1;
 
        /* check for foreign key join */
-       if (!r->exps || list_length(r->exps) != 1)
+       if (list_length(r->exps) != 1)
                return r;
        je = r->exps->h->data;
        if (je && !find_prop(je->p, PROP_JOINIDX))
@@ -1777,11 +1790,24 @@ rel_simplify_count_fk_join(mvc *sql, sql
                r->r = rr;
        }
 
+       /* rewrite, ie remove pkey side if possible */
+       le = (sql_exp*)je->l, re = (sql_exp*)je->l;
+
+       /* both have NULL and there are semantics, the join cannot be removed */
+       if (is_semantics(je) && has_nil(le) && has_nil(re))
+               return r;
+
        (*changes)++;
-       /* rewrite, ie remove pkey side */
-       if (fk_left)
-               return r->l;
-       return r->r;
+       /* if the foreign key column doesn't have NULL values, then return it */
+       if (!has_nil(le) || is_full(r->op) || (fk_left && is_left(r->op)) || 
(!fk_left && is_right(r->op)))
+               return fk_left ? r->l : r->r;
+
+       /* remove NULL values, ie generate a select not null */
+       nje = exp_compare(sql->sa, exp_ref(sql, le), exp_atom(sql->sa, 
atom_general(sql->sa, exp_subtype(le), NULL)), cmp_equal);
+       set_anti(nje);
+       set_has_no_nil(nje);
+       set_semantics(nje);
+       return rel_select(sql->sa, fk_left ? r->l : r->r, nje);
 }
 
 /*
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -828,6 +828,7 @@ rel_basetable(mvc *sql, sql_table *t, co
                        sql_idx *i = cn->data;
                        sql_subtype *t = sql_bind_localtype("lng"); /* hash 
"lng" */
                        char *iname = NULL;
+                       int has_nils = 0;
 
                        /* do not include empty indices in the plan */
                        if ((hash_index(i->type) && list_length(i->columns) <= 
1) || !idx_has_column(i->type))
@@ -837,7 +838,13 @@ rel_basetable(mvc *sql, sql_table *t, co
                                t = sql_bind_localtype("oid");
 
                        iname = sa_strconcat( sa, "%", i->base.name);
-                       e = exp_alias(sa, atname, iname, tname, iname, t, 
CARD_MULTI, 0, 1);
+                       for (node *n = i->columns->h ; n && !has_nils; n = 
n->next) { /* check for NULL values */
+                               sql_kc *kc = n->data;
+
+                               if (kc->c->null)
+                                       has_nils = 1;
+                       }
+                       e = exp_alias(sa, atname, iname, tname, iname, t, 
CARD_MULTI, has_nils, 1);
                        /* index names are prefixed, to make them independent */
                        if (hash_index(i->type)) {
                                p = e->p = prop_create(sa, PROP_HASHIDX, e->p);
diff --git 
a/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-query.stable.out
 
b/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-query.stable.out
--- 
a/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-query.stable.out
+++ 
b/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-plan-1join-query.stable.out
@@ -50,24 +50,24 @@ project (
 % .plan # table_name
 % rel # name
 % clob # type
-% 124 # length
+% 115 # length
 project (
 | left outer join (
-| | table("sys"."fk") [ "fk"."id" NOT NULL HASHCOL , "fk"."%fk_fk1_fkey" NOT 
NULL JOINIDX "sys"."fk"."fk_fk1_fkey" ] COUNT ,
+| | table("sys"."fk") [ "fk"."id" NOT NULL HASHCOL , "fk"."%fk_fk1_fkey" 
JOINIDX "sys"."fk"."fk_fk1_fkey" ] COUNT ,
 | | table("sys"."pk1") [ "pk1"."v1", "pk1"."%TID%" NOT NULL ] COUNT 
-| ) [ "fk"."%fk_fk1_fkey" NOT NULL = "pk1"."%TID%" NOT NULL JOINIDX 
"sys"."fk"."fk_fk1_fkey" ]
+| ) [ "fk"."%fk_fk1_fkey" = "pk1"."%TID%" NOT NULL JOINIDX 
"sys"."fk"."fk_fk1_fkey" ]
 ) [ "fk"."id" NOT NULL HASHCOL , "pk1"."v1" ] [ "fk"."id" ASC NOT NULL HASHCOL 
 ]
 
 #plan select id , v2  from fk left outer join pk2 on fk.fk2 = pk2.pk2 order by 
id;
 % .plan # table_name
 % rel # name
 % clob # type
-% 124 # length
+% 115 # length
 project (
 | left outer join (
-| | table("sys"."fk") [ "fk"."id" NOT NULL HASHCOL , "fk"."%fk_fk2_fkey" NOT 
NULL JOINIDX "sys"."fk"."fk_fk2_fkey" ] COUNT ,
+| | table("sys"."fk") [ "fk"."id" NOT NULL HASHCOL , "fk"."%fk_fk2_fkey" 
JOINIDX "sys"."fk"."fk_fk2_fkey" ] COUNT ,
 | | table("sys"."pk2") [ "pk2"."v2", "pk2"."%TID%" NOT NULL ] COUNT 
-| ) [ "fk"."%fk_fk2_fkey" NOT NULL = "pk2"."%TID%" NOT NULL JOINIDX 
"sys"."fk"."fk_fk2_fkey" ]
+| ) [ "fk"."%fk_fk2_fkey" = "pk2"."%TID%" NOT NULL JOINIDX 
"sys"."fk"."fk_fk2_fkey" ]
 ) [ "fk"."id" NOT NULL HASHCOL , "pk2"."v2" ] [ "fk"."id" ASC NOT NULL HASHCOL 
 ]
 #plan select count(*) from pk1 right outer join fk on fk.fk1 = pk1.pk1;
 % .plan # table_name
@@ -91,23 +91,23 @@ project (
 % .plan # table_name
 % rel # name
 % clob # type
-% 123 # length
+% 114 # length
 project (
 | right outer join (
 | | table("sys"."pk1") [ "pk1"."v1", "pk1"."%TID%" NOT NULL ] COUNT ,
-| | table("sys"."fk") [ "fk"."id" NOT NULL HASHCOL , "fk"."%fk_fk1_fkey" NOT 
NULL JOINIDX "sys"."fk"."fk_fk1_fkey" ] COUNT 
-| ) [ "fk"."%fk_fk1_fkey" NOT NULL = "pk1"."%TID%" NOT NULL JOINIDX 
"sys"."fk"."fk_fk1_fkey" ]
+| | table("sys"."fk") [ "fk"."id" NOT NULL HASHCOL , "fk"."%fk_fk1_fkey" 
JOINIDX "sys"."fk"."fk_fk1_fkey" ] COUNT 
+| ) [ "fk"."%fk_fk1_fkey" = "pk1"."%TID%" NOT NULL JOINIDX 
"sys"."fk"."fk_fk1_fkey" ]
 ) [ "fk"."id" NOT NULL HASHCOL , "pk1"."v1" ] [ "fk"."id" ASC NOT NULL HASHCOL 
 ]
 #plan select id , v2  from pk2 right outer join fk on fk.fk2 = pk2.pk2 order 
by id;
 % .plan # table_name
 % rel # name
 % clob # type
-% 123 # length
+% 114 # length
 project (
 | right outer join (
 | | table("sys"."pk2") [ "pk2"."v2", "pk2"."%TID%" NOT NULL ] COUNT ,
-| | table("sys"."fk") [ "fk"."id" NOT NULL HASHCOL , "fk"."%fk_fk2_fkey" NOT 
NULL JOINIDX "sys"."fk"."fk_fk2_fkey" ] COUNT 
-| ) [ "fk"."%fk_fk2_fkey" NOT NULL = "pk2"."%TID%" NOT NULL JOINIDX 
"sys"."fk"."fk_fk2_fkey" ]
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to