Changeset: 6f6c50e11552 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=6f6c50e11552
Removed Files:
        sql/backends/monet5/UDF/pyapi3/Tests/All
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_00.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_00.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_00.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_01.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_01.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_01.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_02.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_02.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_02.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_03.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_03.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_03.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_04.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_04.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_04.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_05.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_05.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_06.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_06.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_06.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_07.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_07.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_07.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_08.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_08.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_08.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_09.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_09.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_09.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_10.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_10.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_10.stable.err.Windows
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_10.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_11.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_11.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_11.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_12.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_12.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_12.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_13.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_13.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_13.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_14.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_14.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_14.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_15.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_16.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_16.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_16.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_17.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_17.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_17.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_18.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_18.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_18.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_19.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_19.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_19.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_20.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_20.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_20.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_21.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_21.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_21.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_23.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_23.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_23.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_24.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_24.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_24.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_25.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_25.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_25.stable.err.Windows
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_25.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_26.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_26.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_26.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_27.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_27.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_27.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_28.sql
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_28.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi3_28.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_numpy_boolean.malC
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_numpy_boolean.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_numpy_boolean.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_numpy_numeric_nested.malC
        
sql/backends/monet5/UDF/pyapi3/Tests/pyapi_numpy_numeric_nested.stable.err
        
sql/backends/monet5/UDF/pyapi3/Tests/pyapi_numpy_numeric_nested.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_pandas.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_pandas.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_returntypes.malC
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_returntypes.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_returntypes.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_boolean.malC
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_boolean.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_boolean.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_huge.malC
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_huge.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_huge.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_numeric.malC
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_numeric.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_numeric.stable.out
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_string.malC
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_string.stable.err
        sql/backends/monet5/UDF/pyapi3/Tests/pyapi_types_string.stable.out
Modified Files:
        configure.ag
        monetdb5/mal/mal_import.c
        monetdb5/mal/mal_parser.c
        monetdb5/optimizer/opt_prelude.c
        monetdb5/optimizer/opt_prelude.h
        monetdb5/optimizer/opt_support.c
        sql/backends/monet5/UDF/pyapi/pyapi.c
        sql/backends/monet5/UDF/pyapi/pyapi.h
        sql/backends/monet5/UDF/pyapi/pyapi.mal
        sql/backends/monet5/UDF/pyapi/pyheader.h
        sql/backends/monet5/UDF/pyapi/pyloader.c
        sql/backends/monet5/UDF/pyapi3/Makefile.ag
        sql/backends/monet5/UDF/pyapi3/pyapi3.mal
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_statement.c
        sql/include/sql_catalog.h
        sql/server/sql_parser.y
        testing/Mtest.py.in
        tools/merovingian/daemon/forkmserver.c
        tools/merovingian/utils/properties.c
        tools/merovingian/utils/utils.c
Branch: python3udf
Log Message:

Update Python 3 UDFs to work with the current MonetDB version and change how 
they work.

Only one type of Python UDF can be active in the same process: Python 2 or 
Python 3. The active version can be chosen using either --set embedded_py=2 or 
--set embedded_py=3. --set embedded_py=true defaults to Python 2 for backwards 
compatibility reasons.

There are three different Python languages for creating functions: LANGUAGE 
PYTHON, LANGUAGE PYTHON2, LANGUAGE PYTHON3

LANGUAGE PYTHON uses whatever Python is enabled in the server. If no Python is 
enabled they will fail.
LANGUAGE PYTHON2 always uses Python 2; these functions will fail if PYTHON2 is 
not enabled.
LANGUAGE PYTHON3 is the same, but the other way around.


diffs (truncated from 9695 to 300 lines):

diff --git a/configure.ag b/configure.ag
--- a/configure.ag
+++ b/configure.ag
@@ -295,10 +295,17 @@ AC_ARG_ENABLE([rintegration],
 dft_pyintegration=auto
 AC_ARG_ENABLE([pyintegration],
        [AS_HELP_STRING([--enable-pyintegration],
-               [enable support for Python integration into MonetDB 
(default=auto)])],
+               [enable support for Python 2 integration into MonetDB 
(default=auto)])],
        [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)
+
 # The console is a direct client hooked onto the kernel with full
 # administrative privileges, bypassing any security checks.  It is
 # handy only during development.
