Changeset: a9ba7c301167 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/a9ba7c301167 Modified Files: sql/ChangeLog sql/server/rel_exp.c sql/server/sql_decimal.c sql/server/sql_env.c sql/server/sql_mvc.c sql/server/sql_mvc.h sql/server/sql_var.c sql/test/BugTracker-2015/Tests/grantRole.Bug-3772.test sql/test/BugTracker-2018/Tests/grant-role-not-idempotent.Bug-6660.test sql/test/Users/Tests/grantMonetdb.test sql/test/Users/Tests/renameUser.SQL.py sql/test/Users/Tests/role.test sql/test/scoping/Tests/scoping02.test Branch: default Log Message:
Introduce division_min_scale global sql env variable diffs (truncated from 393 to 300 lines): diff --git a/sql/ChangeLog b/sql/ChangeLog --- a/sql/ChangeLog +++ b/sql/ChangeLog @@ -1,3 +1,7 @@ # ChangeLog file for sql # This file is updated with Maddlog +* Tue Sep 10 2024 Lucas Pereira <lucas.pere...@monetdbsolutions.com> +- Introduce division_min_scale SQL environment variable for specifying + minimum scale of the division result. The default value is 3. + diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c --- a/sql/server/rel_exp.c +++ b/sql/server/rel_exp.c @@ -3261,16 +3261,15 @@ exp_scale_algebra(mvc *sql, sql_subfunc sql_subtype *lt = exp_subtype(l); sql_subtype *rt = exp_subtype(r); - if (!EC_INTERVAL(lt->type->eclass) && lt->type->scale == SCALE_FIX && (lt->scale || rt->scale) && - strcmp(sql_func_imp(f->func), "/") == 0) { + if (!EC_INTERVAL(lt->type->eclass) && lt->type->scale == SCALE_FIX && + (lt->scale || rt->scale) && strcmp(sql_func_imp(f->func), "/") == 0) { sql_subtype *res = f->res->h->data; unsigned int scale, digits, digL, scaleL; sql_subtype nlt; /* scale fixing may require a larger type ! */ - /* TODO make '3' setable by user (division_minimal_scale or so) */ - scaleL = (lt->scale < 3) ? 3 : lt->scale; - scaleL += (scaleL < rt->scale)?(rt->scale - scaleL):0; + scaleL = (lt->scale < sql->div_min_scale) ? sql->div_min_scale : lt->scale; + scaleL += (scaleL < rt->scale) ? rt->scale - scaleL : 0; scale = scaleL; scaleL += rt->scale; digL = lt->digits + (scaleL - lt->scale); diff --git a/sql/server/sql_decimal.c b/sql/server/sql_decimal.c --- a/sql/server/sql_decimal.c +++ b/sql/server/sql_decimal.c @@ -201,13 +201,13 @@ number_bits(lng val) val = -val; unsigned bits = 0; #ifdef HAVE_HGE - hge m = ((hge)1)<<bits; - for( ;(val & ~m) > m; bits++) - m = ((hge)1)<<bits; + hge m = (hge)1 << bits; + for( ; (val & ~m) > m; bits++) + m = (hge)1 << bits; #else - lng m = ((lng)1)<<bits; - for( ;(val & ~m) > m; bits++) - m = ((lng)1)<<bits; + lng m = (lng)1 << bits; + for( ; (val & ~m) > m; bits++) + m = ((lng)1) << bits; #endif if (!bits) bits = 1; 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 @@ -54,30 +54,43 @@ str sql_update_var(mvc *m, sql_schema *s, const char *name, const ValRecord *ptr) { if (strcmp(s->base.name, "sys") == 0) { - if (strcmp(name, "debug") == 0 || strcmp(name, "current_timezone") == 0 || strcmp(name, "sql_optimizer") == 0) { + if (strcmp(name, "debug") == 0 || + strcmp(name, "current_timezone") == 0 || + strcmp(name, "sql_optimizer") == 0 || + strcmp(name, "division_min_scale") == 0) { VAR_UPCAST sgn = val_get_number(ptr); - if (VALisnil(ptr)) - throw(SQL,"sql.update_var", SQLSTATE(42000) "Variable '%s.%s' cannot be NULL\n", s->base.name, name); + throw(SQL, "sql_update_var", SQLSTATE(HY009) + "Variable '%s.%s' cannot be NULL", s->base.name, name); if (sgn <= (VAR_UPCAST) GDK_int_min) - throw(SQL,"sql.update_var", SQLSTATE(42000) "Value too small for '%s.%s'\n", s->base.name, name); + throw(SQL, "sql_update_var", SQLSTATE(HY009) + "Value too small for '%s.%s'", s->base.name, name); if (sgn > (VAR_UPCAST) GDK_int_max) - throw(SQL,"sql.update_var", SQLSTATE(42000) "Value too large for '%s.%s'\n", s->base.name, name); - + throw(SQL, "sql_update_var", SQLSTATE(HY009) + "Value too large for '%s.%s'", s->base.name, name); if (/* DISABLES CODE */ (0) && strcmp(name, "debug") == 0) { m->debug = (int) sgn; } else if (strcmp(name, "current_timezone") == 0) { m->timezone = (int) sgn; + } else if (strcmp(name, "division_min_scale") == 0) { + if (sgn >= 0) + m->div_min_scale = (unsigned int) sgn; + else + throw(SQL, "sql_update_var", SQLSTATE(HY009) + "Positive value required for '%s.%s'", s->base.name, name); } else { m->sql_optimizer = (int) sgn; } } else if (strcmp(name, "current_schema") == 0 || strcmp(name, "current_role") == 0) { if (VALisnil(ptr)) - throw(SQL,"sql.update_var", SQLSTATE(42000) "Variable '%s.%s' cannot be NULL\n", s->base.name, name); + throw(SQL,"sql.update_var", SQLSTATE(HY009) + "Variable '%s.%s' cannot be NULL", s->base.name, name); if (strcmp(name, "current_schema") == 0 && !mvc_set_schema(m, ptr->val.sval)) - throw(SQL,"sql.update_var", SQLSTATE(3F000) "Schema (%s) missing\n", ptr->val.sval); + throw(SQL,"sql.update_var", SQLSTATE(3F000) + "Schema (%s) missing\n", ptr->val.sval); else if (strcmp(name, "current_role") == 0 && !mvc_set_role(m, ptr->val.sval)) - throw(SQL,"sql.update_var", SQLSTATE(42000) "Role (%s) missing\n", ptr->val.sval); + throw(SQL,"sql.update_var", SQLSTATE(HY009) + "Role (%s) missing\n", ptr->val.sval); } } return NULL; 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 @@ -814,17 +814,14 @@ mvc_create(sql_store *store, allocator * qc_destroy(m->qc); return NULL; } - if (init_global_variables(m) < 0) { - qc_destroy(m->qc); - list_destroy(m->global_vars); - return NULL; - } + m->sym = NULL; m->role_id = m->user_id = -1; m->timezone = 0; m->sql_optimizer = INT_MAX; m->clientid = clientid; + m->div_min_scale = 3; m->emode = m_normal; m->emod = mod_none; @@ -836,6 +833,12 @@ mvc_create(sql_store *store, allocator * m->cascade_action = NULL; m->runs = NULL; + if (init_global_variables(m) < 0) { + qc_destroy(m->qc); + list_destroy(m->global_vars); + return NULL; + } + if (!(m->schema_path = list_create((fdestroy)_free))) { qc_destroy(m->qc); list_destroy(m->global_vars); 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 @@ -112,8 +112,8 @@ typedef struct sql_frame { /* a single SQL optimizer run */ typedef struct { const char *name; /* the optimizer name itself */ - int nchanges; /* how many changes it did */ - lng time; /* how long it did take (all runs) */ + int nchanges; /* how many changes it did */ + lng time; /* how long it did take (all runs) */ } sql_optimizer_run; typedef struct mvc { @@ -124,45 +124,44 @@ typedef struct mvc { struct scanner scanner; list *params; - sqlid objid; /* when replacing an existing view, it can't be seen */ - sql_func *forward; /* forward definitions for recursive functions */ - list *global_vars; /* SQL declared variables on the global scope */ - sql_frame **frames; /* stack of frames with variables */ + sqlid objid; /* when replacing an existing view, it can't be seen */ + sql_func *forward; /* forward definitions for recursive functions */ + list *global_vars; /* SQL declared variables on the global scope */ + sql_frame **frames; /* stack of frames with variables */ int topframes; int sizeframes; int frame; struct symbol *sym; bool use_views:1, - schema_path_has_sys:1, /* speed up object search */ - schema_path_has_tmp:1, - no_int128:1; + schema_path_has_sys:1, /* speed up object search */ + schema_path_has_tmp:1, + no_int128:1; struct qc *qc; - int clientid; /* id of the owner */ + int clientid; /* id of the owner */ /* session variables */ sqlid user_id; sqlid role_id; - int timezone; /* milliseconds west of UTC */ - int reply_size; /* reply size */ + int timezone; /* milliseconds west of UTC */ + unsigned int div_min_scale; /* minimum scale for division op*/ + int reply_size; /* reply size */ int debug; - int sql_optimizer; /* SQL optimizer mask */ - sql_optimizer_run *runs; /* Information about SQL optimizer runs */ - - char emode; /* execution mode */ - char emod; /* execution modifier */ - + int sql_optimizer; /* SQL optimizer mask */ + sql_optimizer_run *runs; /* Information about SQL optimizer runs */ + char emode; /* execution mode */ + char emod; /* execution modifier */ sql_session *session; sql_store store; /* per query context */ - mapi_query_t type; /* query type */ + mapi_query_t type; /* query type */ /* during query needed flags */ - unsigned int label; /* numbers for relational projection labels */ - int nid; /* numbers for relational names */ - list *cascade_action; /* protection against recursive cascade actions */ - list *schema_path; /* schema search path for object lookup */ + unsigned int label; /* numbers for relational projection labels */ + int nid; /* numbers for relational names */ + list *cascade_action; /* protection against recursive cascade actions */ + list *schema_path; /* schema search path for object lookup */ uintptr_t sp; } mvc; diff --git a/sql/server/sql_var.c b/sql/server/sql_var.c --- a/sql/server/sql_var.c +++ b/sql/server/sql_var.c @@ -32,8 +32,9 @@ destroy_sql_var(void *gdata, void *data) _DELETE(svar); } -#define SQLglobal(sname, name, val) \ - if (!(var = push_global_var(sql, sname, name, &ctype)) || !sqlvar_set(var, VALset(&src, ctype.type->localtype, (char*)(val)))) \ +#define SQL_GLOBAL(sname, name, val) \ + if (!(var = push_global_var(sql, sname, name, &ctype)) || \ + !sqlvar_set(var, VALset(&src, ctype.type->localtype, (char*)(val)))) \ return -1; static int @@ -48,36 +49,38 @@ init_global_variables(mvc *sql) sql_subtype ctype; lng sec = 0; ValRecord src; - const char *opt, *sname = "sys"; + const char *mal_optimizer, *sname = "sys"; sql_var *var; if (!(sql->global_vars = list_create(destroy_sql_var))) return -1; - /* Use hash lookup for global variables */ if (!(sql->global_vars->ht = hash_new(NULL, 16, (fkeyvalue)&var_key))) return -1; sql_find_subtype(&ctype, "int", 0, 0); - SQLglobal(sname, "debug", &sql->debug); - SQLglobal(sname, "sql_optimizer", &sql->sql_optimizer); + SQL_GLOBAL(sname, "debug", &sql->debug); + SQL_GLOBAL(sname, "sql_optimizer", &sql->sql_optimizer); + SQL_GLOBAL(sname, "division_min_scale", &sql->div_min_scale); - sql_find_subtype(&ctype, "varchar", 1024, 0); - SQLglobal(sname, "current_schema", sname); - SQLglobal(sname, "current_user", "monetdb"); - SQLglobal(sname, "current_role", "monetdb"); + sql_find_subtype(&ctype, "varchar", 1024, 0); + SQL_GLOBAL(sname, "current_schema", sname); + SQL_GLOBAL(sname, "current_user", "monetdb"); + SQL_GLOBAL(sname, "current_role", "monetdb"); - /* inherit the optimizer from the server */ - opt = GDKgetenv("sql_optimizer"); - if (!opt) - opt = "default_pipe"; - SQLglobal(sname, "optimizer", opt); + /* TODO: GDKenv var sql_optimizer change to mal_optimizer */ + mal_optimizer = GDKgetenv("sql_optimizer"); + if (!mal_optimizer) + mal_optimizer = "default_pipe"; + /* TODO: Change optmizer to mal_optimizer */ + SQL_GLOBAL(sname, "optimizer", mal_optimizer); sql_find_subtype(&ctype, "sec_interval", inttype2digits(ihour, isec), 0); - SQLglobal(sname, "current_timezone", &sec); + SQL_GLOBAL(sname, "current_timezone", &sec); sql_find_subtype(&ctype, "bigint", 0, 0); - SQLglobal(sname, "last_id", &sec); - SQLglobal(sname, "rowcnt", &sec); + SQL_GLOBAL(sname, "last_id", &sec); + SQL_GLOBAL(sname, "rowcnt", &sec); + return 0; } _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org