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