Changeset: 34be56701bf5 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=34be56701bf5
Modified Files:
        configure.ag
        monetdb5/extras/Makefile.ag
        monetdb5/extras/pyapi/Makefile.ag
        monetdb5/extras/pyapi/connection.c
        monetdb5/extras/pyapi/connection.h
        monetdb5/extras/pyapi/formatinput.c
        monetdb5/extras/pyapi/formatinput.h
        monetdb5/extras/pyapi/pyapi.c
        monetdb5/extras/pyapi/pyapi.h
        monetdb5/extras/pyapi/pyapi.mal
        monetdb5/extras/pyapi/pytypes.c
        monetdb5/extras/pyapi/pytypes.h
        monetdb5/extras/pyapi/type_conversion.c
        monetdb5/extras/pyapi/type_conversion.h
        monetdb5/extras/pyapi/unicode.c
        monetdb5/extras/pyapi/unicode.h
        monetdb5/optimizer/opt_prelude.c
        monetdb5/optimizer/opt_prelude.h
        monetdb5/optimizer/opt_support.c
        sql/backends/monet5/sql_gencode.c
        sql/include/sql_catalog.h
        sql/server/rel_psm.c
        sql/server/sql_parser.y
        tools/merovingian/daemon/forkmserver.c
        tools/merovingian/daemon/merovingian.c
        tools/merovingian/utils/properties.c
        tools/merovingian/utils/utils.c
Branch: python3udf
Log Message:

Initial commit for new branch testing Python3 UDFs using LANGUAGE 
PYTHON3/PYTHON3_MAP.

This should be a relatively short lived branch.

Python3 UDFs can be enabled during configure using --enable-py3integration and 
the mserver should be started with --set embedded_py=true to enable them at 
runtime.

One caveat is that you can't currently compile with both PYTHON2 and PYTHON3 
UDFs enabled because of runtime linking issues. Both PYTHON2 and PYTHON3 use 
the same functions, and if MonetDB is linked against both py2 and py3 libraries 
then py2 code will be called when py3 code is meant to be called, causing 
strange issues. Thus currently you have to specify if you want py2 or py3 udfs 
at compile time.


diffs (truncated from 862 to 300 lines):

diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -279,6 +279,13 @@ AC_ARG_ENABLE(pyintegration,
        enable_pyintegration=$enableval,
        enable_pyintegration=$dft_pyintegration)
 
+dft_py3integration=auto
+AC_ARG_ENABLE(py3integration,
+       AS_HELP_STRING([--enable-py3integration],
+               [enable support for Python 3 integration into MonetDB 
(default=auto)]),
+       enable_py3integration=$enableval,
+       enable_py3integration=$dft_py3integration)
+
 dft_odbc=auto
 AC_ARG_ENABLE(odbc,
        AS_HELP_STRING([--enable-odbc],
@@ -1284,13 +1291,13 @@ case "$have_python3" in
                ;;
 esac
 
-AC_ARG_WITH(pyconfig,
-       AS_HELP_STRING([--with-pyconfig=FILE], [python-config is installed as 
FILE]),
-       have_pyconfig="$withval")
-
-AC_ARG_WITH(pyversion,
-       AS_HELP_STRING([--with-pyversion=FILE], [python is installed as FILE]),
-       have_pyversion="$withval")
+AC_ARG_WITH(py2config,
+       AS_HELP_STRING([--with-py2config=FILE], [python2-config is installed as 
FILE]),
+       have_py2config="$withval")
+
+AC_ARG_WITH(py3config,
+       AS_HELP_STRING([--with-py3config=FILE], [python3-config is installed as 
FILE]),
+       have_py3config="$withval")
 
 dnl Figure out a default for PYTHON2 or PYTHON3
 AC_PATH_PROG(PYTHON,python,no,$PATH)
@@ -2331,27 +2338,24 @@ if test "x$enable_pyintegration" != xno;
                AC_MSG_ERROR([--enable-pyintegration value must be 
yes|no|auto|absolute path of python-config])
                ;;
        esac
-       if test "x$have_pyconfig" = x; then
-               AC_PATH_PROG(PYCMD,python-config,,$XPATH)
-               if test "x$PYCMD" = x; then
+       if test "x$have_py2config" = x; then
+               AC_PATH_PROG(PY2CONFIG,python2-config,,$XPATH)
+               if test "x$PY2CONFIG" = x; then
                        if test "x$enable_pyintegration" = xyes; then
-                               AC_MSG_ERROR([python-config library required 
for Python integration support])
+                               AC_MSG_ERROR([python2-config library required 
for Python integration support])
                        else
                                have_libpy="no"
-                               why_have_libpy="(python-config command not 
found)"
+                               why_have_libpy="(python2-config command not 
found)"
                                enable_pyintegration=no
