Changeset: 7d549528de04 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/7d549528de04 Modified Files: sql/backends/monet5/rel_bin.c sql/backends/monet5/sql_cat.c sql/backends/monet5/sql_gencode.c sql/backends/monet5/sql_gencode.h sql/backends/monet5/sql_user.c sql/common/sql_types.c sql/server/rel_psm.c sql/server/sql_env.c sql/test/miscellaneous/Tests/select_groupby.stable.err Branch: sqlfuncfix Log Message:
Use MAL Symbol 'unsafeProp' to set a SQL MAL function to have side-effects or not. Cleaned instantiation for SQL MAL functions on creation. Now I have to fix te 'unsafeProp' on the backend and add more upgrades diffs (truncated from 1042 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 @@ -1249,10 +1249,11 @@ exp_bin(backend *be, sql_exp *e, stmt *l mod = sql_func_mod(f->func); fimp = sql_func_imp(f->func); - if (f->func->side_effect && left && left->nrcols > 0) { + /* TODO the 'next_value_for' case is an ugly hack, and it will get fixed on 'sequences_7184' branch */ + if ((f->func->side_effect || (!f->func->s && strcmp(f->func->base.name, "next_value_for") == 0)) && left && left->nrcols > 0) { sql_subfunc *f1 = NULL; /* we cannot assume all SQL functions with no arguments have a correspondent with one argument, so attempt to find it. 'rand' function is the exception */ - if (list_empty(exps) && (strcmp(f->func->base.name, "rand") == 0 || (f1 = sql_find_func(sql, f->func->s ? f->func->s->base.name : NULL, f->func->base.name, 1, f->func->type, NULL)))) { + if (list_empty(exps) && ((!f->func->s && strcmp(f->func->base.name, "rand") == 0) || (f1 = sql_find_func(sql, f->func->s ? f->func->s->base.name : NULL, f->func->base.name, 1, f->func->type, NULL)))) { if (f1) f = f1; list_append(l, stmt_const(be, bin_find_smallest_column(be, left), @@ -2127,7 +2128,7 @@ rel2bin_table(backend *be, sql_rel *rel, else getArg(q, 0) = newTmpVariable(be->mb, type); } - if (backend_create_func(be, f->func, NULL, ops) < 0) + if (backend_create_subfunc(be, f, ops) < 0) return NULL; str mod = sql_func_mod(f->func); str fcn = sql_func_imp(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 @@ -1007,28 +1007,6 @@ 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, f->side_effect)) { case -1: throw(SQL,"sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL); @@ -1040,13 +1018,8 @@ create_func(mvc *sql, char *sname, char } switch (nf->lang) { case FUNC_LANG_MAL: - /* 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); - else - throw(SQL, "sql.create_func", SQLSTATE(42000) "%s", sql->errstr); - } + assert(nf->imp); + nf->instantiated = TRUE; /* MAL functions get instantiated while being created */ /* fall through */ case FUNC_LANG_SQL: { char *buf; 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 @@ -956,15 +956,15 @@ monet5_resolve_function(ptr M, sql_func /* Some SQL functions MAL mapping such as count(*) aggregate, the number of arguments don't match */ if (mname == calcRef && fname == getName("=")) { - //f->side_effect = 0; + f->side_effect = 0; return 1; } if (mname == aggrRef && (fname == countRef || fname == count_no_nilRef)) { - //f->side_effect = 0; + f->side_effect = 0; return 1; } if (f->type == F_ANALYTIC) { - //f->side_effect = 0; + f->side_effect = 0; return 1; } @@ -975,7 +975,7 @@ monet5_resolve_function(ptr M, sql_func 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) { - //f->side_effect = (bit) s->def->unsafeProp; + 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))))) { /* I removed this code because, it was triggering many errors on te SQL <-> MAL translation */ @@ -1011,7 +1011,7 @@ monet5_resolve_function(ptr M, sql_func } } if (all_match)*/ - //f->side_effect = (bit) s->def->unsafeProp; + f->side_effect = (bit) s->def->unsafeProp; return 1; } } @@ -1324,7 +1324,7 @@ cleanup: return res; } -int +static int backend_create_func(backend *be, sql_func *f, list *restypes, list *ops) { switch(f->lang) { diff --git a/sql/backends/monet5/sql_gencode.h b/sql/backends/monet5/sql_gencode.h --- a/sql/backends/monet5/sql_gencode.h +++ b/sql/backends/monet5/sql_gencode.h @@ -22,7 +22,6 @@ extern int backend_dumpstmt(backend *be, extern int monet5_has_module(ptr M, char *module); extern int monet5_resolve_function(ptr M, sql_func *f); extern int backend_create_mal_func(mvc *m, sql_func *f); -extern int backend_create_func(backend *be, sql_func *f, list *restypes, list *ops); extern int backend_create_subfunc(backend *be, sql_subfunc *f, list *ops); extern int monet5_create_relational_function(mvc *m, const char *mod, const char *name, sql_rel *rel, stmt *call, list *rel_ops, int inline_func); 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,8 +297,9 @@ 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, FALSE); - + mvc_create_func(&f, m, NULL, s, "db_users", ops, res, F_UNION, FUNC_LANG_MAL, "sql", "db_users", "CREATE FUNCTION db_users () RETURNS TABLE( name varchar(2048)) EXTERNAL NAME sql.db_users;", FALSE, FALSE, TRUE, FALSE); + if (f) + f->instantiated = TRUE; t = mvc_init_create_view(m, s, "users", "create view sys.users as select u.\"name\" as \"name\", " "ui.\"fullname\", ui.\"default_schema\", " 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 @@ -626,7 +626,7 @@ sql_create_arg(sql_allocator *sa, const } static sql_func * -sql_create_func_(sql_allocator *sa, const char *name, const char *mod, const char *imp, sql_ftype type, bit semantics, bit side_effect, +sql_create_func_(sql_allocator *sa, const char *name, const char *mod, const char *imp, sql_ftype type, bit semantics, int fix_scale, unsigned int res_scale, sql_type *res, int nargs, va_list valist) { list *ops = SA_LIST(sa, (fdestroy) &arg_destroy); @@ -660,33 +660,32 @@ sql_create_func_(sql_allocator *sa, cons list_append(funcs, t); /* 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 */ - + if (strlen(imp) != 0 && strlen(mod) != 0) + backend_resolve_function(&(int){0}, t); /* backend_resolve_function sets 'side_effect' flag */ return t; } static sql_func * -sql_create_procedure(sql_allocator *sa, const char *name, const char *mod, const char *imp, bit side_effect, int nargs, ...) +sql_create_procedure(sql_allocator *sa, const char *name, const char *mod, const char *imp, int nargs, ...) { sql_func *res; va_list valist; va_start(valist, nargs); - res = sql_create_func_(sa, name, mod, imp, F_PROC, TRUE, side_effect, SCALE_NONE, 0, NULL, nargs, valist); + res = sql_create_func_(sa, name, mod, imp, F_PROC, TRUE, SCALE_NONE, 0, NULL, nargs, valist); va_end(valist); return res; } static sql_func * -sql_create_func(sql_allocator *sa, const char *name, const char *mod, const char *imp, bit semantics, bit side_effect, int fix_scale, +sql_create_func(sql_allocator *sa, const char *name, const char *mod, const char *imp, bit semantics, int fix_scale, unsigned int res_scale, sql_type *fres, int nargs, ...) { sql_func *res; va_list valist; va_start(valist, nargs); - res = sql_create_func_(sa, name, mod, imp, F_FUNC, semantics, side_effect, fix_scale, res_scale, fres, nargs, valist); + res = sql_create_func_(sa, name, mod, imp, F_FUNC, semantics, fix_scale, res_scale, fres, nargs, valist); va_end(valist); return res; } @@ -698,33 +697,33 @@ sql_create_aggr(sql_allocator *sa, const va_list valist; va_start(valist, nargs); - res = sql_create_func_(sa, name, mod, imp, F_AGGR, semantics, FALSE, SCALE_NONE, 0, fres, nargs, valist); + res = sql_create_func_(sa, name, mod, imp, F_AGGR, semantics, SCALE_NONE, 0, fres, nargs, valist); va_end(valist); return res; } static sql_func * -sql_create_filter(sql_allocator *sa, const char *name, const char *mod, const char *imp, bit semantics, bit side_effect, int fix_scale, +sql_create_filter(sql_allocator *sa, const char *name, const char *mod, const char *imp, bit semantics, int fix_scale, unsigned int res_scale, int nargs, ...) { sql_func *res; va_list valist; va_start(valist, nargs); - res = sql_create_func_(sa, name, mod, imp, F_FILT, semantics, side_effect, fix_scale, res_scale, BIT, nargs, valist); + res = sql_create_func_(sa, name, mod, imp, F_FILT, semantics, fix_scale, res_scale, BIT, nargs, valist); va_end(valist); return res; } static sql_func * -sql_create_union(sql_allocator *sa, const char *name, const char *mod, const char *imp, bit side_effect, int fix_scale, +sql_create_union(sql_allocator *sa, const char *name, const char *mod, const char *imp, int fix_scale, unsigned int res_scale, sql_type *fres, int nargs, ...) { sql_func *res; va_list valist; va_start(valist, nargs); - res = sql_create_func_(sa, name, mod, imp, F_UNION, TRUE, side_effect, fix_scale, res_scale, fres, nargs, valist); + res = sql_create_func_(sa, name, mod, imp, F_UNION, TRUE, fix_scale, res_scale, fres, nargs, valist); va_end(valist); return res; } @@ -736,7 +735,7 @@ sql_create_analytic(sql_allocator *sa, c va_list valist; va_start(valist, nargs); - res = sql_create_func_(sa, name, mod, imp, F_ANALYTIC, TRUE, FALSE, fix_scale, 0, fres, nargs, valist); + res = sql_create_func_(sa, name, mod, imp, F_ANALYTIC, TRUE, fix_scale, 0, fres, nargs, valist); va_end(valist); return res; } @@ -839,8 +838,8 @@ sqltypeinit( sql_allocator *sa) BLOB = *t++ = sql_create_type(sa, "BLOB", 0, 0, 0, EC_BLOB, "blob"); - sql_create_func(sa, "length", "blob", "nitems", FALSE, FALSE, SCALE_NONE, 0, INT, 1, BLOB); - sql_create_func(sa, "octet_length", "blob", "nitems", FALSE, FALSE, SCALE_NONE, 0, INT, 1, BLOB); + sql_create_func(sa, "length", "blob", "nitems", FALSE, SCALE_NONE, 0, INT, 1, BLOB); + sql_create_func(sa, "octet_length", "blob", "nitems", FALSE, SCALE_NONE, 0, INT, 1, BLOB); if (backend_has_module(&(int){0}, "geom")) { /* not the old version, change into check for module existence */ // the geom module is loaded @@ -852,41 +851,41 @@ sqltypeinit( sql_allocator *sa) MBR = *t++ = sql_create_type(sa, "MBR", 0, SCALE_NONE, 0, EC_EXTERNAL, "mbr"); /* mbr operator functions */ - sql_create_func(sa, "mbr_overlap", "geom", "mbrOverlaps", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_overlap", "geom", "mbrOverlaps", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_above", "geom", "mbrAbove", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_above", "geom", "mbrAbove", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_below", "geom", "mbrBelow", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_below", "geom", "mbrBelow", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_right", "geom", "mbrRight", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_right", "geom", "mbrRight", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_left", "geom", "mbrLeft", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_left", "geom", "mbrLeft", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_overlap_or_above", "geom", "mbrOverlapOrAbove", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_overlap_or_above", "geom", "mbrOverlapOrAbove", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_overlap_or_below", "geom", "mbrOverlapOrBelow", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_overlap_or_below", "geom", "mbrOverlapOrBelow", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_overlap_or_right", "geom", "mbrOverlapOrRight", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_overlap_or_right", "geom", "mbrOverlapOrRight", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_overlap_or_left", "geom", "mbrOverlapOrLeft", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_overlap_or_left", "geom", "mbrOverlapOrLeft", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_contains", "geom", "mbrContains", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_contains", "geom", "mbrContains", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_contained", "geom", "mbrContained", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_contained", "geom", "mbrContained", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_equal", "geom", "mbrEqual", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_equal", "geom", "mbrEqual", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "mbr_distance", "geom", "mbrDistance", TRUE, FALSE, SCALE_FIX, 0, DBL, 2, GEOM, GEOM); - sql_create_func(sa, "mbr_distance", "geom", "mbrDistance", TRUE, FALSE, SCALE_FIX, 0, DBL, 2, MBR, MBR); - sql_create_func(sa, "left_shift", "geom", "mbrLeft", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "left_shift", "geom", "mbrLeft", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); - sql_create_func(sa, "right_shift", "geom", "mbrRight", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); - sql_create_func(sa, "right_shift", "geom", "mbrRight", TRUE, FALSE, SCALE_FIX, 0, BIT, 2, MBR, MBR); + sql_create_func(sa, "mbr_overlap", "geom", "mbrOverlaps", TRUE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); + sql_create_func(sa, "mbr_overlap", "geom", "mbrOverlaps", TRUE, SCALE_FIX, 0, BIT, 2, MBR, MBR); + sql_create_func(sa, "mbr_above", "geom", "mbrAbove", TRUE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); + sql_create_func(sa, "mbr_above", "geom", "mbrAbove", TRUE, SCALE_FIX, 0, BIT, 2, MBR, MBR); + sql_create_func(sa, "mbr_below", "geom", "mbrBelow", TRUE, SCALE_FIX, 0, BIT, 2, GEOM, GEOM); + sql_create_func(sa, "mbr_below", "geom", "mbrBelow", TRUE, SCALE_FIX, 0, BIT, 2, MBR, MBR); _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list