Changeset: 78c29ee01cdd for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=78c29ee01cdd
Added Files:
        sql/backends/monet5/Tests/createorreplace.sql
        sql/backends/monet5/Tests/createorreplace.stable.err
        sql/backends/monet5/Tests/createorreplace.stable.out
Modified Files:
        sql/backends/monet5/Tests/All
        sql/server/rel_psm.c
        sql/server/sql_parser.y
        sql/server/sql_scan.c
Branch: default
Log Message:

Add support for CREATE OR REPLACE FUNCTION/AGGREGATE/PROCEDURE/...


diffs (truncated from 496 to 300 lines):

diff --git a/sql/backends/monet5/Tests/All b/sql/backends/monet5/Tests/All
--- a/sql/backends/monet5/Tests/All
+++ b/sql/backends/monet5/Tests/All
@@ -61,6 +61,8 @@ HAVE_LIBPY?pyloader05
 HAVE_LIBPY?pyloader06
 HAVE_LIBPY?pyloader07
 
+HAVE_LIBPY?createorreplace
+
 # should this work?
 #inlineUDF
 
diff --git a/sql/backends/monet5/Tests/createorreplace.sql 
b/sql/backends/monet5/Tests/createorreplace.sql
new file mode 100644
--- /dev/null
+++ b/sql/backends/monet5/Tests/createorreplace.sql
@@ -0,0 +1,55 @@
+# Test 'CREATE OR REPLACE' functionality
+
+START TRANSACTION;
+# first create the initial table and function
+CREATE TABLE createorreplacetable(i INTEGER);
+INSERT INTO createorreplacetable VALUES (2), (4), (6);
+
+# this simple function multiplies elements by 2
+CREATE FUNCTION createorreplacefunc(i INTEGER) RETURNS INTEGER LANGUAGE PYTHON 
{
+       return i * 2;
+};
+
+# (4), (8), (12)
+SELECT createorreplacefunc(i) FROM createorreplacetable;
+
+COMMIT;
+
+START TRANSACTION;
+# try to create the function again: this should fail
+CREATE FUNCTION createorreplacefunc(i INTEGER) RETURNS INTEGER LANGUAGE PYTHON 
{ return i * 3; };
+ROLLBACK;
+
+START TRANSACTION;
+# now replace the function with a function that multiplies elements by 3
+CREATE OR REPLACE FUNCTION createorreplacefunc(i INTEGER) RETURNS INTEGER 
LANGUAGE PYTHON {
+       return i * 3;
+};
+# (6), (12), (18)
+SELECT createorreplacefunc(i) FROM createorreplacetable;
+ROLLBACK;
+
+START TRANSACTION;
+DROP FUNCTION createorreplacefunc;
+COMMIT;
+
+# aggregates
+START TRANSACTION;
+CREATE AGGREGATE createorreplaceaggregate(i INTEGER) RETURNS INTEGER LANGUAGE 
PYTHON {
+       return numpy.min(i);
+};
+# (2)
+SELECT createorreplaceaggregate(i) FROM createorreplacetable;
+
+CREATE OR REPLACE AGGREGATE createorreplaceaggregate(i INTEGER) RETURNS 
INTEGER LANGUAGE PYTHON {
+       return numpy.max(i);
+};
+# (6)
+SELECT createorreplaceaggregate(i) FROM createorreplacetable;
+
+ROLLBACK;
+
+
+START TRANSACTION;
+DROP TABLE createorreplacetable;
+COMMIT;
diff --git a/sql/backends/monet5/Tests/createorreplace.stable.err 
b/sql/backends/monet5/Tests/createorreplace.stable.err
new file mode 100644
--- /dev/null
+++ b/sql/backends/monet5/Tests/createorreplace.stable.err
@@ -0,0 +1,39 @@
+stderr of test 'createorreplace` in directory 'sql/backends/monet5` itself:
+
+
+# 14:49:51 >  
+# 14:49:51 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"mapi_open=true" "--set" "mapi_port=34646" "--set" 
"mapi_usock=/var/tmp/mtest-26151/.s.monetdb.34646" "--set" "monet_prompt=" 
"--forcemito" "--dbpath=/Users/myth/opt/var/MonetDB/mTests_sql_backends_monet5" 
"--set" "embedded_r=yes" "--set" "embedded_py=true"
+# 14:49:51 >  
+
+# builtin opt  gdk_dbpath = /Users/myth/opt/var/monetdb5/dbfarm/demo
+# builtin opt  gdk_debug = 0
+# builtin opt  gdk_vmtrim = no
+# builtin opt  monet_prompt = >
+# builtin opt  monet_daemon = no
+# builtin opt  mapi_port = 50000
+# builtin opt  mapi_open = false
+# builtin opt  mapi_autosense = false
+# builtin opt  sql_optimizer = default_pipe
+# builtin opt  sql_debug = 0
+# cmdline opt  gdk_nr_threads = 0
+# cmdline opt  mapi_open = true
+# cmdline opt  mapi_port = 34646
+# cmdline opt  mapi_usock = /var/tmp/mtest-26151/.s.monetdb.34646
+# cmdline opt  monet_prompt = 
+# cmdline opt  gdk_dbpath = 
/Users/myth/opt/var/MonetDB/mTests_sql_backends_monet5
+# cmdline opt  embedded_r = yes
+# cmdline opt  embedded_py = true
+# cmdline opt  gdk_debug = 536870922
+
+# 14:49:51 >  
+# 14:49:51 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-26151" "--port=34646"
+# 14:49:51 >  
+
+MAPI  = (monetdb) /var/tmp/mtest-26151/.s.monetdb.34646
+QUERY = CREATE FUNCTION createorreplacefunc(i INTEGER) RETURNS INTEGER 
LANGUAGE PYTHON { return i * 3; };
+ERROR = !CREATE FUNCTION: name 'createorreplacefunc' (int(32)) already in use
+
+# 14:49:52 >  
+# 14:49:52 >  "Done."
+# 14:49:52 >  
+
diff --git a/sql/backends/monet5/Tests/createorreplace.stable.out 
b/sql/backends/monet5/Tests/createorreplace.stable.out
new file mode 100644
--- /dev/null
+++ b/sql/backends/monet5/Tests/createorreplace.stable.out
@@ -0,0 +1,124 @@
+stdout of test 'createorreplace` in directory 'sql/backends/monet5` itself:
+
+
+# 14:49:51 >  
+# 14:49:51 >  "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" 
"mapi_open=true" "--set" "mapi_port=34646" "--set" 
"mapi_usock=/var/tmp/mtest-26151/.s.monetdb.34646" "--set" "monet_prompt=" 
"--forcemito" "--dbpath=/Users/myth/opt/var/MonetDB/mTests_sql_backends_monet5" 
"--set" "embedded_r=yes" "--set" "embedded_py=true"
+# 14:49:51 >  
+
+# MonetDB 5 server v11.26.0
+# This is an unreleased version
+# Serving database 'mTests_sql_backends_monet5', using 4 threads
+# Compiled for x86_64-apple-darwin15.6.0/64bit with 128bit integers
+# Found 8.000 GiB available main-memory.
+# Copyright (c) 1993-July 2008 CWI.
+# Copyright (c) August 2008-2016 MonetDB B.V., all rights reserved
+# Visit http://www.monetdb.org/ for further information
+# Listening for connection requests on 
mapi:monetdb://dhcp-46.eduroam.cwi.nl:34646/
+# Listening for UNIX domain connection requests on 
mapi:monetdb:///var/tmp/mtest-26151/.s.monetdb.34646
+# MonetDB/SQL module loaded
+# MonetDB/Python module loaded
+# MonetDB/R   module loaded
+
+Ready.
+# SQL catalog created, loading sql scripts once
+# loading sql script: 09_like.sql
+# loading sql script: 10_math.sql
+# loading sql script: 11_times.sql
+# loading sql script: 12_url.sql
+# loading sql script: 13_date.sql
+# loading sql script: 14_inet.sql
+# loading sql script: 15_querylog.sql
+# loading sql script: 16_tracelog.sql
+# loading sql script: 17_temporal.sql
+# loading sql script: 18_index.sql
+# loading sql script: 20_vacuum.sql
+# loading sql script: 21_dependency_functions.sql
+# loading sql script: 22_clients.sql
+# loading sql script: 23_skyserver.sql
+# loading sql script: 25_debug.sql
+# loading sql script: 26_sysmon.sql
+# loading sql script: 27_rejects.sql
+# loading sql script: 39_analytics.sql
+# loading sql script: 39_analytics_hge.sql
+# loading sql script: 40_json.sql
+# loading sql script: 40_json_hge.sql
+# loading sql script: 41_md5sum.sql
+# loading sql script: 45_uuid.sql
+# loading sql script: 46_profiler.sql
+# loading sql script: 51_sys_schema_extension.sql
+# loading sql script: 72_fits.sql
+# loading sql script: 74_netcdf.sql
+# loading sql script: 75_storagemodel.sql
+# loading sql script: 80_statistics.sql
+# loading sql script: 80_udf.sql
+# loading sql script: 80_udf_hge.sql
+# loading sql script: 90_generator.sql
+# loading sql script: 90_generator_hge.sql
+# loading sql script: 99_system.sql
+
+# 14:49:51 >  
+# 14:49:51 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-26151" "--port=34646"
+# 14:49:51 >  
+
+#START TRANSACTION;
+#CREATE TABLE createorreplacetable(i INTEGER);
+#INSERT INTO createorreplacetable VALUES (2), (4), (6);
+[ 3    ]
+#CREATE FUNCTION createorreplacefunc(i INTEGER) RETURNS INTEGER LANGUAGE 
PYTHON {
+#      return i * 2;
+#};
+#SELECT createorreplacefunc(i) FROM createorreplacetable;
+% sys.L2 # table_name
+% L2 # name
+% int # type
+% 2 # length
+[ 4    ]
+[ 8    ]
+[ 12   ]
+#COMMIT;
+#START TRANSACTION;
+#ROLLBACK;
+#START TRANSACTION;
+#CREATE OR REPLACE FUNCTION createorreplacefunc(i INTEGER) RETURNS INTEGER 
LANGUAGE PYTHON {
+#      return i * 3;
+#};
+#SELECT createorreplacefunc(i) FROM createorreplacetable;
+% sys.L2 # table_name
+% L2 # name
+% int # type
+% 2 # length
+[ 6    ]
+[ 12   ]
+[ 18   ]
+#ROLLBACK;
+#START TRANSACTION;
+#DROP FUNCTION createorreplacefunc;
+#COMMIT;
+#START TRANSACTION;
+#CREATE AGGREGATE createorreplaceaggregate(i INTEGER) RETURNS INTEGER LANGUAGE 
PYTHON {
+#      return numpy.min(i);
+#};
+#SELECT createorreplaceaggregate(i) FROM createorreplacetable;
+% sys.L4 # table_name
+% L3 # name
+% int # type
+% 1 # length
+[ 2    ]
+#CREATE OR REPLACE AGGREGATE createorreplaceaggregate(i INTEGER) RETURNS 
INTEGER LANGUAGE PYTHON {
+#      return numpy.max(i);
+#};
+#SELECT createorreplaceaggregate(i) FROM createorreplacetable;
+% sys.L4 # table_name
+% L3 # name
+% int # type
+% 1 # length
+[ 6    ]
+#ROLLBACK;
+#START TRANSACTION;
+#DROP TABLE createorreplacetable;
+#COMMIT;
+
+# 14:49:52 >  
+# 14:49:52 >  "Done."
+# 14:49:52 >  
+
diff --git a/sql/server/rel_psm.c b/sql/server/rel_psm.c
--- a/sql/server/rel_psm.c
+++ b/sql/server/rel_psm.c
@@ -692,7 +692,7 @@ rel_create_function(sql_allocator *sa, c
 }
 
 static sql_rel *
-rel_create_func(mvc *sql, dlist *qname, dlist *params, symbol *res, dlist 
*ext_name, dlist *body, int type, int lang)
+rel_create_func(mvc *sql, dlist *qname, dlist *params, symbol *res, dlist 
*ext_name, dlist *body, int type, int lang, int replace)
 {
        const char *fname = qname_table(qname);
        const char *sname = qname_schema(qname);
@@ -712,7 +712,9 @@ rel_create_func(mvc *sql, dlist *qname, 
        char is_loader = (type == F_LOADER);
 
        char *F = 
is_loader?"LOADER":(is_aggr?"AGGREGATE":(is_func?"FUNCTION":"PROCEDURE"));
+       char *fn = is_loader?"loader":(is_aggr ? "aggregate" : (is_func ? 
"function" : "procedure"));
        char *KF = type==F_FILT?"FILTER ": type==F_UNION?"UNION ": "";
+       char *kf = type == F_FILT ? "filter " : type == F_UNION ? "union " : "";
 
        assert(res || type == F_PROC || type == F_FILT || type == F_LOADER);
 
@@ -729,31 +731,44 @@ rel_create_func(mvc *sql, dlist *qname, 
 
        type_list = create_type_list(sql, params, 1);
        if ((sf = sql_bind_func_(sql->sa, s, fname, type_list, type)) != NULL 
&& create) {
-               if (params) {
-                       char *arg_list = NULL;
-                       node *n;
-                       
-                       for (n = type_list->h; n; n = n->next) {
-                               char *tpe =  subtype2string((sql_subtype *) 
n->data);
+               if (replace) {
+                       sql_func *func = sf->func;
+                       int action = 0;
+                       if (!mvc_schema_privs(sql, s)) {
+                               return sql_error(sql, 02, "CREATE OR REPLACE 
%s%s: access denied for %s to schema ;'%s'", KF, F, stack_get_string(sql, 
"current_user"), s->base.name);
+                       }
+                       if (mvc_check_dependency(sql, func->base.id, 
!IS_PROC(func) ? FUNC_DEPENDENCY : PROC_DEPENDENCY, NULL))
+                               return sql_error(sql, 02, "CREATE OR REPLACE 
%s%s: there are database objects dependent on %s%s %s;", KF, F, kf, fn, 
func->base.name);
+
+                       mvc_drop_func(sql, s, func, action);
+               } else {
+                       if (params) {
+                               char *arg_list = NULL;
+                               node *n;
                                
-                               if (arg_list) {
-                                       char *t = arg_list;
-                                       arg_list = sql_message("%s, %s", 
arg_list, tpe);
-                                       _DELETE(t);
-                                       _DELETE(tpe);
-                               } else {
-                                       arg_list = tpe;
+                               for (n = type_list->h; n; n = n->next) {
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to