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