Changeset: deffc1d23c48 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/deffc1d23c48
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/rel_physical.c
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_updates.c
Branch: nested
Log Message:

initial steps to move vss rewrites into rel_physical.


diffs (268 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
@@ -5142,23 +5142,12 @@ sub_topn(backend *be, stmt *sub, stmt **
        return sub;
 }
 
-/* BOND k-NN: detect ORDER BY l2sq_distance(vector_col, vector_literal) LIMIT 
k */
+/* vss k-NN */
 static stmt*
-insert_bond(backend *be, sql_rel *rel, stmt *sub, stmt *l)
+vss_topn(backend *be, /*sql_rel *rel,*/ stmt *sub, stmt *l, sql_exp *dist_exp)
 {
        mvc *sql = be->mvc;
        int oldvtop = be->mb->vtop, oldstop = be->mb->stop;
-       list *el = rel_find_exps_by_type(sa_list(sql->sa), rel, e_func);
-       /* Find the vss distance function */
-       sql_exp *dist_exp = NULL;
-       for (node *n = el->h; n; n = n->next) {
-               sql_exp *e = n->data;
-               sql_subfunc *f = e->f;
-               if (strcmp(sql_func_mod(f->func), "vss") == 0) {
-                       dist_exp = e;
-                       break;
-               }
-       }
        if (dist_exp) {
                list *fexps = dist_exp->l;
                sql_exp *le = fexps->h->data;
@@ -5172,12 +5161,11 @@ insert_bond(backend *be, sql_rel *rel, s
                        /* Compile both vector expressions */
                        stmt *ls = exp_bin(be, le, sub, NULL/*psub*/, NULL, 
NULL, NULL, NULL, 0, 0, 0);
                        stmt *rs = exp_bin(be, re, sub, NULL/*psub*/, NULL, 
NULL, NULL, NULL, 0, 0, 0);
-                       //stmt *ls = bin_find_column_nid_deep(be, sub, le->nid);
-                       //stmt *rs = bin_find_column_nid_deep(be, sub, re->nid);
+
                        while (ls && ls->type == st_alias) ls = ls->op1;
                        while (rs && rs->type == st_alias) rs = rs->op1;
-                       if (ls && rs && ls->type == st_list && ls->nested &&
-                               rs->type == st_list && rs->nested) {
+
+                       if (ls && rs && ls->type == st_list && ls->nested && 
rs->type == st_list && rs->nested) {
                                list *col_dims = (le->type == e_column) ? 
ls->op4.lval : rs->op4.lval;
                                list *lit_dims = (le->type == e_column) ? 
rs->op4.lval : ls->op4.lval;
                                //sql_exp *lit_exp = (le->type == e_column) ? 
re : le;
@@ -5290,9 +5278,9 @@ rel2bin_project(backend *be, sql_rel *re
                        return NULL;
        }
 
-//     /* BOND k-NN: detect ORDER BY l2sq_distance(vector_col, vector_literal) 
LIMIT k */
-       if (topn && rel->r && list_length(rel->r) == 1 && !need_distinct(rel))
-               sub = insert_bond(be, rel, sub, l);
+       /* vss k-NN */
+       if (topn && topn->r)
+               sub = vss_topn(be, sub, l, topn->r);
 
        if (rel->spb && rel->card <= CARD_ATOM && !rel->l && be->pp) { /* 
adding constants to a stream (union) */
                int source = pp_counter(be, 1, -1, false);
diff --git a/sql/backends/monet5/rel_physical.c 
b/sql/backends/monet5/rel_physical.c
--- a/sql/backends/monet5/rel_physical.c
+++ b/sql/backends/monet5/rel_physical.c
@@ -707,7 +707,7 @@ rel_hash(sql_rel *r)
                        /* hash projection list exps */
                        if (r->l)
                                h *= rel_hash(r->l);
-                       return h * exps_hash(r->exps) * (r->r ? exps_hash(r->r) 
: 1);
+                       return h * exps_hash(r->exps) * (r->op == op_project && 
r->r ? exps_hash(r->r) : 1);
                case op_groupby:
                        /* hash gbe, aggr exps */
                        h *= rel_hash(r->l);
@@ -1596,6 +1596,38 @@ rel_push_down_topn(visitor *v, sql_rel *
 }
 
 static sql_rel *
+rel_rewrite_vss(visitor *v, sql_rel *rel)
+{
+       (void)v;
+       if (!rel)
+               return rel;
+       if (rel->op == op_topn) { /* check offset/limit (only on limited ranges 
else full compute) ? */
+               sql_rel *l = rel->l;
+               if (l && is_simple_project(l->op) && list_length(l->r) == 1 /* 
only limit on the distances */ && !need_distinct(rel)) {
+                       list *obes = l->r;
+                       sql_exp *dist_exp = NULL;
+                       for (node *n = obes->h; n; n = n->next) {
+                               sql_exp *e = n->data;
+                               if (e->type == e_column)
+                                       e = rel_find_exp(rel, e);
+                               if (e && e->type == e_func) {
+                                       sql_subfunc *f = e->f;
+                                       if (strcmp(sql_func_mod(f->func), 
"vss") == 0) {
+                                               dist_exp = e;
+                                               break;
+                                       }
+                               }
+                       }
+                       if (dist_exp) { /* Todo check for vss.topn_%s with 
right function args and result type */
+                               assert(!rel->r);
+                               rel->r = dist_exp;
+                       }
+               }
+       }
+       return rel;
+}
+
+static sql_rel *
 rel_add_project(visitor *v, sql_rel *rel)
 {
        sql_rel *p = v->parent;
@@ -1629,6 +1661,8 @@ rel_rewrite_physical(visitor *v, sql_rel
                rel = rel_simplify_project(v, rel);
        if (rel)
                rel = rel_push_down_topn(v, rel);
+       if (rel)
+               rel = rel_rewrite_vss(v, rel);
        if (rel) { /* split equi-join/select */
                if (SQLrunning && MT_thread_get_qry_ctx()->pipeline_mode) {
                        rel = rel_count_gt_zero(v, rel);
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
@@ -4832,7 +4832,7 @@ exps_has_group_filter(list *exps)
        return false;
 }
 
-inline list *
+list *
 filter_exps_by_localtype(list *res, list *exps, int8_t localtype)
 {
        for (node *n = exps->h; n; n=n->next) {
@@ -4843,113 +4843,3 @@ filter_exps_by_localtype(list *res, list
        }
        return res;
 }
-
-inline list *
-filter_exps_by_type(list *res, list *exps, expression_type type)
-{
-       for (node *n = exps->h; n; n=n->next) {
-               sql_exp *e = n->data;
-               if (e->type == type)
-                       list_append(res, e);
-       }
-       return res;
-}
-
-inline list *
-rel_find_exps_by_type(list *res, sql_rel *rel, expression_type tpe)
-{
-       if (rel) {
-               switch(rel->op) {
-                       case op_project:
-                       case op_groupby:
-                               if (rel->l)
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               /* PROJECT: rel->r is order by, GROUPBY: rel->r 
is group by exps */
-                               if (rel->r)
-                                       res = filter_exps_by_type(res, rel->r, 
tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_join:
-                       case op_left:
-                       case op_right:
-                       case op_full:
-                       case op_semi:
-                       case op_anti:
-                               if (rel->l)
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               if (rel->r)
-                                       res = rel_find_exps_by_type(res, 
rel->r, tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_except:
-                       case op_inter:
-                               if (rel->l)
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               if (rel->r)
-                                       res = rel_find_exps_by_type(res, 
rel->r, tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_munion:
-                               if (rel->l) { /* l is a list of relations */
-                                       for (node *n = ((list*)rel->l)->h; n; n 
= n->next)
-                                               res = 
rel_find_exps_by_type(res, n->data, tpe);
-                               }
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_select:
-                               if (rel->l)
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_topn:
-                       case op_sample:
-                               if (rel->l)
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_insert:
-                       case op_update:
-                       case op_delete:
-                       case op_truncate:
-                               if (rel->l)
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               if (rel->r)
-                                       res = rel_find_exps_by_type(res, 
rel->r, tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_basetable:
-                       case op_table:
-                               /* Leaf nodes or function calls */
-                               if (rel->l && rel->op == op_table) /* op_table 
can have input relation */
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       case op_ddl:
-                               if (rel->l)
-                                       res = rel_find_exps_by_type(res, 
rel->l, tpe);
-                               if (rel->exps)
-                                       res = filter_exps_by_type(res, 
rel->exps, tpe);
-                               break;
-
-                       default:
-                               break;
-               }
-       }
-       return res;
-}
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -264,8 +264,6 @@ extern sql_exp* topn_limit(sql_rel *rel)
 
 extern int exp_is_rename(sql_exp *e);
 extern int exp_is_useless_rename(sql_exp *e);
-extern list *filter_exps_by_type(list *res, list *exps, expression_type type);
 extern list *filter_exps_by_localtype(list *res, list *exps, int8_t localtype);
-extern list *rel_find_exps_by_type(list *res, sql_rel *rel, expression_type 
type);
 
 #endif /* _REL_EXP_H_ */
diff --git a/sql/server/rel_updates.c b/sql/server/rel_updates.c
--- a/sql/server/rel_updates.c
+++ b/sql/server/rel_updates.c
@@ -1410,7 +1410,7 @@ delete_table(sql_query *query, dlist *qn
                        if (!(r = rel_logical_exp(query, r, opt_where, 
sql_where)))
                                return NULL;
                        e = exp_column(sql->sa, rel_name(r), TID, 
sql_fetch_localtype(TYPE_oid), CARD_MULTI, 0, 1, 1);
-                       if (t->multiset || t->composite || t->vector) {
+                       if (t->multiset || t->composite || t->vector) { /* ???? 
*/
                                sql_exp *te = 
list_fetch(filter_exps_by_localtype(sa_list(sql->sa), ((sql_rel*)r->l)->exps, 
TYPE_oid), 0);
                                e->nid = te? te->nid : rel_base_nid(bt, NULL);
                        } else {
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to