Changeset: 5d4a3a53f572 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5d4a3a53f572
Modified Files:
        sql/backends/monet5/Tests/pyapi18.sql
        sql/backends/monet5/Tests/pyapi18.stable.err
        sql/backends/monet5/Tests/pyapi18.stable.out
        sql/backends/monet5/UDF/pyapi/connection.c
        sql/backends/monet5/UDF/pyapi/pyapi.c
        sql/backends/monet5/UDF/pyapi/type_conversion.c
Branch: default
Log Message:

Merge with Dec2016.


diffs (truncated from 484 to 300 lines):

diff --git a/sql/backends/monet5/Tests/pyapi18.sql 
b/sql/backends/monet5/Tests/pyapi18.sql
--- a/sql/backends/monet5/Tests/pyapi18.sql
+++ b/sql/backends/monet5/Tests/pyapi18.sql
@@ -82,7 +82,8 @@ LANGUAGE PYTHON
 SELECT pyapi_inp_decimal(d) FROM pyapi_ret_decimal();
 
 # test unsupported type
-create table uuid_tbl as select uuid() AS d with data;
-CREATE FUNCTION pyapi_interval(d UUID) RETURNS DOUBLE LANGUAGE PYTHON { return 
d; };
+CREATE TABLE uuid_tbl(d UUID);
+INSERT INTO uuid_tbl VALUES ('54771a16-b4ad-4f1a-a9b7-4d8e8ca6fb7c');
+CREATE FUNCTION pyapi_interval(d UUID) RETURNS STRING LANGUAGE PYTHON { return 
d; };
 SELECT pyapi_interval(d) FROM uuid_tbl;
 ROLLBACK;
diff --git a/sql/backends/monet5/Tests/pyapi18.stable.err 
b/sql/backends/monet5/Tests/pyapi18.stable.err
--- a/sql/backends/monet5/Tests/pyapi18.stable.err
+++ b/sql/backends/monet5/Tests/pyapi18.stable.err
@@ -31,9 +31,6 @@ stderr of test 'pyapi18` in directory 's
 # 18:18:39 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-21503" "--port=39173"
 # 18:18:39 >  
 
-MAPI  = (monetdb) /var/tmp/mtest-21503/.s.monetdb.39173
-QUERY = SELECT pyapi_interval(d) FROM uuid_tbl;
-ERROR = !Unsupported SQL Type: uuid
 
 # 18:18:39 >  
 # 18:18:39 >  "Done."
diff --git a/sql/backends/monet5/Tests/pyapi18.stable.out 
b/sql/backends/monet5/Tests/pyapi18.stable.out
--- a/sql/backends/monet5/Tests/pyapi18.stable.out
+++ b/sql/backends/monet5/Tests/pyapi18.stable.out
@@ -33,8 +33,8 @@ Ready.
 [ 1    ]
 #CREATE FUNCTION pyapi_date(d DATE) RETURNS STRING LANGUAGE PYTHON { return d; 
};
 #SELECT pyapi_date(d) FROM date_table;
-% sys.L1 # table_name
-% L1 # name
+% sys.L2 # table_name
+% L2 # name
 % clob # type
 % 10 # length
 [ "2000-10-10" ]
@@ -43,28 +43,28 @@ Ready.
 [ 1    ]
 #CREATE FUNCTION pyapi_time(d TIME) RETURNS STRING LANGUAGE PYTHON { return d; 
};
 #SELECT pyapi_time(d) FROM time_table;
-% sys.L1 # table_name
-% L1 # name
+% sys.L2 # table_name
+% L2 # name
 % clob # type
-% 8 # length
-[ "12:00:00"   ]
+% 12 # length
+[ "12:00:00.000"       ]
 #CREATE TABLE timestamp_table(d TIMESTAMP); # TIMESTAMP is converted to str
 #INSERT INTO timestamp_table VALUES (cast('2000-1-1 12:00:00' AS TIMESTAMP));
 [ 1    ]
 #CREATE FUNCTION pyapi_timestamp(d TIMESTAMP) RETURNS STRING LANGUAGE PYTHON { 
return d; };
 #SELECT pyapi_timestamp(d) FROM timestamp_table;
-% sys.L1 # table_name
-% L1 # name
+% sys.L2 # table_name
+% L2 # name
 % clob # type
-% 26 # length
-[ "2000-01-01 12:00:00.000000" ]
+% 23 # length
+[ "2000-01-01 12:00:00.000"    ]
 #CREATE TABLE decimal_table(d DECIMAL(10, 3)); # DECIMAL is converted to dbl
 #INSERT INTO decimal_table VALUES (123.4567);
 [ 1    ]
 #CREATE FUNCTION pyapi_decimal(d DECIMAL) RETURNS DOUBLE LANGUAGE PYTHON { 
return d; };
 #SELECT pyapi_decimal(d) FROM decimal_table;
-% sys.L1 # table_name
-% L1 # name
+% sys.L2 # table_name
+% L2 # name
 % double # type
 % 24 # length
 [ 123.457      ]
@@ -76,7 +76,7 @@ Ready.
 #    return result
 #};
 #SELECT * FROM pyapi_ret_date();
