Changeset: 0f5b7529b8b7 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0f5b7529b8b7 Modified Files: clients/Tests/MAL-signatures.stable.out clients/Tests/MAL-signatures.stable.out.int128 sql/backends/monet5/sql.c sql/backends/monet5/sql_subquery.c sql/backends/monet5/sql_subquery.h sql/backends/monet5/sql_subquery.mal Branch: default Log Message:
Added candidate list support for SQLanyequal_grp2 and SQLallnotequal_grp2 diffs (truncated from 560 to 300 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 @@ -246,10 +246,12 @@ stdout of test 'MAL-signatures` in direc [ "aggr", "str_group_concat", "pattern aggr.str_group_concat(X_1:bat[:str], X_2:bat[:str], X_3:bat[:oid], X_4:bit):str ", "CMDBATstr_group_concat;", "" ] [ "aggr", "str_group_concat", "pattern aggr.str_group_concat(X_1:bat[:str], X_2:bat[:str], X_3:bit):str ", "CMDBATstr_group_concat;", "" ] [ "aggr", "str_group_concat", "pattern aggr.str_group_concat(X_1:bat[:str], X_2:bit):str ", "CMDBATstr_group_concat;", "" ] -[ "aggr", "suballnotequal", "command aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLallnotequal_grp2;", "" ] +[ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:oid], X_7:bit):bat[:bit] ", "SQLallnotequal_grp2;", "" ] +[ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLallnotequal_grp2;", "" ] [ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLallnotequal_grp;", "" ] [ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit] ", "SQLallnotequal_grp;", "" ] -[ "aggr", "subanyequal", "command aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLanyequal_grp2;", "" ] +[ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:oid], X_7:bit):bat[:bit] ", "SQLanyequal_grp2;", "" ] +[ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLanyequal_grp2;", "" ] [ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLanyequal_grp;", "" ] [ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit] ", "SQLanyequal_grp;", "" ] [ "aggr", "subavg", "command aggr.subavg(X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit, X_5:bit):bat[:dbl] ", "AGGRsubavg1_dbl;", "" ] 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 @@ -286,10 +286,12 @@ stdout of test 'MAL-signatures` in direc [ "aggr", "str_group_concat", "pattern aggr.str_group_concat(X_1:bat[:str], X_2:bat[:str], X_3:bat[:oid], X_4:bit):str ", "CMDBATstr_group_concat;", "" ] [ "aggr", "str_group_concat", "pattern aggr.str_group_concat(X_1:bat[:str], X_2:bat[:str], X_3:bit):str ", "CMDBATstr_group_concat;", "" ] [ "aggr", "str_group_concat", "pattern aggr.str_group_concat(X_1:bat[:str], X_2:bit):str ", "CMDBATstr_group_concat;", "" ] -[ "aggr", "suballnotequal", "command aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLallnotequal_grp2;", "" ] +[ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:oid], X_7:bit):bat[:bit] ", "SQLallnotequal_grp2;", "" ] +[ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLallnotequal_grp2;", "" ] [ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLallnotequal_grp;", "" ] [ "aggr", "suballnotequal", "pattern aggr.suballnotequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit] ", "SQLallnotequal_grp;", "" ] -[ "aggr", "subanyequal", "command aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLanyequal_grp2;", "" ] +[ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:oid], X_7:bit):bat[:bit] ", "SQLanyequal_grp2;", "" ] +[ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLanyequal_grp2;", "" ] [ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit] ", "SQLanyequal_grp;", "" ] [ "aggr", "subanyequal", "pattern aggr.subanyequal(X_1:bat[:any_1], X_2:bat[:any_1], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit] ", "SQLanyequal_grp;", "" ] [ "aggr", "subavg", "command aggr.subavg(X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit, X_5:bit):bat[:dbl] ", "AGGRsubavg1_dbl;", "" ] diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c --- a/sql/backends/monet5/sql.c +++ b/sql/backends/monet5/sql.c @@ -6638,10 +6638,12 @@ static mel_func sql_init_funcs[] = { command("aggr", "allnotequal", SQLallnotequal, false, "if all values in r are not equal to l return true, else if r has nil nil else false", args(1,3, arg("",bit),batargany("l",1),batargany("r",1))), pattern("aggr", "subanyequal", SQLanyequal_grp, false, "if any value in r is equal to l return true, else if r has nil nil else false", args(1,6, batarg("",bit),batargany("l",1),batargany("r",1),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))), pattern("aggr", "subanyequal", SQLanyequal_grp, false, "if any value in r is equal to l return true, else if r has nil nil else false; with candidate list", args(1,7, batarg("",bit),batargany("l",1),batargany("r",1),batarg("g",oid),batarg("e",oid),batarg("s",oid),arg("no_nil",bit))), - command("aggr", "subanyequal", SQLanyequal_grp2, false, "if any value in r is equal to l return true, else if r has nil nil else false, except if rid is nil (ie empty) then false", args(1,7, batarg("",bit),batargany("l",1),batargany("r",1),batarg("rid",oid),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))), + pattern("aggr", "subanyequal", SQLanyequal_grp2, false, "if any value in r is equal to l return true, else if r has nil nil else false, except if rid is nil (ie empty) then false", args(1,7, batarg("",bit),batargany("l",1),batargany("r",1),batarg("rid",oid),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))), + pattern("aggr", "subanyequal", SQLanyequal_grp2, false, "if any value in r is equal to l return true, else if r has nil nil else false, except if rid is nil (ie empty) then false; with candidate list", args(1,8, batarg("",bit),batargany("l",1),batargany("r",1),batarg("rid",oid),batarg("g",oid),batarg("e",oid),batarg("s",oid),arg("no_nil",bit))), pattern("aggr", "suballnotequal", SQLallnotequal_grp, false, "if all values in r are not equal to l return true, else if r has nil nil else false", args(1,6, batarg("",bit),batargany("l",1),batargany("r",1),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))), pattern("aggr", "suballnotequal", SQLallnotequal_grp, false, "if all values in r are not equal to l return true, else if r has nil nil else false; with candidate list", args(1,7, batarg("",bit),batargany("l",1),batargany("r",1),batarg("g",oid),batarg("e",oid),batarg("s",oid),arg("no_nil",bit))), - command("aggr", "suballnotequal", SQLallnotequal_grp2, false, "if all values in r are not equal to l return true, else if r has nil nil else false, except if rid is nil (ie empty) then true", args(1,7, batarg("",bit),batargany("l",1),batargany("r",1),batarg("rid",oid),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))), + pattern("aggr", "suballnotequal", SQLallnotequal_grp2, false, "if all values in r are not equal to l return true, else if r has nil nil else false, except if rid is nil (ie empty) then true", args(1,7, batarg("",bit),batargany("l",1),batargany("r",1),batarg("rid",oid),batarg("g",oid),batarg("e",oid),arg("no_nil",bit))), + pattern("aggr", "suballnotequal", SQLallnotequal_grp2, false, "if all values in r are not equal to l return true, else if r has nil nil else false, except if rid is nil (ie empty) then true; with candidate list", args(1,8, batarg("",bit),batargany("l",1),batargany("r",1),batarg("rid",oid),batarg("g",oid),batarg("e",oid),batarg("s",oid),arg("no_nil",bit))), // command("aggr", "exist", ALGexist, false, "", args(1,3, arg("",bit),batargany("b",2),argany("h",1))), pattern("aggr", "exist", SQLexist, false, "", args(1,2, arg("",bit), argany("b",1))), pattern("bataggr", "exist", SQLexist, false, "", args(1,2, batarg("",bit), argany("b",1))), diff --git a/sql/backends/monet5/sql_subquery.c b/sql/backends/monet5/sql_subquery.c --- a/sql/backends/monet5/sql_subquery.c +++ b/sql/backends/monet5/sql_subquery.c @@ -738,73 +738,109 @@ bailout: return msg; } -#define SQLanyequal_or_not_grp2_imp(TPE, VAL1, VAL2) \ - do { \ - TPE *lp = (TPE*)Tloc(l, 0), *rp = (TPE*)Tloc(r, 0); \ - for (BUN q = offset, s = 0; s < o; q++, s++) { \ - TPE lv = lp[q], rv = rp[q]; \ - const oid rid = *(oid*)BUNtail(ii, q); \ - const oid id = *(oid*)BUNtail(gi, s); \ - if (ret[id] != VAL1) { \ - if (rid == oid_nil) { \ - ret[id] = VAL2; \ - } else if (is_##TPE##_nil(lv) || is_##TPE##_nil(rv)) { \ - ret[id] = bit_nil; \ - hasnil = 1; \ - } else if (lv == rv) \ - ret[id] = VAL1; \ +#define SQLanyequal_or_not_grp2_imp(TYPE, VAL1, VAL2) \ + do { \ + const TYPE *vals1 = (const TYPE *) Tloc(l, 0); \ + const TYPE *vals2 = (const TYPE *) Tloc(r, 0); \ + while (ncand > 0) { \ + ncand--; \ + i = canditer_next(&ci) - l->hseqbase; \ + if (gids == NULL || \ + (gids[i] >= min && gids[i] <= max)) { \ + if (gids) \ + gid = gids[i] - min; \ + else \ + gid = (oid) i; \ + if (ret[gid] != VAL1) { \ + const oid id = *(oid*)BUNtail(ii, i); \ + if (is_oid_nil(id)) { \ + ret[gid] = VAL2; \ + } else if (is_##TYPE##_nil(vals1[i]) || is_##TYPE##_nil(vals2[i])) { \ + ret[gid] = bit_nil; \ + hasnil = 1; \ + } else if (vals1[i] == vals2[i]) { \ + ret[gid] = VAL1; \ + } \ + } \ } \ } \ } while (0) str -SQLanyequal_grp2(bat *ret, const bat *bid1, const bat *bid2, const bat *Rid, const bat *gp, const bat *gpe, bit *no_nil) +SQLanyequal_grp2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci) { - BAT *l, *r, *rid, *g, *e, *res; - bit F = FALSE, hasnil = 0; - BUN offset = 0; + bat *ret = getArgReference_bat(stk, pci, 0); + bat *lp = getArgReference_bat(stk, pci, 1); + bat *rp = getArgReference_bat(stk, pci, 2); + bat *ip = getArgReference_bat(stk, pci, 3); + bat *gp = getArgReference_bat(stk, pci, 4); + bat *gpe = getArgReference_bat(stk, pci, 5); + bat *sp = pci->argc == 8 ? getArgReference_bat(stk, pci, 6) : NULL; + //bit *no_nil = getArgReference_bit(stk, pci, pci->argc == 8 ? 7 : 6); no_nil argument is ignored + BAT *l = NULL, *r = NULL, *rid = NULL, *g = NULL, *e = NULL, *s = NULL, *res = NULL; + const oid *restrict gids; + oid gid, min, max; + BUN i, ngrp, ncand; + struct canditer ci; + str msg = MAL_SUCCEED; + bit hasnil = 0; - (void)no_nil; - if ((l = BATdescriptor(*bid1)) == NULL) { - throw(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + (void)cntxt; + (void)mb; + + if ((l = BATdescriptor(*lp)) == NULL) { + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; } - if ((r = BATdescriptor(*bid2)) == NULL) { - BBPunfix(l->batCacheid); - throw(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + if ((r = BATdescriptor(*rp)) == NULL) { + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; } - if ((rid = BATdescriptor(*Rid)) == NULL) { - BBPunfix(l->batCacheid); - BBPunfix(r->batCacheid); - throw(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + if ((rid = BATdescriptor(*ip)) == NULL) { + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; } if ((g = BATdescriptor(*gp)) == NULL) { - BBPunfix(l->batCacheid); - BBPunfix(r->batCacheid); - BBPunfix(rid->batCacheid); - throw(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; } if ((e = BATdescriptor(*gpe)) == NULL) { - BBPunfix(l->batCacheid); - BBPunfix(r->batCacheid); - BBPunfix(rid->batCacheid); - BBPunfix(g->batCacheid); - throw(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; + } + if (sp && (s = BATdescriptor(*sp)) == NULL) { + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; + } + + if ((msg = (str)BATgroupaggrinit(l, g, e, s, &min, &max, &ngrp, &ci, &ncand)) != NULL) + goto bailout; + if (g == NULL) { + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "l, r, rid and g must be aligned"); + goto bailout; } - if ((res = BATconstant(0, TYPE_bit, &F, BATcount(e), TRANSIENT)) == NULL) { - BBPunfix(l->batCacheid); - BBPunfix(r->batCacheid); - BBPunfix(rid->batCacheid); - BBPunfix(g->batCacheid); - BBPunfix(e->batCacheid); - throw(SQL, "sql.any =", SQLSTATE(HY013) MAL_MALLOC_FAIL); - } - BAThseqbase(res, e->hseqbase); - assert(BATcount(l) == BATcount(r)); - offset = g->hseqbase - l->hseqbase; - if (BATcount(g) > 0) { - bit *restrict ret = (bit*)Tloc(res, 0); - BATiter gi = bat_iterator(g), ii = bat_iterator(rid); - BUN o = BUNlast(g); + + if (BATcount(l) == 0 || ngrp == 0) { + bit F = FALSE; + if ((res = BATconstant(ngrp == 0 ? 0 : min, TYPE_bit, &F, ngrp, TRANSIENT)) == NULL) { + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; + } + } else { + BATiter ii = bat_iterator(rid); + bit *restrict ret; + + if ((res = COLnew(min, TYPE_bit, ngrp, TRANSIENT)) == NULL) { + msg = createException(SQL, "sql.any =", SQLSTATE(HY005) "Cannot access column descriptor"); + goto bailout; + } + ret = (bit *) Tloc(res, 0); + memset(ret, FALSE, ngrp * sizeof(bit)); + + if (!g || BATtdense(g)) + gids = NULL; + else + gids = (const oid *) Tloc(g, 0); switch (l->ttype) { case TYPE_bit: @@ -838,36 +874,59 @@ SQLanyequal_grp2(bat *ret, const bat *bi const void *nilp = ATOMnilptr(l->ttype); BATiter li = bat_iterator(l), ri = bat_iterator(r); - for (BUN q = offset, s = 0; s < o; q++, s++) { - const void *lv = BUNtail(li, q); - const void *rv = BUNtail(ri, q); - const oid rid = *(oid*)BUNtail(ii, q); - const oid id = *(oid*)BUNtail(gi, s); - - if (ret[id] != TRUE) { - if (rid == oid_nil) { /* empty */ - ret[id] = FALSE; - } else if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) { - ret[id] = bit_nil; - hasnil = 1; - } else if (ocmp(lv, rv) == 0) - ret[id] = TRUE; + while (ncand > 0) { + ncand--; + i = canditer_next(&ci) - l->hseqbase; + if (gids == NULL || + (gids[i] >= min && gids[i] <= max)) { + if (gids) + gid = gids[i] - min; + else + gid = (oid) i; + if (ret[gid] != TRUE) { + const oid id = *(oid*)BUNtail(ii, i); + if (is_oid_nil(id)) { + ret[gid] = FALSE; + } else { + const void *lv = BUNtail(li, i); + const void *rv = BUNtail(ri, i); + if (ocmp(lv, nilp) == 0 || ocmp(rv, nilp) == 0) { + ret[gid] = bit_nil; + hasnil = 1; + } else if (ocmp(lv, rv) == 0) + ret[gid] = TRUE; + } + } } } } } + BATsetcount(res, ngrp); + res->tkey = BATcount(res) <= 1; + res->tsorted = BATcount(res) <= 1; + res->trevsorted = BATcount(res) <= 1; + res->tnil = hasnil != 0; + res->tnonil = hasnil == 0; } - res->hseqbase = g->hseqbase; - res->tnil = hasnil != 0; - res->tnonil = hasnil == 0; - res->tsorted = res->trevsorted = 0; - res->tkey = 0; - BBPunfix(l->batCacheid); - BBPunfix(r->batCacheid); - BBPunfix(g->batCacheid); - BBPunfix(e->batCacheid); - BBPkeepref(*ret = res->batCacheid); - return MAL_SUCCEED; + +bailout: + if (res && !msg) + BBPkeepref(*ret = res->batCacheid); + else if (res) + BBPreclaim(res); + if (l) + BBPunfix(l->batCacheid); + if (r) + BBPunfix(r->batCacheid); + if (rid) + BBPunfix(rid->batCacheid); + if (g) + BBPunfix(g->batCacheid); + if (e) + BBPunfix(e->batCacheid); + if (s) _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list