Changeset: b157119db1f5 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=b157119db1f5 Modified Files: clients/Tests/exports.stable.out gdk/gdk.h gdk/gdk_firstn.c gdk/gdk_join.c monetdb5/modules/kernel/algebra.c monetdb5/optimizer/opt_candidates.c sql/backends/monet5/sql.c sql/backends/monet5/sql_statistics.c sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-1join-query.stable.out sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-1join-view.stable.out sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-2join-query.stable.out sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-2join-view.stable.out Branch: default Log Message:
Merge heads diffs (truncated from 385 to 300 lines): 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 @@ -139,6 +139,7 @@ BUN BATgrows(BAT *b); gdk_return BAThash(BAT *b, BUN masksize); void BAThseqbase(BAT *b, oid o); gdk_return BATimprints(BAT *b); +BAT *BATintersect(BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate); BAT *BATintersectcand(BAT *a, BAT *b); gdk_return BATjoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate) __attribute__((__warn_unused_result__)); gdk_return BATkey(BAT *b, bool onoff); diff --git a/gdk/gdk.h b/gdk/gdk.h --- a/gdk/gdk.h +++ b/gdk/gdk.h @@ -2746,6 +2746,7 @@ gdk_export gdk_return BATthetajoin(BAT * __attribute__ ((__warn_unused_result__)); gdk_export gdk_return BATsemijoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate) __attribute__ ((__warn_unused_result__)); +gdk_export BAT *BATintersect(BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate); gdk_export BAT *BATdiff(BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate); gdk_export gdk_return BATjoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate) __attribute__ ((__warn_unused_result__)); diff --git a/gdk/gdk_firstn.c b/gdk/gdk_firstn.c --- a/gdk/gdk_firstn.c +++ b/gdk/gdk_firstn.c @@ -653,9 +653,9 @@ BATfirstn_grouped(BAT **topn, BAT **gids bn1 = bn; BBPunfix(s->batCacheid); - rc = BATsemijoin(&bn, NULL, b, b, su, bn1, 1, BUN_NONE); + bn = BATintersect(b, b, su, bn1, 1, BUN_NONE); BBPunfix(bn1->batCacheid); - if (rc != GDK_SUCCEED) + if (bn == NULL) return GDK_FAIL; } else { BATiter bi = bat_iterator(b); @@ -725,9 +725,9 @@ BATfirstn_grouped_with_groups(BAT **topn BBPunfix(bn2->batCacheid); return GDK_FAIL; } - rc = BATsemijoin(&bn4, NULL, s, bn2, NULL, NULL, 0, BUN_NONE); + bn4 = BATintersect(s, bn2, NULL, NULL, 0, BUN_NONE); BBPunfix(bn2->batCacheid); - if (rc != GDK_SUCCEED) { + if (bn4 == NULL) { BBPunfix(bn1->batCacheid); return GDK_FAIL; } @@ -801,7 +801,7 @@ BATfirstn_grouped_with_groups(BAT **topn if (gids) { BAT *bn1, *bn2, *bn3, *bn4, *bn5, *bn6, *bn7, *bn8; - if (BATsemijoin(&bn1, NULL, s, bn, NULL, NULL, 0, BUN_NONE) != GDK_SUCCEED) { + if ((bn1 = BATintersect(s, bn, NULL, NULL, 0, BUN_NONE)) == NULL) { BBPunfix(bn->batCacheid); return GDK_FAIL; } diff --git a/gdk/gdk_join.c b/gdk/gdk_join.c --- a/gdk/gdk_join.c +++ b/gdk/gdk_join.c @@ -60,12 +60,14 @@ * right values; two extra Boolean parameters, li and hi, * indicate whether equal values match * - * In addition to these functions, there is one more functions that is - * closely related: + * In addition to these functions, there are two more functions that + * are closely related: + * BATintersect + * intersection: return a candidate list with OIDs of tuples in + * the left input whose value occurs in the right input * BATdiff - * difference: return a candidate list compatible list of OIDs of - * tuples in the left input whose value does not occur in the - * right input + * difference: return a candidate list with OIDs of tuples in the + * left input whose value does not occur in the right input */ /* Perform a bunch of sanity checks on the inputs to a join. */ @@ -3864,9 +3866,10 @@ BATouterjoin(BAT **r1p, BAT **r2p, BAT * GDKdebug & ALGOMASK ? GDKusec() : 0); } -/* Perform a semi-join over l and r. Returns two new, aligned, bats +/* Perform a semi-join over l and r. Returns one or two new, bats * with the oids of matching tuples. The result is in the same order - * as l (i.e. r1 is sorted). */ + * as l (i.e. r1 is sorted). If a single bat is returned, it is a + * candidate list. */ gdk_return BATsemijoin(BAT **r1p, BAT **r2p, BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate) { @@ -3875,10 +3878,23 @@ BATsemijoin(BAT **r1p, BAT **r2p, BAT *l GDKdebug & ALGOMASK ? GDKusec() : 0); } +/* Return a candidate list with the list of rows in l whose value also + * occurs in r. This is just the left output of a semi-join. */ +BAT * +BATintersect(BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate) +{ + BAT *bn; + + if (leftjoin(&bn, NULL, l, r, sl, sr, nil_matches, + false, true, false, estimate, "BATintersect", + GDKdebug & ALGOMASK ? GDKusec() : 0) == GDK_SUCCEED) + return virtualize(bn); + return NULL; +} + /* Return the difference of l and r. The result is a BAT with the * oids of those values in l that do not occur in r. This is what you - * might call an anti-semi-join. The result can be used as a - * candidate list. */ + * might call an anti-semi-join. The result is a candidate list. */ BAT * BATdiff(BAT *l, BAT *r, BAT *sl, BAT *sr, int nil_matches, BUN estimate) { @@ -3887,7 +3903,7 @@ BATdiff(BAT *l, BAT *r, BAT *sl, BAT *sr if (leftjoin(&bn, NULL, l, r, sl, sr, nil_matches, false, false, true, estimate, "BATdiff", GDKdebug & ALGOMASK ? GDKusec() : 0) == GDK_SUCCEED) - return bn; + return virtualize(bn); return NULL; } 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 @@ -508,7 +508,7 @@ ALGintersect(bat *r1, const bat *lid, co { return do_join(r1, NULL, lid, rid, NULL, slid, srid, 0, NULL, NULL, 0, 0, nil_matches, estimate, - BATsemijoin, NULL, NULL, NULL, NULL, "algebra.intersect"); + NULL, NULL, NULL, NULL, BATintersect, "algebra.intersect"); } /* algebra.firstn(b:bat[:any], diff --git a/monetdb5/optimizer/opt_candidates.c b/monetdb5/optimizer/opt_candidates.c --- a/monetdb5/optimizer/opt_candidates.c +++ b/monetdb5/optimizer/opt_candidates.c @@ -44,7 +44,7 @@ OPTcandidatesImplementation(Client cntxt setVarCList(mb,getArg(p,0)); else if(getFunctionId(p) == likeselectRef || getFunctionId(p) == likethetaselectRef) setVarCList(mb,getArg(p,0)); - else if(getFunctionId(p) == intersectRef ) + else if(getFunctionId(p) == intersectRef || getFunctionId(p) == differenceRef ) setVarCList(mb,getArg(p,0)); else if(getFunctionId(p) == uniqueRef ) setVarCList(mb,getArg(p,0)); @@ -52,6 +52,10 @@ OPTcandidatesImplementation(Client cntxt setVarCList(mb,getArg(p,0)); else if(getFunctionId(p) == subsliceRef ) setVarCList(mb,getArg(p,0)); + else if (getFunctionId(p) == projectionRef && + isVarCList(mb,getArg(p,p->retc + 0)) && + isVarCList(mb,getArg(p,p->retc + 1))) + setVarCList(mb,getArg(p,0)); } else if( getModuleId(p) == generatorRef){ if(getFunctionId(p) == selectRef || getFunctionId(p) == thetaselectRef) 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 @@ -1537,9 +1537,9 @@ DELTAsub(bat *result, const bat *col, co BBPunfix(u->batCacheid); throw(MAL, "sql.delta", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING); } - ret = BATsemijoin(&cminu, NULL, u, c_ids, NULL, NULL, 0, BUN_NONE); + cminu = BATintersect(u, c_ids, NULL, NULL, 0, BUN_NONE); BBPunfix(c_ids->batCacheid); - if (ret != GDK_SUCCEED) { + if (cminu == NULL) { BBPunfix(c->batCacheid); BBPunfix(u->batCacheid); throw(MAL, "sql.delta", SQLSTATE(HY001) MAL_MALLOC_FAIL); @@ -1704,7 +1704,7 @@ DELTAproject(bat *result, const bat *sub /* create subsets of u_id and u_val where the tail * values of u_id are also in s, and where those tail * values occur as head value in res */ - if (BATsemijoin(&o, NULL, u_id, s, NULL, NULL, 0, BUN_NONE) != GDK_SUCCEED) { + if ((o = BATintersect(u_id, s, NULL, NULL, 0, BUN_NONE)) == NULL) { BBPunfix(s->batCacheid); BBPunfix(res->batCacheid); BBPunfix(u_id->batCacheid); @@ -1720,7 +1720,7 @@ DELTAproject(bat *result, const bat *sub if (nu_id == NULL || nu_val == NULL || tres == NULL || - BATsemijoin(&o, NULL, nu_id, tres, NULL, NULL, 0, BUN_NONE) != GDK_SUCCEED) { + (o = BATintersect(nu_id, tres, NULL, NULL, 0, BUN_NONE)) == NULL) { BBPunfix(s->batCacheid); BBPunfix(res->batCacheid); BBPreclaim(nu_id); diff --git a/sql/backends/monet5/sql_statistics.c b/sql/backends/monet5/sql_statistics.c --- a/sql/backends/monet5/sql_statistics.c +++ b/sql/backends/monet5/sql_statistics.c @@ -59,8 +59,8 @@ sql_analyze(Client cntxt, MalBlkPtr mb, str msg = getSQLContext(cntxt, mb, &m, NULL); sql_trans *tr = m->session->tr; node *nsch, *ntab, *ncol; - char *query, *dquery; - size_t querylen; + char *query = NULL, *dquery; + size_t querylen = 0; char *maxval = NULL, *minval = NULL; size_t minlen = 0, maxlen = 0; str sch = 0, tbl = 0, col = 0; @@ -76,9 +76,7 @@ sql_analyze(Client cntxt, MalBlkPtr mb, if (msg != MAL_SUCCEED || (msg = checkSQLContext(cntxt)) != NULL) return msg; - querylen = 0; - query = NULL; - dquery = (char *) GDKzalloc(8192); + dquery = (char *) GDKzalloc(96); if (dquery == NULL) { throw(SQL, "analyze", SQLSTATE(HY001) MAL_MALLOC_FAIL); } @@ -112,8 +110,13 @@ sql_analyze(Client cntxt, MalBlkPtr mb, if (tbl && strcmp(bt->name, tbl)) continue; - if (t->persistence != SQL_PERSIST) + if (t->persistence != SQL_PERSIST) { + GDKfree(dquery); + GDKfree(query); + GDKfree(maxval); + GDKfree(minval); throw(SQL, "analyze", SQLSTATE(42S02) "Table '%s' is not persistent", bt->name); + } tfnd = 1; if (isTable(t) && t->columns.set) for (ncol = (t)->columns.set->h; ncol; ncol = ncol->next) { @@ -144,7 +147,7 @@ sql_analyze(Client cntxt, MalBlkPtr mb, if (tostr == BATatoms[TYPE_str].atomToStr) tostr = strToStrSQuote; - snprintf(dquery, 8192, "delete from sys.statistics where \"column_id\" = %d;", c->base.id); + snprintf(dquery, 96, "delete from sys.statistics where \"column_id\" = %d;", c->base.id); cfnd = 1; if (samplesize > 0) { bsample = BATsample(bn, (BUN) samplesize); @@ -174,7 +177,7 @@ sql_analyze(Client cntxt, MalBlkPtr mb, if (bsample && br) BBPunfix(br->batCacheid); } - if( bsample) + if (bsample) BBPunfix(bsample->batCacheid); /* use BATordered(_rev) * and not @@ -190,10 +193,9 @@ sql_analyze(Client cntxt, MalBlkPtr mb, if (maxlen < 4) { GDKfree(maxval); maxval = GDKmalloc(4); - if( maxval== NULL) { + if (maxval == NULL) { GDKfree(dquery); GDKfree(minval); - GDKfree(maxval); throw(SQL, "analyze", SQLSTATE(HY001) MAL_MALLOC_FAIL); } maxlen = 4; @@ -201,9 +203,8 @@ sql_analyze(Client cntxt, MalBlkPtr mb, if (minlen < 4) { GDKfree(minval); minval = GDKmalloc(4); - if( minval== NULL){ + if (minval == NULL){ GDKfree(dquery); - GDKfree(minval); GDKfree(maxval); throw(SQL, "analyze", SQLSTATE(HY001) MAL_MALLOC_FAIL); } diff --git a/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-1join-query.stable.out b/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-1join-query.stable.out --- a/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-1join-query.stable.out +++ b/sql/test/FeatureRequests/Tests/foreign_key_outer_join_dead_code_elimination-explain-1join-query.stable.out @@ -216,15 +216,15 @@ function user.s10_1():void; X_17:bat[:int] := algebra.projection(C_5:bat[:oid], X_8:bat[:int]); X_42:bat[:int] := algebra.projection(X_34:bat[:oid], X_17:bat[:int]); X_40:bat[:oid] := bat.mirror(X_17:bat[:int]); - X_41:bat[:oid] := algebra.difference(X_40:bat[:oid], X_34:bat[:oid], nil:BAT, nil:BAT, false:bit, nil:lng); + C_41:bat[:oid] := algebra.difference(X_40:bat[:oid], X_34:bat[:oid], nil:BAT, nil:BAT, false:bit, nil:lng); X_27:bat[:int] := sql.bind(X_4:int, "sys":str, "pk2":str, "v2":str, 0:int); X_45:bat[:int] := bat.append(X_43:bat[:int], X_42:bat[:int], true:bit); - X_47:bat[:int] := algebra.projection(X_41:bat[:oid], X_17:bat[:int]); + X_47:bat[:int] := algebra.projection(C_41:bat[:oid], X_17:bat[:int]); X_48:bat[:int] := bat.append(X_45:bat[:int], X_47:bat[:int], true:bit); X_56:bat[:int] := bat.new(nil:int); X_55:bat[:int] := algebra.projectionpath(X_35:bat[:oid], C_25:bat[:oid], X_27:bat[:int]); X_57:bat[:int] := bat.append(X_56:bat[:int], X_55:bat[:int], true:bit); - X_59:bat[:int] := algebra.project(X_41:bat[:oid], nil:int); + X_59:bat[:int] := algebra.project(C_41:bat[:oid], nil:int); X_60:bat[:int] := bat.append(X_57:bat[:int], X_59:bat[:int], true:bit); X_73:bat[:str] := bat.new(nil:str); X_79:bat[:int] := bat.new(nil:int); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list