Changeset: 8788a082bb23 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/8788a082bb23
Branch: Jul2021
Log Message:
merged
diffs (truncated from 312 to 300 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
@@ -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/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) {
+ 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);
+ }
*getArgReference_bat(stk, pci, i) = b->batCacheid;
BBPkeepref(b->batCacheid);
} else { // single value return, only for non-grouped
aggregations
- MT_lock_set(&b->theaplock);
- VALinit(&stk->stk[pci->argv[i]], bat_type, Tloc(b, 0));
- MT_lock_unset(&b->theaplock);
+ // 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, "pyapi3.eval",
SQLSTATE(HY013) MAL_MALLOC_FAIL);
+ }
}
}
+ return MAL_SUCCEED;
}
#include "mel.h"
diff --git a/sql/test/BugTracker-2021/Tests/All
b/sql/test/BugTracker-2021/Tests/All
--- a/sql/test/BugTracker-2021/Tests/All
+++ b/sql/test/BugTracker-2021/Tests/All
@@ -21,3 +21,4 @@ type-upcasting-INT2BIGINT.Bug-7144
rollup-distinct-count.Bug-7146
sum-union.Bug-7147
distinct-union.Bug-7148
+HAVE_LIBPY3?python-aggregates-empty.Bug-7158
diff --git
a/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.test
b/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.test
new file mode 100644
--- /dev/null
+++ b/sql/test/BugTracker-2021/Tests/python-aggregates-empty.Bug-7158.test
@@ -0,0 +1,45 @@
+statement ok
+START TRANSACTION
+
+statement ok
+CREATE TABLE test (x INTEGER)
+
+statement ok
+CREATE AGGREGATE python_aggregate(val INTEGER)
+RETURNS INTEGER
+LANGUAGE PYTHON {
+ try:
+ unique = numpy.unique(aggr_group)
+ x = numpy.zeros(shape=(unique.size))
+ for i in range(0, unique.size):
+ x[i] = numpy.sum(val[aggr_group==unique[i]])
+ except NameError:
+ # aggr_group does not exist. no groups, aggregate on all data
+ x = numpy.sum(val)
+ return(x)
+}
+
+query I rowsort
+SELECT python_aggregate(x) FROM test
+----
+NULL
+
+query I rowsort
+SELECT python_aggregate(x) FROM test group by x
+----
+
+statement ok
+CREATE FUNCTION myfunc(val INTEGER)
+RETURNS INTEGER
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list