Changeset: 46db239e93e6 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/46db239e93e6
Modified Files:
        gdk/gdk_join.c
Branch: default
Log Message:

Extend selectjoin implementation to also do nil_on_miss option.


diffs (134 lines):

diff --git a/gdk/gdk_join.c b/gdk/gdk_join.c
--- a/gdk/gdk_join.c
+++ b/gdk/gdk_join.c
@@ -301,7 +301,7 @@ nomatch(BAT **r1p, BAT **r2p, BAT *l, BA
 static gdk_return
 selectjoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r,
           struct canditer *lci, struct canditer *rci,
-          bool nil_matches, bool semi, bool max_one, bool min_one,
+          bool nil_matches, bool nil_on_miss, bool semi, bool max_one, bool 
min_one,
           lng t0, bool swapped, const char *reason)
 {
        BATiter li = bat_iterator(l);
@@ -338,26 +338,30 @@ selectjoin(BAT **r1p, BAT **r2p, BAT *l,
        }
        bncount = BATcount(bn);
        if (bncount == 0) {
-               BBPunfix(bn->batCacheid);
+               BBPreclaim(bn);
                if (min_one) {
                        GDKerror("not enough matches");
                        return GDK_FAIL;
                }
-               return nomatch(r1p, r2p, l, r, lci, false, false,
-                              reason, t0);
+               if (!nil_on_miss)
+                       return nomatch(r1p, r2p, l, r, lci, false, false,
+                                      reason, t0);
+               /* special case: return nil on RHS */
+               bncount = 1;
+               bn = NULL;
        }
        if (bncount > 1) {
                if (semi)
                        bncount = 1;
                if (max_one) {
-                       BBPunfix(bn->batCacheid);
+                       BBPreclaim(bn);
                        GDKerror("more than one match");
                        return GDK_FAIL;
                }
        }
        BAT *r1 = COLnew(0, TYPE_oid, lci->ncand * bncount, TRANSIENT);
        if (r1 == NULL) {
-               BBPunfix(bn->batCacheid);
+               BBPreclaim(bn);
                return GDK_FAIL;
        }
        r1->tsorted = true;
@@ -368,20 +372,37 @@ selectjoin(BAT **r1p, BAT **r2p, BAT *l,
        r1->tnonil = true;
        BAT *r2 = NULL;
        if (r2p) {
-               r2 = COLnew(0, TYPE_oid, lci->ncand * bncount, TRANSIENT);
+               if (bn)
+                       r2 = COLnew(0, TYPE_oid, lci->ncand * bncount, 
TRANSIENT);
+               else
+                       r2 = BATconstant(0, TYPE_void, &oid_nil, lci->ncand * 
bncount, TRANSIENT);
                if (r2 == NULL) {
-                       BBPunfix(bn->batCacheid);
+                       BBPreclaim(bn);
                        BBPreclaim(r1);
                        return GDK_FAIL;
                }
-               r2->tsorted = lci->ncand == 1 || bncount == 1;
-               r2->trevsorted = bncount == 1;
-               r2->tseqbase = lci->ncand == 1 && BATtdense(bn) ? bn->tseqbase 
: oid_nil;
-               r2->tkey = lci->ncand == 1;
-               r2->tnil = false;
-               r2->tnonil = true;
+               if (bn) {
+                       r2->tsorted = lci->ncand == 1 || bncount == 1;
+                       r2->trevsorted = bncount == 1;
+                       r2->tseqbase = lci->ncand == 1 && BATtdense(bn) ? 
bn->tseqbase : oid_nil;
+                       r2->tkey = lci->ncand == 1;
+                       r2->tnil = false;
+                       r2->tnonil = true;
+               }
        }
-       if (BATtdense(bn)) {
+       if (bn == NULL) {
+               oid *o1p = (oid *) Tloc(r1, 0);
+               BUN p, q = bncount;
+
+               do {
+                       GDK_CHECK_TIMEOUT(timeoffset, counter,
+                                         GOTO_LABEL_TIMEOUT_HANDLER(bailout));
+                       for (p = 0; p < q; p++) {
+                               *o1p++ = o;
+                       }
+                       o = canditer_next(lci);
+               } while (!is_oid_nil(o));
+       } else if (BATtdense(bn)) {
                oid *o1p = (oid *) Tloc(r1, 0);
                oid *o2p = r2 ? (oid *) Tloc(r2, 0) : NULL;
                oid bno = bn->tseqbase;
@@ -422,11 +443,11 @@ selectjoin(BAT **r1p, BAT **r2p, BAT *l,
        }
        BATsetcount(r1, lci->ncand * bncount);
        *r1p = r1;
-       if (r2p) {
+       if (bn && r2p) {
                BATsetcount(r2, lci->ncand * bncount);
                *r2p = r2;
        }
-       BBPunfix(bn->batCacheid);
+       BBPreclaim(bn);
        TRC_DEBUG(ALGO, "l=" ALGOBATFMT ","
                  "r=" ALGOBATFMT ",sl=" ALGOOPTBATFMT ","
                  "sr=" ALGOOPTBATFMT ",nil_matches=%s;%s %s "
@@ -3886,7 +3907,7 @@ leftjoin(BAT **r1p, BAT **r2p, BAT *l, B
             (l->ttype == TYPE_void && is_oid_nil(l->tseqbase)))) {
                /* single value to join, use select */
                rc = selectjoin(r1p, r2p, l, r, &lci, &rci,
-                               nil_matches, semi, max_one, min_one,
+                               nil_matches, nil_on_miss, semi, max_one, 
min_one,
                                t0, false, func);
                goto doreturn;
        } else if (BATtdense(r) && rci.tpe == cand_dense) {
@@ -4256,13 +4277,13 @@ BATjoin(BAT **r1p, BAT **r2p, BAT *l, BA
        if (lci.ncand == 1 || (BATordered(l) && BATordered_rev(l)) || (l->ttype 
== TYPE_void && is_oid_nil(l->tseqbase))) {
                /* single value to join, use select */
                rc = selectjoin(r1p, r2p, l, r, &lci, &rci,
-                               nil_matches, false, false, false,
+                               nil_matches, false, false, false, false,
                                t0, false, __func__);
                goto doreturn;
        } else if (rci.ncand == 1 || (BATordered(r) && BATordered_rev(r)) || 
(r->ttype == TYPE_void && is_oid_nil(r->tseqbase))) {
                /* single value to join, use select */
                rc = selectjoin(r2p ? r2p : &r2, r1p, r, l, &rci, &lci,
-                               nil_matches, false, false, false,
+                               nil_matches, false, false, false, false,
                                t0, true, __func__);
                if (rc == GDK_SUCCEED && r2p == NULL)
                        BBPunfix(r2->batCacheid);
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to