Changeset: 9099eb848f28 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/9099eb848f28 Modified Files: monetdb5/extras/rapi/rapi.c sql/backends/monet5/Tests/rapi18.sql sql/backends/monet5/Tests/rapi18.stable.out sql/backends/monet5/UDF/pyapi3/pyapi3.c sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.sql sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.stable.out Branch: Oct2020 Log Message:
More cleanup and R aggregates also had the same issue diffs (158 lines): 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 @@ -537,6 +537,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); @@ -650,6 +684,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 */ + BBPunfix(b->batCacheid); + msg = empty_return(mb, stk, pci, pci->retc, b->hseqbase); + goto wrapup; + } } // check the BAT count, if it is bigger than RAPI_MAX_TUPLES, fail @@ -772,9 +812,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/sql/backends/monet5/Tests/rapi18.sql b/sql/backends/monet5/Tests/rapi18.sql --- a/sql/backends/monet5/Tests/rapi18.sql +++ b/sql/backends/monet5/Tests/rapi18.sql @@ -20,4 +20,8 @@ CREATE TABLE rapi18bad as select * from select count(distinct g) from rapi18bad; select g, rapi18(n) from rapi18bad group by g; +create table empty_table(col1 int); +select rapi18(col1) from empty_table; +select rapi18(col1) from empty_table group by col1; + ROLLBACK; diff --git a/sql/backends/monet5/Tests/rapi18.stable.out b/sql/backends/monet5/Tests/rapi18.stable.out --- a/sql/backends/monet5/Tests/rapi18.stable.out +++ b/sql/backends/monet5/Tests/rapi18.stable.out @@ -584,6 +584,18 @@ stdout of test 'rapi18` in directory 'sq [ 498, 42 ] [ 499, 42 ] [ 500, 42 ] +#create table empty_table(col1 int); +#select rapi18(col1) from empty_table; +% sys.%1 # table_name +% %1 # name +% double # type +% 24 # length +[ NULL ] +#select rapi18(col1) from empty_table group by col1; +% sys.%1 # table_name +% %1 # name +% double # type +% 24 # length #ROLLBACK; # 17:22:21 > 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 @@ -1641,6 +1641,8 @@ static str CreateEmptyReturn(MalBlkPtr m 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, "pyapi3.eval", SQLSTATE(HY013) MAL_MALLOC_FAIL); } @@ -1649,7 +1651,15 @@ static str CreateEmptyReturn(MalBlkPtr m } else { // single value return, only for non-grouped aggregations // return NULL to conform to SQL aggregates int tpe = getArgType(mb, pci, i); - VALinit(&stk->stk[pci->argv[i]], tpe, ATOMnilptr(tpe)); + 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, "pyapi3.eval", SQLSTATE(HY013) MAL_MALLOC_FAIL); + } } } return MAL_SUCCEED; diff --git a/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.sql b/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.sql --- a/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.sql +++ b/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.sql @@ -18,6 +18,8 @@ LANGUAGE PYTHON { SELECT python_aggregate(x) FROM test; +SELECT python_aggregate(x) FROM test group by x; + CREATE FUNCTION myfunc(val INTEGER) RETURNS INTEGER LANGUAGE PYTHON { diff --git a/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.stable.out b/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.stable.out --- a/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.stable.out +++ b/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.stable.out @@ -26,6 +26,11 @@ stdout of test 'python-aggregates-empty. % int # type % 1 # length [ NULL ] +#SELECT python_aggregate(x) FROM test group by x; +% sys.%1 # table_name +% %1 # name +% int # type +% 1 # length #CREATE FUNCTION myfunc(val INTEGER) #RETURNS INTEGER #LANGUAGE PYTHON { _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list