Changeset: 2d8900bfb52e for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=2d8900bfb52e Added Files: sql/server/rel_basetable.c sql/server/rel_basetable.h Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_statement.c sql/include/sql_catalog.h sql/rel.txt sql/server/CMakeLists.txt sql/server/rel_distribute.c sql/server/rel_dump.c sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_optimizer.c sql/server/rel_propagate.c sql/server/rel_psm.c sql/server/rel_rel.c sql/server/rel_rel.h sql/server/rel_schema.c sql/server/rel_select.c sql/server/rel_select.h sql/server/rel_unnest.c sql/server/rel_updates.c sql/server/sql_partition.c sql/test/BugTracker-2015/Tests/crash.Bug-3736.test sql/test/BugTracker-2017/Tests/caching_stats_bug.6374.test sql/test/Dependencies/Tests/dependency_DBobjects.test sql/test/Dependencies/Tests/dependency_loop.test sql/test/Tests/truncate-statements-extra.test sql/test/astro/Tests/astro.test sql/test/merge-partitions/Tests/mergepart31.test sql/test/mergetables/Tests/mergequery.test sql/test/mergetables/Tests/part-elim.test Branch: default Log Message:
base tables now keep a rel_base_t in rel->r, where we keep the used columns (using a bit vector) This reduces overhead when using large tables. moved all code related too basetables into rel_basetable.h/c. diffs (truncated from 2073 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 @@ -10,6 +10,7 @@ #include "rel_bin.h" #include "rel_rel.h" +#include "rel_basetable.h" #include "rel_exp.h" #include "rel_psm.h" #include "rel_prop.h" diff --git a/sql/backends/monet5/sql_statement.c b/sql/backends/monet5/sql_statement.c --- a/sql/backends/monet5/sql_statement.c +++ b/sql/backends/monet5/sql_statement.c @@ -1925,8 +1925,8 @@ stmt_tdiff2(backend *be, stmt *op1, stmt else q = pushNil(mb, q, TYPE_bat); /* left candidate */ q = pushNil(mb, q, TYPE_bat); /* right candidate */ - q = pushBit(mb, q, FALSE); /* nil matches */ - q = pushBit(mb, q, TRUE); /* clear nils */ + q = pushBit(mb, q, FALSE); /* nil matches */ + q = pushBit(mb, q, TRUE); /* not in */ q = pushNil(mb, q, TYPE_lng); /* estimate */ if (q) { 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 @@ -272,6 +272,7 @@ extern node *ol_rehash(objlist *ol, cons #define ol_length(ol) (list_length(ol->l)) #define ol_first_node(ol) (ol->l->h) #define ol_last_node(ol) (ol->l->t) +#define ol_fetch(ol,nr) (list_fetch(ol->l, nr)) extern void cs_new(changeset * cs, sql_allocator *sa, fdestroy destroy); extern void cs_destroy(changeset * cs, void *data); diff --git a/sql/rel.txt b/sql/rel.txt --- a/sql/rel.txt +++ b/sql/rel.txt @@ -3,6 +3,9 @@ BASETABLE (card MULTI) -> exps is list of column expressions (also used for aliases) -> l (sql_table) + -> r [ sql_column * (dict table) ] -> TODO specified through flag? + -> r rel_base_t { alias table name, disallowed (read access), bitvector of used columns/tid/idxs + -> r rel_optimizer rel_rename_part puts parent merge table in there TABLE (card MULTI) -> flags TABLE_PROD_FUNC, TABLE_FROM_RELATION, TRIGGER_WRAPPER diff --git a/sql/server/CMakeLists.txt b/sql/server/CMakeLists.txt --- a/sql/server/CMakeLists.txt +++ b/sql/server/CMakeLists.txt @@ -42,6 +42,7 @@ target_sources(sqlserver rel_prop.c rel_exp.c rel_rel.c + rel_basetable.c rel_rewriter.c rel_unnest.c rel_optimizer.c @@ -54,6 +55,7 @@ target_sources(sqlserver rel_xml.c rel_dump.c rel_dump.h rel_exp.h rel_rel.h + rel_basetable.h rel_unnest.h rel_optimizer.h rel_partition.h diff --git a/sql/server/rel_basetable.c b/sql/server/rel_basetable.c new file mode 100644 --- /dev/null +++ b/sql/server/rel_basetable.c @@ -0,0 +1,471 @@ +/* + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * Copyright 1997 - July 2008 CWI, August 2008 - 2021 MonetDB B.V. + */ + +#include "monetdb_config.h" +#include "rel_rel.h" +#include "rel_exp.h" +#include "rel_prop.h" +#include "rel_basetable.h" +#include "rel_remote.h" +#include "sql_privileges.h" + +#define USED_LEN(nr) ((nr+31)/32) +#define rel_base_set_used(b,nr) b->used[(nr)/32] |= (1<<((nr)%32)) +#define rel_base_is_used(b,nr) ((b->used[(nr)/32]&(1<<((nr)%32))) != 0) + +typedef struct rel_base_t { + sql_table *mt; + char *name; + int disallowed; /* ie check per column */ + int used[FLEXIBLE_ARRAY_MEMBER]; +} rel_base_t; + +void +rel_base_disallow(sql_rel *r) +{ + rel_base_t *ba = r->r; + ba->disallowed = 1; +} + +char * +rel_base_name(sql_rel *r) +{ + sql_table *t = r->l; + rel_base_t *ba = r->r; + if (ba->name) + return ba->name; + return t->base.name; +} + +char * +rel_base_rename(sql_rel *r, char *name) +{ + rel_base_t *ba = r->r; + ba->name = name; + return name; +} + +int +rel_base_use( mvc *sql, sql_rel *rt, int nr) +{ + assert(is_basetable(rt->op)); + sql_table *t = rt->l; + rel_base_t *ba = rt->r; + + if (ba->disallowed && nr < ol_length(t->columns)) { + sql_column *c = ol_fetch(t->columns, nr); + if (!column_privs(sql, c, PRIV_SELECT)) + return -1; + } + rel_base_set_used(ba, nr); + return 0; +} + +void +rel_base_use_tid( mvc *sql, sql_rel *rt) +{ + sql_table *t = rt->l; + rel_base_use(sql, rt, ol_length(t->columns)); +} + +void +rel_base_use_all( mvc *sql, sql_rel *rel) +{ + sql_table *t = rel->l; + rel_base_t *ba = rel->r; + + if (ba->disallowed) { + int i = 0; + for (node *cn = ol_first_node(t->columns); cn; cn = cn->next, i++) { + sql_column *c = cn->data; + if (!column_privs(sql, c, PRIV_SELECT)) + continue; + rel_base_set_used(ba, i); + } + } else { + int len = USED_LEN(ol_length(t->columns) + 1 + ol_length(t->idxs)); + for (int i = 0; i < len; i++) + ba->used[i] = ~0; + } +} + +sql_rel * +rel_basetable(mvc *sql, sql_table *t, const char *atname) +{ + sql_allocator *sa = sql->sa; + sql_rel *rel = rel_create(sa); + int nrcols = ol_length(t->columns), end = nrcols + 1 + ol_length(t->idxs); + rel_base_t *ba = (rel_base_t*)sa_zalloc(sa, sizeof(rel_base_t) + sizeof(int)*USED_LEN(end)); + + if(!rel || !ba) + return NULL; + + assert(atname); + if (strcmp(atname, t->base.name) != 0) + ba->name = sa_strdup(sa, atname); + for(int i = nrcols; i<end; i++) + rel_base_set_used(ba, i); + rel->l = t; + rel->r = ba; + rel->op = op_basetable; + rel->card = CARD_MULTI; + rel->nrcols = nrcols; + return rel; +} + +sql_rel * +rel_base_bind_column_( sql_rel *rel, const char *cname, int *exp_has_nil) +{ + sql_table *t = rel->l; + node *n = ol_find_name(t->columns, cname); + if (n && exp_has_nil) { + sql_column *c = n->data; + *exp_has_nil = c->null; + } + if (n) + return rel; + return NULL; +} + +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); + + 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) { + p = e->p = prop_create(sql->sa, PROP_HASHCOL, e->p); + p->value = NULL; + } + set_basecol(e); + return e; +} + +static sql_exp * +bind_col(mvc *sql, sql_rel *rel, char *name, sql_column *c ) +{ + if (rel_base_use(sql, rel, c->colnr)) { + /* error */ + return NULL; + } + return bind_col_exp(sql, name, c); +} + +sql_exp * +rel_base_bind_colnr( mvc *sql, sql_rel *rel, int nr) +{ + sql_table *t = rel->l; + rel_base_t *ba = rel->r; + return bind_col(sql, rel, ba->name?ba->name:t->base.name, ol_fetch(t->columns, nr)); +} + +sql_exp * +rel_base_bind_column( mvc *sql, sql_rel *rel, const char *cname, int no_tname) +{ + sql_table *t = rel->l; + rel_base_t *ba = rel->r; + (void)no_tname; + node *n = ol_find_name(t->columns, cname); + if (!n) + return NULL; + return bind_col(sql, rel, ba->name?ba->name:t->base.name, n->data); +} + +sql_rel * +rel_base_bind_column2_( sql_rel *rel, const char *tname, const char *cname) +{ + sql_table *t = rel->l; + rel_base_t *ba = rel->r; + + assert(ba); + if ((ba->name && strcmp(ba->name, tname) != 0) || (!ba->name && strcmp(t->base.name, tname) != 0)) + return NULL; + node *n = ol_find_name(t->columns, cname); + if (!n) + return NULL; + return rel; +} + +sql_exp * +rel_base_bind_column2( mvc *sql, sql_rel *rel, const char *tname, const char *cname) +{ + sql_table *t = rel->l; + rel_base_t *ba = rel->r; + + assert(ba); + if ((ba->name && strcmp(ba->name, tname) != 0) || (!ba->name && strcmp(t->base.name, tname) != 0)) + return NULL; + node *n = ol_find_name(t->columns, cname); + if (!n) + return NULL; + sql_column *c = n->data; + return bind_col(sql, rel, ba->name?ba->name:t->base.name, c); +} + +list * +rel_base_projection( mvc *sql, sql_rel *rel, int intern) +{ + int i = 0; + sql_table *t = rel->l; + rel_base_t *ba = rel->r; + char *name = ba->name?ba->name:t->base.name; + list *exps = new_exp_list(sql->sa); + prop *p; + + for (node *cn = ol_first_node(t->columns); cn; cn = cn->next, i++) { + if (rel_base_is_used(ba, i)) + append(exps, bind_col_exp(sql, name, cn->data)); + } + if (intern && rel_base_is_used(ba, i)) _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list