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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list