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

Reply via email to