Line data Source code
1 : /*
2 : * SPDX-License-Identifier: MPL-2.0
3 : *
4 : * This Source Code Form is subject to the terms of the Mozilla Public
5 : * License, v. 2.0. If a copy of the MPL was not distributed with this
6 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 : *
8 : * Copyright 2024 MonetDB Foundation;
9 : * Copyright August 2008 - 2023 MonetDB B.V.;
10 : * Copyright 1997 - July 2008 CWI.
11 : */
12 :
13 : /*
14 : * Environment variables
15 : * =====================
16 : *
17 : * The processing setting of the SQL front-end can collect information
18 : * for postprocessing and debugging by setting a flag
19 : * using the SQL construct:
20 : * SET <variable>=<string>
21 : * SET <variable>=<boolean>
22 : * SET <variable>=<int>
23 : *
24 : * The SQL engine comes with a limited set of environment variables
25 : * to control its behavior.
26 : * The 'debug' variable takes an integer and sets the Mserver global
27 : * debug flag. (See MonetDB documentation.)
28 : *
29 : * By default all remaining variables are stored as strings and
30 : * any type analysis is up to the user. The can be freely used by the
31 : * SQL programmer for inclusion in his queries.
32 : *
33 : * The limited number of built-in variables defined above are
34 : * strongly typed the hard way.
35 : * Moreover, they have a counterpart representation in the
36 : * MVC structure to ease inspection during query processing.
37 : *
38 : * The variables can be retrieved using the table producing function var();
39 : */
40 :
41 : #include "monetdb_config.h"
42 : #include "sql_env.h"
43 : #include "sql_semantic.h"
44 : #include "sql_privileges.h"
45 : #include "mal_exception.h"
46 :
47 : #ifdef HAVE_HGE
48 : #define VAR_UPCAST hge
49 : #else
50 : #define VAR_UPCAST lng
51 : #endif
52 :
53 : str
54 37222 : sql_update_var(mvc *m, sql_schema *s, const char *name, const ValRecord *ptr)
55 : {
56 37222 : if (strcmp(s->base.name, "sys") == 0) {
57 37222 : if (strcmp(name, "debug") == 0 ||
58 37218 : strcmp(name, "current_timezone") == 0 ||
59 166 : strcmp(name, "sql_optimizer") == 0 ||
60 166 : strcmp(name, "division_min_scale") == 0) {
61 37056 : VAR_UPCAST sgn = val_get_number(ptr);
62 37056 : if (VALisnil(ptr))
63 2 : throw(SQL, "sql_update_var", SQLSTATE(HY009)
64 : "Variable '%s.%s' cannot be NULL", s->base.name, name);
65 37054 : if (sgn <= (VAR_UPCAST) GDK_int_min)
66 0 : throw(SQL, "sql_update_var", SQLSTATE(HY009)
67 : "Value too small for '%s.%s'", s->base.name, name);
68 37054 : if (sgn > (VAR_UPCAST) GDK_int_max)
69 1 : throw(SQL, "sql_update_var", SQLSTATE(HY009)
70 : "Value too large for '%s.%s'", s->base.name, name);
71 37053 : if (/* DISABLES CODE */ (0) && strcmp(name, "debug") == 0) {
72 : m->debug = (int) sgn;
73 37053 : } else if (strcmp(name, "current_timezone") == 0) {
74 37049 : m->timezone = (int) sgn;
75 4 : } else if (strcmp(name, "division_min_scale") == 0) {
76 0 : if (sgn >= 0)
77 0 : m->div_min_scale = (unsigned int) sgn;
78 : else
79 0 : throw(SQL, "sql_update_var", SQLSTATE(HY009)
80 : "Positive value required for '%s.%s'", s->base.name, name);
81 : } else {
82 4 : m->sql_optimizer = (int) sgn;
83 : }
84 166 : } else if (strcmp(name, "current_schema") == 0 || strcmp(name, "current_role") == 0) {
85 166 : if (VALisnil(ptr))
86 2 : throw(SQL,"sql.update_var", SQLSTATE(HY009)
87 : "Variable '%s.%s' cannot be NULL", s->base.name, name);
88 164 : if (strcmp(name, "current_schema") == 0 && !mvc_set_schema(m, ptr->val.sval))
89 1 : throw(SQL,"sql.update_var", SQLSTATE(3F000)
90 1 : "Schema (%s) missing\n", ptr->val.sval);
91 163 : else if (strcmp(name, "current_role") == 0 && !mvc_set_role(m, ptr->val.sval))
92 9 : throw(SQL,"sql.update_var", SQLSTATE(HY009)
93 9 : "Role (%s) missing\n", ptr->val.sval);
94 : }
95 : }
96 : return NULL;
97 : }
98 :
99 : int
100 225 : sql_create_env(mvc *m, sql_schema *s)
101 : {
102 225 : list *res, *ops;
103 225 : sql_func *f = NULL;
104 :
105 225 : res = sa_list(m->sa);
106 225 : list_append(res, sql_create_arg(m->sa, "name", sql_bind_subtype(m->sa, "varchar", 1024, 0), ARG_OUT));
107 225 : list_append(res, sql_create_arg(m->sa, "value", sql_bind_subtype(m->sa, "varchar", 2048, 0), ARG_OUT));
108 :
109 : /* add function */
110 225 : ops = sa_list(m->sa);
111 225 : mvc_create_func(&f, m, NULL, s, "env", ops, res, F_UNION, FUNC_LANG_MAL, "inspect", "getEnvironment", "CREATE FUNCTION env() RETURNS TABLE( name varchar(1024), value varchar(2048)) EXTERNAL NAME inspect.\"getEnvironment\";", FALSE, FALSE, TRUE, FALSE, FALSE, FALSE);
112 225 : if (f)
113 225 : f->instantiated = TRUE;
114 :
115 225 : res = sa_list(m->sa);
116 225 : list_append(res, sql_create_arg(m->sa, "schema", sql_bind_localtype("str"), ARG_OUT));
117 225 : list_append(res, sql_create_arg(m->sa, "name", sql_bind_localtype("str"), ARG_OUT));
118 225 : list_append(res, sql_create_arg(m->sa, "type", sql_bind_localtype("str"), ARG_OUT));
119 225 : list_append(res, sql_create_arg(m->sa, "value", sql_bind_localtype("str"), ARG_OUT));
120 :
121 : /* add function */
122 225 : ops = sa_list(m->sa);
123 225 : mvc_create_func(&f, m, NULL, s, "var", ops, res, F_UNION, FUNC_LANG_MAL, "sql", "sql_variables", "create function \"sys\".\"var\"() returns table(\"schema\" string, \"name\" string, \"type\" string, \"value\" string) external name \"sql\".\"sql_variables\";", FALSE, FALSE, TRUE, FALSE, FALSE, FALSE);
124 225 : if (f)
125 225 : f->instantiated = TRUE;
126 225 : return 0;
127 : }
|