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