@@ -1116,13 +1123,13 @@ AS_CASE([$have_python3],
        [
                PYTHON3="$have_python3"])
 
-AC_ARG_WITH([pyconfig],
-       [AS_HELP_STRING([--with-pyconfig=FILE], [python-config is installed as 
FILE])],
-       [have_pyconfig="$withval"])
+AC_ARG_WITH([py2config],
+       [AS_HELP_STRING([--with-py2config=FILE], [python2-config is installed 
as FILE])],
+       [have_py2config="$withval"])
 
-AC_ARG_WITH([pyversion],
-       [AS_HELP_STRING([--with-pyversion=FILE], [python is installed as 
FILE])],
-       [have_pyversion="$withval"])
+AC_ARG_WITH(py3config,
+       AS_HELP_STRING([--with-py3config=FILE], [python3-config is installed as 
FILE]),
+       have_py3config="$withval")
 
 # Figure out a default for PYTHON2 or PYTHON3
 AC_PATH_PROG([PYTHON], [python], [no], [$PATH])
@@ -1863,24 +1870,22 @@ AS_VAR_IF([enable_pyintegration], [no], 
                [/*], [XPATH="$enable_pyintegration"
                       enable_pyintegration=yes],
                [AC_MSG_ERROR([--enable-pyintegration value must be 
yes|no|auto|absolute path of python-config])])
-       AS_VAR_IF([have_pyconfig], [], [
-               AC_PATH_PROG([PYCMD], [python2-config], [no], [$PATH])
-               AS_VAR_IF([PYCMD], [no], [
+       AS_VAR_IF([have_py2config], [], [
+               AC_PATH_PROG([PY2CONFIG], [python2-config], [no], [$PATH])
+               AS_VAR_IF([PY2CONFIG], [no], [
                        AC_PATH_PROG([PYCMD2], [python-config], [no], [$PATH])
                        AS_VAR_IF([PYCMD2], [no], [
                                AS_VAR_IF([enable_pyintegration], [yes],
-                               [AC_MSG_ERROR([python-config library required 
for Python integration support])],
+                               [AC_MSG_ERROR([python2-config library required 
for Python integration support])],
                                [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)"
                                ])
-                       ], [PYCMD="$PYCMD2"])
+                       ], [PY2CONFIG="$PYCMD2"])
                ], [])
-       ], [PYCMD="$have_pyconfig"])
-       AS_VAR_IF([have_pyversion], [],
-               [PYTHON_CMD=$PYTHON2],
-               [PYTHON_CMD=$have_pyversion])
+       ], [PY2CONFIG="$have_py2config"])
+       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
@@ -1903,7 +1908,7 @@ AS_VAR_IF([enable_pyintegration], [no], 
                         enable_pyintegration="no"
                         disable_pyintegration="(numpy/arrayobject.h not 
found)"])],
                [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')))"`
                 AS_VAR_IF([HAVEPYTHONHEADER], [True],
                        [have_libpy=yes
@@ -1918,6 +1923,90 @@ AS_VAR_IF([enable_pyintegration], [no], 
                                 disable_pyintegration="Python.h not 
found"])])])])
 AM_CONDITIONAL([HAVE_LIBPY], [test x"$have_libpy" != xno])
 
+
+# Python 3 UDFs
+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])
 AS_VAR_IF([SEMOP], [True],
        [AC_CHECK_FUNC([semtimedop],
@@ -3046,6 +3135,7 @@ for comp in \
        'geom        ' \
        'console     ' \
        'pyintegration' \
+       'py3integration' \
        'rintegration' \
        'odbc        ' \
        'testing     ' \
diff --git a/monetdb5/mal/mal_import.c b/monetdb5/mal/mal_import.c
--- a/monetdb5/mal/mal_import.c
+++ b/monetdb5/mal/mal_import.c
@@ -156,7 +156,6 @@ malLoadScript(Client c, str name, bstrea
        c->blkmode = oldblkmode; \
        c->srcFile = oldsrcFile;
 
-
 #ifdef HAVE_EMBEDDED
 extern char* mal_init_inline;
 #endif
@@ -167,7 +166,7 @@ extern char* mal_init_inline;
 str
 malInclude(Client c, str name, int listing)
 {
-       str s= MAL_SUCCEED;
+       str s = MAL_SUCCEED;
        str filename;
        str p;
 
diff --git a/monetdb5/mal/mal_parser.c b/monetdb5/mal/mal_parser.c
--- a/monetdb5/mal/mal_parser.c
+++ b/monetdb5/mal/mal_parser.c
@@ -949,6 +949,17 @@ static str parseModule(Client cntxt)
        return "";
 }
 
+#define pyapi_enableflag "embedded_py"
+// returns the currently enabled python version, if any
+// defaults to python 2 if none is enabled
+static int
+enabled_python_version() {
+    char* env = GDKgetenv(pyapi_enableflag);
+    if (env && strncmp(env, "3", 1) == 0)
+       return 3;
+       return 2;
+}
+
 /*
  * Include statement
  * An include statement is immediately taken into effect. This
@@ -995,6 +1006,20 @@ parseInclude(Client cntxt)
        }
        skipToEnd(cntxt);
 
+       // loading both the python 2 and python 3 DLLs messes up the server
+       // thus we only load whichever one is enabled (if any)
+       if (strncmp(modnme, "pyapi", 5) == 0) {
+               if (strcmp(modnme, "pyapi3") == 0) {
+                       if (enabled_python_version() != 3) {
+                               return "";
+                       }
+               } else {
+                       if (enabled_python_version() != 2) {
+                               return "";
+                       }
+               }
+       }
+
        s = loadLibrary(modnme, FALSE);
        if (s) {
                parseError(cntxt, s);
diff --git a/monetdb5/optimizer/opt_prelude.c b/monetdb5/optimizer/opt_prelude.c
--- a/monetdb5/optimizer/opt_prelude.c
+++ b/monetdb5/optimizer/opt_prelude.c
@@ -182,6 +182,9 @@ str batrapiRef;
 str pyapiRef;
 str batpyapiRef;
 str pyapimapRef;
+str pyapi3Ref;
+str batpyapi3Ref;
+str pyapi3mapRef;
 str subeval_aggrRef;
 str rankRef;
 str dense_rankRef;
@@ -409,6 +412,9 @@ void optimizerInit(void)
     pyapiRef = putName("pyapi");
     batpyapiRef = putName("batpyapi");
     pyapimapRef = putName("batpyapimap");
+    pyapi3Ref = putName("pyapi3");
+    batpyapi3Ref = putName("batpyapi3");
+    pyapi3mapRef = putName("batpyapi3map");
        subeval_aggrRef = putName("subeval_aggr");
        rankRef = putName("rank");
        dense_rankRef = putName("dense_rank");
diff --git a/monetdb5/optimizer/opt_prelude.h b/monetdb5/optimizer/opt_prelude.h
--- a/monetdb5/optimizer/opt_prelude.h
+++ b/monetdb5/optimizer/opt_prelude.h
@@ -175,6 +175,9 @@ mal_export  str batrapiRef;
 mal_export  str pyapiRef;
 mal_export  str batpyapiRef;
 mal_export  str pyapimapRef;
+mal_export  str pyapi3Ref;
+mal_export  str batpyapi3Ref;
+mal_export  str pyapi3mapRef;
 mal_export  str subeval_aggrRef;
 mal_export  str rankRef;
 mal_export  str dense_rankRef;
diff --git a/monetdb5/optimizer/opt_support.c b/monetdb5/optimizer/opt_support.c
--- a/monetdb5/optimizer/opt_support.c
+++ b/monetdb5/optimizer/opt_support.c
@@ -432,6 +432,8 @@ hasSideEffects(InstrPtr p, int strict)
                
        if( getModuleId(p) == pyapiRef ||
                getModuleId(p) == pyapimapRef ||
+               getModuleId(p) == pyapi3Ref ||
+               getModuleId(p) == pyapi3mapRef ||
                getModuleId(p) == rapiRef)
                return TRUE;
 
@@ -563,7 +565,8 @@ int isMapOp(InstrPtr p){
                 (getModuleId(p) != batcalcRef && getModuleId(p) != batRef && 
strncmp(getModuleId(p), "bat", 3) == 0) ||
                 (getModuleId(p) == mkeyRef)) && !isOrderDepenent(p) &&
                 getModuleId(p) != batrapiRef &&
-                getModuleId(p) != batpyapiRef;
+                getModuleId(p) != batpyapiRef &&
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to