Changeset: 896b634f58e0 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=896b634f58e0
Modified Files:
        sql/backends/monet5/sql_gencode.c
        sql/backends/monet5/sql_upgrades.c
        sql/test/BugTracker-2012/Tests/create_function.Bug-3172.sql
        sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.err
        sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.out
        
sql/test/BugTracker-2012/Tests/table_function_with_column_subselects.Bug-3172.sql
        
sql/test/BugTracker-2012/Tests/table_function_with_column_subselects.Bug-3172.stable.err
        
sql/test/BugTracker-2019/Tests/disallow_duplicate_column_aliases.Bug-6723.stable.out
        sql/test/BugTracker-2019/Tests/prepare-types.Bug-6724.stable.out
        sql/test/emptydb-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        
sql/test/emptydb-upgrade-chain-hge/Tests/upgrade.stable.out.powerpc64.int128
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out.32bit
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out.powerpc64
        sql/test/emptydb-upgrade-chain/Tests/upgrade.stable.out.powerpc64.int128
        sql/test/emptydb-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/emptydb-upgrade/Tests/upgrade.stable.out
        sql/test/emptydb-upgrade/Tests/upgrade.stable.out.32bit
        sql/test/emptydb-upgrade/Tests/upgrade.stable.out.int128
        sql/test/emptydb/Tests/check.stable.out
        sql/test/emptydb/Tests/check.stable.out.32bit
        sql/test/emptydb/Tests/check.stable.out.int128
        sql/test/testdb-upgrade-chain-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out.32bit
        sql/test/testdb-upgrade-chain/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade-hge/Tests/upgrade.stable.out.int128
        sql/test/testdb-upgrade/Tests/upgrade.stable.out
        sql/test/testdb-upgrade/Tests/upgrade.stable.out.32bit
        sql/test/testdb-upgrade/Tests/upgrade.stable.out.int128
Branch: Nov2019
Log Message:

Merge with Apr2019 branch.


diffs (truncated from 952 to 300 lines):