-% . # table_name
+% .L1 # table_name
 % d # name
 % date # type
 % 10 # length
@@ -89,7 +89,7 @@ Ready.
 #    return result
 #};
 #SELECT * FROM pyapi_ret_time();
-% . # table_name
+% .L1 # table_name
 % d # name
 % time # type
 % 8 # length
@@ -102,7 +102,7 @@ Ready.
 #    return result
 #};
 #SELECT * FROM pyapi_ret_timestamp();
-% . # table_name
+% .L1 # table_name
 % d # name
 % timestamp # type
 % 26 # length
@@ -115,7 +115,7 @@ Ready.
 #    return result
 #};
 #SELECT * FROM pyapi_ret_decimal();
-% . # table_name
+% .L1 # table_name
 % d # name
 % decimal # type
 % 20 # length
@@ -135,13 +135,21 @@ Ready.
 #    return numpy.mean(d) # average 100k decimal values
 #};
 #SELECT pyapi_inp_decimal(d) FROM pyapi_ret_decimal();
-% .L1 # table_name
-% L1 # name
+% .L3 # table_name
+% L3 # name
 % double # type
 % 24 # length
 [ 5e+04        ]
-#create table uuid_tbl as select uuid() AS d with data;
-#CREATE FUNCTION pyapi_interval(d UUID) RETURNS DOUBLE LANGUAGE PYTHON { 
return d; };
+#CREATE TABLE uuid_tbl(d UUID);
+#INSERT INTO uuid_tbl VALUES ('54771a16-b4ad-4f1a-a9b7-4d8e8ca6fb7c');
+[ 1    ]
+#CREATE FUNCTION pyapi_interval(d UUID) RETURNS STRING LANGUAGE PYTHON { 
return d; };
+#SELECT pyapi_interval(d) FROM uuid_tbl;
+% sys.L2 # table_name
+% L2 # name
+% clob # type
+% 36 # length
+[ "54771a16-b4ad-4f1a-a9b7-4d8e8ca6fb7c"       ]
 #ROLLBACK;
 
 # 18:18:39 >  
diff --git a/sql/backends/monet5/UDF/pyapi/connection.c 
b/sql/backends/monet5/UDF/pyapi/connection.c
--- a/sql/backends/monet5/UDF/pyapi/connection.c
+++ b/sql/backends/monet5/UDF/pyapi/connection.c
@@ -63,7 +63,7 @@ static PyObject *
                 }
                 PyDict_SetItem(result, 
PyString_FromString(output->cols[i].name), numpy_array);
                 Py_DECREF(numpy_array);
-                BBPunfix(b->batCacheid);
+                BBPunfix(input.bat->batCacheid);
             }
             _connection_cleanup_result(output);
             return result;
diff --git a/sql/backends/monet5/UDF/pyapi/pyapi.c 
b/sql/backends/monet5/UDF/pyapi/pyapi.c
--- a/sql/backends/monet5/UDF/pyapi/pyapi.c
+++ b/sql/backends/monet5/UDF/pyapi/pyapi.c
@@ -104,7 +104,6 @@ CREATE_SQL_FUNCTION_PTR(str,batstr_2time
 CREATE_SQL_FUNCTION_PTR(str,batstr_2time_daytime);
 CREATE_SQL_FUNCTION_PTR(str,batstr_2_date);
 CREATE_SQL_FUNCTION_PTR(str,batdbl_num2dec_lng);
-CREATE_SQL_FUNCTION_PTR(str,SQLbatstr_cast);
 
 static MT_Lock pyapiLock;
 static MT_Lock queryLock;
@@ -156,8 +155,9 @@ PyAPIevalAggrMap(Client cntxt, MalBlkPtr
 }
 
 int GetSQLType(sql_subtype *sql_subtype);
+bit IsStandardBATType(int type);
 bit ConvertableSQLType(sql_subtype *sql_subtype);
-str ConvertFromSQLType(Client cntxt, BAT *b, sql_subtype *sql_subtype, BAT 
**ret_bat, int *ret_type);
+str ConvertFromSQLType(BAT *b, sql_subtype *sql_subtype, BAT **ret_bat, int 
*ret_type);
 str ConvertToSQLType(Client cntxt, BAT *b, sql_subtype *sql_subtype, BAT 
**ret_bat, int *ret_type);
 
 //! The main PyAPI function, this function does everything PyAPI related
@@ -315,22 +315,6 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb
         }
         if (argnode) {
             inp->sql_subtype = &((sql_arg*)argnode->data)->type;
-
-            if (ConvertableSQLType(inp->sql_subtype)) { // if the sql type is 
set, we have to do some conversion
-                if (inp->scalar) {
-                    // todo: scalar SQL types
-                    msg = PyError_CreateException("Scalar SQL types haven't 
been implemented yet... sorry", NULL);
-                    goto wrapup;
-                } else {
-                    BAT *ret_bat = NULL;
-                    msg = ConvertFromSQLType(cntxt, inp->bat, 
inp->sql_subtype, &ret_bat, &inp->bat_type);
-                    if (msg != MAL_SUCCEED) {
-                        goto wrapup;
-                    }
-                    inp->bat = ret_bat;
-                }
-            }
-            b = inp->bat;
             argnode = argnode->next;
         }
     }
