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 37833 : sql_update_var(mvc *m, sql_schema *s, const char *name, const ValRecord *ptr)
55 : {
56 37833 : if (strcmp(s->base.name, "sys") == 0) {
57 37833 : if (strcmp(name, "debug") == 0 || strcmp(name, "current_timezone") == 0 || strcmp(name, "sql_optimizer") == 0) {
58 37689 : VAR_UPCAST sgn = val_get_number(ptr);
59 :
60 37690 : if (VALisnil(ptr))
61 2 : throw(SQL,"sql.update_var", SQLSTATE(42000) "Variable '%s.%s' cannot be NULL\n", s->base.name, name);
62 37688 : if (sgn <= (VAR_UPCAST) GDK_int_min)
63 0 : throw(SQL,"sql.update_var", SQLSTATE(42000) "Value too small for '%s.%s'\n", s->base.name, name);
64 37688 : if (sgn > (VAR_UPCAST) GDK_int_max)
65 1 : throw(SQL,"sql.update_var", SQLSTATE(42000) "Value too large for '%s.%s'\n", s->base.name, name);
66 :
67 37687 : if (/* DISABLES CODE */ (0) && strcmp(name, "debug") == 0) {
68 : m->debug = (int) sgn;
69 37687 : } else if (strcmp(name, "current_timezone") == 0) {
70 37684 : m->timezone = (int) sgn;
71 : } else {
72 3 : m->sql_optimizer = (int) sgn;
73 : }
74 144 : } else if (strcmp(name, "current_schema") == 0 || strcmp(name, "current_role") == 0) {
75 144 : if (VALisnil(ptr))
76 2 : throw(SQL,"sql.update_var", SQLSTATE(42000) "Variable '%s.%s' cannot be NULL\n", s->base.name, name);
77 142 : if (strcmp(name, "current_schema") == 0 && !mvc_set_schema(m, ptr->val.sval))
78 1 : throw(SQL,"sql.update_var", SQLSTATE(3F000) "Schema (%s) missing\n", ptr->val.sval);
79 141 : else if (strcmp(name, "current_role") == 0 && !mvc_set_role(m, ptr->val.sval))
80 8 : throw(SQL,"sql.update_var", SQLSTATE(42000) "Role (%s) missing\n", ptr->val.sval);
81 : }
82 : }
83 : return NULL;
84 : }
85 :
86 : int
87 221 : sql_create_env(mvc *m, sql_schema *s)
88 : {
89 221 : list *res, *ops;
90 221 : sql_func *f = NULL;
91 :
92 221 : res = sa_list(m->sa);
93 221 : list_append(res, sql_create_arg(m->sa, "name", sql_bind_subtype(m->sa, "varchar", 1024, 0), ARG_OUT));
94 221 : list_append(res, sql_create_arg(m->sa, "value", sql_bind_subtype(m->sa, "varchar", 2048, 0), ARG_OUT));
95 :
96 : /* add function */
97 221 : ops = sa_list(m->sa);
98 221 : 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);
99 221 : if (f)
100 221 : f->instantiated = TRUE;
101 :
102 221 : res = sa_list(m->sa);
103 221 : list_append(res, sql_create_arg(m->sa, "schema", sql_bind_localtype("str"), ARG_OUT));
104 221 : list_append(res, sql_create_arg(m->sa, "name", sql_bind_localtype("str"), ARG_OUT));
105 221 : list_append(res, sql_create_arg(m->sa, "type", sql_bind_localtype("str"), ARG_OUT));
106 221 : list_append(res, sql_create_arg(m->sa, "value", sql_bind_localtype("str"), ARG_OUT));
107 :
108 : /* add function */
109 221 : ops = sa_list(m->sa);
110 221 : 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);
111 221 : if (f)
112 221 : f->instantiated = TRUE;
113 221 : return 0;
114 : }
|