Changeset: 60e8e6f0ebbe for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/60e8e6f0ebbe Modified Files: gdk/gdk_join.c monetdb5/modules/mal/wlc.c sql/backends/monet5/sql_execute.c Branch: default Log Message:
Merged with Jul2021 diffs (truncated from 704 to 300 lines): diff --git a/gdk/gdk_join.c b/gdk/gdk_join.c --- a/gdk/gdk_join.c +++ b/gdk/gdk_join.c @@ -3323,9 +3323,11 @@ joincost(BAT *r, struct canditer *lci, s * non-persistent bats */ MT_lock_set(&r->theaplock); if (!(BBP_status(r->batCacheid) & BBPEXISTING) /* || r->theap->dirty */ || GDKinmemory(r->theap->farmid)) -#endif rcost += cnt * 2.0; MT_lock_unset(&r->theaplock); +#else + rcost += cnt * 2.0; +#endif } } if (rci->ncand != BATcount(r) && rci->tpe != cand_mask) { diff --git a/gdk/gdk_logger.c b/gdk/gdk_logger.c --- a/gdk/gdk_logger.c +++ b/gdk/gdk_logger.c @@ -1412,6 +1412,7 @@ bm_get_counts(logger *lg) cnt = BATcount(b); } else { deleted++; + lid = 1; } if (BUNappend(lg->catalog_cnt, &cnt, false) != GDK_SUCCEED) return GDK_FAIL; diff --git a/gdk/gdk_project.c b/gdk/gdk_project.c --- a/gdk/gdk_project.c +++ b/gdk/gdk_project.c @@ -606,6 +606,15 @@ BATproject2(BAT *restrict l, BAT *restri assert(r2 == NULL || tpe == ATOMtype(r2->ttype)); assert(r2 == NULL || r1->hseqbase + r1i.count == r2->hseqbase); + if (r2 && r1i.count == 0) { + /* unlikely special case: r1 is empty, so we just have r2 */ + r1 = r2; + r2 = NULL; + bat_iterator_end(&r1i); + r1i = r2i; + r2i = bat_iterator(r2); + } + if (BATtdense(l) && lcount > 0) { lo = l->tseqbase; hi = l->tseqbase + lcount; @@ -715,10 +724,12 @@ BATproject2(BAT *restrict l, BAT *restri bn->tnonil = l->tnonil & r1->tnonil; bn->tsorted = l->batCount <= 1 || (l->tsorted & r1->tsorted) - || (l->trevsorted & r1->trevsorted); + || (l->trevsorted & r1->trevsorted) + || r1->batCount <= 1; bn->trevsorted = l->batCount <= 1 || (l->tsorted & r1->trevsorted) - || (l->trevsorted & r1->tsorted); + || (l->trevsorted & r1->tsorted) + || r1->batCount <= 1; bn->tkey = l->batCount <= 1 || (l->tkey & r1->tkey); } diff --git a/monetdb5/extras/rapi/rapi.c b/monetdb5/extras/rapi/rapi.c --- a/monetdb5/extras/rapi/rapi.c +++ b/monetdb5/extras/rapi/rapi.c @@ -543,6 +543,40 @@ static char *RAPIinstalladdons(void) { return NULL; } +static str +empty_return(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, size_t retcols, oid seqbase) +{ + for (size_t i = 0; i < retcols; i++) { + if (isaBatType(getArgType(mb, pci, i))) { + BAT *b = COLnew(seqbase, getBatType(getArgType(mb, pci, i)), 0, TRANSIENT); + if (!b) { + for (size_t j = 0; j < i; j++) { + if (isaBatType(getArgType(mb, pci, j))) + BBPunfix(*getArgReference_bat(stk, pci, j)); + else + VALclear(&stk->stk[pci->argv[j]]); + } + return createException(MAL, "rapi.eval", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + *getArgReference_bat(stk, pci, i) = b->batCacheid; + BBPkeepref(b->batCacheid); + } else { // single value return, only for non-grouped aggregations + // return NULL to conform to SQL aggregates + int tpe = getArgType(mb, pci, i); + if (!VALinit(&stk->stk[pci->argv[i]], tpe, ATOMnilptr(tpe))) { + for (size_t j = 0; j < i; j++) { + if (isaBatType(getArgType(mb, pci, j))) + BBPunfix(*getArgReference_bat(stk, pci, j)); + else + VALclear(&stk->stk[pci->argv[j]]); + } + return createException(MAL, "rapi.eval", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + } + } + return MAL_SUCCEED; +} + static str RAPIeval(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, bit grouped) { sql_func * sqlfun = NULL; str exprStr = *getArgReference_str(stk, pci, pci->retc + 1); @@ -656,6 +690,12 @@ static str RAPIeval(Client cntxt, MalBlk msg = createException(MAL, "rapi.eval", SQLSTATE(HY013) MAL_MALLOC_FAIL); goto wrapup; } + if (BATcount(b) == 0) { /* empty input, generate trivial return */ + /* I expect all inputs to have the same size, so this should be safe */ + msg = empty_return(mb, stk, pci, pci->retc, b->hseqbase); + BBPunfix(b->batCacheid); + goto wrapup; + } } // check the BAT count, if it is bigger than RAPI_MAX_TUPLES, fail @@ -780,9 +820,9 @@ static str RAPIeval(Client cntxt, MalBlk } msg = MAL_SUCCEED; } + wrapup: /* unprotect environment, so it will be eaten by the GC. */ UNPROTECT(1); - wrapup: MT_lock_unset(&rapiLock); if (argnames) free(argnames); diff --git a/monetdb5/modules/mal/wlc.c b/monetdb5/modules/mal/wlc.c --- a/monetdb5/modules/mal/wlc.c +++ b/monetdb5/modules/mal/wlc.c @@ -872,11 +872,8 @@ WLCdelete(Client cntxt, MalBlkPtr mb, Ma b= BBPquickdesc(bid, false); if( BATcount(b) == 0) return MAL_SUCCEED; - msg = WLCstart(cntxt, "wlr.delete"); - if(msg) { - BBPunfix(b->batCacheid); + if ((msg = WLCstart(cntxt, "wlr.delete"))) return msg; - } cntxt->wlc_kind = WLC_UPDATE; p = newStmt(cntxt->wlc, "wlr","delete"); p = pushStr(cntxt->wlc, p, getVarConstant(mb, getArg(pci,1)).val.sval); diff --git a/sql/backends/monet5/Tests/rapi18.test b/sql/backends/monet5/Tests/rapi18.test --- a/sql/backends/monet5/Tests/rapi18.test +++ b/sql/backends/monet5/Tests/rapi18.test @@ -26,5 +26,17 @@ select g, rapi18(n) from rapi18bad group 1000 values hashing to 11dbd9e3e1c8fd598a3eaf93a417a852 statement ok +create table empty_table(col1 int) + +query R rowsort +select rapi18(col1) from empty_table +---- +NULL + +query R rowsort +select rapi18(col1) from empty_table group by col1 +---- + +statement ok ROLLBACK diff --git a/sql/backends/monet5/UDF/capi/Tests/capi07.test b/sql/backends/monet5/UDF/capi/Tests/capi07.test --- a/sql/backends/monet5/UDF/capi/Tests/capi07.test +++ b/sql/backends/monet5/UDF/capi/Tests/capi07.test @@ -15,7 +15,7 @@ CREATE AGGREGATE capi07(inp INTEGER) RET statement ok CREATE TABLE integers(i INTEGER) -statement ok +statement ok rowcount 6 INSERT INTO integers VALUES (3), (4), (1), (2), (5), (6) query I rowsort @@ -23,6 +23,18 @@ SELECT capi07(i) FROM integers ---- 21 +statement ok rowcount 6 +TRUNCATE integers + +query I rowsort +SELECT capi07(i) FROM integers +---- +NULL + +query I rowsort +SELECT capi07(i) FROM integers GROUP BY i +---- + statement ok ROLLBACK diff --git a/sql/backends/monet5/UDF/capi/capi.c b/sql/backends/monet5/UDF/capi/capi.c --- a/sql/backends/monet5/UDF/capi/capi.c +++ b/sql/backends/monet5/UDF/capi/capi.c @@ -379,6 +379,40 @@ static timestamp timestamp_from_data(cud static char valid_path_characters[] = "abcdefghijklmnopqrstuvwxyz"; +static str +empty_return(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, size_t retcols, oid seqbase) +{ + for (size_t i = 0; i < retcols; i++) { + if (isaBatType(getArgType(mb, pci, i))) { + BAT *b = COLnew(seqbase, getBatType(getArgType(mb, pci, i)), 0, TRANSIENT); + if (!b) { + for (size_t j = 0; j < i; j++) { + if (isaBatType(getArgType(mb, pci, j))) + BBPunfix(*getArgReference_bat(stk, pci, j)); + else + VALclear(&stk->stk[pci->argv[j]]); + } + return createException(MAL, "cudf.eval", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + *getArgReference_bat(stk, pci, i) = b->batCacheid; + BBPkeepref(b->batCacheid); + } else { // single value return, only for non-grouped aggregations + // return NULL to conform to SQL aggregates + int tpe = getArgType(mb, pci, i); + if (!VALinit(&stk->stk[pci->argv[i]], tpe, ATOMnilptr(tpe))) { + for (size_t j = 0; j < i; j++) { + if (isaBatType(getArgType(mb, pci, j))) + BBPunfix(*getArgReference_bat(stk, pci, j)); + else + VALclear(&stk->stk[pci->argv[j]]); + } + return createException(MAL, "cudf.eval", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } + } + } + return MAL_SUCCEED; +} + static str CUDFeval(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, bool grouped) { @@ -971,8 +1005,19 @@ static str CUDFeval(Client cntxt, MalBlk } else { // deal with BAT input bat_type = getBatType(getArgType(mb, pci, i)); - input_bats[index] = - BATdescriptor(*getArgReference_bat(stk, pci, i)); + if (!(input_bats[index] = + BATdescriptor(*getArgReference_bat(stk, pci, i)))) { + msg = createException(MAL, "cudf.eval", MAL_MALLOC_FAIL); + goto wrapup; + } + if (BATcount(input_bats[index]) == 0) { + /* empty input, generate trivial return */ + /* I expect all inputs to have the same size, + so this should be safe */ + msg = empty_return(mb, stk, pci, output_count, + input_bats[index]->hseqbase); + goto wrapup; + } } if (bat_type == TYPE_bit) { diff --git a/sql/backends/monet5/UDF/pyapi3/pyapi3.c b/sql/backends/monet5/UDF/pyapi3/pyapi3.c --- a/sql/backends/monet5/UDF/pyapi3/pyapi3.c +++ b/sql/backends/monet5/UDF/pyapi3/pyapi3.c @@ -53,7 +53,7 @@ typedef struct _AggrParams{ } AggrParams; static void ComputeParallelAggregation(AggrParams *p); -static void CreateEmptyReturn(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, +static str CreateEmptyReturn(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, size_t retcols, oid seqbase); static const char *FunctionBasePath(void) @@ -296,7 +296,7 @@ static str PyAPIeval(Client cntxt, MalBl // one of the input BATs is empty, don't execute the function at // all // just return empty BATs - CreateEmptyReturn(mb, stk, pci, retcols, seqbase); + msg = CreateEmptyReturn(mb, stk, pci, retcols, seqbase); goto wrapup; } } @@ -1635,22 +1635,38 @@ wrapup: gstate = Python_ReleaseGIL(gstate); } -static void CreateEmptyReturn(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, +static str CreateEmptyReturn(MalBlkPtr mb, MalStkPtr stk, InstrPtr pci, size_t retcols, oid seqbase) { - size_t i; - for (i = 0; i < retcols; i++) { - int bat_type = getBatType(getArgType(mb, pci, i)); - BAT *b = COLnew(seqbase, bat_type, 0, TRANSIENT); + for (size_t i = 0; i < retcols; i++) { if (isaBatType(getArgType(mb, pci, i))) { + BAT *b = COLnew(seqbase, getBatType(getArgType(mb, pci, i)), 0, TRANSIENT); + if (!b) { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list