Changeset: 0e500eac6fcc for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0e500eac6fcc
Modified Files:
        monetdb5/extras/pyapi/connection.c
        monetdb5/extras/pyapi/pyapi.c
        monetdb5/extras/pyapi/pyapi.h
Branch: pythonudf
Log Message:

Use function pointers to execute SQL statements because Windows does not like 
unresolved references.

Previously we just relied on the SQL module being loaded at runtime, and left 
the references unresolved at link time. This is not allowed on Windows.


diffs (187 lines):

diff --git a/monetdb5/extras/pyapi/connection.c 
b/monetdb5/extras/pyapi/connection.c
--- a/monetdb5/extras/pyapi/connection.c
+++ b/monetdb5/extras/pyapi/connection.c
@@ -9,6 +9,9 @@
 #define PyString_FromString PyUnicode_FromString
 #endif
 
+CREATE_SQL_FUNCTION_PTR(void,res_table_destroy,(res_table*));
+CREATE_SQL_FUNCTION_PTR(str,SQLstatementIntern_ext,(Client, str *, str, int, 
bit, res_table **, bit));
+
 static PyObject *
 _connection_execute(Py_ConnectionObject *self, PyObject *args)
 {
@@ -230,13 +233,13 @@ PyTypeObject Py_ConnectionType = {
 
 void _connection_cleanup_result(void* output) 
 {
-    res_table_destroy((res_table*) output);
+    (*res_table_destroy_ptr)((res_table*) output);
 }
 
 char* _connection_query(Client cntxt, char* query, res_table** result) {
     str res = MAL_SUCCEED;
     Client c = cntxt;
-    res = SQLstatementIntern_ext(c, &query, "name", 1, 0, result, 1);
+    res = (*SQLstatementIntern_ext_ptr)(c, &query, "name", 1, 0, result, 1);
     return res;
 }
 
@@ -262,6 +265,9 @@ void _connection_init(void)
 {
     import_array();
 
+    LOAD_SQL_FUNCTION_PTR(res_table_destroy);
+    LOAD_SQL_FUNCTION_PTR(SQLstatementIntern_ext);
+
     if (PyType_Ready(&Py_ConnectionType) < 0)
         return;
 }
diff --git a/monetdb5/extras/pyapi/pyapi.c b/monetdb5/extras/pyapi/pyapi.c
old mode 100755
new mode 100644
--- a/monetdb5/extras/pyapi/pyapi.c
+++ b/monetdb5/extras/pyapi/pyapi.c
@@ -94,6 +94,18 @@ static char* FunctionBasePath(void) {
     return basepath;
 }
 
+CREATE_SQL_FUNCTION_PTR(str,batbte_dec2_dbl,(bat*, int*, bat*));
+CREATE_SQL_FUNCTION_PTR(str,batsht_dec2_dbl,(bat*, int*, bat*));
+CREATE_SQL_FUNCTION_PTR(str,batint_dec2_dbl,(bat*, int*, bat*));
+CREATE_SQL_FUNCTION_PTR(str,batwrd_dec2_dbl,(bat*, int*, bat*));
+CREATE_SQL_FUNCTION_PTR(str,batlng_dec2_dbl,(bat*, int*, bat*));
+CREATE_SQL_FUNCTION_PTR(str,bathge_dec2_dbl,(bat*, int*, bat*));
+CREATE_SQL_FUNCTION_PTR(str,batstr_2time_timestamp,(bat*, bat*, int*));
+CREATE_SQL_FUNCTION_PTR(str,batstr_2time_daytime,(bat*, bat*, int*));
+CREATE_SQL_FUNCTION_PTR(str,batstr_2_date,(bat*, bat*));
+CREATE_SQL_FUNCTION_PTR(str,batdbl_num2dec_lng,(bat*, bat*, int*,int*));
+CREATE_SQL_FUNCTION_PTR(str,SQLbatstr_cast,(Client, MalBlkPtr, MalStkPtr, 
InstrPtr));
+
 static MT_Lock pyapiLock;
 static MT_Lock queryLock;
 static int pyapiInitialized = FALSE;
@@ -1588,6 +1600,18 @@ str
                 return createException(MAL, "pyapi.eval", "Failed to load 
function \"loads\" from Marshal module.");
             }
             PyEval_SaveThread();
+            LOAD_SQL_FUNCTION_PTR(batbte_dec2_dbl);
+            LOAD_SQL_FUNCTION_PTR(batsht_dec2_dbl);
+            LOAD_SQL_FUNCTION_PTR(batint_dec2_dbl);
+            LOAD_SQL_FUNCTION_PTR(batwrd_dec2_dbl);
+            LOAD_SQL_FUNCTION_PTR(batlng_dec2_dbl);
+            LOAD_SQL_FUNCTION_PTR(bathge_dec2_dbl);
+            LOAD_SQL_FUNCTION_PTR(bathge_dec2_dbl);
+            LOAD_SQL_FUNCTION_PTR(batstr_2time_timestamp);
+            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);
             pyapiInitialized++;
         }
         MT_lock_unset(&pyapiLock);
