Changeset: f2a5e72ab618 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f2a5e72ab618
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
Branch: linear-hashing
Log Message:

use algebra.semijoin in case of single column relational semijoin


diffs (186 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
@@ -2227,6 +2227,7 @@ rel2bin_semijoin(backend *be, sql_rel *r
        list *l; 
        node *en = NULL, *n;
        stmt *left = NULL, *right = NULL, *join = NULL, *jl, *jr, *c;
+       int semi_used = 0;
 
        if (rel->op == op_anti && !list_empty(rel->exps) && 
list_length(rel->exps) == 1 && ((sql_exp*)rel->exps->h->data)->flag == 
mark_notin)
                return rel2bin_antijoin(be, rel, refs);
@@ -2244,7 +2245,37 @@ rel2bin_semijoin(backend *be, sql_rel *r
         *      first cheap join(s) (equality or idx) 
         *      second selects/filters 
         */
-       if (rel->exps) {
+       if (rel->op != op_anti && rel->exps && list_length(rel->exps) == 1) {
+               sql_exp *e = rel->exps->h->data;
+
+               if (e->type == e_cmp && (e->flag == cmp_equal || e->flag == 
mark_in) && !e->anti && !e->f) {
+                       stmt *r, *l = exp_bin(be, e->l, left, NULL, NULL, NULL, 
NULL, NULL);
+                       int swap = 0;
+
+                       if (!l) {
+                               swap = 1;
+                               l = exp_bin(be, e->l, right, NULL, NULL, NULL, 
NULL, NULL);
+                       }
+                       r = exp_bin(be, e->r, left, right, NULL, NULL, NULL, 
NULL);
+
+                       if (swap) {
+                               stmt *t = l;
+                               l = r;
+                               r = t;
+                       }
+
+                       if (!l || !r)
+                               return NULL;
+                       join = stmt_semijoin(be, l, r); 
+                       if (join)
+                               join = stmt_result(be, join, 0);
+                       if (!join)
+                               return NULL;
+                       semi_used = 1;
+               }
+       }
+               
+       if (!semi_used && rel->exps) {
                int idx = 0;
                list *jexps = sa_list(sql->sa);
                list *lje = sa_list(sql->sa);
@@ -2318,13 +2349,14 @@ rel2bin_semijoin(backend *be, sql_rel *r
                        stmt *r = bin_first_column(be, right);
                        join = stmt_join(be, l, r, 0, cmp_all); 
                }
-       } else {
+       } else if (!semi_used) {
                stmt *l = bin_first_column(be, left);
                stmt *r = bin_first_column(be, right);
                join = stmt_join(be, l, r, 0, cmp_all); 
        }
-       jl = stmt_result(be, join, 0);
-       if (en) {
+       if (!semi_used)
+               jl = stmt_result(be, join, 0);
+       if (!semi_used && en) {
                stmt *sub, *sel = NULL;
                list *nl;
 
@@ -2374,13 +2406,15 @@ rel2bin_semijoin(backend *be, sql_rel *r
        /* construct relation */
        l = sa_list(sql->sa);
 
-       /* We did a full join, thats too much. 
-          Reduce this using difference and intersect */
-       c = stmt_mirror(be, left->op4.lval->h->data);
-       if (rel->op == op_anti) {
-               join = stmt_tdiff(be, c, jl);
-       } else {
-               join = stmt_tinter(be, c, jl);
+       if (!semi_used) {
+               /* We did a full join, thats too much. 
+               Reduce this using difference and intersect */
+               c = stmt_mirror(be, left->op4.lval->h->data);
+               if (rel->op == op_anti) {
+                       join = stmt_tdiff(be, c, jl);
+               } else {
+                       join = stmt_tinter(be, c, jl);
+               }
        }
 
        /* project all the left columns */
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
@@ -1978,6 +1978,40 @@ stmt_join(backend *be, stmt *op1, stmt *
        return NULL;
 }
 
+stmt *
+stmt_semijoin(backend *be, stmt *op1, stmt *op2)
+{
+       MalBlkPtr mb = be->mb;
+       InstrPtr q = NULL;
+
+       if (op1->nr < 0 || op2->nr < 0)
+               return NULL;
+
+       q = newStmt(mb, algebraRef, semijoinRef);
+       q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
+       q = pushArgument(mb, q, op1->nr);
+       q = pushArgument(mb, q, op2->nr);
+       q = pushNil(mb, q, TYPE_bat);
+       q = pushNil(mb, q, TYPE_bat);
+       q = pushBit(mb, q, FALSE);
+       q = pushNil(mb, q, TYPE_lng);
+       if (q == NULL)
+               return NULL;
+       if (q) {
+               stmt *s = stmt_create(be->mvc->sa, st_semijoin);
+
+               s->op1 = op1;
+               s->op2 = op2;
+               s->flag = cmp_equal;
+               s->key = 0;
+               s->nrcols = 2;
+               s->nr = getDestVar(q);
+               s->q = q;
+               return s;
+       }
+       return NULL;
+}
+
 static InstrPtr 
 stmt_project_join(backend *be, stmt *op1, stmt *op2, stmt *ins) 
 {
@@ -3228,6 +3262,7 @@ tail_type(stmt *st)
                        st = st->op2;
                        continue;
 
+               case st_semijoin:
                case st_uselect:
                case st_uselect2:
                case st_limit:
@@ -3316,6 +3351,7 @@ stmt_has_null(stmt *s)
        switch (s->type) {
        case st_aggr:
        case st_Nop:
+       case st_semijoin:
        case st_uselect:
        case st_uselect2:
        case st_atom:
@@ -3384,6 +3420,7 @@ const char *
        case st_result:
        case st_append:
        case st_gen_group:
+       case st_semijoin:
        case st_uselect:
        case st_uselect2:
        case st_limit:
@@ -3445,6 +3482,7 @@ schema_name(sql_allocator *sa, stmt *st)
 {
        switch (st->type) {
        case st_const:
+       case st_semijoin:
        case st_join:
        case st_join2:
        case st_joinN:
diff --git a/sql/backends/monet5/sql_statement.h 
b/sql/backends/monet5/sql_statement.h
--- a/sql/backends/monet5/sql_statement.h
+++ b/sql/backends/monet5/sql_statement.h
@@ -66,6 +66,7 @@ typedef enum stmt_type {
        st_join,
        st_join2,
        st_joinN,
+       st_semijoin,
 
        st_export,
        st_append,
@@ -185,6 +186,7 @@ extern stmt *stmt_join(backend *be, stmt
 extern stmt *stmt_join2(backend *be, stmt *l, stmt *ra, stmt *rb, int cmp, int 
anti, int swapped);
 /* generic join operator, with a left and right statement list */
 extern stmt *stmt_genjoin(backend *be, stmt *l, stmt *r, sql_subfunc *op, int 
anti, int swapped);
+extern stmt *stmt_semijoin(backend *be, stmt *op1, stmt *op2);
 
 extern stmt *stmt_project(backend *be, stmt *op1, stmt *op2);
 extern stmt *stmt_project_delta(backend *be, stmt *col, stmt *upd, stmt *ins);
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to