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