@@ -2620,7 +2644,7 @@ str ConvertFromSQLType(Client cntxt, BAT
         stk->stk[6].val.ival = digits;
         stk->stk[6].vtype = TYPE_int;
 
-        res = SQLbatstr_cast(cntxt, &mb, stk, pci);
+        res = (*SQLbatstr_cast_ptr)(cntxt, &mb, stk, pci);
 
         if (res == MAL_SUCCEED) {
             *ret_bat = BATdescriptor(stk->stk[0].val.bval);
@@ -2642,23 +2666,23 @@ str ConvertFromSQLType(Client cntxt, BAT
         switch(bat_type) 
         {
             case TYPE_bte:
-                res = batbte_dec2_dbl(&result, &hpos, &b->batCacheid);
+                res = (*batbte_dec2_dbl_ptr)(&result, &hpos, &b->batCacheid);
                 break;
             case TYPE_sht:
-                res = batsht_dec2_dbl(&result, &hpos, &b->batCacheid);
+                res = (*batsht_dec2_dbl_ptr)(&result, &hpos, &b->batCacheid);
                 break;
             case TYPE_int:
-                res = batint_dec2_dbl(&result, &hpos, &b->batCacheid);
+                res = (*batint_dec2_dbl_ptr)(&result, &hpos, &b->batCacheid);
                 break;
             case TYPE_wrd:
-                res = batwrd_dec2_dbl(&result, &hpos, &b->batCacheid);
+                res = (*batwrd_dec2_dbl_ptr)(&result, &hpos, &b->batCacheid);
                 break;
             case TYPE_lng:
-                res = batlng_dec2_dbl(&result, &hpos, &b->batCacheid);
+                res = (*batlng_dec2_dbl_ptr)(&result, &hpos, &b->batCacheid);
                 break;
 #ifdef HAVE_HGE
             case TYPE_hge:
-                res = bathge_dec2_dbl(&result, &hpos, &b->batCacheid);
+                res = (*bathge_dec2_dbl_ptr)(&result, &hpos, &b->batCacheid);
                 break;
 #endif
             default: 
@@ -2687,16 +2711,16 @@ ConvertToSQLType(Client cntxt, BAT *b, e
     switch(sqltype)
     {
         case sql_timestamp:
-            res = batstr_2time_timestamp(&result_bat, &b->batCacheid, &digits);
+            res = (*batstr_2time_timestamp_ptr)(&result_bat, &b->batCacheid, 
&digits);
             break;
         case sql_time:
-            res = batstr_2time_daytime(&result_bat, &b->batCacheid, &digits);
+            res = (*batstr_2time_daytime_ptr)(&result_bat, &b->batCacheid, 
&digits);
             break;
         case sql_date:
-            res = batstr_2_date(&result_bat, &b->batCacheid);
+            res = (*batstr_2_date_ptr)(&result_bat, &b->batCacheid);
             break;
         case sql_decimal:
-            res = batdbl_num2dec_lng(&result_bat, &b->batCacheid, &digits, 
&scale);
+            res = (*batdbl_num2dec_lng_ptr)(&result_bat, &b->batCacheid, 
&digits, &scale);
             break;
         default: 
             return createException(MAL, "pyapi.eval", "Convert To SQL Type: 
Unrecognized SQL type %s (%d).", sql_subtype->type->sqlname, sqltype);
@@ -2863,3 +2887,16 @@ bool Python_ReleaseGIL(bool state)
     PyGILState_Release(gstate);
     return 0;
 }
+
+pyapi_export 
+void* lookup_function(char *func, char* library) {
+    void *dl, *fun;
+    dl = mdlopen(library, RTLD_NOW | RTLD_GLOBAL);
+    if (dl == NULL) {
+        return NULL;
+    }
+    fun = dlsym(dl, func);
+    dlclose(dl);
+    return fun;
+}
+
diff --git a/monetdb5/extras/pyapi/pyapi.h b/monetdb5/extras/pyapi/pyapi.h
--- a/monetdb5/extras/pyapi/pyapi.h
+++ b/monetdb5/extras/pyapi/pyapi.h
@@ -62,6 +62,7 @@
 #endif
 
 #ifdef _PYAPI_WARNINGS_
+bool option_warning;
 #define WARNING_MESSAGE(...) {           \
     if (option_warning) {                \
     fprintf(stderr, __VA_ARGS__);        \
@@ -90,4 +91,16 @@ pyapi_export str PyAPIprelude(void *ret)
 
 int PyAPIEnabled(void);
 
+pyapi_export void* lookup_function(char *func, char* library);
+
+#define CREATE_SQL_FUNCTION_PTR(retval, fcnname, params) \
+    typedef retval (*fcnname##_ptr_tpe)params;                   \
+    fcnname##_ptr_tpe fcnname##_ptr = NULL;
+
+#define LOAD_SQL_FUNCTION_PTR(fcnname)                                   \
+    fcnname##_ptr = (fcnname##_ptr_tpe) lookup_function(#fcnname, "sql");      
  \
+    if (fcnname##_ptr == NULL) {                                         \
+        WARNING_MESSAGE("Failed to load function %s", #fcnname);               
        \
+    }
+
 #endif /* _PYPI_LIB_ */
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to