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 checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list