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