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
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to