Changeset: 07ba4978af36 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/07ba4978af36
Modified Files:
sql/backends/monet5/rel_bin.c
sql/backends/monet5/sql_cat.c
sql/backends/monet5/sql_gencode.c
sql/backends/monet5/sql_user.c
sql/common/sql_types.c
sql/server/rel_psm.c
sql/server/sql_env.c
sql/server/sql_mvc.c
sql/server/sql_mvc.h
sql/storage/sql_storage.h
sql/storage/store.c
Branch: sqlfuncfix
Log Message:
Cleanup side_effects flag propagation
diffs (truncated from 331 to 300 lines):
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -1243,7 +1243,7 @@ exp_bin(backend *be, sql_exp *e, stmt *l
stmt *rows = NULL;
const char *mod, *fimp;
- /* attempt to instantiate nosql functions now, so we can know
if we can push candidate lists */
+ /* attempt to instantiate MAL functions now, so we can know if
we can push candidate lists */
if (f->func->lang == FUNC_LANG_MAL &&
backend_create_mal_func(be->mvc, f->func) < 0)
return NULL;
mod = sql_func_mod(f->func);
diff --git a/sql/backends/monet5/sql_cat.c b/sql/backends/monet5/sql_cat.c
--- a/sql/backends/monet5/sql_cat.c
+++ b/sql/backends/monet5/sql_cat.c
@@ -1011,8 +1011,29 @@ create_func(mvc *sql, char *sname, char
sql->errstr[0] = '\0';
}
}
+ /* set side-effects flag */
+ switch(f->lang) {
+ case FUNC_LANG_R:
+ case FUNC_LANG_PY:
+ case FUNC_LANG_PY3:
+ case FUNC_LANG_MAP_PY:
+ case FUNC_LANG_MAP_PY3:
+ case FUNC_LANG_C:
+ case FUNC_LANG_CPP:
+ f->side_effect = (list_empty(f->res) || list_empty(f->ops)); /*
TODO make this more precise? */
+ break;
+ case FUNC_LANG_MAL:
+ /* TODO using the 'unsafeProp' from the MAL definition causes
many system functions to have a different value */
+ f->side_effect = f->type != F_FILT && (list_empty(f->res) ||
list_empty(f->ops));
+ break;
+ case FUNC_LANG_SQL:
+ f->side_effect = list_empty(f->res) == 1;
+ break;
+ default:
+ throw(SQL,"sql.create_func", SQLSTATE(42000) "%s %s: cannot
create new functions using the current language", base, F);
+ }
- switch (mvc_create_func(&nf, sql, NULL, s, f->base.name, f->ops,
f->res, f->type, f->lang, f->mod, f->imp, f->query, f->varres, f->vararg,
f->system)) {
+ switch (mvc_create_func(&nf, sql, NULL, s, f->base.name, f->ops,
f->res, f->type, f->lang, f->mod, f->imp, f->query, f->varres, f->vararg,
f->system, f->side_effect)) {
case -1:
throw(SQL,"sql.create_func", SQLSTATE(HY013)
MAL_MALLOC_FAIL);
case -2:
@@ -1023,7 +1044,7 @@ create_func(mvc *sql, char *sname, char
}
switch (nf->lang) {
case FUNC_LANG_MAL:
- /* instantiate MAL functions while being created */
+ /* instantiate MAL functions while being created */
if (backend_create_mal_func(sql, nf) < 0) {
if (strlen(sql->errstr) > 6 && sql->errstr[5] == '!')
throw(SQL, "sql.create_func", "%s",
sql->errstr);
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
@@ -955,12 +955,18 @@ monet5_resolve_function(ptr M, sql_func
return 0;
/* Some SQL functions MAL mapping such as count(*) aggregate, the
number of arguments don't match */
- if (mname == calcRef && fname == getName("="))
+ if (mname == calcRef && fname == getName("=")) {
+ //f->side_effect = 0;
return 1;
- if (mname == aggrRef && (fname == countRef || fname == count_no_nilRef))
+ }
+ if (mname == aggrRef && (fname == countRef || fname ==
count_no_nilRef)) {
+ //f->side_effect = 0;
return 1;
- if (f->type == F_ANALYTIC)
+ }
+ if (f->type == F_ANALYTIC) {
+ //f->side_effect = 0;
return 1;
+ }
c = MCgetClient(clientID);
for (m = findModule(c->usermodule, mname); m; m = m->link) {
@@ -968,9 +974,10 @@ monet5_resolve_function(ptr M, sql_func
InstrPtr sig = getSignature(s);
int argc = sig->argc - sig->retc, nfargs =
list_length(f->ops), nfres = list_length(f->res);
- if ((sig->varargs & VARARGS) == VARARGS || f->vararg ||
f->varres)
+ if ((sig->varargs & VARARGS) == VARARGS || f->vararg ||
f->varres) {
+ //f->side_effect = (bit) s->def->unsafeProp;
return 1;
- else if (nfargs == argc && (nfres == sig->retc ||
(sig->retc == 1 && (IS_FILT(f) || IS_PROC(f))))) {
+ } else if (nfargs == argc && (nfres == sig->retc ||
(sig->retc == 1 && (IS_FILT(f) || IS_PROC(f))))) {
/* I removed this code because, it was
triggering many errors on te SQL <-> MAL translation */
/* Check for types of inputs and outputs. SQL
procedures and filter functions always return 1 value in the MAL implementation
bool all_match = true;
@@ -1004,7 +1011,8 @@ monet5_resolve_function(ptr M, sql_func
}
}
if (all_match)*/
- return 1;
+ //f->side_effect = (bit) s->def->unsafeProp;
+ return 1;
}
}
}
diff --git a/sql/backends/monet5/sql_user.c b/sql/backends/monet5/sql_user.c
--- a/sql/backends/monet5/sql_user.c
+++ b/sql/backends/monet5/sql_user.c
@@ -297,7 +297,7 @@ monet5_create_privileges(ptr _mvc, sql_s
ops = sa_list(m->sa);
/* following funcion returns a table (single column) of user names
with the approriate scenario (sql) */
- mvc_create_func(&f, m, NULL, s, "db_users", ops, res, F_UNION,
FUNC_LANG_MAL, "sql", NULL, "CREATE FUNCTION db_users () RETURNS TABLE( name
varchar(2048)) EXTERNAL NAME sql.db_users;", FALSE, FALSE, TRUE);
+ mvc_create_func(&f, m, NULL, s, "db_users", ops, res, F_UNION,
FUNC_LANG_MAL, "sql", NULL, "CREATE FUNCTION db_users () RETURNS TABLE( name
varchar(2048)) EXTERNAL NAME sql.db_users;", FALSE, FALSE, TRUE, FALSE);
t = mvc_init_create_view(m, s, "users",
"create view sys.users as select u.\"name\" as
\"name\", "
diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -654,7 +654,6 @@ sql_create_func_(sql_allocator *sa, cons
t->instantiated = TRUE;
t->lang = FUNC_LANG_INT;
t->semantics = semantics;
- t->side_effect = side_effect;
t->fix_scale = fix_scale;
t->s = NULL;
t->system = TRUE;
@@ -662,6 +661,7 @@ sql_create_func_(sql_allocator *sa, cons
/* grouping aggregate doesn't have a backend */
assert(strlen(imp) == 0 || strlen(mod) == 0 ||
backend_resolve_function(&(int){0}, t));
+ t->side_effect = side_effect; /* backend_resolve_function may set
'side_effect' flag in the future */
return t;
}
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
@@ -944,7 +944,7 @@ rel_create_func(sql_query *query, dlist
sql->params = NULL;
if (create) {
- switch (mvc_create_func(&f, sql, sql->sa, s, fname, l,
restype, type, lang, mod, imp, lang_body, (type == F_LOADER)?TRUE:FALSE,
vararg, FALSE)) {
+ switch (mvc_create_func(&f, sql, sql->sa, s, fname, l,
restype, type, lang, mod, imp, lang_body, (type == F_LOADER)?TRUE:FALSE,
vararg, FALSE, FALSE)) {
case -1:
return sql_error(sql, 01,
SQLSTATE(HY013) MAL_MALLOC_FAIL);
case -2:
@@ -963,7 +963,7 @@ rel_create_func(sql_query *query, dlist
if (create) { /* needed for recursive functions */
q = query_cleaned(sql->ta, q);
- switch (mvc_create_func(&f, sql, sql->sa, s, fname, l,
restype, type, lang, sql_shared_module_name, NULL, q, FALSE, vararg, FALSE)) {
+ switch (mvc_create_func(&f, sql, sql->sa, s, fname, l,
restype, type, lang, sql_shared_module_name, NULL, q, FALSE, vararg, FALSE,
FALSE)) {
case -1:
return sql_error(sql, 01,
SQLSTATE(HY013) MAL_MALLOC_FAIL);
case -2:
@@ -1001,7 +1001,7 @@ rel_create_func(sql_query *query, dlist
sql->params = NULL;
if (create) {
q = query_cleaned(sql->ta, q);
- switch (mvc_create_func(&f, sql, sql->sa, s, fname, l,
restype, type, lang, fmod, NULL, q, FALSE, vararg, FALSE)) {
+ switch (mvc_create_func(&f, sql, sql->sa, s, fname, l,
restype, type, lang, fmod, NULL, q, FALSE, vararg, FALSE, FALSE)) {
case -1:
return sql_error(sql, 01,
SQLSTATE(HY013) MAL_MALLOC_FAIL);
case -2:
diff --git a/sql/server/sql_env.c b/sql/server/sql_env.c
--- a/sql/server/sql_env.c
+++ b/sql/server/sql_env.c
@@ -88,7 +88,7 @@ sql_create_env(mvc *m, sql_schema *s)
/* add function */
ops = sa_list(m->sa);
- mvc_create_func(&f, m, NULL, s, "env", ops, res, F_UNION,
FUNC_LANG_MAL, "inspect", NULL, "CREATE FUNCTION env() RETURNS TABLE( name
varchar(1024), value varchar(2048)) EXTERNAL NAME inspect.\"getEnvironment\";",
FALSE, FALSE, TRUE);
+ mvc_create_func(&f, m, NULL, s, "env", ops, res, F_UNION,
FUNC_LANG_MAL, "inspect", NULL, "CREATE FUNCTION env() RETURNS TABLE( name
varchar(1024), value varchar(2048)) EXTERNAL NAME inspect.\"getEnvironment\";",
FALSE, FALSE, TRUE, FALSE);
res = sa_list(m->sa);
list_append(res, sql_create_arg(m->sa, "schema",
sql_bind_localtype("str"), ARG_OUT));
@@ -98,6 +98,6 @@ sql_create_env(mvc *m, sql_schema *s)
/* add function */
ops = sa_list(m->sa);
- mvc_create_func(&f, m, NULL, s, "var", ops, res, F_UNION,
FUNC_LANG_MAL, "sql", NULL, "create function \"sys\".\"var\"() returns
table(\"schema\" string, \"name\" string, \"type\" string, \"value\" string)
external name \"sql\".\"sql_variables\";", FALSE, FALSE, TRUE);
+ mvc_create_func(&f, m, NULL, s, "var", ops, res, F_UNION,
FUNC_LANG_MAL, "sql", NULL, "create function \"sys\".\"var\"() returns
table(\"schema\" string, \"name\" string, \"type\" string, \"value\" string)
external name \"sql\".\"sql_variables\";", FALSE, FALSE, TRUE, FALSE);
return 0;
}
diff --git a/sql/server/sql_mvc.c b/sql/server/sql_mvc.c
--- a/sql/server/sql_mvc.c
+++ b/sql/server/sql_mvc.c
@@ -1037,16 +1037,17 @@ mvc_drop_type(mvc *m, sql_schema *s, sql
}
int
-mvc_create_func(sql_func **f, mvc *m, sql_allocator *sa, sql_schema *s, const
char *name, list *args, list *res, sql_ftype type, sql_flang lang, const char
*mod, const char *impl, const char *query, bit varres, bit vararg, bit system)
+mvc_create_func(sql_func **f, mvc *m, sql_allocator *sa, sql_schema *s, const
char *name, list *args, list *res, sql_ftype type, sql_flang lang,
+ const char *mod, const char *impl, const char
*query, bit varres, bit vararg, bit system, bit side_effect)
{
int lres = LOG_OK;
TRC_DEBUG(SQL_TRANS, "Create function: %s\n", name);
if (sa) {
- *f = create_sql_func(m->store, sa, name, args, res, type, lang,
mod, impl, query, varres, vararg, system);
+ *f = create_sql_func(m->store, sa, name, args, res, type, lang,
mod, impl, query, varres, vararg, system, side_effect);
(*f)->s = s;
} else
- lres = sql_trans_create_func(f, m->session->tr, s, name, args,
res, type, lang, mod, impl, query, varres, vararg, system);
+ lres = sql_trans_create_func(f, m->session->tr, s, name, args,
res, type, lang, mod, impl, query, varres, vararg, system, side_effect);
return lres;
}
diff --git a/sql/server/sql_mvc.h b/sql/server/sql_mvc.h
--- a/sql/server/sql_mvc.h
+++ b/sql/server/sql_mvc.h
@@ -194,7 +194,8 @@ extern sql_trigger *mvc_bind_trigger(mvc
extern int mvc_create_type(mvc *sql, sql_schema *s, const char *sqlname,
unsigned int digits, unsigned int scale, int radix, const char *impl);
extern int mvc_drop_type(mvc *sql, sql_schema *s, sql_type *t, int
drop_action);
-extern int mvc_create_func(sql_func **f, mvc *m, sql_allocator *sa, sql_schema
*s, const char *name, list *args, list *res, sql_ftype type, sql_flang lang,
const char *mod, const char *impl, const char *query, bit varres, bit vararg,
bit system);
+extern int mvc_create_func(sql_func **f, mvc *m, sql_allocator *sa, sql_schema
*s, const char *name, list *args, list *res, sql_ftype type, sql_flang lang,
+ const char *mod, const char
*impl, const char *query, bit varres, bit vararg, bit system, bit side_effect);
extern int mvc_drop_func(mvc *c, sql_schema *s, sql_func * func, int
drop_action);
extern int mvc_drop_all_func(mvc *c, sql_schema *s, list *list_func, int
drop_action);
diff --git a/sql/storage/sql_storage.h b/sql/storage/sql_storage.h
--- a/sql/storage/sql_storage.h
+++ b/sql/storage/sql_storage.h
@@ -346,7 +346,8 @@ extern int sql_trans_commit(sql_trans *t
extern int sql_trans_create_type(sql_trans *tr, sql_schema *s, const char
*sqlname, unsigned int digits, unsigned int scale, int radix, const char *impl);
extern int sql_trans_drop_type(sql_trans *tr, sql_schema * s, sqlid id, int
drop_action);
-extern int sql_trans_create_func(sql_func **fres, sql_trans *tr, sql_schema
*s, const char *func, list *args, list *res, sql_ftype type, sql_flang lang,
const char *mod, const char *impl, const char *query, bit varres, bit vararg,
bit system);
+extern int sql_trans_create_func(sql_func **fres, sql_trans *tr, sql_schema
*s, const char *func, list *args, list *res, sql_ftype type, sql_flang lang,
+ const char
*mod, const char *impl, const char *query, bit varres, bit vararg, bit system,
bit side_effect);
extern int sql_trans_drop_func(sql_trans *tr, sql_schema *s, sqlid id, int
drop_action);
extern int sql_trans_drop_all_func(sql_trans *tr, sql_schema *s, list
*list_func, int drop_action);
@@ -437,7 +438,8 @@ extern sql_key * key_create_done(struct
extern sql_idx *create_sql_idx(struct sqlstore *store, sql_allocator *sa,
sql_table *t, const char *nme, idx_type it);
extern sql_idx *create_sql_ic(struct sqlstore *store, sql_allocator *sa,
sql_idx *i, sql_column *c);
extern sql_idx *create_sql_idx_done(sql_idx *i);
-extern sql_func *create_sql_func(struct sqlstore *store, sql_allocator *sa,
const char *func, list *args, list *res, sql_ftype type, sql_flang lang, const
char *mod, const char *impl, const char *query, bit varres, bit vararg, bit
system);
+extern sql_func *create_sql_func(struct sqlstore *store, sql_allocator *sa,
const char *func, list *args, list *res, sql_ftype type, sql_flang lang, const
char *mod,
+ const char
*impl, const char *query, bit varres, bit vararg, bit system, bit side_effect);
/* for alter we need to duplicate a table */
extern sql_table *dup_sql_table(sql_allocator *sa, sql_table *t);
diff --git a/sql/storage/store.c b/sql/storage/store.c
--- a/sql/storage/store.c
+++ b/sql/storage/store.c
@@ -939,8 +939,6 @@ load_func(sql_trans *tr, sql_schema *s,
t->instantiated = t->lang != FUNC_LANG_SQL && t->lang != FUNC_LANG_MAL;
t->type = (sql_ftype) store->table_api.column_find_int(tr,
find_sql_column(funcs, "type"), rid);
t->side_effect = (bit) store->table_api.column_find_bte(tr,
find_sql_column(funcs, "side_effect"), rid);
- if (t->type==F_FILT)
- t->side_effect=FALSE;
t->varres = (bit) store->table_api.column_find_bte(tr,
find_sql_column(funcs, "varres"), rid);
t->vararg = (bit) store->table_api.column_find_bte(tr,
find_sql_column(funcs, "vararg"), rid);
t->system = (bit) store->table_api.column_find_bte(tr,
find_sql_column(funcs, "system"), rid);
@@ -990,9 +988,6 @@ load_func(sql_trans *tr, sql_schema *s,
}
}
}
- if (t->type == F_FUNC && !t->res)
- t->type = F_PROC;
- t->side_effect = (t->type==F_FILT || (t->res && (t->lang==FUNC_LANG_SQL
|| !list_empty(t->ops))))?FALSE:TRUE;
return t;
}
@@ -1468,11 +1463,10 @@ insert_functions(sql_trans *tr, sql_tabl
sqlstore *store = tr->store;
for (node *n = funcs_list->h; n; n = n->next) {
sql_func *f = n->data;
- bit se = (f->type == F_AGGR) ? FALSE : f->side_effect;
int number = 0, ftype = (int) f->type, flang = (int)
FUNC_LANG_INT;
sqlid next_schema = f->s ? f->s->base.id : 0;
- if ((res = store->table_api.table_insert(tr, sysfunc,
&f->base.id, &f->base.name, &f->imp, &f->mod, &flang, &ftype, &se, &f->varres,
&f->vararg, &next_schema, &f->system, &f->semantics)))
+ if ((res = store->table_api.table_insert(tr, sysfunc,
&f->base.id, &f->base.name, &f->imp, &f->mod, &flang, &ftype, &f->side_effect,
&f->varres, &f->vararg, &next_schema, &f->system, &f->semantics)))
return res;
if (f->res && (res = insert_args(tr, sysarg, f->res,
f->base.id, "res_%d", &number)))
return res;
@@ -4815,7 +4809,7 @@ sql_trans_drop_type(sql_trans *tr, sql_s
sql_func *
create_sql_func(sqlstore *store, sql_allocator *sa, const char *func, list
*args, list *res, sql_ftype type, sql_flang lang, const char *mod,
- const char *impl, const char *query, bit varres, bit vararg,
bit system)
+ const char *impl, const char *query, bit
varres, bit vararg, bit system, bit side_effect)
{
sql_func *t = SA_ZNEW(sa, sql_func);
@@ -4827,7 +4821,7 @@ create_sql_func(sqlstore *store, sql_all
t->lang = lang;
t->instantiated = lang != FUNC_LANG_SQL && lang != FUNC_LANG_MAL;
t->semantics = TRUE;
- t->side_effect = (type==F_FILT || (res && (lang==FUNC_LANG_SQL ||
!list_empty(args))))?FALSE:TRUE;
+ t->side_effect = side_effect;
t->varres = varres;
t->vararg = vararg;
t->ops = args;
@@ -4841,14 +4835,13 @@ create_sql_func(sqlstore *store, sql_all
int
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list