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

Reply via email to