Changeset: 645703fa8a3b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/645703fa8a3b
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/include/sql_catalog.h
        sql/storage/sql_storage.h
Branch: dict
Log Message:

merged with default


diffs (truncated from 3903 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
@@ -4139,7 +4139,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);
        }
@@ -5088,14 +5088,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);
@@ -5362,7 +5362,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/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -1163,7 +1163,7 @@ alter_table(Client cntxt, mvc *sql, char
                                        sql_kc *kc = m->data;
 
                                        if (kc->c->base.id == c->base.id)
-                                               throw(SQL,"sql.alter_table", 
SQLSTATE(40000) "NOT NULL CONSTRAINT: cannot change NOT NULL CONSTRAINT for 
column '%s' as its part of the PRIMARY KEY\n", c->base.name);
+                                               throw(SQL,"sql.alter_table", 
SQLSTATE(40000) "NOT NULL CONSTRAINT: cannot remove NOT NULL CONSTRAINT for 
column '%s' part of the PRIMARY KEY\n", c->base.name);
                                }
                        }
                        switch (mvc_null(sql, nc, c->null)) {
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
@@ -614,7 +614,7 @@ typedef struct sql_column {
        int colnr;
        bit null;
        char *def;
-       char unique;            /* NOT UNIQUE, UNIQUE, SUB_UNIQUE */
+       char unique;            /* 0 NOT UNIQUE, 1 SUB_UNIQUE, 2 UNIQUE */
        int drop_action;        /* only used for alter statements */
        char *storage_type;
        int sorted;             /* for DECLARED (dupped tables) we keep order 
info */
@@ -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,12 +152,12 @@ 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);
                p->value = c->t->pkey;
-       } else if (c->unique == 1) {
+       } else if (c->unique == 2) {
                p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
                p->value = NULL;
        }
@@ -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);
@@ -324,7 +325,7 @@ rel_base_add_columns( mvc *sql, sql_rel 
                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);
                        p->value = c->t->pkey;
-               } else if (c->unique == 1) {
+               } else if (c->unique == 2) {
                        p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p);
                        p->value = NULL;
                }
@@ -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);
@@ -370,7 +371,7 @@ rewrite_basetable(mvc *sql, sql_rel *rel
                        if (c->t->pkey && 
((sql_kc*)c->t->pkey->k.columns->h->data)->c == c) {
                                p = e->p = prop_create(sa, PROP_HASHCOL, e->p);
                                p->value = c->t->pkey;
-                       } else if (c->unique == 1) {
+                       } else if (c->unique == 2) {
                                p = e->p = prop_create(sa, PROP_HASHCOL, e->p);
                                p->value = NULL;
                        }
@@ -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,17 +437,17 @@ 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;
-                       } else if (rc->unique == 1) {
+                       } else if (rc->unique == 2) {
                                prop *p = ne->p = prop_create(sql->sa, 
PROP_HASHCOL, ne->p);
                                p->value = NULL;
                        }
@@ -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
@@ -320,6 +320,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 (e->type != e_atom && e->type != e_cmp && is_unique(e))
+               mnstr_printf(fout, " UNIQUE");
        if (e->p) {
                prop *p = e->p;
                char *pv;
@@ -1032,7 +1034,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;
@@ -1531,6 +1533,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;
@@ -1881,7 +1889,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
@@ -357,6 +357,7 @@ exp_rank_op( sql_allocator *sa, list *l,
        e->l = l;
        e->r = append(append(sa_list(sa), gbe), obe);
        e->f = f;
+       e->semantics = f->func->semantics;
        return e;
 }
 
@@ -369,6 +370,7 @@ exp_aggr( sql_allocator *sa, list *l, sq
        e->card = card;
        e->l = l;
        e->f = a;
+       e->semantics = a->func->semantics;
        if (distinct)
                set_distinct(e);
        if (no_nils)
@@ -635,8 +637,21 @@ have_nil(list *exps)
        return has_nil;
 }
 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to