diff --git a/sql/backends/monet5/sql_gencode.c 
b/sql/backends/monet5/sql_gencode.c
--- a/sql/backends/monet5/sql_gencode.c
+++ b/sql/backends/monet5/sql_gencode.c
@@ -833,7 +833,7 @@ backend_call(backend *be, Client c, cq *
                        sql_subtype *pt = cq->params + i;
 
                        if (!atom_cast(m->sa, a, pt)) {
-                               sql_error(m, 003, SQLSTATE(42000) "wrong type 
for argument %d of " "function call: %s, expected %s\n", i + 1, 
atom_type(a)->type->sqlname, pt->type->sqlname);
+                               sql_error(m, 003, SQLSTATE(42000) "wrong type 
for argument %d of function call: %s, expected %s\n", i + 1, 
atom_type(a)->type->sqlname, pt->type->sqlname);
                                break;
                        }
                        if (atom_null(a)) {
@@ -855,31 +855,33 @@ backend_call(backend *be, Client c, cq *
 int
 monet5_resolve_function(ptr M, sql_func *f)
 {
+       Client c;
+       Module m;
+       mvc *sql = (mvc *) M;
        str mname = getName(f->mod), fname = getName(f->imp);
-       (void) M;
 
        if (!mname || !fname)
                return 0;
 
-       for (Module m = getModule(mname); m; m = m->link) {
+       /* Some SQL functions MAL mapping such as count(*) aggregate, the 
number or arguments don't match */
+       if (mname == calcRef && fname == getName("="))
+               return 1;
+       if (mname == aggrRef && fname == countRef)
+               return 1;
+       if (mname == sqlRef && (fname == first_valueRef || fname ==  minRef || 
fname == maxRef))
+               return 1;
+
+       c = MCgetClient(sql->clientid);
+       for (m = findModule(c->usermodule, mname); m; m = m->link) {
                for (Symbol s = findSymbolInModule(m, fname); s; s = s->peer) {
                        InstrPtr sig = getSignature(s);
-                       int argc = sig->argc - sig->retc;
+                       int argc = sig->argc - sig->retc, fargs = 
list_length(f->ops);
 
-                       if ((!f->ops && argc == 0) || list_length(f->ops) == 
argc || (sig->varargs & VARARGS) == VARARGS)
+                       if (fargs == argc || (sig->varargs & VARARGS) == 
VARARGS)
                                return 1;
                }
        }
        return 0;
-/*
-       node *n;
-       newFcnCall(f->mod, f->imp);
-       for (n = f->ops->h; n; n = n->next) {
-               sql_arg *a = n->data;
-
-               q = push ?type? (mb, q, a->);
-       }
-*/
 }
 
 static int
@@ -1015,6 +1017,83 @@ backend_create_c_func(backend *be, sql_f
        return 0;
 }
 
+/* Parse the SQL query from the function, and extract the MAL function from 
the generated abstract syntax tree */
+static int
+mal_function_find_implementation_address(mvc *m, sql_func *f)
+{
+       mvc *o = m;
+       buffer *b = NULL;
+       bstream *bs = NULL;
+       stream *buf = NULL;
+       char *n = NULL;
+       int len = _strlen(f->query);
+       sql_schema *s = cur_schema(m);
+       dlist *l, *ext_name;
+
+       if (!(m = ZNEW(mvc))) {
+               (void) sql_error(o, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+               goto bailout;
+       }
+       m->type = Q_PARSE;
+       m->user_id = m->role_id = USER_MONETDB;
+
+       if (!(m->session = sql_session_create(0, 0))) {
+               (void) sql_error(o, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+               goto bailout;
+       }
+       if (s)
+               m->session->schema = s;
+
+       if (!(m->sa = sa_create())) {
+               (void) sql_error(o, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+               goto bailout;
+       }
+       if (!(b = (buffer*)GDKmalloc(sizeof(buffer)))) {
+               (void) sql_error(o, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+               goto bailout;
+       }
+       if (!(n = GDKmalloc(len + 2))) {
+               (void) sql_error(o, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+               goto bailout;
+       }
+       snprintf(n, len + 2, "%s\n", f->query);
+       len++;
+       buffer_init(b, n, len);
+       if (!(buf = buffer_rastream(b, "sqlstatement"))) {
+               (void) sql_error(o, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+               goto bailout;
+       }
+       if (!(bs = bstream_create(buf, b->len))) {
+               (void) sql_error(o, 02, SQLSTATE(HY001) MAL_MALLOC_FAIL);
+               goto bailout;
+       }
+       scanner_init(&m->scanner, bs, NULL);
+       m->scanner.mode = LINE_1; 
+       bstream_next(m->scanner.rs);
+
+       (void) sqlparse(m); /* blindly ignore errors */
+       assert(m->sym->token == SQL_CREATE_FUNC);
+       l = m->sym->data.lval;
+       ext_name = l->h->next->next->next->data.lval;
+       f->imp = sa_strdup(f->sa, qname_fname(ext_name)); /* found the 
implementation, set it */
+
+bailout:
+       if (m) {
+               bstream_destroy(m->scanner.rs);
+               if (m->session)
+                       sql_session_destroy(m->session); 
+               if (m->sa)
+                       sa_destroy(m->sa);
+               _DELETE(m);
+       }
+       m = o;
+       if (n)
+               GDKfree(n);
+       if (b)
+               GDKfree(b);
+       return m->errstr[0] == '\0'; /* m was set back to o */
+}
+
 static int
 backend_create_sql_func(backend *be, sql_func *f, list *restypes, list *ops)
 {
@@ -1026,7 +1105,18 @@ backend_create_sql_func(backend *be, sql
        int i, retseen = 0, sideeffects = 0, vararg = (f->varres || f->vararg), 
no_inline = 0;
        sql_rel *r;
 
-       /* nothing to do for internal and ready (not recompiling) functions */
+       /* nothing to do for internal and ready (not recompiling) functions, 
besides finding respective MAL implementation */
+       if (!f->sql && (f->lang == FUNC_LANG_INT || f->lang == FUNC_LANG_MAL)) {
+               if (f->lang == FUNC_LANG_MAL && !f->imp && 
!mal_function_find_implementation_address(m, f))
+                       return -1;
+               if (!backend_resolve_function(be->mvc, f)) {
+                       if (f->lang == FUNC_LANG_INT)
+                               (void) sql_error(m, 02, SQLSTATE(HY005) 
"Implementation for function %s.%s not found", f->mod, f->imp);
+                       else
+                               (void) sql_error(m, 02, SQLSTATE(HY005) 
"Implementation for function %s.%s not found (%s.%s)", f->mod, f->imp, 
f->s->base.name, f->base.name);
+                       return -1;
+               }
+       }
        if (!f->sql || (!vararg && f->sql > 1))
                return 0;
        if (!vararg)
diff --git a/sql/backends/monet5/sql_upgrades.c 
b/sql/backends/monet5/sql_upgrades.c
--- a/sql/backends/monet5/sql_upgrades.c
+++ b/sql/backends/monet5/sql_upgrades.c
@@ -1879,41 +1879,31 @@ sql_update_apr2019_sp1(Client c)
 }
 
 static str
-sql_update_apr2019_sp2(Client c)
+sql_update_apr2019_sp2(Client c, mvc *sql, const char *prev_schema, bool 
*systabfixed)
 {
-       /* Determine if system function sys.prod(decimal) exists in 
sys.functions, if so remove them.
-        * see also 
https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=f93d5290abe4
-        */
-       char *err = NULL;
-       char *qry = "select f.id from sys.functions f where f.name = 'prod' and 
func = 'prod'"
-               " and mod in ('sql', 'aggr') and language = 0 and f.type in 
(3,6) and f.system"
-               " and schema_id in (select s.id from sys.schemas s where s.name 
= 'sys')"
-               " and f.id in (select a.func_id from sys.args a where a.type = 
'decimal'"
-               " and type_digits in (2,4,9,18,38) and a.name in 
('arg','arg_1') and inout = 1 and number = 1);";
-       res_table *output = NULL;
+       size_t bufsize = 1000, pos = 0;
+       char *buf = GDKmalloc(bufsize), *err;
+
+       if (buf == NULL)
+               throw(SQL, "sql_update_apr2019_sp2", SQLSTATE(HY001) 
MAL_MALLOC_FAIL);
+
+       if (!*systabfixed) {
+               sql_fix_system_tables(c, sql, prev_schema);
+               *systabfixed = true;
+       }
 
-       err = SQLstatementIntern(c, &qry, "update", true, false, &output);
-       if (err == NULL) {
-               BAT *b = BATdescriptor(output->cols[0].b);
-               if (b) {
-                       if (BATcount(b) > 0) {
-                               /* found entries, we need to remove them 
sys.functions and sys.args */
-                               char *upd = "delete from sys.functions f where 
f.name = 'prod' and func = 'prod'"
-                                       " and mod in ('sql', 'aggr') and 
language = 0 and f.type in (3,6) and f.system"
-                                       " and schema_id in (select s.id from 
sys.schemas s where s.name = 'sys')"
-                                       " and f.id in (select a.func_id from 
sys.args a where a.type = 'decimal'"
-                                       " and type_digits in (2,4,9,18,38) and 
a.name in ('arg','arg_1') and inout = 1 and number = 1);\n"
-                                       "delete from sys.args where func_id not 
in (select id from sys.functions);\n";
+       pos += snprintf(buf + pos, bufsize - pos, "set schema sys;\n");
+
+       /* 11_times.sql */
+       pos += snprintf(buf + pos, bufsize - pos,
+                       "drop procedure sys.times();\n");
 
-                               printf("Running database upgrade 
commands:\n%s\n", upd);
-                               err = SQLstatementIntern(c, &upd, "update", 
true, false, NULL);
-                       }
-                       BBPunfix(b->batCacheid);
-               }
-       }
-       if (output != NULL)
-               res_tables_destroy(output);
+       pos += snprintf(buf + pos, bufsize - pos, "set schema \"%s\";\n", 
prev_schema);
 
+       assert(pos < bufsize);
+       printf("Running database upgrade commands:\n%s\n", buf);
+       err = SQLstatementIntern(c, &buf, "update", true, false, NULL);
+       GDKfree(buf);
        return err;             /* usually MAL_SUCCEED */
 }
 
@@ -2104,7 +2094,6 @@ sql_update_nov2019(Client c, mvc *sql, c
        pos = 0;
        pos += snprintf(buf + pos, bufsize - pos,
                        "set schema \"sys\";\n"
-                       "drop procedure sys.times();\n"
                        "create function sys.deltas (\"schema\" string)"
                        " returns table (\"id\" int, \"cleared\" boolean, 
\"immutable\" bigint, \"inserted\" bigint, \"updates\" bigint, \"deletes\" 
bigint, \"level\" int)"
                        " external name \"sql\".\"deltas\";\n"
@@ -2503,10 +2492,13 @@ SQLupgrades(Client c, mvc *m)
                freeException(err);
                res = -1;
        }
-       if (!res && (err = sql_update_apr2019_sp2(c)) != NULL) {
-               fprintf(stderr, "!%s\n", err);
-               freeException(err);
-               res = -1;
+
+       if (!res && sql_bind_func(m->sa, s, "times", NULL, NULL, F_PROC)) {
+               if (!res && (err = sql_update_apr2019_sp2(c, m, prev_schema, 
&systabfixed)) != NULL) {
+                       fprintf(stderr, "!%s\n", err);
+                       freeException(err);
+                       res = -1;
+               }
        }
 
        sql_find_subtype(&tp, "string", 0, 0);
diff --git a/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.sql 
b/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.sql
--- a/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.sql
+++ b/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.sql
@@ -1,5 +1,6 @@
-create function x(a int, b int) 
-  returns table (c int,d int)
-  external name sql.x;
+create function x(a int, b int) returns table (c int,d int) external name 
sql.x; --error, sql.x doesn't exist
 
+start transaction;
+create function x(a int, b int) returns table (c int,d int) begin return 
select a, b; end;
 select * from x((select id from _tables), (select schema_id from _tables));
+rollback;
diff --git a/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.err 
b/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.err
--- a/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.err
+++ b/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.err
@@ -29,7 +29,11 @@ stderr of test 'create_function.Bug-3172
 # 16:07:20 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" 
"--host=/var/tmp/mtest-27661" "--port=38365"
 # 16:07:20 >  
 
-MAPI  = (monetdb) /var/tmp/mtest-27483/.s.monetdb.35395
+MAPI  = (monetdb) /var/tmp/mtest-23748/.s.monetdb.37404
+QUERY = create function x(a int, b int) returns table (c int,d int) external 
name sql.x; --error, sql.x doesn't exist
+ERROR = !CREATE FUNCTION: external name sql.x not bound (sys.x)
+CODE  = 3F000
+MAPI  = (monetdb) /var/tmp/mtest-23748/.s.monetdb.37404
 QUERY = select * from x((select id from _tables), (select schema_id from 
_tables));
 ERROR = !SELECT: 'x' requires a single sub query
 CODE  = 42000
diff --git a/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.out 
b/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.out
--- a/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.out
+++ b/sql/test/BugTracker-2012/Tests/create_function.Bug-3172.stable.out
@@ -40,6 +40,7 @@ stdout of test 'create_function.Bug-3172
 # loading sql script: 40_geom.sql
 # loading sql script: 80_udf.sql
 # loading sql script: 99_system.sql
+# MonetDB/SQL module loaded
 
 # 13:24:28 >  
 # 13:24:28 >  "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=lodz" 
"--port=38620"
diff --git 
a/sql/test/BugTracker-2012/Tests/table_function_with_column_subselects.Bug-3172.sql
 
b/sql/test/BugTracker-2012/Tests/table_function_with_column_subselects.Bug-3172.sql
--- 
a/sql/test/BugTracker-2012/Tests/table_function_with_column_subselects.Bug-3172.sql
+++ 
b/sql/test/BugTracker-2012/Tests/table_function_with_column_subselects.Bug-3172.sql
@@ -1,7 +1,6 @@
+create function x(a int, b int) returns table (c int,d int) external name 
sql.x; --error, sql.x doesn't exist
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to