-                               disable_pyintegration="(python-config command 
not found)"
+                               disable_pyintegration="(python2-config command 
not found)"
                        fi
                fi
        else
-               PYCMD="$have_pyconfig"
+               PY2CONFIG="$have_py2config"
        fi
 
-       if test "x$have_pyversion" = x; then
-               PYTHON_CMD=$PYTHON2
-       else
-               PYTHON_CMD=$have_pyversion
-       fi
+       PYTHON_CMD=$PYTHON2
+
        NUMPYVER=`$PYTHON_CMD -c "import numpy; 
print(int(numpy.__version__.split('.').__getitem__(1)) >= 7)"`
        #check numpyconfig.h because autoconf tests includes by compiling a 
small C program, and other numpy headers do not compile without Python.h
        AC_CHECK_HEADER(
@@ -2379,7 +2383,7 @@ if test "x$enable_pyintegration" != xno;
                fi
        else
                libpy_CFLAGS=`$PYTHON_CMD -c "from distutils.sysconfig import 
get_python_inc; import numpy; print(' -I' + get_python_inc() + ' -I' + 
numpy.get_include());"`
-               libpy_LIBS=`$PYCMD --ldflags`
+               libpy_LIBS=`$PY2CONFIG --ldflags`
                HAVEPYTHONHEADER=`$PYTHON_CMD -c "import distutils.sysconfig, 
os; print(os.path.isfile(os.path.join(distutils.sysconfig.get_python_inc(), 
'Python.h')))"`
                if [test "x$HAVEPYTHONHEADER" = xTrue]; then
                        have_libpy=yes
@@ -2410,6 +2414,88 @@ AM_CONDITIONAL(HAVE_LIBPY, test x"$have_
 AM_CONDITIONAL(HAVE_LIBPANDAS, test x"$have_libpandas" != xno)
 AM_CONDITIONAL(HAVE_LIBSCIPY, test x"$have_libscipy" != xno)
 
+# Python 3 API
+have_libpy3=no
+if test "x$enable_py3integration" != xno; then
+       case "$enable_py3integration" in
+       yes|auto)
+               XPATH="$PATH"
+               ;;
+       /*)
+               XPATH="$enable_py3integration"
+               enable_py3integration=yes
+               ;;
+       *)
+               AC_MSG_ERROR([--enable-py3integration value must be 
yes|no|auto|absolute path of python-config])
+               ;;
+       esac
+       if test "x$have_py3config" = x; then
+               # for some god forsaken reason autoconf thinks python2-config 
and python3-config are the same program, so we have to explicitly tell it not 
to select python2-config when we want python3-config
+               AC_PATH_PROG(PY3CONFIG,python3-config,,$XPATH,$PY2CONFIG)
+               if test "x$PY3CONFIG" = x; then
+                       if test "x$enable_py3integration" = xyes; then
+                               AC_MSG_ERROR([python3-config required for 
Python3 integration support])
+                       else
+                               have_libpy3="no"
+                               why_have_libpy3="(python3-config command not 
found)"
+                               enable_py3integration=no
+                               disable_py3integration="(python3-config command 
not found)"
+                       fi
+               fi
+       else
+               PY3CONFIG="$have_py3config"
+       fi
+
+       PYTHON_CMD=$PYTHON3
+
+       NUMPYVER=`$PYTHON_CMD -c "import numpy; 
print(int(numpy.__version__.split('.').__getitem__(1)) >= 7)"`
+       # check numpyconfig.h because autoconf tests includes by compiling a 
small C program, and other numpy headers do not compile without Python.h
+       AC_CHECK_HEADER(
+           [numpy/numpyconfig.h], 
+               [NUMPYHEADERS=True],
+               [NUMPYHEADERS=`$PYTHON_CMD -c "import numpy, os; 
print(os.path.isfile(os.path.join(numpy.get_include(), 
'numpy/arrayobject.h')))"`]
+               )
+       if [test "x$NUMPYVER" = x] || [test "x$NUMPYVER" = xFalse]; then
+               if test "x$enable_py3integration" = xyes; then
+                       AC_MSG_ERROR([numpy version >= 1.7.0 required for 
Python3 integration support])
+               else
+                       have_libpy3="no"
+                       why_have_libpy3="(numpy version >= 1.7.0 not found)"
+                       enable_py3integration=no
+                       disable_py3integration="(numpy version >= 1.7.0 not 
found)"
+               fi
+       elif [test "x$NUMPYHEADERS" = xFalse ]; then
+               if test "x$enable_py3integration" = xyes; then
+                       AC_MSG_ERROR([numpy/arrayobject.h not found])
+               else
+                       have_libpy3="no"
+                       why_have_libpy3="(numpy/arrayobject.h not found)"
+                       enable_py3integration=no
+                       disable_py3integration="(numpy/arrayobject.h not found)"
+               fi
+       else
+               libpy3_CFLAGS=`$PYTHON_CMD -c "from distutils.sysconfig import 
get_python_inc; import numpy; print(' -I' + get_python_inc() + ' -I' + 
numpy.get_include());"`
+               libpy3_LIBS=`$PY3CONFIG --ldflags`
+               HAVEPYTHONHEADER=`$PYTHON_CMD -c "import distutils.sysconfig, 
os; print(os.path.isfile(os.path.join(distutils.sysconfig.get_python_inc(), 
'Python.h')))"`
+               if [test "x$HAVEPYTHONHEADER" = xTrue]; then
+                       have_libpy3=yes
+                       AC_DEFINE(HAVE_LIBPY3, 1, [Define if we can link to 
python])
+                       AC_SUBST(libpy3_CFLAGS, $libpy3_CFLAGS)
+                       AC_SUBST(libpy3_LIBS, $libpy3_LIBS)
+               else
+                       if test "x$enable_py3integration" = xyes; then
+                               AC_MSG_ERROR([Python.h not found])
+                       else
+                               have_libpy3="no"
+                               why_have_libpy3="Python.h not found"
+                               enable_py3integration=no
+                               disable_py3integration="Python.h not found"
+                       fi
+               fi
+       fi
+fi
+AM_CONDITIONAL(HAVE_LIBPY3, test x"$have_libpy3" != xno)
+
 AC_CHECK_HEADER([sys/sem.h], [SEMOP=True], [SEMOP=False])
 if [test "x$SEMOP" = "xTrue"]; then
        AC_CHECK_FUNC(semtimedop, [AC_DEFINE(HAVE_SEMTIMEDOP, 1, [Define if 
semtimedop exists])],)
@@ -3698,6 +3784,7 @@ for comp in \
        'console     ' \
        'microhttpd  ' \
        'pyintegration' \
+       'py3integration' \
        'rintegration' \
        'odbc        ' \
        'jdbc        ' \
diff --git a/monetdb5/extras/Makefile.ag b/monetdb5/extras/Makefile.ag
--- a/monetdb5/extras/Makefile.ag
+++ b/monetdb5/extras/Makefile.ag
@@ -4,5 +4,5 @@
 #
 # Copyright 1997 - July 2008 CWI, August 2008 - 2016 MonetDB B.V.
 
-SUBDIRS = HAVE_SPHINXCLIENT?sphinx mal_optimizer_template HAVE_LIBR?rapi 
HAVE_LIBPY?pyapi
+SUBDIRS = HAVE_SPHINXCLIENT?sphinx mal_optimizer_template HAVE_LIBR?rapi 
HAVE_LIBPY?pyapi HAVE_LIBPY3?pyapi3
 
diff --git a/monetdb5/extras/pyapi/Makefile.ag 
b/monetdb5/extras/pyapi/Makefile.ag
--- a/monetdb5/extras/pyapi/Makefile.ag
+++ b/monetdb5/extras/pyapi/Makefile.ag
@@ -18,6 +18,7 @@ INCLUDES = \
        ../../../sql/server \
        ../../../sql/storage \
        $(libpy_CFLAGS)
+       
 
 MTSAFE
 
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
@@ -178,9 +178,22 @@ static PyMethodDef _connectionObject_met
     {NULL,NULL,0,NULL}  /* Sentinel */
 };
 
