Changeset: 2351b33482a4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/2351b33482a4
Modified Files:
        monetdb5/modules/kernel/algebra.c
        sql/backends/monet5/rel_pphash.c
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
Branch: manti
Log Message:

added an algebra.selectNotFalse() function for the manti-joins to filter out the
rows that definitely don't match


diffs (265 lines):

diff --git a/monetdb5/modules/kernel/algebra.c 
b/monetdb5/modules/kernel/algebra.c
--- a/monetdb5/modules/kernel/algebra.c
+++ b/monetdb5/modules/kernel/algebra.c
@@ -478,6 +478,91 @@ ALGmarkselect(Client ctx, bat *r1, bat *
 }
 
 static str
+ALGselectNotFalse(Client ctx, bat *r1, bat *r2, const bat *gid, const bat 
*mark, const bat *pred, const bit *Aggr)
+{
+       (void) ctx;
+       BAT *g = BATdescriptor(*gid); /* oid */
+       BAT *m = BATdescriptor(*mark); /* bit */
+       BAT *p = BATdescriptor(*pred); /* bit */
+       BAT *res1 = NULL, *res2 = NULL;
+       bit aggr = *Aggr;
+
+       if (!g || !m || !p)
+               goto error;
+       BUN nr = BATcount(g), q = 0;
+       assert (nr == BATcount(m) && nr == BATcount(p));
+
+       if ((res1 = COLnew(0, TYPE_oid, nr, TRANSIENT)) == NULL || (res2 = 
COLnew(0, TYPE_bit, nr, TRANSIENT)) == NULL)
+               goto error;
+       assert(g->tsorted);
+       oid *ri1 = Tloc(res1, 0);
+       bit *ri2 = Tloc(res2, 0);
+       bit *mi = Tloc(m, 0);
+       bit *pi = Tloc(p, 0);
+       oid c = g->hseqbase;
+
+       if (nr) {
+               if (!aggr || g->ttype == TYPE_void) { /* void case ? */
+                       for (BUN n = 0; n < nr; n++, c++) {
+                               ri1[q] = c;
+                               ri2[q] = (mi[n] == FALSE || pi[n] == 
FALSE)?FALSE:(mi[n] == bit_nil || pi[n] == bit_nil)?bit_nil:TRUE;
+                               q += (ri2[q] != FALSE); /* filter out the rows 
that are surely FALSE */
+                       }
+               } else { /* the aggregated variant */
+                       oid *gi = Tloc(g, 0);
+                       oid cur = gi[0];
+                       bit m = (mi[0] == FALSE || pi[0] == FALSE)?FALSE:(mi[0] 
== bit_nil || pi[0] == bit_nil)?bit_nil:TRUE;
+                       bool all_unequal = (m == FALSE)?TRUE:FALSE;
+                       for (BUN n = 1; n < nr; n++, c++) {
+                               if (cur != gi[n] && !all_unequal) {
+                                       ri1[q] = c;
+                                       ri2[q] = m;
+                                       q++;
+                                       cur = gi[n];
+                                       m = (mi[n] == FALSE || pi[n] == 
FALSE)?FALSE:(mi[n] == bit_nil || pi[n] == bit_nil)?bit_nil:TRUE;
+                                       all_unequal = (m == FALSE)?TRUE:FALSE;
+                               }
+                               m = (m == FALSE && (mi[n] == FALSE || pi[n] == 
FALSE))?FALSE:(m == bit_nil || mi[n] == bit_nil || pi[n] == 
bit_nil)?bit_nil:TRUE;
+                               all_unequal = all_unequal & (m == FALSE);
+                       }
+                       if (!all_unequal) {
+                               ri1[q] = c;
+                               ri2[q] = m;
+                               q++;
+                       }
+               }
+       }
+       BATsetcount(res1, q);
+       BATsetcount(res2, q);
+       res1->tsorted = true;
+       res1->tkey = true;
+       res1->trevsorted = false;
+       res2->tsorted = false;
+       res2->trevsorted = false;
+       res1->tnil = false;
+       res1->tnonil = true;
+       res2->tnonil = false;
+       res2->tkey = false;
+
+       BBPreclaim(g);
+       BBPreclaim(m);
+       BBPreclaim(p);
+
+       BBPkeepref(res1);
+       BBPkeepref(res2);
+       *r1 = res1->batCacheid;
+       *r2 = res2->batCacheid;
+       return MAL_SUCCEED;
+error:
+       BBPreclaim(g);
+       BBPreclaim(m);
+       BBPreclaim(p);
+       BBPreclaim(res1);
+       BBPreclaim(res2);
+       throw(MAL, "algebra.selectNotFalse", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
+}
+
+static str
 ALGsingle(Client ctx, bat *r, bat *cands, bat *ids)
 {
        (void)ctx;
@@ -515,9 +600,9 @@ ALGouterselect(Client ctx, bat *r1, bat 
        bit any = *Any, single = *Single; /* any or normal comparison semantics 
*/
 
        if (!g || !m || !p) {
-               if (g) BBPreclaim(g);
-               if (m) BBPreclaim(m);
-               if (p) BBPreclaim(p);
+               BBPreclaim(g);
+               BBPreclaim(m);
+               BBPreclaim(p);
                throw(MAL, "algebra.outerselect", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
        }
        BUN nr = BATcount(g), q = 0;
@@ -526,7 +611,7 @@ ALGouterselect(Client ctx, bat *r1, bat 
                BBPreclaim(g);
                BBPreclaim(m);
                BBPreclaim(p);
-               if (res1) BBPreclaim(res1);
+               BBPreclaim(res1);
                throw(MAL, "algebra.outerselect", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
        }
        assert(g->tsorted);
@@ -534,10 +619,9 @@ ALGouterselect(Client ctx, bat *r1, bat 
        bit *ri2 = Tloc(res2, 0);
        bit *mi = Tloc(m, 0);
        bit *pi = Tloc(p, 0);
-       oid cur = oid_nil;
+       oid c = g->hseqbase;
 
        if (g->ttype == TYPE_void) { /* void case ? */
-               oid c = g->hseqbase;
                for (BUN n = 0; n < nr; n++, c++) {
                        ri1[q] = c;
                        ri2[q] = (any && (mi[n] == bit_nil || pi[n] == 
bit_nil))?bit_nil:(mi[n] == TRUE && pi[n] == TRUE)?TRUE:FALSE;
@@ -545,7 +629,7 @@ ALGouterselect(Client ctx, bat *r1, bat 
                }
        } else {
                oid *gi = Tloc(g, 0);
-               oid c = g->hseqbase;
+               oid cur = oid_nil;
                if (nr)
                        cur = gi[0];
                bool used = false;
@@ -618,7 +702,6 @@ error:
        throw(MAL, "algebra.outerselect", SQLSTATE(HY002) "more than one 
match");
 }
 
-
 static str
 ALGselectNotNil(Client ctx, bat *result, const bat *bid)
 {
@@ -2009,6 +2092,7 @@ static mel_func algebra_init_funcs[] = {
  command("algebra", "markselect", ALGmarkselect, false, "Group on group-ids, 
return aggregated anyequal or allnotequal", args(2,6, batarg("",oid), 
batarg("", bit), batarg("gid",oid), batarg("m", bit), batarg("p", bit), 
arg("any", bit))),
  command("algebra", "single", ALGsingle, false, "Check for single result 
ids.", args(1,3, batarg("r",oid), batarg("cands", oid), batarg("i", oid))),
  command("algebra", "outerselect", ALGouterselect, false, "Per input lid 
return at least one row, if none of the predicates (p) hold, return a nil, else 
'all' true cases.", args(2,7, batarg("",oid), batarg("", bit), batarg("lid", 
oid), batarg("rid", bit), batarg("predicate", bit), arg("any", bit), 
arg("single", bit))),
+ command("algebra", "selectNotFalse", ALGselectNotFalse, false, "Return (gid, 
mark&&pred), if mark&&pred != FALSE. If 'aggr', group on gid, return aggregated 
(gid, mark&&pred)", args(2,6, batarg("",oid), batarg("", bit), batarg("gid", 
oid), batarg("mark", bit), batarg("pred", bit), arg('aggr',bit))),
  command("algebra", "selectNotNil", ALGselectNotNil, false, "Select all 
not-nil values", args(1,2, batargany("",1),batargany("b",1))),
  command("algebra", "sort", ALGsort11, false, "Returns a copy of the BAT 
sorted on tail values. The order is descending if the reverse bit is set. This 
is a stable sort if the stable bit is set.", args(1,5, 
batargany("",1),batargany("b",1),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
  command("algebra", "sort", ALGsort12, false, "Returns a copy of the BAT 
sorted on tail values and a BAT that specifies how the input was reordered. The 
order is descending if the reverse bit is set. This is a stable sort if the 
stable bit is set.", args(2,6, 
batargany("",1),batarg("",oid),batargany("b",1),arg("reverse",bit),arg("nilslast",bit),arg("stable",bit))),
diff --git a/sql/backends/monet5/rel_pphash.c b/sql/backends/monet5/rel_pphash.c
--- a/sql/backends/monet5/rel_pphash.c
+++ b/sql/backends/monet5/rel_pphash.c
@@ -607,7 +607,7 @@ rel2bin_oahash_select(backend *be, stmt 
 }
 
 static stmt *
-rel2bin_oahash_outerselect(backend *be, stmt *sub, list *sexps, sql_rel *rel, 
stmt *probed_ids, stmt *hash_ids, stmt **prb_mrk, bool cart, bool mark)
+rel2bin_oahash_outerselect(backend *be, stmt *sub, list *sexps, sql_rel *rel, 
stmt *probed_ids, stmt *hash_ids, stmt **prb_mrk, bool cart, bool mark, bool 
manti)
 {
        assert (is_outerjoin(rel->op) || !list_empty(rel->attr));
        stmt *sel = NULL, *m = prb_mrk?*prb_mrk:NULL;
@@ -631,7 +631,9 @@ rel2bin_oahash_outerselect(backend *be, 
                if (sel)
                        lgids = stmt_project(be, sel, lgids);
                stmt *outer = NULL;
-               if (en->next || !mark)
+               if (manti)
+                       outer = stmt_selectNotFalse(be, lgids, m, p, !en->next);
+               else if (en->next || !mark)
                        outer = stmt_outerselect(be, lgids, m, p, is_any(e), 
!en->next && is_single(rel));
                else
                        outer = stmt_markselect(be, lgids, m, p, is_any(e));
@@ -894,7 +896,7 @@ rel2bin_oahash_groupjoin(backend *be, sq
                append(sexps,e);
        }
        if (!list_empty(sexps)) {
-               stmt *sel = rel2bin_oahash_outerselect(be, sub, sexps, rel, 
probed_ids, hash_ids, &prb_mrk, list_empty(jexps), mark);
+               stmt *sel = rel2bin_oahash_outerselect(be, sub, sexps, rel, 
probed_ids, hash_ids, &prb_mrk, list_empty(jexps), mark, mark&&!exist);
                list *lp = sa_list(be->mvc->sa);
                for (node *n = probe_side->h; n; n = n->next) {
                        stmt *c = stmt_project(be, sel, n->data);
@@ -997,7 +999,7 @@ rel2bin_oahash_leftouterjoin(backend *be
                sub = rel2bin_oahash_equi_join(be, rel, refs, jexps, 
&probed_ids, &probe_sub, NULL /* nulls */, &prb_mrk, NULL /* hsh_mrk */, 
&probe_side, &hash_side, !list_empty(sexps) /* has_outerselect */);
        }
        if (!list_empty(sexps)) {
-               stmt *sel = rel2bin_oahash_outerselect(be, sub, sexps, rel, 
probed_ids, hash_ids, &prb_mrk, list_empty(jexps), false);
+               stmt *sel = rel2bin_oahash_outerselect(be, sub, sexps, rel, 
probed_ids, hash_ids, &prb_mrk, list_empty(jexps), false /* mark */, false /* 
manti */);
                list *lp = sa_list(be->mvc->sa);
                for (node *n = probe_side->h; n; n = n->next) {
                        stmt *c = stmt_project(be, sel, n->data);
@@ -1277,7 +1279,7 @@ rel2bin_oahash_fullouterjoin(backend *be
                sub = rel2bin_oahash_equi_join(be, rel, refs, jexps, 
&probed_ids, &probe_sub, NULL /* nulls */, &m /* prb_mrk */, &hsh_mrk, 
&probe_side, &hash_side, !list_empty(sexps) /* has_outerselect */);
        }
        if (!list_empty(sexps)) {
-               stmt *sel = rel2bin_oahash_outerselect(be, sub, sexps, rel, 
probed_ids, hash_ids, &m, list_empty(jexps), false);
+               stmt *sel = rel2bin_oahash_outerselect(be, sub, sexps, rel, 
probed_ids, hash_ids, &m, list_empty(jexps), false /* mark */, false /* manti 
*/);
                if (sel == NULL) return NULL;
                list *lp = sa_list(sql->sa);
                for (node *n = probe_side->h; n; n = n->next) {
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
@@ -9,6 +9,7 @@
  */
 
 #include "monetdb_config.h"
+#include "mal_type.h"
 #include "sql_mem.h"
 #include "sql_stack.h"
 #include "sql_statement.h"
@@ -2309,6 +2310,38 @@ stmt_markselect(backend *be, stmt *g, st
 }
 
 stmt *
+stmt_selectNotFalse(backend *be, stmt *g, stmt *m, stmt *p, bool aggr)
+{
+       MalBlkPtr mb = be->mb;
+       InstrPtr q;
+
+       q = newStmtArgs(mb, algebraRef, putName("selectNotFalse"), 6);
+       q = pushReturn(mb, q, newTmpVariable(mb, newBatType(TYPE_bit)));
+       q = pushArgument(mb, q, g->nr); /* group ids */
+       q = pushArgument(mb, q, m->nr); /* mark flag */
+       q = pushArgument(mb, q, p->nr); /* predicate */
+       q = pushBit(mb, q, (aggr)?TRUE:FALSE);
+       pushInstruction(mb, q);
+
+       if (!q)
+               return NULL;
+       stmt *s = stmt_create(be->mvc->sa, st_uselect2);
+       if (s == NULL) {
+               freeInstruction(be->mb, q);
+               return NULL;
+       }
+
+       s->op1 = g;
+       s->op2 = m;
+       s->flag = MARKJOIN;
+       s->key = 0;
+       s->nrcols = g->nrcols;
+       s->nr = getDestVar(q);
+       s->q = q;
+       return s;
+}
+
+stmt *
 stmt_markjoin(backend *be, stmt *l, stmt *r, bool nil_matches, bool final)
 {
        MalBlkPtr mb = be->mb;
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
@@ -208,6 +208,7 @@ extern stmt *stmt_outerselect(backend *b
 extern stmt *stmt_thetaselect(backend *be, stmt *op1, stmt *op2, stmt *val, 
const char *cmp, sql_subtype *tpe);
 extern stmt *stmt_markselect(backend *be, stmt *g, stmt *m, stmt *p, bool any);
 extern stmt *stmt_markjoin(backend *be, stmt *l, stmt *r, bool nil_matches, 
bool final);
+extern stmt *stmt_selectNotFalse(backend *be, stmt *g, stmt *m, stmt *p, bool 
aggr);
 
 extern stmt *stmt_tunion(backend *be, stmt *op1, stmt *op2);
 extern stmt *stmt_tdiff(backend *be, stmt *op1, stmt *op2, stmt *lcand);
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to