Changeset: 4c321453d17c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=4c321453d17c
Modified Files:
        sql/server/rel_psm.c
        sql/server/rel_select.c
        sql/server/sql_semantic.c
        sql/server/sql_semantic.h
Branch: scoping2
Log Message:

Scoping search on variables


diffs (248 lines):

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
@@ -57,27 +57,6 @@ rel_psm_stmt(sql_allocator *sa, sql_exp 
        return NULL;
 }
 
-/* vname can be
-       - 'parameter of the function' (ie in the param list)
-       - local variable, declared earlier
-       - global variable, also declared earlier
-*/
-static void*
-resolve_variable_on_scope(mvc *sql, sql_schema *s, const char *sname, const 
char *vname, sql_var **var, sql_arg **a, sql_subtype **tpe, int *level, const 
char *action)
-{
-       if (!sname && (*var = stack_find_var_frame(sql, vname, level))) { /* 
check if variable is known from the stack */
-               *tpe = &((*var)->var.tpe);
-       } else if (!sname && (*a = sql_bind_param(sql, vname))) { /* then if it 
is a parameter */
-               *tpe = &((*a)->type);
-               *level = 1;
-       } else if ((*var = find_global_var(sql, s, vname))) { /* then if it is 
a global var */
-               *tpe = &((*var)->var.tpe);
-               *level = 0;
-       } else
-               return sql_error(sql, 01, SQLSTATE(42000) "%s: Variable 
'%s%s%s' unknown", action, sname ? sname : "", sname ? "." : "", vname);
-       return level;
-}
-
 /* SET [ schema '.' ] variable = value and set ( [ schema1 '.' ] variable1, 
.., [ schemaN '.' ] variableN) = (query) */
 static sql_exp *
 psm_set_exp(sql_query *query, dnode *n)
@@ -94,14 +73,11 @@ psm_set_exp(sql_query *query, dnode *n)
                exp_kind ek = {type_value, card_value, FALSE};
                const char *sname = qname_schema(qname);
                const char *vname = qname_schema_object(qname);
-               sql_schema *s = cur_schema(sql);
+               sql_schema *s = NULL;
                sql_var *var = NULL;
                sql_arg *a = NULL;
 
-               if (sname && !(s = mvc_bind_schema(sql, sname)))
-                       return sql_error(sql, 02, SQLSTATE(3F000) "SET: No such 
schema '%s'", sname);
-
-               if (!resolve_variable_on_scope(sql, s, sname, vname, &var, &a, 
&tpe, &level, "SET"))
+               if (!find_variable_on_scope(sql, &s, sname, vname, &var, &a, 
&tpe, &level, "SET"))
                        return NULL;
                if (!(e = rel_value_exp2(query, &rel, val, sql_sel | sql_psm, 
ek)))
                        return NULL;
@@ -134,14 +110,11 @@ psm_set_exp(sql_query *query, dnode *n)
                        const char *sname = qname_schema(nqname);
                        const char *vname = qname_schema_object(nqname);
                        sql_exp *v = n->data;
-                       sql_schema *s = cur_schema(sql);
+                       sql_schema *s = NULL;
                        sql_var *var = NULL;
                        sql_arg *a = NULL;
 
-                       if (sname && !(s = mvc_bind_schema(sql, sname)))
-                               return sql_error(sql, 02, SQLSTATE(3F000) "SET: 
No such schema '%s'", sname);
-
-                       if (!resolve_variable_on_scope(sql, s, sname, vname, 
&var, &a, &tpe, &level, "SET"))
+                       if (!find_variable_on_scope(sql, &s, sname, vname, 
&var, &a, &tpe, &level, "SET"))
                                return NULL;
 
                        v = exp_ref(sql, v);
@@ -181,7 +154,6 @@ rel_psm_declare(mvc *sql, dnode *n)
                        dlist *qname = ids->data.lval;
                        const char *sname = qname_schema(qname);
                        const char *tname = qname_schema_object(qname);
-                       sql_schema *s = cur_schema(sql);
                        sql_exp *r = NULL;
                        sql_arg *a;
 
@@ -192,7 +164,7 @@ rel_psm_declare(mvc *sql, dnode *n)
                                return sql_error(sql, 01, SQLSTATE(42000) 
"DECLARE: Variable '%s' declared as a parameter", tname);
                        /* check if we overwrite a scope local variable declare 
x; declare x; */
                        if (frame_find_var(sql, tname))
-                               return sql_error(sql, 01, SQLSTATE(42000) 
"DECLARE: Variable '%s.%s' already declared", s->base.name, tname);
+                               return sql_error(sql, 01, SQLSTATE(42000) 
"DECLARE: Variable '%s' already declared", tname);
                        /* variables are put on stack, globals on a separate 
list */
                        if (!frame_push_var(sql, tname, ctype))
                                return sql_error(sql, 02, SQLSTATE(HY013) 
MAL_MALLOC_FAIL);
@@ -589,17 +561,14 @@ rel_select_into( sql_query *query, symbo
                dlist *qname = n->data.lval;
                const char *sname = qname_schema(qname);
                const char *vname = qname_schema_object(qname);
-               sql_schema *s = cur_schema(sql);
+               sql_schema *s = NULL;
                sql_exp *v = m->data;
                int level;
                sql_var *var;
                sql_subtype *tpe;
                sql_arg *a = NULL;
 
-               if (sname && !(s = mvc_bind_schema(sql, sname)))
-                       return sql_error(sql, 02, SQLSTATE(3F000) "SELECT INTO: 
No such schema '%s'", sname);
-
-               if (!resolve_variable_on_scope(sql, s, sname, vname, &var, &a, 
&tpe, &level, "SELECT INTO"))
+               if (!find_variable_on_scope(sql, &s, sname, vname, &var, &a, 
&tpe, &level, "SELECT INTO"))
                        return NULL;
 
                v = exp_ref(sql, v);
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -973,36 +973,26 @@ table_ref(sql_query *query, sql_rel *rel
        }
 }
 
-static inline sql_exp *
-rel_exp_variable_on_scope(mvc *sql, sql_schema *s, const char *sname, const 
char *vname)
+static sql_exp *
+rel_exp_variable_on_scope(mvc *sql, const char *sname, const char *vname)
 {
+       sql_schema *s = NULL;
+       sql_subtype *tpe;
        sql_var *var = NULL;
        sql_arg *a = NULL;
        int level = 1;
 
-       if (!sname && (var = stack_find_var_frame(sql, vname, &level))) /* 
check if variable is known from the stack */
-               return exp_param_or_declared(sql->sa, NULL, sa_strdup(sql->sa, 
var->name), &(var->var.tpe), level);
-       if (!sname && (a = sql_bind_param(sql, vname))) /* then if it is a 
parameter */
-               return exp_param_or_declared(sql->sa, NULL, sa_strdup(sql->sa, 
vname), &(a->type), 1);
-       if ((var = find_global_var(sql, s, vname))) /* then if it is a global 
var */
-               return exp_param_or_declared(sql->sa, sa_strdup(sql->sa, 
var->sname), sa_strdup(sql->sa, var->name), &(var->var.tpe), 0);
+       (void) tpe;
+       if (find_variable_on_scope(sql, &s, sname, vname, &var, &a, &tpe, 
&level, "SELECT")) {
+               if (var) /* if variable is known from the stack or a global var 
*/
+                       return exp_param_or_declared(sql->sa, var->sname ? 
sa_strdup(sql->sa, var->sname) : NULL, sa_strdup(sql->sa, var->name), 
&(var->var.tpe), level);
+               if (a) /* if variable is a parameter */
+                       return exp_param_or_declared(sql->sa, NULL, 
sa_strdup(sql->sa, vname), &(a->type), level);
+       }
        return NULL;
 }
 
 static sql_exp *
-rel_var_ref(mvc *sql, const char *sname, const char *vname)
-{
-       sql_schema *s = cur_schema(sql);
-       sql_exp *res = NULL;
-
-       if (sname && !(s = mvc_bind_schema(sql, sname)))
-               return sql_error(sql, 02, SQLSTATE(3F000) "SELECT: no such 
schema '%s'", sname);
-       if (!(res = rel_exp_variable_on_scope(sql, s, sname, vname)))
-               return sql_error(sql, 02, SQLSTATE(42000) "SELECT: identifier 
'%s%s%s' unknown", sname ? sname : "", sname ? "." : "", vname);
-       return res;
-}
-
-static sql_exp *
 exps_get_exp(list *exps, int nth)
 {
        node *n = NULL;
@@ -1126,7 +1116,7 @@ rel_column_ref(sql_query *query, sql_rel
                        }
                }
                if (!exp) /* If no column was found, try a variable or 
parameter */
-                       exp = rel_exp_variable_on_scope(sql, cur_schema(sql), 
NULL, name);
+                       exp = rel_exp_variable_on_scope(sql, NULL, name);
 
                if (!exp)
                        return sql_error(sql, 02, SQLSTATE(42000) "SELECT: 
identifier '%s' unknown", name);
@@ -4968,7 +4958,7 @@ rel_value_exp2(sql_query *query, sql_rel
                dlist *l = se->data.lval;
                const char *sname = qname_schema(l);
                const char *vname = qname_schema_object(l);
-               return rel_var_ref(sql, sname, vname);
+               return rel_exp_variable_on_scope(sql, sname, vname);
        }
        case SQL_VALUES:
        case SQL_WITH:
diff --git a/sql/server/sql_semantic.c b/sql/server/sql_semantic.c
--- a/sql/server/sql_semantic.c
+++ b/sql/server/sql_semantic.c
@@ -118,7 +118,7 @@ tmp_schema(mvc *sql)
                                CALL; \
                        } \
                        EXTRA; \
-                       if (!sql->search_path_has_tmp) { /* if 'tmp' is not in 
the search path, search it before all others */ \
+                       if (!res && !sql->search_path_has_tmp) { /* if 'tmp' is 
not in the search path, search it before all others */ \
                                found = mvc_bind_schema(sql, "tmp"); \
                                CALL; \
                        } \
@@ -149,7 +149,7 @@ tmp_schema(mvc *sql)
 
 #define table_extra \
        do { \
-               if (strcmp(objstr, "table") == 0 && (res = 
stack_find_table(sql, name))) /* for tables, first try a declared table from 
the stack */ \
+               if (!res && strcmp(objstr, "table") == 0 && (res = 
stack_find_table(sql, name))) /* for tables, first try a declared table from 
the stack */ \
                        return res; \
        } while (0)
 
@@ -203,6 +203,44 @@ find_trigger_on_scope(mvc *sql, sql_sche
        return res;
 }
 
+/* A variable can be any of the following, from the innermost to the outermost:
+       - 'parameter of the function' (ie in the param list)
+       - local variable, declared earlier
+       - global variable, also declared earlier
+*/
+#define variable_extra \
+       do { \
+               if (!res) { \
+                       if ((*var = stack_find_var_frame(sql, name, level))) { 
/* check if variable is known from the stack */ \
+                               *tpe = &((*var)->var.tpe); \
+                               res = true; \
+                       } else if ((*a = sql_bind_param(sql, name))) { /* then 
if it is a parameter */ \
+                               *tpe = &((*a)->type); \
+                               *level = 1; \
+                               res = true; \
+                       } \
+               } \
+       } while (0)
+
+#define var_find_on_global \
+       do { \
+               if ((*var = find_global_var(sql, found, name))) { /* then if it 
is a global var */ \
+                       *tpe = &((*var)->var.tpe); \
+                       *level = 0; \
+                       res = true; \
+               } \
+       } while (0)
+
+bool
+find_variable_on_scope(mvc *sql, sql_schema **s, const char *sname, const char 
*name, sql_var **var, sql_arg **a, sql_subtype **tpe, int *level, const char 
*error)
+{
+       const char *objstr = "variable";
+       bool res = false;
+
+       search_object_on_path(var_find_on_global, variable_extra, 
SQLSTATE(42000));
+       return res;
+}
+
 char *
 qname_schema(dlist *qname)
 {
diff --git a/sql/server/sql_semantic.h b/sql/server/sql_semantic.h
--- a/sql/server/sql_semantic.h
+++ b/sql/server/sql_semantic.h
@@ -27,6 +27,7 @@ extern sql_sequence *find_sequence_on_sc
 extern sql_idx *find_idx_on_scope(mvc *sql, sql_schema **s, const char *sname, 
const char *name, const char *error);
 extern sql_type *find_type_on_scope(mvc *sql, sql_schema **s, const char 
*sname, const char *name, const char *error);
 extern sql_trigger *find_trigger_on_scope(mvc *sql, sql_schema **s, const char 
*sname, const char *name, const char *error);
+extern bool find_variable_on_scope(mvc *sql, sql_schema **s, const char 
*sname, const char *name, sql_var **var, sql_arg **a, sql_subtype **tpe, int 
*level, const char *error);
 
 extern char *qname_schema(dlist *qname);
 extern char *qname_schema_object(dlist *qname);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to