Changeset: a12f2ddfd2d2 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a12f2ddfd2d2
Modified Files:
clients/Tests/MAL-signatures.stable.out
clients/Tests/MAL-signatures.stable.out.int128
clients/Tests/exports.stable.out
gdk/gdk_cross.c
monetdb5/modules/kernel/algebra.c
monetdb5/modules/kernel/algebra.h
monetdb5/modules/kernel/algebra.mal
monetdb5/optimizer/opt_postfix.c
Branch: default
Log Message:
Also optimize crossproducts with two outputs into one if possible
diffs (202 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,6 +573,7 @@ stdout of test 'MAL-signatures` in direc
[ "algebra", "bandjoin", "command algebra.bandjoin(X_1:bat[:any_1],
X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:any_1, X_6:any_1, X_7:bit,
X_8:bit, X_9:lng):bat[:oid] ", "ALGbandjoin1;", "" ]
[ "algebra", "bandjoin", "command algebra.bandjoin(X_2:bat[:any_1],
X_3:bat[:any_1], X_4:bat[:oid], X_5:bat[:oid], X_6:any_1, X_7:any_1, X_8:bit,
X_9:bit, X_10:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGbandjoin;", "" ]
[ "algebra", "copy", "command algebra.copy(X_1:bat[:any_1]):bat[:any_1] ",
"ALGcopy;", "" ]
+[ "algebra", "crossproduct", "command algebra.crossproduct(X_1:bat[:any_1],
X_2:bat[:any_2], X_3:bit):bat[:oid] ", "ALGcrossproduct1;", "" ]
[ "algebra", "crossproduct", "command algebra.crossproduct(X_2:bat[:any_1],
X_3:bat[:any_2], X_4:bit) (X_0:bat[:oid], X_1:bat[:oid]) ",
"ALGcrossproduct2;", "" ]
[ "algebra", "difference", "command algebra.difference(X_1:bat[:any_1],
X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bit, X_6:bit,
X_7:lng):bat[:oid] ", "ALGdifference;", "" ]
[ "algebra", "exist", "command algebra.exist(X_1:bat[:any_1],
X_2:any_1):bit ", "ALGexist;", "" ]
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,6 +682,7 @@ stdout of test 'MAL-signatures` in direc
[ "algebra", "bandjoin", "command algebra.bandjoin(X_1:bat[:any_1],
X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:any_1, X_6:any_1, X_7:bit,
X_8:bit, X_9:lng):bat[:oid] ", "ALGbandjoin1;", "" ]
[ "algebra", "bandjoin", "command algebra.bandjoin(X_2:bat[:any_1],
X_3:bat[:any_1], X_4:bat[:oid], X_5:bat[:oid], X_6:any_1, X_7:any_1, X_8:bit,
X_9:bit, X_10:lng) (X_0:bat[:oid], X_1:bat[:oid]) ", "ALGbandjoin;", "" ]
[ "algebra", "copy", "command algebra.copy(X_1:bat[:any_1]):bat[:any_1] ",
"ALGcopy;", "" ]
+[ "algebra", "crossproduct", "command algebra.crossproduct(X_1:bat[:any_1],
X_2:bat[:any_2], X_3:bit):bat[:oid] ", "ALGcrossproduct1;", "" ]
[ "algebra", "crossproduct", "command algebra.crossproduct(X_2:bat[:any_1],
X_3:bat[:any_2], X_4:bit) (X_0:bat[:oid], X_1:bat[:oid]) ",
"ALGcrossproduct2;", "" ]
[ "algebra", "difference", "command algebra.difference(X_1:bat[:any_1],
X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bit, X_6:bit,
X_7:lng):bat[:oid] ", "ALGdifference;", "" ]
[ "algebra", "exist", "command algebra.exist(X_1:bat[:any_1],
X_2:any_1):bit ", "ALGexist;", "" ]
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
@@ -802,6 +802,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 ALGcrossproduct1(bat *l, const bat *lid, const bat *rid, const bit
*max_one);
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);
diff --git a/gdk/gdk_cross.c b/gdk/gdk_cross.c
--- a/gdk/gdk_cross.c
+++ b/gdk/gdk_cross.c
@@ -18,7 +18,7 @@
gdk_return
BATsubcross(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, bool
max_one)
{
- BAT *bn1, *bn2;
+ BAT *bn1, *bn2 = NULL;
struct canditer ci1, ci2;
BUN cnt1, cnt2;
oid *restrict p;
@@ -33,10 +33,12 @@ BATsubcross(BAT **r1p, BAT **r2p, BAT *l
}
bn1 = COLnew(0, TYPE_oid, cnt1 * cnt2, TRANSIENT);
- bn2 = COLnew(0, TYPE_oid, cnt1 * cnt2, TRANSIENT);
- if (bn1 == NULL || bn2 == NULL) {
+ if (r2p)
+ bn2 = COLnew(0, TYPE_oid, cnt1 * cnt2, TRANSIENT);
+ if (!bn1 || (r2p && !bn2)) {
BBPreclaim(bn1);
- BBPreclaim(bn2);
+ if (bn2)
+ BBPreclaim(bn2);
return GDK_FAIL;
}
if (cnt1 > 0 && cnt2 > 0) {
@@ -55,23 +57,29 @@ BATsubcross(BAT **r1p, BAT **r2p, BAT *l
}
BATtseqbase(bn1, cnt2 == 1 ? *(oid *) Tloc(bn1, 0) : oid_nil);
- BATsetcount(bn2, cnt1 * cnt2);
- bn2->tsorted = cnt1 <= 1 || cnt2 <= 1;
- bn2->trevsorted = cnt2 <= 1;
- bn2->tkey = cnt1 <= 1;
- bn2->tnil = false;
- bn2->tnonil = true;
- p = (oid *) Tloc(bn2, 0);
- for (i = 0; i < cnt1; i++) {
- for (j = 0; j < cnt2; j++) {
- *p++ = canditer_next(&ci2);
+ if (bn2) {
+ BATsetcount(bn2, cnt1 * cnt2);
+ bn2->tsorted = cnt1 <= 1 || cnt2 <= 1;
+ bn2->trevsorted = cnt2 <= 1;
+ bn2->tkey = cnt1 <= 1;
+ bn2->tnil = false;
+ bn2->tnonil = true;
+ p = (oid *) Tloc(bn2, 0);
+ for (i = 0; i < cnt1; i++) {
+ for (j = 0; j < cnt2; j++) {
+ *p++ = canditer_next(&ci2);
+ }
+ canditer_reset(&ci2);
}
- canditer_reset(&ci2);
+ BATtseqbase(bn2, cnt1 == 1 ? *(oid *) Tloc(bn2, 0) :
oid_nil);
}
- BATtseqbase(bn2, cnt1 == 1 ? *(oid *) Tloc(bn2, 0) : oid_nil);
}
*r1p = bn1;
- *r2p = bn2;
- TRC_DEBUG(ALGO, "BATsubcross()=(" ALGOBATFMT "," ALGOBATFMT ")\n",
ALGOBATPAR(bn1), ALGOBATPAR(bn2));
+ if (r2p)
+ *r2p = bn2;
+ if (r2p)
+ TRC_DEBUG(ALGO, "BATsubcross()=(" ALGOBATFMT "," ALGOBATFMT
")\n", ALGOBATPAR(bn1), ALGOBATPAR(bn2));
+ else
+ TRC_DEBUG(ALGO, "BATsubcross()=(" ALGOBATFMT ")\n",
ALGOBATPAR(bn1));
return GDK_SUCCEED;
}
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
@@ -785,10 +785,10 @@ ALGunique1(bat *result, const bat *bid)
return ALGunique2(result, bid, NULL);
}
-str
-ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right, const bit
*max_one)
+static str
+ALGcrossproduct(bat *l, bat *r, const bat *left, const bat *right, const bit
*max_one)
{
- BAT *L, *R, *bn1, *bn2;
+ BAT *L, *R, *bn1, *bn2 = NULL;
gdk_return ret;
if ((L = BATdescriptor(*left)) == NULL) {
@@ -798,18 +798,31 @@ ALGcrossproduct2(bat *l, bat *r, const b
BBPunfix(L->batCacheid);
throw(MAL, "algebra.crossproduct", SQLSTATE(HY002)
RUNTIME_OBJECT_MISSING);
}
- ret = BATsubcross(&bn1, &bn2, L, R, NULL, NULL,
+ ret = BATsubcross(&bn1, r ? &bn2 : NULL, L, R, NULL, NULL,
max_one && !is_bit_nil(*max_one) &&
*max_one);
BBPunfix(L->batCacheid);
BBPunfix(R->batCacheid);
if (ret != GDK_SUCCEED)
throw(MAL, "algebra.crossproduct", GDK_EXCEPTION);
BBPkeepref(*l = bn1->batCacheid);
- BBPkeepref(*r = bn2->batCacheid);
+ if (r)
+ BBPkeepref(*r = bn2->batCacheid);
return MAL_SUCCEED;
}
str
+ALGcrossproduct1(bat *l, const bat *left, const bat *right, const bit *max_one)
+{
+ return ALGcrossproduct(l, NULL, left, right, max_one);
+}
+
+str
+ALGcrossproduct2(bat *l, bat *r, const bat *left, const bat *right, const bit
*max_one)
+{
+ return ALGcrossproduct(l, r, left, right, max_one);
+}
+
+str
ALGprojection(bat *result, const bat *lid, const bat *rid)
{
BAT *left, *right,*bn= NULL;
@@ -1459,6 +1472,7 @@ mel_func algebra_init_funcs[] = {
command("algebra", "unique", ALGunique2, false, "Select all unique values
from the tail of the first input.\nInput is a dense-headed BAT, the second
input is a\ndense-headed BAT with sorted tail, output is a dense-headed\nBAT
with in the tail the head value of the input BAT that was\nselected. The
output BAT is sorted on the tail value. The\nsecond input BAT is a list of
candidates.", args(1,3, batarg("",oid),batargany("b",1),batarg("s",oid))),
command("algebra", "unique", ALGunique1, false, "Select all unique values
from the tail of the input.\nInput is a dense-headed BAT, output is a
dense-headed BAT with\nin the tail the head value of the input BAT that was
selected.\nThe output BAT is sorted on the tail value.", args(1,2,
batarg("",oid),batargany("b",1))),
command("algebra", "crossproduct", ALGcrossproduct2, false, "Returns 2
columns with all BUNs, consisting of the head-oids\nfrom 'left' and 'right' for
which there are BUNs in 'left'\nand 'right' with equal tails", args(2,5,
batarg("l",oid),batarg("r",oid),batargany("left",1),batargany("right",2),arg("max_one",bit))),
+ command("algebra", "crossproduct", ALGcrossproduct1, false, "Compute the
cross product of both input bats; but only produce left output", args(1,4,
batarg("",oid),batargany("left",1),batargany("right",2),arg("max_one",bit))),
command("algebra", "join", ALGjoin, false, "Join", args(2,8,
batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
command("algebra", "join", ALGjoin1, false, "Join; only produce left output",
args(1,7,
batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
command("algebra", "leftjoin", ALGleftjoin, false, "Left join with candidate
lists", args(2,8,
batarg("",oid),batarg("",oid),batargany("l",1),batargany("r",1),batarg("sl",oid),batarg("sr",oid),arg("nil_matches",bit),arg("estimate",lng))),
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
@@ -51,6 +51,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 ALGcrossproduct1(bat *l, const bat *lid, const bat *rid, const
bit *max_one);
mal_export str ALGcrossproduct2(bat *l, bat *r, const bat *lid, const bat
*rid, const bit *max_one);
/* end legacy join functions */
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
@@ -182,6 +182,10 @@ comment "Returns 2 columns with all BUNs
from 'left' and 'right' for which there are BUNs in 'left'
and 'right' with equal tails";
+command crossproduct(left:bat[:any_1], right:bat[:any_2], max_one:bit)
:bat[:oid]
+address ALGcrossproduct1
+comment "Compute the crossproduct of both input bats; but only produce left
output";
+
command
join(l:bat[:any_1],r:bat[:any_1],sl:bat[:oid],sr:bat[:oid],nil_matches:bit,estimate:lng)
(:bat[:oid],:bat[:oid])
address ALGjoin
comment "Join";
diff --git a/monetdb5/optimizer/opt_postfix.c b/monetdb5/optimizer/opt_postfix.c
--- a/monetdb5/optimizer/opt_postfix.c
+++ b/monetdb5/optimizer/opt_postfix.c
@@ -37,7 +37,8 @@ OPTpostfixImplementation(Client cntxt, M
|| getFunctionId(p) == outerjoinRef
|| getFunctionId(p) == thetajoinRef
|| getFunctionId(p) == bandjoinRef
-
|| getFunctionId(p) == rangejoinRef) && getVarEolife(mb, getArg(p,
p->retc -1)) == i){
+
|| getFunctionId(p) == rangejoinRef
+
|| getFunctionId(p) == crossRef) && getVarEolife(mb, getArg(p,
p->retc -1)) == i){
delArgument(p, p->retc -1);
typeChecker(cntxt->usermodule, mb, p, i, TRUE);
actions++;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list