Changeset: 704f7d5b217c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=704f7d5b217c
Modified Files:
        clients/Tests/MAL-signatures.stable.out
        clients/Tests/MAL-signatures.stable.out.int128
        clients/Tests/exports.stable.out
        gdk/ChangeLog.Jun2020
        gdk/gdk.h
        gdk/gdk_cross.c
        monetdb5/ChangeLog.Jun2020
        monetdb5/modules/kernel/algebra.c
        monetdb5/modules/kernel/algebra.h
        monetdb5/modules/kernel/algebra.mal
        sql/backends/monet5/sql_statement.c
        sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.stable.out
Branch: Jun2020
Log Message:

Added a max_one:bit argument to algebra.crossproduct.


diffs (216 lines):

diff --git a/clients/Tests/MAL-signatures.stable.out 
b/clients/Tests/MAL-signatures.stable.out
--- a/clients/Tests/MAL-signatures.stable.out
+++ b/clients/Tests/MAL-signatures.stable.out
@@ -573,7 +573,7 @@ stdout of test 'MAL-signatures` in direc
 [ "algebra",   "antijoin",     "function algebra.antijoin(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) 
(X_0:bat[:oid], X_1:bat[:oid]);",   "",     ""      ]
 [ "algebra",   "bandjoin",     "command algebra.bandjoin(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], c1:any_1, c2:any_1, li:bit, hi:bit, 
estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGbandjoin;", "Band join: 
values in l and r match if r - c1 <[=] l <[=] r + c2"       ]
 [ "algebra",   "copy", "command algebra.copy(b:bat[:any_1]):bat[:any_1] ",     
"ALGcopy;",     "Returns physical copy of a BAT."       ]
-[ "algebra",   "crossproduct", "command algebra.crossproduct(left:bat[:any_1], 
right:bat[:any_2]) (l:bat[:oid], r:bat[:oid]) ",        "ALGcrossproduct2;",    
"Returns 2 columns with all BUNs, consisting of the head-oids\n\t  from 'left' 
and 'right' for which there are BUNs in 'left'\n\t  and 'right' with equal 
tails"        ]
+[ "algebra",   "crossproduct", "command algebra.crossproduct(left:bat[:any_1], 
right:bat[:any_2], max_one:bit) (l:bat[:oid], r:bat[:oid]) ",   
"ALGcrossproduct2;",    "Returns 2 columns with all BUNs, consisting of the 
head-oids\n\t  from 'left' and 'right' for which there are BUNs in 'left'\n\t  
and 'right' with equal tails"        ]
 [ "algebra",   "difference",   "command algebra.difference(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, nil_clears:bit, 
estimate:lng):bat[:oid] ",       "ALGdifference;",       "Difference of l and r 
with candidate lists"    ]
 [ "algebra",   "exist",        "command algebra.exist(b:bat[:any_1], 
val:any_1):bit ", "ALGexist;",    "Returns whether 'val' occurs in b."    ]
 [ "algebra",   "fetch",        "command algebra.fetch(b:bat[:any_1], 
x:oid):any_1 ",   "ALGfetchoid;", "Returns the value of the BUN at x-th 
position with 0 <= x < b.count"   ]
diff --git a/clients/Tests/MAL-signatures.stable.out.int128 
b/clients/Tests/MAL-signatures.stable.out.int128
--- a/clients/Tests/MAL-signatures.stable.out.int128
+++ b/clients/Tests/MAL-signatures.stable.out.int128
@@ -682,7 +682,7 @@ stdout of test 'MAL-signatures` in direc
 [ "algebra",   "antijoin",     "function algebra.antijoin(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, estimate:lng) 
(X_0:bat[:oid], X_1:bat[:oid]);",   "",     ""      ]
 [ "algebra",   "bandjoin",     "command algebra.bandjoin(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], c1:any_1, c2:any_1, li:bit, hi:bit, 
estimate:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGbandjoin;", "Band join: 
values in l and r match if r - c1 <[=] l <[=] r + c2"       ]
 [ "algebra",   "copy", "command algebra.copy(b:bat[:any_1]):bat[:any_1] ",     
"ALGcopy;",     "Returns physical copy of a BAT."       ]
-[ "algebra",   "crossproduct", "command algebra.crossproduct(left:bat[:any_1], 
right:bat[:any_2]) (l:bat[:oid], r:bat[:oid]) ",        "ALGcrossproduct2;",    
"Returns 2 columns with all BUNs, consisting of the head-oids\n\t  from 'left' 
and 'right' for which there are BUNs in 'left'\n\t  and 'right' with equal 
tails"        ]
+[ "algebra",   "crossproduct", "command algebra.crossproduct(left:bat[:any_1], 
right:bat[:any_2], max_one:bit) (l:bat[:oid], r:bat[:oid]) ",   
"ALGcrossproduct2;",    "Returns 2 columns with all BUNs, consisting of the 
head-oids\n\t  from 'left' and 'right' for which there are BUNs in 'left'\n\t  
and 'right' with equal tails"        ]
 [ "algebra",   "difference",   "command algebra.difference(l:bat[:any_1], 
r:bat[:any_1], sl:bat[:oid], sr:bat[:oid], nil_matches:bit, nil_clears:bit, 
estimate:lng):bat[:oid] ",       "ALGdifference;",       "Difference of l and r 
with candidate lists"    ]
 [ "algebra",   "exist",        "command algebra.exist(b:bat[:any_1], 
val:any_1):bit ", "ALGexist;",    "Returns whether 'val' occurs in b."    ]
 [ "algebra",   "fetch",        "command algebra.fetch(b:bat[:any_1], 
x:oid):any_1 ",   "ALGfetchoid;", "Returns the value of the BUN at x-th 
position with 0 <= x < b.count"   ]
diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out
--- a/clients/Tests/exports.stable.out
+++ b/clients/Tests/exports.stable.out
@@ -186,7 +186,7 @@ void BATsetcount(BAT *b, BUN cnt);
 BAT *BATslice(BAT *b, BUN low, BUN high);
 gdk_return BATsort(BAT **sorted, BAT **order, BAT **groups, BAT *b, BAT *o, 
BAT *g, bool reverse, bool nilslast, bool stable) 
__attribute__((__warn_unused_result__));
 gdk_return BATstr_group_concat(ValPtr res, BAT *b, BAT *s, BAT *sep, bool 
skip_nils, bool abort_on_error, bool nil_if_empty, const char *restrict 
separator);
-gdk_return BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr) 
__attribute__((__warn_unused_result__));
+gdk_return BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, 
bool max_one) __attribute__((__warn_unused_result__));
 gdk_return BATsum(void *res, int tp, BAT *b, BAT *s, bool skip_nils, bool 
abort_on_error, bool nil_if_empty);
 gdk_return BATthetajoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT 
*sr, int op, bool nil_matches, BUN estimate) 
__attribute__((__warn_unused_result__));
 BAT *BATthetaselect(BAT *b, BAT *s, const void *val, const char *op);
@@ -803,7 +803,7 @@ str ALGcount_nil(lng *result, const bat 
 str ALGcount_no_nil(lng *result, const bat *bid);
 str ALGcovariance(dbl *res, const bat *bid1, const bat *bid2);
 str ALGcovariancep(dbl *res, const bat *bid1, const bat *bid2);
-str ALGcrossproduct2(bat *l, bat *r, const bat *lid, const bat *rid);
+str ALGcrossproduct2(bat *l, bat *r, const bat *lid, const bat *rid, const bit 
*max_one);
 str ALGdifference(bat *r1, const bat *lid, const bat *rid, const bat *slid, 
const bat *srid, const bit *nil_matches, const bit *not_in, const lng 
*estimate);
 str ALGexist(bit *ret, const bat *bid, const void *val);
 str ALGfetchoid(ptr ret, const bat *bid, const oid *pos);
diff --git a/gdk/ChangeLog.Jun2020 b/gdk/ChangeLog.Jun2020
--- a/gdk/ChangeLog.Jun2020
+++ b/gdk/ChangeLog.Jun2020
@@ -2,9 +2,9 @@
 # This file is updated with Maddlog
 
 * Tue Apr 28 2020 Sjoerd Mullender <sjo...@acm.org>
-- The functions BATintersect and BATsemijoin have an extra argument,
-  bool max_one, which indicates that there must be no more than one
-  match in the join.
+- The functions BATintersect BATsemijoin, and BATsubcross have an
+  extra argument, bool max_one, which indicates that there must be no
+  more than one match in the join.
 
 * Mon Apr 20 2020 Sjoerd Mullender <sjo...@acm.org>
 - The "unique" property on BATs was removed.  The property indicated
diff --git a/gdk/gdk.h b/gdk/gdk.h
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -2049,7 +2049,7 @@ gdk_export BAT *BATselect(BAT *b, BAT *s
 gdk_export BAT *BATthetaselect(BAT *b, BAT *s, const void *val, const char 
*op);
 
 gdk_export BAT *BATconstant(oid hseq, int tt, const void *val, BUN cnt, role_t 
role);
-gdk_export gdk_return BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT 
*sl, BAT *sr)
+gdk_export gdk_return BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT 
*sl, BAT *sr, bool max_one)
        __attribute__((__warn_unused_result__));
 
 gdk_export gdk_return BATleftjoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT 
*sl, BAT *sr, bool nil_matches, BUN estimate)
diff --git a/gdk/gdk_cross.c b/gdk/gdk_cross.c
--- a/gdk/gdk_cross.c
+++ b/gdk/gdk_cross.c
@@ -13,9 +13,10 @@
 /* Calculate a cross product between bats l and r with optional
  * candidate lists sl for l and sr for r.
  * The result is two bats r1 and r2 which contain the OID (head
- * values) of the input bats l and r. */
+ * values) of the input bats l and r.
+ * If max_one is set, r can have at most one row. */
 gdk_return
-BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr)
+BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, bool 
max_one)
 {
        BAT *bn1, *bn2;
        struct canditer ci1, ci2;
@@ -26,6 +27,11 @@ BATsubcross(BAT **r1p, BAT **r2p, BAT *l
        cnt1 = canditer_init(&ci1, l, sl);
        cnt2 = canditer_init(&ci2, r, sr);
 
+       if (max_one && cnt2 > 1) {
+               GDKerror("more than one match");
+               return GDK_FAIL;
+       }
+
        bn1 = COLnew(0, TYPE_oid, cnt1 * cnt2, TRANSIENT);
        bn2 = COLnew(0, TYPE_oid, cnt1 * cnt2, TRANSIENT);
        if (bn1 == NULL || bn2 == NULL) {
diff --git a/monetdb5/ChangeLog.Jun2020 b/monetdb5/ChangeLog.Jun2020
--- a/monetdb5/ChangeLog.Jun2020
+++ b/monetdb5/ChangeLog.Jun2020
@@ -2,9 +2,9 @@
 # This file is updated with Maddlog
 
 * Tue Apr 28 2020 Sjoerd Mullender <sjo...@acm.org>
-- The functions algegra.intersect and algebra.semijoin have an extra
-  argument, bool max_one, which indicates that there must be no more
-  than one match in the join.
+- The functions algegra.intersect, algebra.semijoin, and
+  algebra.crossproduct have an extra argument, bool max_one, which
+  indicates that there must be no more than one match in the join.
 
 * Mon Apr 20 2020 Sjoerd Mullender <sjo...@acm.org>
 - The example module opt_sql_append is not installed in the binary
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
@@ -748,7 +748,7 @@ ALGunique1(bat *result, const bat *bid)
 }
 
 str
-ALGcrossproduct2( bat *l, bat *r, const bat *left, const bat *right)
+ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right, const bit 
*max_one)
 {
        BAT *L, *R, *bn1, *bn2;
        gdk_return ret;
@@ -760,7 +760,8 @@ ALGcrossproduct2( bat *l, bat *r, const 
                BBPunfix(L->batCacheid);
                throw(MAL, "algebra.crossproduct", SQLSTATE(HY002) 
RUNTIME_OBJECT_MISSING);
        }
-       ret = BATsubcross(&bn1, &bn2, L, R, NULL, NULL);
+       ret = BATsubcross(&bn1, &bn2, L, R, NULL, NULL,
+                                         max_one && !is_bit_nil(*max_one) && 
*max_one);
        BBPunfix(L->batCacheid);
        BBPunfix(R->batCacheid);
        if (ret != GDK_SUCCEED)
diff --git a/monetdb5/modules/kernel/algebra.h 
b/monetdb5/modules/kernel/algebra.h
--- a/monetdb5/modules/kernel/algebra.h
+++ b/monetdb5/modules/kernel/algebra.h
@@ -47,7 +47,7 @@ mal_export str ALGdifference(bat *r1, co
 mal_export str ALGintersect(bat *r1, const bat *lid, const bat *rid, const bat 
*slid, const bat *srid, const bit *nil_matches, const bit *max_one, const lng 
*estimate);
 
 /* legacy join functions */
-mal_export str ALGcrossproduct2(bat *l, bat *r, const bat *lid, const bat 
*rid);
+mal_export str ALGcrossproduct2(bat *l, bat *r, const bat *lid, const bat 
*rid, const bit *max_one);
 /* end legacy join functions */
 
 mal_export str ALGfirstn(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr 
pci);
diff --git a/monetdb5/modules/kernel/algebra.mal 
b/monetdb5/modules/kernel/algebra.mal
--- a/monetdb5/modules/kernel/algebra.mal
+++ b/monetdb5/modules/kernel/algebra.mal
@@ -175,7 +175,7 @@ comment "Select all unique values from t
 # @+ Join operations
 # The core of every relational engine.
 # The join collection provided by the GDK kernel.
-command crossproduct( left:bat[:any_1], right:bat[:any_2])
+command crossproduct( left:bat[:any_1], right:bat[:any_2], max_one:bit)
                (l:bat[:oid],r:bat[:oid])
 address ALGcrossproduct2
 comment "Returns 2 columns with all BUNs, consisting of the head-oids
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
@@ -1992,6 +1992,7 @@ stmt_join_cand(backend *be, stmt *op1, s
                q = pushReturn(mb, q, newTmpVariable(mb, TYPE_any));
                q = pushArgument(mb, q, op1->nr);
                q = pushArgument(mb, q, op2->nr);
+               q = pushBit(mb, q, FALSE); /* max_one */
                assert(!lcand && !rcand);
                if (q == NULL)
                        return NULL;
diff --git a/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.stable.out 
b/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.stable.out
--- a/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.stable.out
+++ b/sql/test/BugTracker-2017/Tests/side-effect.Bug-6397.stable.out
@@ -43,26 +43,26 @@ stdout of test 'side-effect.Bug-6397` in
 % 161 # length
 function user.s4_0():void;
     X_5:void := querylog.define("explain select count(*) from 
my_generate_series(1,5) as t1,\nmy_generate_series(1,100) as t2;":str, 
"default_pipe":str, 28:int);
-barrier X_95:bit := language.dataflow();
-    X_31:bat[:str] := bat.pack(".%5":str);
-    X_32:bat[:str] := bat.pack("%5":str);
-    X_33:bat[:str] := bat.pack("bigint":str);
-    X_34:bat[:int] := bat.pack(64:int);
-    X_35:bat[:int] := bat.pack(0:int);
+barrier X_96:bit := language.dataflow();
+    X_32:bat[:str] := bat.pack(".%5":str);
+    X_33:bat[:str] := bat.pack("%5":str);
+    X_34:bat[:str] := bat.pack("bigint":str);
+    X_35:bat[:int] := bat.pack(64:int);
+    X_36:bat[:int] := bat.pack(0:int);
     X_13:bat[:int] := user.my_generate_series(1:int, 5:int);
     X_14:lng := aggr.count(X_13:bat[:int]);
     X_21:bat[:lng] := sql.single(X_14:lng);
     X_19:bat[:int] := user.my_generate_series(1:int, 100:int);
     X_20:lng := aggr.count(X_19:bat[:int]);
     X_22:bat[:lng] := sql.single(X_20:lng);
-    (X_23:bat[:oid], X_24:bat[:oid]) := algebra.crossproduct(X_21:bat[:lng], 
X_22:bat[:lng]);
-    X_25:bat[:lng] := algebra.projection(X_23:bat[:oid], X_21:bat[:lng]);
-    X_26:bat[:lng] := algebra.projection(X_24:bat[:oid], X_22:bat[:lng]);
-    X_27:bat[:lng] := batcalc.*(X_25:bat[:lng], X_26:bat[:lng], nil:BAT, 
nil:BAT);
+    (X_23:bat[:oid], X_24:bat[:oid]) := algebra.crossproduct(X_21:bat[:lng], 
X_22:bat[:lng], false:bit);
+    X_26:bat[:lng] := algebra.projection(X_23:bat[:oid], X_21:bat[:lng]);
+    X_27:bat[:lng] := algebra.projection(X_24:bat[:oid], X_22:bat[:lng]);
+    X_28:bat[:lng] := batcalc.*(X_26:bat[:lng], X_27:bat[:lng], nil:BAT, 
nil:BAT);
     language.pass(X_21:bat[:lng]);
     language.pass(X_22:bat[:lng]);
-exit X_95:bit;
-    sql.resultSet(X_31:bat[:str], X_32:bat[:str], X_33:bat[:str], 
X_34:bat[:int], X_35:bat[:int], X_27:bat[:lng]);
+exit X_96:bit;
+    sql.resultSet(X_32:bat[:str], X_33:bat[:str], X_34:bat[:str], 
X_35:bat[:int], X_36:bat[:int], X_28:bat[:lng]);
 end user.s4_0;
 #inline               actions= 0 time=1 usec 
 #remap                actions= 1 time=32 usec 
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to