@@ -475,6 +459,11 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb
                             size_t size = 0;
                             size_t position = 0;
                             char *result_ptr;
+                            BAT **result_columns = GDKzalloc(sizeof(BAT*) * 
output->nr_cols);
+                            if (!result_columns) {
+                                msg = createException(MAL, "pyapi.eval", 
MAL_MALLOC_FAIL" result column set.");
+                                goto wrapup;
+                            }
 
                             for (i = 0; i < output->nr_cols; i++) {
                                 res_col col = output->cols[i];
@@ -482,26 +471,31 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb
                                 sql_subtype *subtype = &col.type;
 
                                 // if the sql type is set, we have to do some 
conversion
-                                // we do this before sending the BATs to the 
other process, otherwise there are complaints about not being able to find a 
BATdescriptor
-                                if (ConvertableSQLType(subtype)) {
+                                // we do this before sending the BATs to the 
other process
+                                if (!IsStandardBATType(b->ttype) || 
ConvertableSQLType(subtype)) {
                                     BAT *ret_bat = NULL;
                                     int ret_type;
-                                    msg = ConvertFromSQLType(cntxt, b, 
subtype, &ret_bat, &ret_type);
+                                    msg = ConvertFromSQLType(b, subtype, 
&ret_bat, &ret_type);
                                     if (msg != MAL_SUCCEED) {
+                                        BBPunfix(b->batCacheid);
+                                        _connection_cleanup_result(output);
+                                        GDKfree(result_columns);
+                                        msg = createException(MAL, 
"pyapi.eval", "Failed to convert BAT.");
                                         goto wrapup;
                                     }
-                                    output->cols[i].b = ret_bat->batCacheid;
+                                    BBPunfix(b->batCacheid);
+                                    result_columns[i] = ret_bat;
+                                } else {
+                                    result_columns[i] = b;
                                 }
-                                BBPunfix(col.b);
                             }
 
                             // first obtain the total size of the shared 
memory region
                             // the region is structured as 
[COLNAME][BAT][DATA]([VHEAP][VHEAPDATA])
                             for (i = 0; i < output->nr_cols; i++) {
                                 res_col col = output->cols[i];
-                                BAT* b = BATdescriptor(col.b);
+                                BAT* b = result_columns[i];
                                 size += GDKbatcopysize(b, col.name);
-                                BBPunfix(b->batCacheid);
                             }
 
                             query_ptr->memsize = size;
@@ -515,16 +509,19 @@ str PyAPIeval(Client cntxt, MalBlkPtr mb
                             if (GDKinitmmap(query_ptr->mmapid + 0, size, 
(void**) &result_ptr, NULL, &msg) != GDK_SUCCEED) {
                                 _connection_cleanup_result(output);
                                 GDKchangesemval(query_sem, 1, 1, &msg);
+                                msg = createException(MAL, "pyapi.eval", "");
+                                GDKfree(result_columns);
                                 goto wrapup;
                             }
 
                             // copy the data into the shared memory region
                             for (i = 0; i < output->nr_cols; i++) {
                                 res_col col = output->cols[i];
-                                BAT* b = BATdescriptor(col.b);
+                                BAT* b = result_columns[i];
                                 result_ptr += GDKbatcopy(result_ptr + 
position, b, col.name);
                                 BBPunfix(b->batCacheid);
                             }
+                            GDKfree(result_columns);
                             //detach the main process from this piece of 
shared memory so the child process can delete it
                             _connection_cleanup_result(output);
                         }
@@ -1338,7 +1335,6 @@ str
                        LOAD_SQL_FUNCTION_PTR(batstr_2time_daytime);
                        LOAD_SQL_FUNCTION_PTR(batstr_2_date);
                        LOAD_SQL_FUNCTION_PTR(batdbl_num2dec_lng);
-                       LOAD_SQL_FUNCTION_PTR(SQLbatstr_cast);
             if (msg != MAL_SUCCEED) {
                 MT_lock_unset(&pyapiLock);
                 return msg;
@@ -1583,13 +1579,30 @@ PyObject *PyArrayObject_FromBAT(PyInput 
 
     assert(!inp->scalar); //input has to be a BAT
 
-    if (b == NULL)
-    {
+    if (!b) {
         // No BAT was found, we can't do anything in this case
         msg = createException(MAL, "pyapi.eval", MAL_MALLOC_FAIL" bat.");
         goto wrapup;
     }
 
+    if (!IsStandardBATType(inp->bat_type) || 
ConvertableSQLType(inp->sql_subtype)) { // if the sql type is set, we have to 
do some conversion
+        if (inp->scalar) {
+            // todo: scalar SQL types
+            msg = PyError_CreateException("Scalar SQL types haven't been 
implemented yet... sorry", NULL);
+            goto wrapup;
+        } else {
+            BAT *ret_bat = NULL;
+            msg = ConvertFromSQLType(inp->bat, inp->sql_subtype, &ret_bat, 
&inp->bat_type);
+            if (msg != MAL_SUCCEED) {
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to