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