-PyTypeObject Py_ConnectionType = {
-    PyObject_HEAD_INIT(NULL)
-    0,
+PyTypeObject Py_ConnectionType = {  
+    _PyObject_EXTRA_INIT
+// in python3 they use structs within structs to represent this information, 
and many compilers throw warnings if you don't use separate braces
+// to initialize these separate structs. However, in Python2, they use 
#defines to put this information in, so we have these nice #ifdefs
+#ifdef IS_PY3K
+    { { 
+#endif
+        1, NULL 
+#ifdef IS_PY3K
+    }
+#endif 
+    , 0
+#ifdef IS_PY3K
+    }
+#endif
+    ,
     "monetdb._connection",
     sizeof(Py_ConnectionObject),
     0,
@@ -262,7 +275,7 @@ PyObject *Py_Connection_Create(Client cn
     return (PyObject*) op;
 }
 
-void _connection_init(void)
+NUMPY_IMPORT_ARRAY_RETTYPE _connection_init(void)
 {
     import_array();
 
@@ -270,5 +283,6 @@ void _connection_init(void)
     LOAD_SQL_FUNCTION_PTR(SQLstatementIntern, "lib_sql.dll");
 
     if (PyType_Ready(&Py_ConnectionType) < 0)
-        return;
+        return NUMPY_IMPORT_ARRAY_RETVAL;
+    return NUMPY_IMPORT_ARRAY_RETVAL;
 }
diff --git a/monetdb5/extras/pyapi/connection.h 
b/monetdb5/extras/pyapi/connection.h
--- a/monetdb5/extras/pyapi/connection.h
+++ b/monetdb5/extras/pyapi/connection.h
@@ -24,14 +24,14 @@ typedef struct {
     int query_sem;
 } Py_ConnectionObject;
 
-extern PyTypeObject Py_ConnectionType;
+PyAPI_DATA(PyTypeObject) Py_ConnectionType;
 
 #define Py_Connection_Check(op) (Py_TYPE(op) == &Py_ConnectionType)
 #define Py_Connection_CheckExact(op) (Py_TYPE(op) == &Py_ConnectionType)
 
 PyObject *Py_Connection_Create(Client cntxt, bit mapped, QueryStruct 
*query_ptr, int query_sem);
 
-void _connection_init(void);
+NUMPY_IMPORT_ARRAY_RETTYPE _connection_init(void);
 char* _connection_query(Client cntxt, char* query, res_table** result);
 void _connection_cleanup_result(void* output);
 
diff --git a/monetdb5/extras/pyapi/formatinput.c 
b/monetdb5/extras/pyapi/formatinput.c
--- a/monetdb5/extras/pyapi/formatinput.c
+++ b/monetdb5/extras/pyapi/formatinput.c
@@ -375,6 +375,7 @@ finally:
     return newcode;
 }
 
-void _formatinput_init(void) {
+NUMPY_IMPORT_ARRAY_RETTYPE _formatinput_init(void) {
     import_array();
+    return NUMPY_IMPORT_ARRAY_RETVAL;
 }
diff --git a/monetdb5/extras/pyapi/formatinput.h 
b/monetdb5/extras/pyapi/formatinput.h
--- a/monetdb5/extras/pyapi/formatinput.h
+++ b/monetdb5/extras/pyapi/formatinput.h
@@ -22,6 +22,6 @@ extern PyObject *marshal_loads;
 
 char* FormatCode(char* code, char **args, size_t argcount, size_t tabwidth, 
PyObject **code_object, char **return_message);
 
-void _formatinput_init(void);
+NUMPY_IMPORT_ARRAY_RETTYPE _formatinput_init(void);
 
 #endif /* _PY_FORMAT_INPUT_LIB_ */
diff --git a/monetdb5/extras/pyapi/pyapi.c b/monetdb5/extras/pyapi/pyapi.c
--- a/monetdb5/extras/pyapi/pyapi.c
+++ b/monetdb5/extras/pyapi/pyapi.c
@@ -33,10 +33,13 @@
 #define PythonUnicodeType char
 #else
 #define PythonUnicodeType Py_UNICODE
-
 #endif
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to