Changeset: ca83a16d80a1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=ca83a16d80a1
Modified Files:
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql.c
sql/backends/monet5/sql_cat.c
sql/backends/monet5/sql_execute.c
sql/backends/monet5/sql_gencode.c
sql/backends/monet5/sql_statement.c
sql/backends/monet5/sql_upgrades.c
sql/server/rel_exp.c
sql/server/rel_optimizer.c
sql/server/rel_optimizer.h
sql/server/rel_rel.c
sql/server/rel_rel.h
sql/server/sql_mvc.c
sql/server/sql_mvc.h
sql/server/sql_partition.c
Branch: Oct2020
Log Message:
Introducing storage based optimization for the cases when storage data can be
used for optimization.
This had to committed on Oct2020 because this optimization as well valued based
one were allowed on prepared statements, which we can't.
diffs (truncated from 427 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
@@ -3572,11 +3572,11 @@ rel2bin_sample(backend *be, sql_rel *rel
static stmt *
sql_parse(backend *be, const char *query, char mode)
{
- sql_rel *r = rel_parse(be->mvc, be->mvc->session->schema, (char*)query,
mode);
+ sql_rel *rel = rel_parse(be->mvc, be->mvc->session->schema,
(char*)query, mode);
stmt *sq = NULL;
- if (r && (r = rel_unnest(be->mvc ,r)) != NULL && (r =
rel_optimizer(be->mvc , r, 1)) != NULL)
- sq = rel_bin(be, r);
+ if ((rel = sql_processrelation(be->mvc, rel, 1, 1)))
+ sq = rel_bin(be, rel);
return sq;
}
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -115,11 +115,12 @@ sql_symbol2relation(backend *be, symbol
sql_rel *rel;
sql_query *query = query_create(be->mvc);
lng Tbegin;
+ int extra_opts = be->mvc->emode != m_prepare;
rel = rel_semantic(query, sym);
Tbegin = GDKusec();
if (rel)
- rel = sql_processrelation(be->mvc, rel, 1);
+ rel = sql_processrelation(be->mvc, rel, extra_opts, extra_opts);
if (rel)
rel = rel_distribute(be->mvc, rel);
if (rel)
@@ -409,7 +410,7 @@ create_table_or_view(mvc *sql, char* sna
r = rel_parse(sql, s, nt->query, m_deps);
if (r)
- r = sql_processrelation(sql, r, 0);
+ r = sql_processrelation(sql, r, 0, 0);
if (r) {
list *id_l = rel_dependencies(sql, r);
mvc_create_dependencies(sql, id_l, nt->base.id,
VIEW_DEPENDENCY);
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
@@ -479,7 +479,7 @@ create_trigger(mvc *sql, char *sname, ch
throw(SQL, "sql.catalog",SQLSTATE(HY013)
MAL_MALLOC_FAIL);
r = rel_parse(sql, s, buf, m_deps);
if (r)
- r = sql_processrelation(sql, r, 0);
+ r = sql_processrelation(sql, r, 0, 0);
if (r) {
list *id_l = rel_dependencies(sql, r);
mvc_create_dependencies(sql, id_l, tri->base.id,
TRIGGER_DEPENDENCY);
@@ -812,7 +812,7 @@ create_func(mvc *sql, char *sname, char
throw(SQL, "sql.create_func", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
r = rel_parse(sql, s, buf, m_deps);
if (r)
- r = sql_processrelation(sql, r, 0);
+ r = sql_processrelation(sql, r, 0, 0);
if (r) {
node *n;
list *id_l = rel_dependencies(sql, r);
diff --git a/sql/backends/monet5/sql_execute.c
b/sql/backends/monet5/sql_execute.c
--- a/sql/backends/monet5/sql_execute.c
+++ b/sql/backends/monet5/sql_execute.c
@@ -701,7 +701,7 @@ RAstatement(Client c, MalBlkPtr mb, MalS
int oldstop = c->curprg->def->stop;
if (*opt && rel)
- rel = sql_processrelation(m, rel, 0);
+ rel = sql_processrelation(m, rel, 1, 1);
if ((msg = MSinitClientPrg(c, "user", "test")) != MAL_SUCCEED) {
rel_destroy(rel);
@@ -832,7 +832,7 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
rel = rel_read(m, expr, &pos, refs);
stack_pop_frame(m);
if (rel)
- rel = sql_processrelation(m, rel, 1);
+ rel = sql_processrelation(m, rel, 1, 1);
if (!rel) {
if (strlen(m->errstr) > 6 && m->errstr[5] == '!')
msg = createException(SQL, "RAstatement2", "%s",
m->errstr);
diff --git a/sql/backends/monet5/sql_gencode.c
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -1143,7 +1143,7 @@ backend_create_sql_func(backend *be, sql
f->sql++;
r = rel_parse(m, f->s, f->query, m_instantiate);
if (r)
- r = sql_processrelation(m, r, 1);
+ r = sql_processrelation(m, r, 1, 0);
if (r)
r = rel_distribute(m, r);
if (r)
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
@@ -3406,7 +3406,7 @@ stmt_func(backend *be, stmt *ops, const
p = find_prop(rel->p, PROP_REMOTE);
if (p)
rel->p = prop_remove(rel->p, p);
- rel = sql_processrelation(be->mvc, rel, 0);
+ rel = sql_processrelation(be->mvc, rel, 1, 1);
if (p) {
p->p = rel->p;
rel->p = p;
diff --git a/sql/backends/monet5/sql_upgrades.c
b/sql/backends/monet5/sql_upgrades.c
--- a/sql/backends/monet5/sql_upgrades.c
+++ b/sql/backends/monet5/sql_upgrades.c
@@ -1059,7 +1059,7 @@ sql_update_nov2019_missing_dependencies(
r = rel_parse(sql, s, relt, m_deps);
if (r)
- r = sql_processrelation(sql, r,
0);
+ r = sql_processrelation(sql, r,
0, 0);
if (r) {
list *id_l =
rel_dependencies(sql, r);
@@ -1093,7 +1093,7 @@ sql_update_nov2019_missing_dependencies(
r = rel_parse(sql, s, relt, m_deps);
if (r)
- r = sql_processrelation(sql, r,
0);
+ r = sql_processrelation(sql, r,
0, 0);
if (r) {
list *id_l =
rel_dependencies(sql, r);
@@ -1121,7 +1121,7 @@ sql_update_nov2019_missing_dependencies(
r = rel_parse(sql, s, relt,
m_deps);
if (r)
- r =
sql_processrelation(sql, r, 0);
+ r =
sql_processrelation(sql, r, 0, 0);
if (r) {
list *id_l =
rel_dependencies(sql, r);
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
@@ -857,10 +857,6 @@ exp_rel(mvc *sql, sql_rel *rel)
if (e == NULL)
return NULL;
- /*
- rel = sql_processrelation(sql, rel, 0);
- rel = rel_distribute(sql, rel);
- */
e->l = rel;
e->flag = PSM_REL;
e->card = rel->single?CARD_ATOM:rel->card;
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -1171,7 +1171,7 @@ reorder_join(visitor *v, sql_rel *rel)
static sql_rel *
rel_join_order(visitor *v, sql_rel *rel)
{
- visitor ev = { .sql = v->sql };
+ visitor ev = { .sql = v->sql, .value_based_opt = v->value_based_opt,
.storage_based_opt = v->storage_based_opt };
if (!rel)
return rel;
@@ -1507,7 +1507,7 @@ rel_push_func_down(visitor *v, sql_rel *
return rel;
if (exps_can_push_func(exps, rel) && exps_need_push_down(exps))
{
sql_rel *nrel, *ol = l, *or = r;
- visitor nv = { .sql = v->sql, .parent = v->parent };
+ visitor nv = { .sql = v->sql, .parent = v->parent,
.value_based_opt = v->value_based_opt, .storage_based_opt =
v->storage_based_opt };
/* we need a full projection, group by's and unions
cannot be extended
* with more expressions */
@@ -5647,7 +5647,7 @@ rel_push_project_down_union(visitor *v,
}
static int
-sql_class_base_score(mvc *sql, sql_column *c, sql_subtype *t, bool
equality_based)
+sql_class_base_score(visitor *v, sql_column *c, sql_subtype *t, bool
equality_based)
{
int de;
@@ -5672,7 +5672,7 @@ sql_class_base_score(mvc *sql, sql_colum
case TYPE_dbl:
return 75 - 53;
default: {
- if (equality_based && c && (de =
mvc_is_duplicate_eliminated(sql, c)))
+ if (equality_based && c && v->storage_based_opt && (de
= mvc_is_duplicate_eliminated(v->sql, c)))
return 150 - de * 8;
/* strings and blobs not duplicate eliminated don't get
any points here */
return 0;
@@ -5682,7 +5682,7 @@ sql_class_base_score(mvc *sql, sql_colum
/* Compute the efficiency of using this expression earl y in a group by
list */
static int
-score_gbe(mvc *sql, sql_rel *rel, sql_exp *e)
+score_gbe(visitor *v, sql_rel *rel, sql_exp *e)
{
int res = 0;
sql_subtype *t = exp_subtype(e);
@@ -5691,9 +5691,9 @@ score_gbe(mvc *sql, sql_rel *rel, sql_ex
if (e->card == CARD_ATOM) /* constants are trivial to group */
res += 1000;
/* can we find out if the underlying table is sorted */
- if (find_prop(e->p, PROP_HASHCOL) || (c && mvc_is_unique(sql, c))) /*
distinct columns */
+ if (find_prop(e->p, PROP_HASHCOL) || (c && v->storage_based_opt &&
mvc_is_unique(v->sql, c))) /* distinct columns */
res += 700;
- if (c && mvc_is_sorted(sql, c))
+ if (c && v->storage_based_opt && mvc_is_sorted(v->sql, c))
res += 500;
if (find_prop(e->p, PROP_SORTIDX)) /* has sort index */
res += 300;
@@ -5701,7 +5701,7 @@ score_gbe(mvc *sql, sql_rel *rel, sql_ex
res += 200;
/* prefer the shorter var types over the longer ones */
- res += sql_class_base_score(sql, c, t, true); /* smaller the type,
better */
+ res += sql_class_base_score(v, c, t, true); /* smaller the type, better
*/
return res;
}
@@ -5722,7 +5722,7 @@ rel_groupby_order(visitor *v, sql_rel *r
/* first sorting step, give priority for integers and sorted
columns */
for (i = 0, n = gbe->h; n; i++, n = n->next) {
exps[i] = n->data;
- scores[i] = score_gbe(v->sql, rel, exps[i]);
+ scores[i] = score_gbe(v, rel, exps[i]);
}
GDKqsort(scores, exps, NULL, ngbe, sizeof(int), sizeof(void *),
TYPE_int, true, true);
@@ -7447,25 +7447,25 @@ rel_use_index(visitor *v, sql_rel *rel)
}
static int
-score_se_base(mvc *sql, sql_rel *rel, sql_exp *e)
+score_se_base(visitor *v, sql_rel *rel, sql_exp *e)
{
int res = 0;
sql_subtype *t = exp_subtype(e);
sql_column *c = NULL;
/* can we find out if the underlying table is sorted */
- if ((c = exp_find_column(rel, e, -2)) && mvc_is_sorted(sql, c))
+ if ((c = exp_find_column(rel, e, -2)) && v->storage_based_opt &&
mvc_is_sorted(v->sql, c))
res += 600;
if (find_prop(e->p, PROP_SORTIDX)) /* has sort index */
res += 400;
/* prefer the shorter var types over the longer ones */
- res += sql_class_base_score(sql, c, t,
is_equality_or_inequality_exp(e->flag)); /* smaller the type, better */
+ res += sql_class_base_score(v, c, t,
is_equality_or_inequality_exp(e->flag)); /* smaller the type, better */
return res;
}
static int
-score_se(mvc *sql, sql_rel *rel, sql_exp *e)
+score_se(visitor *v, sql_rel *rel, sql_exp *e)
{
int score = 0;
if (e->type == e_cmp && !is_complex_exp(e->flag)) {
@@ -7482,7 +7482,7 @@ score_se(mvc *sql, sql_rel *rel, sql_exp
break;
l = ll;
}
- score += score_se_base(sql, rel, l);
+ score += score_se_base(v, rel, l);
}
score += exp_keyvalue(e);
return score;
@@ -7502,7 +7502,7 @@ rel_select_order(visitor *v, sql_rel *re
for (i = 0, n = rel->exps->h; n; i++, n = n->next) {
exps[i] = n->data;
- scores[i] = score_se(v->sql, rel, n->data);
+ scores[i] = score_se(v, rel, n->data);
}
GDKqsort(scores, exps, NULL, nexps, sizeof(int), sizeof(void
*), TYPE_int, true, true);
@@ -8949,8 +8949,8 @@ rel_merge_table_rewrite(visitor *v, sql_
int skip = 0;
list *exps = NULL;
- /* do not include empty
partitions */
- if (pt && isTable(pt) &&
pt->access == TABLE_READONLY && !store_funcs.count_col(v->sql->session->tr,
pt->columns.set->h->data, 1))
+ /* do not include empty
partitions. Don't skip when storage_based_opt is not applicable */
+ if (v->storage_based_opt && pt
&& isTable(pt) && pt->access == TABLE_READONLY &&
!store_funcs.count_col(v->sql->session->tr, pt->columns.set->h->data, 1))
continue;
prel = rel_rename_part(v->sql,
prel, tname, t);
@@ -9250,7 +9250,7 @@ rel_merge_table_rewrite(visitor *v, sql_
}
rel_destroy(rel);
if (sel) {
- visitor iv = { .sql = v->sql };
+ visitor iv = { .sql = v->sql,
.value_based_opt = v->value_based_opt, .storage_based_opt =
v->storage_based_opt };
sel->l = nrel;
sel = rel_visitor_topdown(&iv, sel,
&rel_push_select_down_union);
if (iv.changes)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list