Changeset: 560d8446f548 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/560d8446f548
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/include/sql_catalog.h
        sql/include/sql_relation.h
        sql/server/rel_basetable.c
        sql/server/rel_dump.c
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_psm.c
        sql/server/rel_rel.c
        sql/server/rel_schema.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/server/rel_updates.c
        sql/storage/sql_catalog.c
        sql/storage/store.c
        tools/monetdbe/monetdbe.c
Branch: antipush
Log Message:

Added new 'unique' flag if the expression values are unique. Next step clean 
properties and update optimizers


diffs (truncated from 1162 to 300 lines):

diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -4154,7 +4154,7 @@ sql_stack_add_inserted( mvc *sql, const 
        ti->nn = name;
        for (n = ol_first_node(t->columns); n; n = n->next) {
                sql_column *c = n->data;
-               sql_exp *ne = exp_column(sql->sa, name, c->base.name, &c->type, 
CARD_MULTI, c->null, 0);
+               sql_exp *ne = exp_column(sql->sa, name, c->base.name, &c->type, 
CARD_MULTI, c->null, is_column_unique(c), 0);
 
                append(exps, ne);
        }
@@ -5103,14 +5103,14 @@ sql_stack_add_updated(mvc *sql, const ch
                sql_column *c = n->data;
 
                if (updates[c->colnr]) {
-                       sql_exp *oe = exp_column(sql->sa, on, c->base.name, 
&c->type, CARD_MULTI, c->null, 0);
-                       sql_exp *ne = exp_column(sql->sa, nn, c->base.name, 
&c->type, CARD_MULTI, c->null, 0);
+                       sql_exp *oe = exp_column(sql->sa, on, c->base.name, 
&c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
+                       sql_exp *ne = exp_column(sql->sa, nn, c->base.name, 
&c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
 
                        append(exps, oe);
                        append(exps, ne);
                } else {
-                       sql_exp *oe = exp_column(sql->sa, on, c->base.name, 
&c->type, CARD_MULTI, c->null, 0);
-                       sql_exp *ne = exp_column(sql->sa, nn, c->base.name, 
&c->type, CARD_MULTI, c->null, 0);
+                       sql_exp *oe = exp_column(sql->sa, on, c->base.name, 
&c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
+                       sql_exp *ne = exp_column(sql->sa, nn, c->base.name, 
&c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
 
                        append(exps, oe);
                        append(exps, ne);
@@ -5377,7 +5377,7 @@ sql_stack_add_deleted(mvc *sql, const ch
        ti->nn = name;
        for (n = ol_first_node(t->columns); n; n = n->next) {
                sql_column *c = n->data;
-               sql_exp *ne = exp_column(sql->sa, name, c->base.name, &c->type, 
CARD_MULTI, c->null, 0);
+               sql_exp *ne = exp_column(sql->sa, name, c->base.name, &c->type, 
CARD_MULTI, c->null, is_column_unique(c), 0);
 
                append(exps, ne);
        }
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -797,6 +797,7 @@ typedef struct {
 } sql_emit_col;
 
 extern int nested_mergetable(sql_trans *tr, sql_table *t, const char *sname, 
const char *tname);
+extern bool is_column_unique(sql_column *c);
 sql_export sql_part *partition_find_part(sql_trans *tr, sql_table *pt, 
sql_part *pp);
 extern node *members_find_child_id(list *l, sqlid id);
 
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -56,6 +56,7 @@ typedef struct expression {
         semantics:1,   /* is vs = semantics (nil = nil vs unknown != unknown), 
ranges with or without nil, aggregation with or without nil */
         need_no_nil:1,
         has_no_nil:1,
+        unique:1,      /* expression has unique values, but it may have 
multiple NULL values! */
 
         base:1,
         ref:1,         /* used to indicate an other expression may reference 
this one */
@@ -230,7 +231,10 @@ typedef enum operator_type {
 #define set_nulls_first(e)     ((e)->nulls_last=0)
 #define set_direction(e, dir)  ((e)->ascending = (dir&1), (e)->nulls_last = 
(dir&2)?1:0)
 
-#define is_anti(e)             ((e)->anti)
+#define is_unique(e)           ((e)->unique)
+#define set_unique(e)          (e)->unique = 1
+#define set_not_unique(e)      (e)->unique = 0
+#define is_anti(e)                     ((e)->anti)
 #define set_anti(e)            (e)->anti = 1
 #define is_semantics(e)        ((e)->semantics)
 #define set_semantics(e)       (e)->semantics = 1
diff --git a/sql/server/rel_basetable.c b/sql/server/rel_basetable.c
--- a/sql/server/rel_basetable.c
+++ b/sql/server/rel_basetable.c
@@ -152,7 +152,7 @@ static sql_exp *
 bind_col_exp(mvc *sql, char *name, sql_column *c)
 {
        prop *p = NULL;
-       sql_exp *e = exp_column(sql->sa, name, c->base.name, &c->type, 
CARD_MULTI, c->null, 0);
+       sql_exp *e = exp_column(sql->sa, name, c->base.name, &c->type, 
CARD_MULTI, c->null, is_column_unique(c), 0);
 
        if (c->t->pkey && ((sql_kc*)c->t->pkey->k.columns->h->data)->c == c) {
                p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
@@ -241,14 +241,14 @@ rel_base_projection( mvc *sql, sql_rel *
                        append(exps, bind_col_exp(sql, name, cn->data));
        }
        if ((intern && rel_base_is_used(ba, i)) || list_empty(exps)) /* Add TID 
column if no column is used */
-               append(exps, exp_column(sql->sa, name, TID, 
sql_bind_localtype("oid"), CARD_MULTI, 0, 1));
+               append(exps, exp_column(sql->sa, name, TID, 
sql_bind_localtype("oid"), CARD_MULTI, 0, 1, 1));
        i++;
        if (intern) {
                for (node *in = ol_first_node(t->idxs); in; in = in->next, i++) 
{
                        if (rel_base_is_used(ba, i)) {
                                sql_idx *i = in->data;
                                sql_subtype *t = sql_bind_localtype("lng"); /* 
hash "lng" */
-                               int has_nils = 0;
+                               int has_nils = 0, unique;
 
                                if ((hash_index(i->type) && 
list_length(i->columns) <= 1) || !idx_has_column(i->type))
                                        continue;
@@ -263,7 +263,8 @@ rel_base_projection( mvc *sql, sql_rel *
                                        if (kc->c->null)
                                                has_nils = 1;
                                }
-                               sql_exp *e = exp_column(sql->sa, name, iname, 
t, CARD_MULTI, has_nils, 1);
+                               unique = list_length(i->columns) == 1 && 
is_column_unique(((sql_kc*)i->columns->h->data)->c);
+                               sql_exp *e = exp_column(sql->sa, name, iname, 
t, CARD_MULTI, has_nils, unique, 1);
                                if (hash_index(i->type)) {
                                        p = e->p = prop_create(sql->sa, 
PROP_HASHIDX, e->p);
                                        p->value = i;
@@ -315,7 +316,7 @@ rel_base_add_columns( mvc *sql, sql_rel 
 
        for (cn = ol_first_node(t->columns); cn; cn = cn->next, i++) {
                sql_column *c = cn->data;
-               sql_exp *e = exp_alias(sql->sa, atname, c->base.name, tname, 
c->base.name, &c->type, CARD_MULTI, c->null, 0);
+               sql_exp *e = exp_alias(sql->sa, atname, c->base.name, tname, 
c->base.name, &c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
 
                if (e == NULL) {
                        rel_destroy(r);
@@ -361,7 +362,7 @@ rewrite_basetable(mvc *sql, sql_rel *rel
                                continue;
 
                        sql_column *c = cn->data;
-                       sql_exp *e = exp_alias(sa, atname, c->base.name, tname, 
c->base.name, &c->type, CARD_MULTI, c->null, 0);
+                       sql_exp *e = exp_alias(sa, atname, c->base.name, tname, 
c->base.name, &c->type, CARD_MULTI, c->null, is_column_unique(c), 0);
 
                        if (e == NULL) {
                                rel_destroy(rel);
@@ -378,7 +379,7 @@ rewrite_basetable(mvc *sql, sql_rel *rel
                        append(rel->exps, e);
                }
                if (rel_base_is_used(ba, i) || list_empty(rel->exps)) /* Add 
TID column if no column is used */
-                       append(rel->exps, exp_alias(sa, atname, TID, tname, 
TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1));
+                       append(rel->exps, exp_alias(sa, atname, TID, tname, 
TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1, 1));
                i++;
 
                for (cn = ol_first_node(t->idxs); cn; cn = cn->next, i++) {
@@ -389,7 +390,7 @@ rewrite_basetable(mvc *sql, sql_rel *rel
                        sql_idx *i = cn->data;
                        sql_subtype *t;
                        char *iname = NULL;
-                       int has_nils = 0;
+                       int has_nils = 0, unique;
 
                        /* do not include empty indices in the plan */
                        if ((hash_index(i->type) && list_length(i->columns) <= 
1) || !idx_has_column(i->type))
@@ -403,7 +404,8 @@ rewrite_basetable(mvc *sql, sql_rel *rel
                                if (kc->c->null)
                                        has_nils = 1;
                        }
-                       e = exp_alias(sa, atname, iname, tname, iname, t, 
CARD_MULTI, has_nils, 1);
+                       unique = list_length(i->columns) == 1 && 
is_column_unique(((sql_kc*)i->columns->h->data)->c);
+                       e = exp_alias(sa, atname, iname, tname, iname, t, 
CARD_MULTI, has_nils, unique, 1);
                        /* index names are prefixed, to make them independent */
                        if (hash_index(i->type)) {
                                p = e->p = prop_create(sa, PROP_HASHIDX, e->p);
@@ -435,13 +437,13 @@ rel_rename_part(mvc *sql, sql_rel *p, sq
                const char *nname = exp_name(e);
 
                if (nname[0] == '%' && strcmp(nname, TID) == 0) {
-                       list_append(p->exps, exp_alias(sql->sa, mtalias, TID, 
pname, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1));
+                       list_append(p->exps, exp_alias(sql->sa, mtalias, TID, 
pname, TID, sql_bind_localtype("oid"), CARD_MULTI, 0, 1, 1));
                        rel_base_use_tid(sql, p);
                } else if (nname[0] != '%' && (cn = ol_find_name(mt->columns, 
nname))) {
                        sql_column *c = cn->data, *rc = ol_fetch(t->columns, 
c->colnr);
 
                        /* with name find column in merge table, with colnr 
find column in member */
-                       sql_exp *ne = exp_alias(sql->sa, mtalias, c->base.name, 
pname, rc->base.name, &rc->type, CARD_MULTI, rc->null, 0);
+                       sql_exp *ne = exp_alias(sql->sa, mtalias, c->base.name, 
pname, rc->base.name, &rc->type, CARD_MULTI, rc->null, is_column_unique(rc), 0);
                        if (rc->t->pkey && 
((sql_kc*)rc->t->pkey->k.columns->h->data)->c == rc) {
                                prop *p = ne->p = prop_create(sql->sa, 
PROP_HASHCOL, ne->p);
                                p->value = rc->t->pkey;
@@ -469,7 +471,7 @@ rel_rename_part(mvc *sql, sql_rel *p, sq
                        sql_subtype *t = (ri->type == join_idx) ? 
sql_bind_localtype("oid") : sql_bind_localtype("lng");
                        char *iname1 = sa_strconcat(sql->sa, "%", 
i->base.name), *iname2 = sa_strconcat(sql->sa, "%", ri->base.name);
 
-                       sql_exp *ne = exp_alias(sql->sa, mtalias, iname1, 
pname, iname2, t, CARD_MULTI, has_nil(e), 1);
+                       sql_exp *ne = exp_alias(sql->sa, mtalias, iname1, 
pname, iname2, t, CARD_MULTI, has_nil(e), is_unique(e), 1);
                        /* index names are prefixed, to make them independent */
                        if (hash_index(ri->type)) {
                                prop *p = ne->p = prop_create(sql->sa, 
PROP_HASHIDX, ne->p);
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -290,10 +290,8 @@ exp_print(mvc *sql, stream *fout, sql_ex
                mnstr_printf(fout, " NULLS LAST");
        if (e->type != e_atom && e->type != e_cmp && !has_nil(e))
                mnstr_printf(fout, " NOT NULL");
-       /*
-       if (is_basecol(e))
-               mnstr_printf(fout, " BASECOL");
-               */
+       if (e->type != e_atom && e->type != e_cmp && is_unique(e))
+               mnstr_printf(fout, " UNIQUE");
        if (e->p) {
                prop *p = e->p;
                char *pv;
@@ -1003,7 +1001,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                                if (!exp && rrel)
                                        exp = rel_bind_column2(sql, rrel, 
tname, cname, 0);
                        } else if (!exp) {
-                               exp = exp_column(sql->sa, tname, cname, NULL, 
CARD_ATOM, 1, cname[0] == '%');
+                               exp = exp_column(sql->sa, tname, cname, NULL, 
CARD_ATOM, 1, 0, cname[0] == '%');
                        }
                }
                break;
@@ -1351,6 +1349,12 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                skipWS(r, pos);
                set_has_no_nil(exp);
        }
+       /* [ UNIQUE ] */
+       if (strncmp(r+*pos, "UNIQUE",  strlen("UNIQUE")) == 0) {
+               (*pos)+= (int) strlen("UNIQUE");
+               skipWS(r, pos);
+               set_unique(exp);
+       }
 
        if (!(exp = read_exp_properties(sql, exp, r, pos)))
                return NULL;
@@ -1829,7 +1833,7 @@ rel_read(mvc *sql, char *r, int *pos, li
                                        if (r[*pos] == ',')
                                                (*pos)++;
 
-                                       next = exp_column(sql->sa, nrname, 
ncname, &a->type, CARD_MULTI, 1, 0);
+                                       next = exp_column(sql->sa, nrname, 
ncname, &a->type, CARD_MULTI, 1, 0, 0);
                                        set_basecol(next);
                                        append(outputs, next);
                                        m = m->next;
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -392,6 +392,7 @@ exp_atom(sql_allocator *sa, atom *a)
        e->l = a;
        if (!a->isnull)
                set_has_no_nil(e);
+       set_unique(e);
        return e;
 }
 
@@ -639,7 +640,7 @@ have_nil(list *exps)
 }
 
 sql_exp *
-exp_column(sql_allocator *sa, const char *rname, const char *cname, 
sql_subtype *t, unsigned int card, int has_nils, int intern)
+exp_column(sql_allocator *sa, const char *rname, const char *cname, 
sql_subtype *t, unsigned int card, int has_nils, int unique, int intern)
 {
        sql_exp *e = exp_create(sa, e_column);
 
@@ -655,6 +656,8 @@ exp_column(sql_allocator *sa, const char
                e->tpe = *t;
        if (!has_nils)
                set_has_no_nil(e);
+       if (unique)
+               set_unique(e);
        if (intern)
                set_intern(e);
        return e;
@@ -687,6 +690,8 @@ exp_propagate(sql_allocator *sa, sql_exp
                set_no_nil(ne);
        if (!has_nil(oe))
                set_has_no_nil(ne);
+       if (is_unique(oe))
+               set_unique(ne);
        if (is_basecol(oe))
                set_basecol(ne);
        ne->p = prop_copy(sa, oe->p);
@@ -698,7 +703,7 @@ exp_ref(mvc *sql, sql_exp *e)
 {
        if (!exp_name(e))
                exp_label(sql->sa, e, ++sql->label);
-       return exp_propagate(sql->sa, exp_column(sql->sa, exp_relname(e), 
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_intern(e)), e);
+       return exp_propagate(sql->sa, exp_column(sql->sa, exp_relname(e), 
exp_name(e), exp_subtype(e), exp_card(e), has_nil(e), is_unique(e), 
is_intern(e)), e);
 }
 
 sql_exp *
@@ -717,9 +722,9 @@ exp_ref_save(mvc *sql, sql_exp *e)
 }
 
 sql_exp *
-exp_alias(sql_allocator *sa, const char *arname, const char *acname, const 
char *org_rname, const char *org_cname, sql_subtype *t, unsigned int card, int 
has_nils, int intern)
+exp_alias(sql_allocator *sa, const char *arname, const char *acname, const 
char *org_rname, const char *org_cname, sql_subtype *t, unsigned int card, int 
has_nils, int unique, int intern)
 {
-       sql_exp *e = exp_column(sa, org_rname, org_cname, t, card, has_nils, 
intern);
+       sql_exp *e = exp_column(sa, org_rname, org_cname, t, card, has_nils, 
unique, intern);
 
        if (e == NULL)
                return NULL;
@@ -737,16 +742,16 @@ exp_alias_or_copy( mvc *sql, const char 
                tname = exp_relname(old);
 
        if (!cname && exp_name(old) && has_label(old)) {
-               ne = exp_column(sql->sa, exp_relname(old), exp_name(old), 
exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, 
has_nil(old), is_intern(old));
+               ne = exp_column(sql->sa, exp_relname(old), exp_name(old), 
exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, 
has_nil(old), is_unique(old), is_intern(old));
                return exp_propagate(sql->sa, ne, old);
        } else if (!cname) {
                exp_label(sql->sa, old, ++sql->label);
-               ne = exp_column(sql->sa, exp_relname(old), exp_name(old), 
exp_subtype(old), orel && old->card != CARD_ATOM?orel->card:CARD_ATOM, 
has_nil(old), is_intern(old));
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to