Changeset: d750ee07df6e for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=d750ee07df6e
Modified Files:
gdk/gdk_utils.c
gdk/gdk_utils.h
monetdb5/extras/pyapi/Benchmarks/monetdb_testing.py
monetdb5/extras/pyapi/Tests/pyapi_returntypes.stable.err
monetdb5/mal/mal_client.h
sql/backends/monet5/sql.c
tools/embeddedpy/embeddedpy.c
Branch: pyapi
Log Message:
Merge with embedded branch, removed some hacks.
diffs (truncated from 829 to 300 lines):
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -1572,6 +1572,10 @@ GDKclrerr(void)
*buf = 0;
}
+jmp_buf GDKfataljump;
+str GDKfatalmsg;
+bit GDKfataljumpenable = 0;
+
/* coverity[+kill] */
void
GDKfatal(const char *format, ...)
@@ -1592,26 +1596,30 @@ GDKfatal(const char *format, ...)
va_start(ap, format);
vsnprintf(message + len, sizeof(message) - (len + 2), format, ap);
va_end(ap);
+ if (!GDKfataljumpenable) {
+ fputs(message, stderr);
+ fputs("\n", stderr);
+ fflush(stderr);
- fputs(message, stderr);
- fputs("\n", stderr);
- fflush(stderr);
-
- /*
- * Real errors should be saved in the lock file for post-crash
- * inspection.
- */
- if (GDKexiting()) {
- fflush(stdout);
- MT_exit_thread(1);
- /* exit(1); */
- } else {
- GDKlog("%s", message);
-#ifdef COREDUMP
- abort();
-#else
- GDKexit(1);
-#endif
+ /*
+ * Real errors should be saved in the lock file for post-crash
+ * inspection.
+ */
+ if (GDKexiting()) {
+ fflush(stdout);
+ MT_exit_thread(1);
+ /* exit(1); */
+ } else {
+ GDKlog("%s", message);
+ #ifdef COREDUMP
+ abort();
+ #else
+ GDKexit(1);
+ #endif
+ }
+ } else { // in embedded mode, we really don't want to kill our host
+ GDKfatalmsg = GDKstrdup(message);
+ longjmp(GDKfataljump, 42);
}
}
diff --git a/gdk/gdk_utils.h b/gdk/gdk_utils.h
--- a/gdk/gdk_utils.h
+++ b/gdk/gdk_utils.h
@@ -10,6 +10,7 @@
#define _GDK_UTILS_H_
#include <monet_options.h>
+#include <setjmp.h>
gdk_export BAT *GDKkey;
gdk_export BAT *GDKval;
@@ -94,4 +95,8 @@ gdk_export const char *GDKversion(void);
gdk_export int GDKextractParentAndLastDirFromPath(const char *path, char
*last_dir_parent, char *last_dir);
+// these are used in embedded mode to jump out of GDKfatal
+gdk_export jmp_buf GDKfataljump;
+gdk_export str GDKfatalmsg;
+gdk_export bit GDKfataljumpenable;
#endif /* _GDK_UTILS_H_ */
diff --git a/monetdb5/extras/pyapi/Benchmarks/monetdb_testing.py
b/monetdb5/extras/pyapi/Benchmarks/monetdb_testing.py
--- a/monetdb5/extras/pyapi/Benchmarks/monetdb_testing.py
+++ b/monetdb5/extras/pyapi/Benchmarks/monetdb_testing.py
@@ -572,7 +572,12 @@ else:
f.close()
database_final()
- input_type = "integer"
+ input_columns = dict()
+ input_columns['a'] = 'integer'
+
+ output_columns = dict()
+ output_columns['_normal_return'] = 'integer'
+
function_name = str(args_test_type).lower()
function = None
if function_name == "identity":
@@ -590,6 +595,22 @@ else:
return numpy.percentile(a, 50)
function = quantile
return_value = "integer"
+ if function_name == "voter_classification":
+ input_columns = dict()
+ input_columns['county'] = 'string'
+ input_columns['precinct'] = 'string'
+ input_columns['sex'] = 'string'
+ input_columns['race'] = 'string'
+ input_columns['ethnicity'] = 'string'
+ input_columns['age'] = 'string'
+ input_columns['pr_precinct'] = 'string'
+ input_columns['pr_republican_percentage'] = 'string'
+ input_columns['pr_republican_percentage'] = 'string'
+ #todo
+
+ def voter_classification(input_cols):
+ return False
+
import inspect
inspect_result = inspect.getsourcelines(function)
diff --git a/monetdb5/extras/pyapi/Tests/pyapi_returntypes.stable.err
b/monetdb5/extras/pyapi/Tests/pyapi_returntypes.stable.err
--- a/monetdb5/extras/pyapi/Tests/pyapi_returntypes.stable.err
+++ b/monetdb5/extras/pyapi/Tests/pyapi_returntypes.stable.err
@@ -31,45 +31,45 @@ stderr of test 'pyapi_returntypes` in di
# 23:33:07 > "mclient" "-lmal" "-ftest" "-Eutf-8" "-i" "-e"
"--host=/var/tmp/mtest-20340" "--port=36739"
# 23:33:07 >
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = r:bat[:oid,:int] := pyapi.eval(nil:ptr,"return(\"Test\")");
ERROR = !MALException:pyapi.eval:Could not convert from type STRING to type int
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = (r:bat[:oid,:int], s:bat[:oid,:int]) := pyapi.eval(nil:ptr,"class
NewClass:\n x = 5\n\nreturn(NewClass())");
ERROR = !MALException:pyapi.eval:Unsupported result object. Expected either a
list, dictionary, a numpy array, a numpy masked array or a pandas data frame,
but received an object of type "<type 'instance'>"
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = (r:bat[:oid,:int], s:bat[:oid,:int]) :=
pyapi.eval(nil:ptr,"return(12)");
ERROR = !MALException:pyapi.eval:A single scalar was returned, yet we expect a
list of 2 columns. We can only convert a single scalar into a single column,
thus the result is invalid.
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = (r:bat[:oid,:int], s:bat[:oid,:int]) :=
pyapi.eval(nil:ptr,"return(numpy.array([12]))");
ERROR = !MALException:pyapi.eval:A single array was returned, yet we expect a
list of 2 columns. The result is invalid.
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = (r:bat[:oid,:int], s:bat[:oid,:int]) :=
pyapi.eval(nil:ptr,"return([12])");
ERROR = !MALException:pyapi.eval:A single array was returned, yet we expect a
list of 2 columns. The result is invalid.
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = r:bat[:oid,:int] := pyapi.eval(nil:ptr,"return([[33,24,55],
[44,66,345]])");
ERROR = !MALException:pyapi.eval:An array of size 2 was returned, yet we
expect a list of 1 columns. The result is invalid.
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = a:bat[:oid,:str] := pyapi.eval(nil:ptr,"x =
unicode(\"hello\")\nreturn(x.encode(\"utf32\"))");
ERROR = !MALException:pyapi.eval:Invalid string encoding used. Please return a
regular ASCII string, or a Numpy_Unicode object.
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = bb:bat[:oid,:int] := pyapi.eval(nil:ptr,"return (1");
ERROR = !MALException:pyapi.eval:Could not parse Python code
- ! 1. def pyfun(_columns,_column_types,_values):
- !> 2. return (1
+ !def pyfun(_columns,_column_types,_values):
+ ! return (1
!invalid syntax (<string>, line 2)
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = cc:bat[:oid,:int] := pyapi.eval(nil:ptr,"x = 4\n x++\n\treturn (x)");
ERROR = !MALException:pyapi.eval:Could not parse Python code
- ! 1. def pyfun(_columns,_column_types,_values):
- ! 2. x = 4
- !> 3. x++
- ! 4. return (x)
+ !def pyfun(_columns,_column_types,_values):
+ ! x = 4
+ ! x++
+ ! return (x)
!unexpected indent (<string>, line 3)
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = (str1:bat[:oid,:str], str2:bat[:oid,:str]) := pyapi.eval(nil:ptr,"x =
unicode(\"hello\")\nreturn(numpy.array([[x.encode(\"utf32\")],
[x.encode(\"utf32\")]]))");
ERROR = !MALException:pyapi.eval:Invalid string encoding used. Please return a
regular ASCII string, or a Numpy_Unicode object.
-MAPI = (monetdb) /var/tmp/mtest-14418/.s.monetdb.33668
+MAPI = (monetdb) /var/tmp/mtest-8465/.s.monetdb.38932
QUERY = (str1:bat[:oid,:str], str2:bat[:oid,:str]) :=
pyapi.eval(nil:ptr,"return(numpy.array([[\"Hëllo\", \"Hello Again\"], [\"Hello
Again Again\",\"That's quite enough.\"]]))");
ERROR = !MALException:pyapi.eval:Invalid string encoding used. Please return a
regular ASCII string, or a Numpy_Unicode object.
diff --git a/monetdb5/mal/mal_client.h b/monetdb5/mal/mal_client.h
--- a/monetdb5/mal/mal_client.h
+++ b/monetdb5/mal/mal_client.h
@@ -164,12 +164,6 @@ typedef struct CLIENT {
*/
void *sqlcontext;
- /* -->HACK<--
- This is used as a hack to insert data into tables directly from a BAT.
This should be removed later.
- */
- void **_append_bats;
- char **_append_column_names;
- int _append_columns;
/*
* keep track of which instructions are currently being executed
*/
diff --git a/sql/backends/monet5/sql.c b/sql/backends/monet5/sql.c
--- a/sql/backends/monet5/sql.c
+++ b/sql/backends/monet5/sql.c
@@ -1963,22 +1963,7 @@ mvc_append_wrap(Client cntxt, MalBlkPtr
sql_table *t;
sql_column *c;
BAT *b = 0;
-
- //HACK
- //This is where we check the client for any columns to append INSTEAD
OF THE SUPPLIED COLUMNS TO THIS FUNCTION
- //If they are there, we append those columns instead
- //This should be changed to a proper function that takes a BAT and
inserts it into a table
- if (cntxt->_append_columns > 0) {
- int i;
- for(i = 0; i < cntxt->_append_columns; i++) {
- if (strcmp(cname, cntxt->_append_column_names[i]) == 0)
{
- ins = (ptr) ((BAT**)cntxt->_append_bats)[i];
- break;
- }
- }
- tpe = TYPE_bat;
- }
-
+
*res = 0;
if ((msg = getSQLContext(cntxt, mb, &m, NULL)) != NULL)
return msg;
diff --git a/tools/embeddedpy/embeddedpy.c b/tools/embeddedpy/embeddedpy.c
--- a/tools/embeddedpy/embeddedpy.c
+++ b/tools/embeddedpy/embeddedpy.c
@@ -27,22 +27,29 @@
#include "mal_linker.h"
#include "msabaoth.h"
#include "sql_scenario.h"
+#include "gdk_utils.h"
#include "pyapi.h"
#include "pytypes.h"
/////////////////////////////////////////////////////////////////////////////////////////////////
-// copy paste from embedded.c
-bool monetdb_isinit(void);
-int monetdb_startup(char* dir, char silent);
-char* monetdb_query(char* query, void** result);
+// copy paste from embedded.h
+typedef struct append_data {
+ char* colname;
+ ssize_t batid;
+} append_data;
+
+str monetdb_startup(char* dir, char silent);
+str monetdb_query(char* query, void** result);
+str monetdb_create_table(char *schema, char *table_name, append_data *ad, int
ncols);
+str monetdb_append(const char* schema, const char* table, append_data *ad, int
ncols);
void monetdb_cleanup_result(void* output);
-str monetdb_get_columns(char *table_name, int *column_count, char
***column_names, int **column_types);
-str monetdb_create_table(char *table_name, size_t columns, BAT **bats, char
**column_names);
-str monetdb_insert_into_table(char *table_name, size_t columns, BAT **bats,
char **column_names);
+static str monetdb_get_columns(const char* schema_name, const char
*table_name, int *column_count, char ***column_names, int **column_types) ;
+
+static bit monetdb_embedded_initialized = 0;
+static MT_Lock monetdb_embedded_lock;
/////////////////////////////////////////////////////////////////////////////////////////////////
-//LOCALSTATEDIR
PyObject *monetdb_init(PyObject *self, PyObject *args)
{
(void) self;
@@ -52,17 +59,18 @@ PyObject *monetdb_init(PyObject *self, P
}
{
+ char *msg;
char *directory = &(((PyStringObject*)args)->ob_sval[0]);
printf("Making directory %s\n", directory);
if (GDKcreatedir(directory) != GDK_SUCCEED) {
PyErr_Format(PyExc_Exception, "Failed to create
directory %s.", directory);
return NULL;
}
- if (monetdb_startup(directory, 1) < 0) {
- PyErr_SetString(PyExc_Exception, "Failed to initialize
MonetDB with the specified directory.");
+ msg = monetdb_startup(directory, 1);
+ if (msg != MAL_SUCCEED) {
+ PyErr_Format(PyExc_Exception, "Failed to initialize
MonetDB. %s", msg);
return NULL;
}
- GDKsetenv("enable_numpystringarray", "true");
PyAPIprelude(NULL);
}
Py_RETURN_NONE;
@@ -75,7 +83,7 @@ PyObject *monetdb_sql(PyObject *self, Py
PyErr_SetString(PyExc_TypeError, "Expected a SQL query as a
single string argument.");
return NULL;
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list