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 : * authors M Kersten, N Nes
15 : * SQL catalog support implementation
16 : * This module contains the wrappers around the SQL catalog operations
17 : */
18 : #include "monetdb_config.h"
19 : #include "sql_cat.h"
20 : #include "sql_gencode.h"
21 : #include "sql_optimizer.h"
22 : #include "sql_scenario.h"
23 : #include "sql_mvc.h"
24 : #include "sql_qc.h"
25 : #include "sql_partition.h"
26 : #include "sql_statistics.h"
27 : #include "mal_namespace.h"
28 : #include "opt_prelude.h"
29 : #include "querylog.h"
30 : #include "mal_builder.h"
31 :
32 : #include "rel_select.h"
33 : #include "rel_prop.h"
34 : #include "rel_rel.h"
35 : #include "rel_exp.h"
36 : #include "rel_bin.h"
37 : #include "rel_dump.h"
38 : #include "orderidx.h"
39 : #include "sql_user.h"
40 :
41 : #define initcontext() \
42 : if ((msg = getSQLContext(cntxt, mb, &sql, NULL)) != NULL) \
43 : return msg; \
44 : if ((msg = checkSQLContext(cntxt)) != NULL) \
45 : return msg; \
46 : if (store_readonly(sql->session->tr->store)) \
47 : throw(SQL,"sql.cat",SQLSTATE(25006) "Schema statements cannot be executed on a readonly database.");
48 :
49 : static char *
50 26345 : SaveArgReference(MalStkPtr stk, InstrPtr pci, int arg)
51 : {
52 26345 : char *val = *getArgReference_str(stk, pci, arg);
53 :
54 31893 : if (strNil(val))
55 : val = NULL;
56 26345 : return val;
57 : }
58 :
59 : static int
60 2289 : table_has_updates(sql_trans *tr, sql_table *t)
61 : {
62 2289 : node *n;
63 2289 : int cnt = 0;
64 2289 : sqlstore *store = tr->store;
65 :
66 7137 : for ( n = ol_first_node(t->columns); !cnt && n; n = n->next) {
67 4848 : sql_column *c = n->data;
68 :
69 4848 : size_t upd = store->storage_api.count_col( tr, c, 2/* count updates */);
70 4848 : cnt |= upd > 0;
71 : }
72 2289 : return cnt;
73 : }
74 :
75 : static char *
76 584 : rel_check_tables(mvc *sql, sql_table *nt, sql_table *nnt, const char *errtable)
77 : {
78 584 : node *n, *m, *nn, *mm;
79 :
80 584 : if (ol_length(nt->columns) != ol_length(nnt->columns))
81 1 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table doesn't match %s definition", errtable, errtable);
82 1872 : for (n = ol_first_node(nt->columns), m = ol_first_node(nnt->columns); n && m; n = n->next, m = m->next) {
83 1296 : sql_column *nc = n->data;
84 1296 : sql_column *mc = m->data;
85 :
86 1296 : if (subtype_cmp(&nc->type, &mc->type) != 0)
87 2 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table column type doesn't match %s definition", errtable, errtable);
88 1294 : if (nc->null != mc->null)
89 3 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table column NULL check doesn't match %s definition", errtable, errtable);
90 1291 : if (isRangePartitionTable(nt) || isListPartitionTable(nt)) {
91 481 : if ((nc->def || mc->def) && (!nc->def || !mc->def || strcmp(nc->def, mc->def) != 0))
92 2 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table column DEFAULT value doesn't match %s definition", errtable, errtable);
93 : }
94 : }
95 576 : if (ol_length(nt->keys) != ol_length(nnt->keys))
96 2 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key doesn't match %s definition", errtable, errtable);
97 574 : if (ol_length(nt->keys))
98 133 : for (n = ol_first_node(nt->keys), m = ol_first_node(nnt->keys); n && m; n = n->next, m = m->next) {
99 71 : sql_key *ni = n->data;
100 71 : sql_key *mi = m->data;
101 :
102 71 : if (ni->type != mi->type)
103 0 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable);
104 71 : if (list_length(ni->columns) != list_length(mi->columns))
105 0 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable);
106 148 : for (nn = ni->columns->h, mm = mi->columns->h; nn && mm; nn = nn->next, mm = mm->next) {
107 79 : sql_kc *nni = nn->data;
108 79 : sql_kc *mmi = mm->data;
109 :
110 79 : if (nni->c->colnr != mmi->c->colnr)
111 2 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key's columns doesn't match %s definition", errtable, errtable);
112 : }
113 : }
114 :
115 : /* For indexes, empty ones can be ignored, which makes validation trickier */
116 572 : n = ol_length(nt->idxs) ? ol_first_node(nt->idxs) : NULL;
117 572 : m = ol_length(nnt->idxs) ? ol_first_node(nnt->idxs) : NULL;
118 580 : for (; n || m; n = n->next, m = m->next) {
119 : sql_idx *ni, *mi;
120 :
121 122 : while (n) {
122 68 : ni = n->data;
123 68 : if ((!hash_index(ni->type) || list_length(ni->columns) > 1) && idx_has_column(ni->type))
124 : break;
125 60 : n = n->next;
126 : }
127 122 : while (m) {
128 68 : mi = m->data;
129 68 : if ((!hash_index(mi->type) || list_length(mi->columns) > 1) && idx_has_column(mi->type))
130 : break;
131 60 : m = m->next;
132 : }
133 :
134 62 : if (!n && !m) /* no more idxs to check, done */
135 : break;
136 8 : if ((m && !n) || (!m && n))
137 0 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index type doesn't match %s definition", errtable, errtable);
138 :
139 8 : assert(m && n);
140 8 : ni = n->data;
141 8 : mi = m->data;
142 8 : if (ni->type != mi->type)
143 0 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index type doesn't match %s definition", errtable, errtable);
144 8 : if (list_length(ni->columns) != list_length(mi->columns))
145 0 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table key type doesn't match %s definition", errtable, errtable);
146 24 : for (nn = ni->columns->h, mm = mi->columns->h; nn && mm; nn = nn->next, mm = mm->next) {
147 16 : sql_kc *nni = nn->data;
148 16 : sql_kc *mmi = mm->data;
149 :
150 16 : if (nni->c->colnr != mmi->c->colnr)
151 0 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table index's columns doesn't match %s definition", errtable, errtable);
152 : }
153 : }
154 :
155 572 : if (nested_mergetable(sql->session->tr, nt/*mergetable*/, nnt->s->base.name, nnt->base.name/*parts*/))
156 2 : throw(SQL,"sql.rel_check_tables",SQLSTATE(3F000) "ALTER %s: to be added table is a parent of the %s", errtable, errtable);
157 : return MAL_SUCCEED;
158 : }
159 :
160 : static char*
161 595 : validate_alter_table_add_table(mvc *sql, char* call, char *msname, char *mtname, char *psname, char *ptname,
162 : sql_table **mt, sql_table **pt, int update)
163 : {
164 595 : char *msg = MAL_SUCCEED;
165 595 : sql_schema *ms = NULL, *ps = NULL;
166 595 : sql_table *rmt = NULL, *rpt = NULL;
167 :
168 595 : if (!(ms = mvc_bind_schema(sql, msname)))
169 0 : throw(SQL,call,SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", msname);
170 595 : if (!(ps = mvc_bind_schema(sql, psname)))
171 0 : throw(SQL,call,SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", psname);
172 595 : if (!mvc_schema_privs(sql, ms))
173 0 : throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), ms->base.name);
174 595 : if (!mvc_schema_privs(sql, ps))
175 0 : throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), ps->base.name);
176 595 : if (!(rmt = mvc_bind_table(sql, ms, mtname)))
177 0 : throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", mtname, ms->base.name);
178 595 : if (!(rpt = mvc_bind_table(sql, ps, ptname)))
179 0 : throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", ptname, ps->base.name);
180 :
181 595 : const char *errtable = TABLE_TYPE_DESCRIPTION(rmt->type, rmt->properties);
182 595 : if (!update && (!isMergeTable(rmt) && !isReplicaTable(rmt)))
183 1 : throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: cannot add table '%s.%s' to %s '%s.%s'", psname, ptname, errtable, msname, mtname);
184 594 : if (isView(rpt))
185 0 : throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: can't add a view into a %s", errtable);
186 594 : if (isDeclaredTable(rpt))
187 0 : throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: can't add a declared table into a %s", errtable);
188 594 : if (isTempSchema(rpt->s))
189 0 : throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: can't add a temporary table into a %s", errtable);
190 594 : if (ms->base.id != ps->base.id)
191 0 : throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: all children tables of '%s.%s' must be part of schema '%s'", msname, mtname, msname);
192 594 : if (rmt->base.id == rpt->base.id)
193 1 : throw(SQL,call,SQLSTATE(42000) "ALTER TABLE: a %s can't be a child of itself", errtable);
194 593 : node *n = members_find_child_id(rmt->members, rpt->base.id);
195 593 : if (n && !update)
196 7 : throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: table '%s.%s' is already part of %s '%s.%s'", psname, ptname, errtable, msname, mtname);
197 586 : if (!n && update)
198 2 : throw(SQL,call,SQLSTATE(42S02) "ALTER TABLE: table '%s.%s' isn't part of %s '%s.%s'", psname, ptname, errtable, msname, mtname);
199 584 : if ((msg = rel_check_tables(sql, rmt, rpt, errtable)) != MAL_SUCCEED)
200 : return msg;
201 :
202 570 : *mt = rmt;
203 570 : *pt = rpt;
204 570 : return MAL_SUCCEED;
205 : }
206 :
207 : static char *
208 312 : alter_table_add_table(mvc *sql, char *msname, char *mtname, char *psname, char *ptname)
209 : {
210 312 : sql_table *mt = NULL, *pt = NULL;
211 312 : str msg = validate_alter_table_add_table(sql, "sql.alter_table_add_table", msname, mtname, psname, ptname, &mt, &pt, 0);
212 :
213 312 : if (msg == MAL_SUCCEED) {
214 302 : if (isRangePartitionTable(mt))
215 0 : return createException(SQL, "sql.alter_table_add_table",SQLSTATE(42000) "ALTER TABLE: a range partition is required while adding under a range partition table");
216 302 : if (isListPartitionTable(mt))
217 0 : return createException(SQL, "sql.alter_table_add_table",SQLSTATE(42000) "ALTER TABLE: a value partition is required while adding under a list partition table");
218 302 : switch (sql_trans_add_table(sql->session->tr, mt, pt)) {
219 0 : case -1:
220 0 : return createException(SQL,"sql.alter_table_add_table",SQLSTATE(HY013) MAL_MALLOC_FAIL);
221 3 : case -2:
222 : case -3:
223 3 : return createException(SQL,"sql.alter_table_add_table",SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
224 : default:
225 : break;
226 : }
227 : }
228 : return msg;
229 : }
230 :
231 :
232 : static char *
233 224 : alter_table_add_range_partition(mvc *sql, char *msname, char *mtname, char *psname, char *ptname, ptr min, ptr max,
234 : bit with_nills, int update, lng cnt)
235 : {
236 224 : sql_table *mt = NULL, *pt = NULL;
237 224 : sql_part *err = NULL;
238 224 : str msg = MAL_SUCCEED, err_min = NULL, err_max = NULL, conflict_err_min = NULL, conflict_err_max = NULL;
239 224 : int tp1 = 0, errcode = 0, min_null = 0, max_null = 0;
240 224 : size_t length = 0;
241 224 : sql_subtype tpe;
242 :
243 224 : if ((msg = validate_alter_table_add_table(sql, "sql.alter_table_add_range_partition", msname, mtname, psname, ptname, &mt, &pt, update))) {
244 : return msg;
245 210 : } else if (!isRangePartitionTable(mt)) {
246 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
247 : "ALTER TABLE: cannot add range partition into a %s table",
248 0 : (isListPartitionTable(mt))?"list partition":"merge");
249 0 : goto finish;
250 210 : } else if (!update && partition_find_part(sql->session->tr, pt, NULL)) {
251 1 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
252 : "ALTER TABLE: table '%s.%s' is already part of another table",
253 : psname, ptname);
254 1 : goto finish;
255 : }
256 :
257 209 : find_partition_type(&tpe, mt);
258 209 : tp1 = tpe.type->localtype;
259 209 : min_null = ATOMcmp(tp1, min, ATOMnilptr(tp1)) == 0;
260 209 : max_null = ATOMcmp(tp1, max, ATOMnilptr(tp1)) == 0;
261 :
262 209 : if (!min_null && !max_null && ATOMcmp(tp1, min, max) > 0) {
263 2 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) "ALTER TABLE: minimum value is higher than maximum value");
264 2 : goto finish;
265 : }
266 207 : if (!min_null && !max_null && ATOMcmp(tp1, min, max) == 0) {
267 3 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000) "ALTER TABLE: minimum value is equal to the maximum value");
268 3 : goto finish;
269 : }
270 :
271 204 : if (cnt) {
272 18 : if (isPartitionedByColumnTable(mt)) {
273 17 : throw(SQL, "sql.alter_table_add_range_partition", SQLSTATE(M0M29) "ALTER TABLE: there are values in column %s outside the partition range", mt->part.pcol->base.name);
274 1 : } else if (isPartitionedByExpressionTable(mt)) {
275 1 : throw(SQL, "sql.alter_table_add_range_partition", SQLSTATE(M0M29) "ALTER TABLE: there are values in the expression outside the partition range");
276 : } else {
277 0 : assert(0);
278 : }
279 : }
280 :
281 186 : errcode = sql_trans_add_range_partition(sql->session->tr, mt, pt, tpe, min, max, with_nills, update, &err);
282 186 : switch (errcode) {
283 : case 0:
284 : break;
285 0 : case -1:
286 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
287 0 : break;
288 1 : case -2:
289 : case -3:
290 1 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
291 : "ALTER TABLE: failed due to conflict with another transaction");
292 1 : break;
293 0 : case -10:
294 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
295 : "ALTER TABLE: minimum value length is higher than %d", STORAGE_MAX_VALUE_LENGTH);
296 0 : break;
297 0 : case -11:
298 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
299 : "ALTER TABLE: maximum value length is higher than %d", STORAGE_MAX_VALUE_LENGTH);
300 0 : break;
301 38 : case -12:
302 38 : assert(err);
303 38 : if (is_bit_nil(err->with_nills)) {
304 4 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
305 4 : "ALTER TABLE: conflicting partitions: table %s.%s stores every possible value", err->t->s->base.name, err->base.name);
306 34 : } else if (with_nills && err->with_nills) {
307 6 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
308 : "ALTER TABLE: conflicting partitions: table %s.%s stores null values and only "
309 6 : "one partition can store null values at the time", err->t->s->base.name, err->base.name);
310 : } else {
311 28 : ssize_t (*atomtostr)(str *, size_t *, const void *, bool) = BATatoms[tp1].atomToStr;
312 28 : const void *nil = ATOMnilptr(tp1);
313 28 : sql_table *errt = mvc_bind_table(sql, mt->s, err->base.name);
314 :
315 28 : if (!errt) {
316 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
317 0 : "ALTER TABLE: cannot find partition table %s.%s", err->t->s->base.name, err->base.name);
318 0 : goto finish;
319 : }
320 28 : if (!ATOMcmp(tp1, nil, err->part.range.minvalue)) {
321 9 : if (!(conflict_err_min = GDKstrdup("absolute min value")))
322 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
323 19 : } else if (atomtostr(&conflict_err_min, &length, err->part.range.minvalue, true) < 0) {
324 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
325 : }
326 0 : if (msg)
327 0 : goto finish;
328 :
329 28 : if (!ATOMcmp(tp1, nil, err->part.range.maxvalue)) {
330 8 : if (!(conflict_err_max = GDKstrdup("absolute max value")))
331 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
332 20 : } else if (atomtostr(&conflict_err_max, &length, err->part.range.maxvalue, true) < 0) {
333 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
334 : }
335 0 : if (msg)
336 0 : goto finish;
337 :
338 28 : if (!ATOMcmp(tp1, nil, min)) {
339 5 : if (!(err_min = GDKstrdup("absolute min value")))
340 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
341 23 : } else if (atomtostr(&err_min, &length, min, true) < 0) {
342 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
343 : }
344 0 : if (msg)
345 0 : goto finish;
346 :
347 28 : if (!ATOMcmp(tp1, nil, max)) {
348 7 : if (!(err_max = GDKstrdup("absolute max value")))
349 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
350 21 : } else if (atomtostr(&err_max, &length, max, true) < 0) {
351 0 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
352 : }
353 0 : if (msg)
354 0 : goto finish;
355 :
356 28 : msg = createException(SQL,"sql.alter_table_add_range_partition",SQLSTATE(42000)
357 : "ALTER TABLE: conflicting partitions: %s to %s and %s to %s from table %s.%s",
358 28 : err_min, err_max, conflict_err_min, conflict_err_max, errt->s->base.name, errt->base.name);
359 : }
360 : break;
361 : default:
362 0 : assert(0);
363 : }
364 :
365 192 : finish:
366 192 : if (err_min)
367 28 : GDKfree(err_min);
368 192 : if (err_max)
369 28 : GDKfree(err_max);
370 192 : if (conflict_err_min)
371 28 : GDKfree(conflict_err_min);
372 192 : if (conflict_err_max)
373 28 : GDKfree(conflict_err_max);
374 : return msg;
375 : }
376 :
377 : static char *
378 59 : alter_table_add_value_partition(mvc *sql, MalStkPtr stk, InstrPtr pci, char *msname, char *mtname, char *psname,
379 : char *ptname, bit with_nills, int update, lng cnt)
380 : {
381 59 : sql_table *mt = NULL, *pt = NULL;
382 59 : str msg = MAL_SUCCEED;
383 59 : sql_part *err = NULL;
384 59 : int errcode = 0, i = 0, ninserts = 0;
385 59 : sql_subtype tpe;
386 59 : list *values = NULL;
387 :
388 59 : assert(with_nills == false || with_nills == true); /* No nills allowed here */
389 59 : if ((msg = validate_alter_table_add_table(sql, "sql.alter_table_add_value_partition", msname, mtname, psname, ptname,
390 : &mt, &pt, update))) {
391 : return msg;
392 58 : } else if (!isListPartitionTable(mt)) {
393 0 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
394 : "ALTER TABLE: cannot add value partition into a %s table",
395 0 : (isRangePartitionTable(mt))?"range partition":"merge");
396 0 : goto finish;
397 58 : } else if (!update && partition_find_part(sql->session->tr, pt, NULL)) {
398 0 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
399 : "ALTER TABLE: table '%s.%s' is already part of another table",
400 : psname, ptname);
401 0 : goto finish;
402 : }
403 :
404 58 : find_partition_type(&tpe, mt);
405 58 : ninserts = pci->argc - pci->retc - 7;
406 58 : if (ninserts <= 0 && !with_nills) {
407 0 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000) "ALTER TABLE: no values in the list");
408 0 : goto finish;
409 : }
410 :
411 58 : if (cnt) {
412 3 : if (isPartitionedByColumnTable(mt)) {
413 2 : throw(SQL, "sql.alter_table_add_value_partition", SQLSTATE(M0M29) "ALTER TABLE: there are values in column %s outside the partition list of values", mt->part.pcol->base.name);
414 1 : } else if (isPartitionedByExpressionTable(mt)) {
415 1 : throw(SQL, "sql.alter_table_add_value_partition", SQLSTATE(M0M29) "ALTER TABLE: there are values in the expression outside the partition list of values");
416 : } else {
417 0 : assert(0);
418 : }
419 : }
420 :
421 55 : values = list_create((fdestroy) &part_value_destroy);
422 219 : for ( i = pci->retc+7; i < pci->argc; i++){
423 165 : sql_part_value *nextv = NULL;
424 165 : ValRecord *vnext = &(stk)->stk[(pci)->argv[i]];
425 165 : ptr pnext = VALget(vnext);
426 165 : size_t len = ATOMlen(vnext->vtype, pnext);
427 :
428 165 : if (VALisnil(vnext)) { /* check for an eventual null value which cannot be */
429 0 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
430 : "ALTER TABLE: list value cannot be null");
431 0 : list_destroy2(values, sql->session->tr->store);
432 0 : goto finish;
433 : }
434 :
435 165 : nextv = ZNEW(sql_part_value); /* instantiate the part value */
436 165 : nextv->value = NEW_ARRAY(char, len);
437 165 : memcpy(nextv->value, pnext, len);
438 165 : nextv->length = len;
439 :
440 165 : if (list_append_sorted(values, nextv, &tpe, sql_values_list_element_validate_and_insert) != NULL) {
441 1 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
442 : "ALTER TABLE: there are duplicated values in the list");
443 1 : list_destroy2(values, sql->session->tr->store);
444 1 : _DELETE(nextv->value);
445 1 : _DELETE(nextv);
446 1 : goto finish;
447 : }
448 : }
449 :
450 54 : errcode = sql_trans_add_value_partition(sql->session->tr, mt, pt, tpe, values, with_nills, update, &err);
451 54 : if (errcode <= -10) {
452 0 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
453 : "ALTER TABLE: value at position %d length is higher than %d",
454 : (errcode * -1) - 10, STORAGE_MAX_VALUE_LENGTH);
455 : } else {
456 54 : switch (errcode) {
457 : case 0:
458 : break;
459 0 : case -1:
460 0 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(HY013) MAL_MALLOC_FAIL);
461 0 : break;
462 0 : case -2:
463 : case -3:
464 0 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
465 : "ALTER TABLE: failed due to conflict with another transaction");
466 0 : break;
467 5 : case -4:
468 5 : msg = createException(SQL,"sql.alter_table_add_value_partition",SQLSTATE(42000)
469 : "ALTER TABLE: the new partition is conflicting with the existing partition %s.%s",
470 5 : err->t->s->base.name, err->base.name);
471 5 : break;
472 : default:
473 0 : assert(0);
474 : }
475 : }
476 :
477 : finish:
478 : return msg;
479 : }
480 :
481 : static char *
482 180 : alter_table_del_table(mvc *sql, char *msname, char *mtname, char *psname, char *ptname, int drop_action)
483 : {
484 180 : sql_schema *ms = NULL, *ps = NULL;
485 180 : sql_table *mt = NULL, *pt = NULL;
486 180 : node *n = NULL;
487 :
488 180 : if (!(ms = mvc_bind_schema(sql, msname)))
489 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", msname);
490 180 : if (!(ps = mvc_bind_schema(sql, psname)))
491 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", psname);
492 180 : if (!mvc_schema_privs(sql, ms))
493 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), ms->base.name);
494 180 : if (!mvc_schema_privs(sql, ps))
495 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), ps->base.name);
496 180 : if (!(mt = mvc_bind_table(sql, ms, mtname)))
497 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", mtname, ms->base.name);
498 180 : if (!(pt = mvc_bind_table(sql, ps, ptname)))
499 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", ptname, ps->base.name);
500 180 : const char *errtable = TABLE_TYPE_DESCRIPTION(mt->type, mt->properties);
501 180 : if (!isMergeTable(mt) && !isReplicaTable(mt))
502 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(42S02) "ALTER TABLE: cannot drop table '%s.%s' to %s '%s.%s'", psname, ptname, errtable, msname, mtname);
503 180 : if (!(n = members_find_child_id(mt->members, pt->base.id)))
504 10 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(42S02) "ALTER TABLE: table '%s.%s' isn't part of %s '%s.%s'", ps->base.name, ptname, errtable, ms->base.name, mtname);
505 :
506 170 : switch (sql_trans_del_table(sql->session->tr, mt, pt, drop_action)) {
507 0 : case -1:
508 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(HY013) MAL_MALLOC_FAIL);
509 0 : case -2:
510 : case -3:
511 0 : throw(SQL,"sql.alter_table_del_table",SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
512 : default:
513 : break;
514 : }
515 : return MAL_SUCCEED;
516 : }
517 :
518 : static char *
519 2294 : alter_table_set_access(mvc *sql, char *sname, char *tname, int access)
520 : {
521 2294 : sql_schema *s = NULL;
522 2294 : sql_table *t = NULL;
523 :
524 2294 : if (!(s = mvc_bind_schema(sql, sname)))
525 0 : throw(SQL,"sql.alter_table_set_access",SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", sname);
526 2294 : if (s && !mvc_schema_privs(sql, s))
527 0 : throw(SQL,"sql.alter_table_set_access",SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
528 2294 : if (!(t = mvc_bind_table(sql, s, tname)))
529 0 : throw(SQL,"sql.alter_table_set_access",SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", tname, s->base.name);
530 2294 : if (!isTable(t))
531 1 : throw(SQL,"sql.alter_table_set_access",SQLSTATE(42000) "ALTER TABLE: access changes on %sS not supported", TABLE_TYPE_DESCRIPTION(t->type, t->properties));
532 2293 : if (t->access != access) {
533 2293 : if (access && table_has_updates(sql->session->tr, t))
534 0 : throw(SQL,"sql.alter_table_set_access",SQLSTATE(40000) "ALTER TABLE: set READ or INSERT ONLY not possible with outstanding updates (wait until updates are flushed)\n");
535 :
536 2293 : switch (mvc_access(sql, t, access)) {
537 0 : case -1:
538 0 : throw(SQL,"sql.alter_table_set_access",SQLSTATE(HY013) MAL_MALLOC_FAIL);
539 0 : case -2:
540 : case -3:
541 0 : throw(SQL,"sql.alter_table_set_access",SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
542 : default:
543 : break;
544 : }
545 : }
546 : return MAL_SUCCEED;
547 : }
548 :
549 : static char *
550 345 : create_trigger(mvc *sql, char *sname, char *tname, char *triggername, int time, int orientation, int event, char *old_name, char *new_name, char *condition, char *query, int replace)
551 : {
552 345 : sql_trigger *tri = NULL, *other = NULL;
553 345 : sql_schema *s = NULL;
554 345 : sql_table *t = NULL;
555 345 : const char *base = replace ? "CREATE OR REPLACE TRIGGER" : "CREATE TRIGGER";
556 :
557 1031 : if (!strNil(sname) && !strNil(tname)) {
558 341 : if (!(s = mvc_bind_schema(sql, sname)))
559 0 : throw(SQL,"sql.create_trigger",SQLSTATE(3F000) "%s: no such schema '%s'", base, sname);
560 341 : if (!mvc_schema_privs(sql, s))
561 0 : throw(SQL,"sql.create_trigger",SQLSTATE(42000) "%s: access denied for %s to schema '%s'", base, get_string_global_var(sql, "current_user"), s->base.name);
562 341 : if (!(t = mvc_bind_table(sql, s, tname)))
563 0 : throw(SQL,"sql.create_trigger",SQLSTATE(3F000) "%s: unknown table '%s'", base, tname);
564 341 : if (isView(t))
565 0 : throw(SQL,"sql.create_trigger",SQLSTATE(3F000) "%s: cannot create trigger on view '%s'", base, tname);
566 : } else {
567 4 : if (!(s = mvc_bind_schema(sql, "sys")))
568 0 : throw(SQL,"sql.create_trigger",SQLSTATE(3F000) "%s: no such schema '%s'", base, sname);
569 : }
570 :
571 345 : if ((other = mvc_bind_trigger(sql, s, triggername)) && !replace)
572 0 : throw(SQL,"sql.create_trigger",SQLSTATE(3F000) "%s: name '%s' already in use", base, triggername);
573 :
574 345 : if (replace && other) {
575 5 : if (other->t->base.id != t->base.id) /* defensive line */
576 0 : throw(SQL,"sql.create_trigger",SQLSTATE(3F000) "%s: the to be replaced trigger '%s' is not from table '%s'", base, triggername, tname);
577 5 : switch (mvc_drop_trigger(sql, s, other)) {
578 0 : case -1:
579 0 : throw(SQL,"sql.create_trigger", SQLSTATE(HY013) MAL_MALLOC_FAIL);
580 2 : case -2:
581 : case -3:
582 2 : throw(SQL,"sql.create_trigger", SQLSTATE(42000) "%s: transaction conflict detected", base);
583 : default:
584 : break;
585 : }
586 : }
587 343 : switch (mvc_create_trigger(&tri, sql, t, triggername, time, orientation, event, old_name, new_name, condition, query)) {
588 0 : case -1:
589 0 : throw(SQL,"sql.create_trigger", SQLSTATE(HY013) MAL_MALLOC_FAIL);
590 0 : case -2:
591 : case -3:
592 0 : throw(SQL,"sql.create_trigger", SQLSTATE(42000) "%s: transaction conflict detected", base);
593 343 : default: {
594 343 : char *buf;
595 343 : sql_rel *r = NULL;
596 343 : allocator *sa = sql->sa;
597 :
598 343 : if (!(sql->sa = sa_create(sql->pa))) {
599 0 : sql->sa = sa;
600 0 : throw(SQL, "sql.create_trigger", SQLSTATE(HY013) MAL_MALLOC_FAIL);
601 : }
602 343 : if (!(buf = sa_strdup(sql->sa, query))) {
603 0 : sa_destroy(sql->sa);
604 0 : sql->sa = sa;
605 0 : throw(SQL, "sql.create_trigger", SQLSTATE(HY013) MAL_MALLOC_FAIL);
606 : }
607 343 : r = rel_parse(sql, s, buf, m_deps);
608 343 : if (r)
609 338 : r = sql_processrelation(sql, r, 0, 0, 0, 0);
610 338 : if (r) {
611 338 : list *blist = rel_dependencies(sql, r);
612 338 : if (mvc_create_dependencies(sql, blist, tri->base.id, TRIGGER_DEPENDENCY)) {
613 0 : sa_destroy(sql->sa);
614 0 : sql->sa = sa;
615 0 : throw(SQL, "sql.create_trigger", SQLSTATE(HY013) MAL_MALLOC_FAIL);
616 : }
617 : }
618 343 : sa_destroy(sql->sa);
619 343 : sql->sa = sa;
620 343 : if (!r) {
621 5 : if (strlen(sql->errstr) > 6 && sql->errstr[5] == '!')
622 5 : throw(SQL, "sql.create_trigger", "%s", sql->errstr);
623 : else
624 0 : throw(SQL, "sql.create_trigger", SQLSTATE(42000) "%s", sql->errstr);
625 : }
626 : }
627 : }
628 : return MAL_SUCCEED;
629 : }
630 :
631 : static char *
632 84 : drop_trigger(mvc *sql, char *sname, char *tname, int if_exists)
633 : {
634 84 : sql_trigger *tri = NULL;
635 84 : sql_schema *s = NULL;
636 :
637 168 : if (!strNil(sname) && !(s = mvc_bind_schema(sql, sname))) {
638 0 : if (if_exists)
639 : return MAL_SUCCEED;
640 0 : throw(SQL,"sql.drop_trigger",SQLSTATE(3F000) "DROP TRIGGER: no such schema '%s'", sname);
641 : }
642 3 : if (!s)
643 3 : s = mvc_bind_schema(sql, "sys");
644 84 : if (s && !mvc_schema_privs(sql, s))
645 0 : throw(SQL,"sql.drop_trigger",SQLSTATE(42000) "DROP TRIGGER: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
646 :
647 84 : if ((tri = mvc_bind_trigger(sql, s, tname)) == NULL) {
648 0 : if (if_exists)
649 : return MAL_SUCCEED;
650 0 : throw(SQL,"sql.drop_trigger", SQLSTATE(3F000) "DROP TRIGGER: unknown trigger %s\n", tname);
651 : }
652 84 : switch (mvc_drop_trigger(sql, s, tri)) {
653 0 : case -1:
654 0 : throw(SQL,"sql.drop_trigger",SQLSTATE(HY013) MAL_MALLOC_FAIL);
655 1 : case -2:
656 : case -3:
657 1 : throw(SQL,"sql.drop_trigger",SQLSTATE(42000) "DROP TRIGGER: transaction conflict detected");
658 : default:
659 : break;
660 : }
661 : return MAL_SUCCEED;
662 : }
663 :
664 : char *
665 3679 : drop_table(mvc *sql, char *sname, char *tname, int drop_action, int if_exists)
666 : {
667 3679 : sql_schema *s = NULL;
668 3679 : sql_table *t = NULL;
669 :
670 3679 : if (!(s = mvc_bind_schema(sql, sname))) {
671 0 : if (if_exists)
672 : return MAL_SUCCEED;
673 0 : throw(SQL,"sql.drop_table",SQLSTATE(3F000) "DROP TABLE: no such schema '%s'", sname);
674 : }
675 3679 : if (!(t = mvc_bind_table(sql, s, tname))) {
676 0 : if (if_exists)
677 : return MAL_SUCCEED;
678 0 : throw(SQL,"sql.drop_table", SQLSTATE(42S02) "DROP TABLE: no such table '%s'", tname);
679 : }
680 3679 : if (isView(t))
681 1 : throw(SQL,"sql.drop_table", SQLSTATE(42000) "DROP TABLE: cannot drop VIEW '%s'", tname);
682 3678 : if (t->system)
683 1 : throw(SQL,"sql.drop_table", SQLSTATE(42000) "DROP TABLE: cannot drop system table '%s'", tname);
684 3677 : if (!mvc_schema_privs(sql, s) && !(isTempSchema(s) && t->persistence == SQL_LOCAL_TEMP))
685 2 : throw(SQL,"sql.drop_table", SQLSTATE(42000) "DROP TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
686 :
687 3675 : if (!drop_action && t->keys) {
688 4447 : for (node *n = ol_first_node(t->keys); n; n = n->next) {
689 1236 : sql_key *k = n->data;
690 :
691 1236 : if (k->type == ukey || k->type == pkey) {
692 876 : struct os_iter oi;
693 876 : os_iterator(&oi, k->t->s->keys, sql->session->tr, NULL);
694 22689 : for (sql_base *b = oi_next(&oi); b; b=oi_next(&oi)) {
695 21815 : sql_key *fk = (sql_key*)b;
696 21815 : sql_fkey *rk = (sql_fkey*)b;
697 :
698 21815 : if (fk->type != fkey || rk->rkey != k->base.id)
699 21796 : continue;
700 :
701 : /* make sure it is not a self referencing key */
702 19 : if (fk->t != t)
703 2 : throw(SQL,"sql.drop_table", SQLSTATE(40000) "DROP TABLE: FOREIGN KEY %s.%s depends on %s", k->t->base.name, k->base.name, tname);
704 : }
705 : }
706 : }
707 : }
708 :
709 3211 : if (!drop_action && mvc_check_dependency(sql, t->base.id, TABLE_DEPENDENCY, NULL))
710 17 : throw (SQL,"sql.drop_table",SQLSTATE(42000) "DROP TABLE: unable to drop table %s (there are database objects which depend on it)\n", t->base.name);
711 :
712 3656 : return mvc_drop_table(sql, s, t, drop_action);
713 : }
714 :
715 : char *
716 218 : drop_view(mvc *sql, char *sname, char *tname, int drop_action, int if_exists)
717 : {
718 218 : sql_table *t = NULL;
719 218 : sql_schema *ss = NULL;
720 :
721 218 : if (!(ss = mvc_bind_schema(sql, sname))) {
722 0 : if (if_exists)
723 : return MAL_SUCCEED;
724 0 : throw(SQL,"sql.drop_view", SQLSTATE(3F000) "DROP VIEW: no such schema '%s'", sname);
725 : }
726 218 : if (!(t = mvc_bind_table(sql, ss, tname))) {
727 0 : if (if_exists)
728 : return MAL_SUCCEED;
729 0 : throw(SQL,"sql.drop_view",SQLSTATE(42S02) "DROP VIEW: unknown view '%s'", tname);
730 : }
731 218 : if (!mvc_schema_privs(sql, ss) && !(isTempSchema(ss) && t && t->persistence == SQL_LOCAL_TEMP))
732 0 : throw(SQL,"sql.drop_view", SQLSTATE(42000) "DROP VIEW: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), ss->base.name);
733 218 : if (!isView(t))
734 0 : throw(SQL,"sql.drop_view", SQLSTATE(42000) "DROP VIEW: unable to drop view '%s': is a table", tname);
735 218 : if (t->system)
736 1 : throw(SQL,"sql.drop_view", SQLSTATE(42000) "DROP VIEW: cannot drop system view '%s'", tname);
737 217 : if (!drop_action && mvc_check_dependency(sql, t->base.id, VIEW_DEPENDENCY, NULL))
738 3 : throw(SQL,"sql.drop_view", SQLSTATE(42000) "DROP VIEW: cannot drop view '%s', there are database objects which depend on it", t->base.name);
739 214 : return mvc_drop_table(sql, ss, t, drop_action);
740 : }
741 :
742 : static str
743 150 : drop_key(mvc *sql, char *sname, char *tname, char *kname, int drop_action)
744 : {
745 150 : node *n;
746 150 : sql_schema *s = cur_schema(sql);
747 150 : sql_table *t = NULL;
748 150 : sql_key *key;
749 :
750 150 : if (!(s = mvc_bind_schema(sql, sname)))
751 0 : throw(SQL,"sql.drop_key", SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", sname);
752 150 : if (!mvc_schema_privs(sql, s))
753 0 : throw(SQL,"sql.drop_key", SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
754 150 : if (!(t = mvc_bind_table(sql, s, tname)))
755 0 : throw(SQL,"sql.drop_key", SQLSTATE(42S02) "ALTER TABLE: no such table '%s'", tname);
756 150 : if (!(n = ol_find_name(t->keys, kname)))
757 3 : throw(SQL,"sql.drop_key", SQLSTATE(42000) "ALTER TABLE: no such constraint '%s'", kname);
758 147 : key = n->data;
759 147 : if (!drop_action && mvc_check_dependency(sql, key->base.id, KEY_DEPENDENCY, NULL))
760 1 : throw(SQL,"sql.drop_key", SQLSTATE(42000) "ALTER TABLE: cannot drop constraint '%s': there are database objects which depend on it", key->base.name);
761 146 : switch (mvc_drop_key(sql, s, key, drop_action)) {
762 0 : case -1:
763 0 : throw(SQL,"sql.drop_key",SQLSTATE(HY013) MAL_MALLOC_FAIL);
764 0 : case -2:
765 : case -3:
766 0 : throw(SQL,"sql.drop_key",SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
767 : default:
768 : break;
769 : }
770 : return MAL_SUCCEED;
771 : }
772 :
773 : static str
774 109 : IDXdrop(mvc *sql, const char *sname, const char *tname, const char *iname, void (*func)(BAT *))
775 : {
776 109 : BAT *b = mvc_bind(sql, sname, tname, iname, RDONLY), *nb = NULL;
777 :
778 109 : if (!b)
779 0 : throw(SQL,"sql.drop_index", SQLSTATE(HY005) "Column can not be accessed");
780 109 : if (VIEWtparent(b)) {
781 109 : nb = BBP_desc(VIEWtparent(b));
782 109 : BBPunfix(b->batCacheid);
783 109 : if (!(b = BATdescriptor(nb->batCacheid)))
784 0 : throw(SQL,"sql.drop_index", SQLSTATE(HY005) "Column can not be accessed");
785 : }
786 :
787 109 : func(b);
788 109 : BBPunfix(b->batCacheid);
789 109 : return MAL_SUCCEED;
790 : }
791 :
792 : static void
793 42 : dummy(BAT *b)
794 : {
795 42 : (void) b;
796 42 : }
797 :
798 : static str
799 160 : drop_index(mvc *sql, char *sname, char *iname)
800 : {
801 160 : sql_schema *s = NULL;
802 160 : sql_idx *i = NULL;
803 160 : str msg = MAL_SUCCEED;
804 :
805 160 : if (!(s = mvc_bind_schema(sql, sname)))
806 0 : throw(SQL,"sql.drop_index", SQLSTATE(3F000) "DROP INDEX: no such schema '%s'", sname);
807 160 : if (!mvc_schema_privs(sql, s))
808 0 : throw(SQL,"sql.drop_index", SQLSTATE(42000) "DROP INDEX: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
809 160 : if (!(i = mvc_bind_idx(sql, s, iname)))
810 0 : throw(SQL,"sql.drop_index", SQLSTATE(42S12) "DROP INDEX: no such index '%s'", iname);
811 160 : if (i->key)
812 1 : throw(SQL,"sql.drop_index", SQLSTATE(42S12) "DROP INDEX: cannot drop index '%s', because the constraint '%s' depends on it", iname, i->key->base.name);
813 159 : if (i->type == ordered_idx || i->type == imprints_idx) {
814 109 : sql_kc *ic = i->columns->h->data;
815 109 : sql_class icls = ic->c->type.type->eclass;
816 151 : if ((msg = IDXdrop(sql, s->base.name, ic->c->t->base.name, ic->c->base.name, i->type == ordered_idx ? OIDXdestroy : (icls == EC_STRING ? STRMPdestroy : dummy))))
817 : return msg;
818 : }
819 159 : switch (mvc_drop_idx(sql, s, i)) {
820 0 : case -1:
821 0 : throw(SQL,"sql.drop_index",SQLSTATE(HY013) MAL_MALLOC_FAIL);
822 0 : case -2:
823 : case -3:
824 0 : throw(SQL,"sql.drop_index",SQLSTATE(42000) "DROP INDEX: transaction conflict detected");
825 : default:
826 : break;
827 : }
828 : return NULL;
829 : }
830 :
831 : static str
832 313 : create_seq(mvc *sql, char *sname, char *seqname, sql_sequence *seq)
833 : {
834 313 : sql_schema *s = NULL;
835 :
836 313 : (void)seqname;
837 313 : if (!(s = mvc_bind_schema(sql, sname)))
838 0 : throw(SQL,"sql.create_seq", SQLSTATE(3F000) "CREATE SEQUENCE: no such schema '%s'", sname);
839 313 : if (!mvc_schema_privs(sql, s))
840 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: insufficient privileges for '%s' in schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
841 313 : if (find_sql_sequence(sql->session->tr, s, seq->base.name))
842 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: name '%s' already in use", seq->base.name);
843 313 : if (is_lng_nil(seq->start) || is_lng_nil(seq->minvalue) || is_lng_nil(seq->maxvalue) ||
844 313 : is_lng_nil(seq->increment) || is_lng_nil(seq->cacheinc) || is_bit_nil(seq->cycle))
845 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: sequence properties must be non-NULL");
846 313 : if (seq->start < seq->minvalue)
847 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: start value is less than the minimum ("LLFMT" < "LLFMT")", seq->start, seq->minvalue);
848 313 : if (seq->start > seq->maxvalue)
849 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: start value is higher than the maximum ("LLFMT" > "LLFMT")", seq->start, seq->maxvalue);
850 313 : if (seq->maxvalue < seq->minvalue)
851 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: maximum value is less than the minimum ("LLFMT" < "LLFMT")", seq->maxvalue, seq->minvalue);
852 313 : if (seq->increment == 0)
853 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: sequence increment cannot be 0");
854 313 : if (seq->cacheinc <= 0)
855 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: sequence cache must be positive");
856 313 : lng calc = llabs(seq->increment) * seq->cacheinc;
857 313 : if (calc < llabs(seq->increment) || calc < seq->cacheinc)
858 0 : throw(SQL,"sql.create_seq", SQLSTATE(42000) "CREATE SEQUENCE: The specified range of cached values cannot be set. Either reduce increment or cache value");
859 313 : switch (sql_trans_create_sequence(sql->session->tr, s, seq->base.name, seq->start, seq->minvalue, seq->maxvalue, seq->increment, seq->cacheinc, seq->cycle, seq->bedropped)) {
860 0 : case -1:
861 0 : throw(SQL,"sql.create_seq",SQLSTATE(HY013) MAL_MALLOC_FAIL);
862 0 : case -2:
863 : case -3:
864 0 : throw(SQL,"sql.create_seq",SQLSTATE(42000) "CREATE SEQUENCE: transaction conflict detected");
865 : default:
866 : break;
867 : }
868 : return NULL;
869 : }
870 :
871 : static str
872 45 : alter_seq(mvc *sql, char *sname, char *seqname, sql_sequence *seq, const lng *val)
873 : {
874 45 : sql_schema *s = NULL;
875 45 : sql_sequence *nseq = NULL;
876 :
877 45 : (void)seqname;
878 45 : if (!(s = mvc_bind_schema(sql, sname)))
879 0 : throw(SQL,"sql.alter_seq", SQLSTATE(3F000) "ALTER SEQUENCE: no such schema '%s'", sname);
880 45 : if (!mvc_schema_privs(sql, s))
881 0 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: insufficient privileges for '%s' in schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
882 45 : if (!(nseq = find_sql_sequence(sql->session->tr, s, seq->base.name)))
883 0 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: no such sequence '%s'", seq->base.name);
884 : /* if seq properties hold NULL values, then they should be ignored during the update */
885 : /* first alter the known values */
886 45 : switch (sql_trans_alter_sequence(sql->session->tr, nseq, seq->minvalue, seq->maxvalue, seq->increment, seq->cacheinc, seq->cycle)) {
887 0 : case -1:
888 0 : throw(SQL,"sql.alter_seq",SQLSTATE(HY013) MAL_MALLOC_FAIL);
889 0 : case -2:
890 : case -3:
891 0 : throw(SQL,"sql.alter_seq",SQLSTATE(42000) "ALTER SEQUENCE: transaction conflict detected");
892 : default:
893 45 : break;
894 : }
895 45 : if (nseq->maxvalue < nseq->minvalue)
896 0 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: maximum value is less than the minimum ("LLFMT" < "LLFMT")", nseq->maxvalue, nseq->minvalue);
897 45 : if (nseq->increment == 0)
898 0 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: sequence increment cannot be 0");
899 45 : if (nseq->cacheinc <= 0)
900 0 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: sequence cache must be positive");
901 45 : lng calc = llabs(nseq->increment) * nseq->cacheinc;
902 45 : if (calc < llabs(nseq->increment) || calc < nseq->cacheinc)
903 0 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: The specified range of cached values cannot be set. Either reduce increment or cache value");
904 45 : if (val) {
905 45 : if (is_lng_nil(*val))
906 0 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: sequence value must be non-NULL");
907 45 : if (*val < nseq->minvalue)
908 1 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: cannot set sequence start to a value less than the minimum ("LLFMT" < "LLFMT")", *val, nseq->minvalue);
909 44 : if (*val > nseq->maxvalue)
910 1 : throw(SQL,"sql.alter_seq", SQLSTATE(42000) "ALTER SEQUENCE: cannot set sequence start to a value higher than the maximum ("LLFMT" > "LLFMT")", *val, nseq->maxvalue);
911 43 : switch (sql_trans_sequence_restart(sql->session->tr, nseq, *val)) {
912 0 : case -1:
913 0 : throw(SQL,"sql.alter_seq",SQLSTATE(HY013) MAL_MALLOC_FAIL);
914 0 : case -2:
915 : case -3:
916 0 : throw(SQL,"sql.alter_seq",SQLSTATE(42000) "ALTER SEQUENCE: transaction conflict detected");
917 0 : case -4:
918 0 : throw(SQL,"sql.alter_seq",SQLSTATE(42000) "ALTER SEQUENCE: failed to restart sequence %s.%s", sname, nseq->base.name);
919 : default:
920 : break;
921 : }
922 : }
923 : return MAL_SUCCEED;
924 : }
925 :
926 : static str
927 32 : drop_seq(mvc *sql, char *sname, char *name)
928 : {
929 32 : sql_schema *s = NULL;
930 32 : sql_sequence *seq = NULL;
931 :
932 32 : if (!(s = mvc_bind_schema(sql, sname)))
933 0 : throw(SQL,"sql.drop_seq", SQLSTATE(3F000) "DROP SEQUENCE: no such schema '%s'", sname);
934 32 : if (!mvc_schema_privs(sql, s))
935 0 : throw(SQL,"sql.drop_seq", SQLSTATE(42000) "DROP SEQUENCE: insufficient privileges for '%s' in schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
936 32 : if (!(seq = find_sql_sequence(sql->session->tr, s, name)))
937 0 : throw(SQL,"sql.drop_seq", SQLSTATE(42M35) "DROP SEQUENCE: no such sequence '%s'", name);
938 32 : if (mvc_check_dependency(sql, seq->base.id, BEDROPPED_DEPENDENCY, NULL))
939 2 : throw(SQL,"sql.drop_seq", SQLSTATE(2B000) "DROP SEQUENCE: unable to drop sequence %s (there are database objects which depend on it)\n", seq->base.name);
940 :
941 30 : switch (sql_trans_drop_sequence(sql->session->tr, s, seq, 0)) {
942 0 : case -1:
943 0 : throw(SQL,"sql.drop_seq",SQLSTATE(HY013) MAL_MALLOC_FAIL);
944 0 : case -2:
945 : case -3:
946 0 : throw(SQL,"sql.drop_seq",SQLSTATE(42000) "DROP SEQUENCE: transaction conflict detected");
947 : default:
948 : break;
949 : }
950 : return NULL;
951 : }
952 :
953 : static str
954 568 : drop_func(mvc *sql, char *sname, char *name, sqlid fid, sql_ftype type, int action)
955 : {
956 568 : sql_schema *s = NULL;
957 568 : char *F = NULL, *fn = NULL;
958 568 : int res = 0;
959 :
960 568 : FUNC_TYPE_STR(type, F, fn)
961 :
962 568 : if (!(s = mvc_bind_schema(sql, sname))) {
963 0 : if (fid == -2) /* if exists option */
964 : return MAL_SUCCEED;
965 0 : throw(SQL,"sql.drop_func", SQLSTATE(3F000) "DROP %s: no such schema '%s'", F, sname);
966 : }
967 568 : if (!mvc_schema_privs(sql, s))
968 0 : throw(SQL,"sql.drop_func", SQLSTATE(42000) "DROP %s: access denied for %s to schema '%s'", F, get_string_global_var(sql, "current_user"), s->base.name);
969 568 : if (fid >= 0) {
970 536 : sql_base *b = os_find_id(s->funcs, sql->session->tr, fid);
971 536 : if (b) {
972 536 : sql_func *func = (sql_func*)b;
973 :
974 576 : if (!action && mvc_check_dependency(sql, func->base.id, !IS_PROC(func) ? FUNC_DEPENDENCY : PROC_DEPENDENCY, NULL))
975 4 : throw(SQL,"sql.drop_func", SQLSTATE(42000) "DROP %s: there are database objects dependent on %s %s;", F, fn, func->base.name);
976 532 : res = mvc_drop_func(sql, s, func, action);
977 : }
978 32 : } else if (fid == -2) { /* if exists option */
979 : return MAL_SUCCEED;
980 : } else { /* fid == -1 */
981 32 : list *list_func = sql_find_funcs_by_name(sql, s->base.name, name, type, false);
982 :
983 32 : if (!list_empty(list_func))
984 76 : for (node *n = list_func->h; n; n = n->next) {
985 44 : sql_func *func = n->data;
986 :
987 57 : if (!action && mvc_check_dependency(sql, func->base.id, !IS_PROC(func) ? FUNC_DEPENDENCY : PROC_DEPENDENCY, list_func)) {
988 0 : list_destroy(list_func);
989 0 : throw(SQL,"sql.drop_func", SQLSTATE(42000) "DROP %s: there are database objects dependent on %s %s;", F, fn, func->base.name);
990 : }
991 : }
992 32 : res = mvc_drop_all_func(sql, s, list_func, action);
993 32 : list_destroy(list_func);
994 : }
995 :
996 564 : switch (res) {
997 0 : case -1:
998 0 : throw(SQL,"sql.drop_func",SQLSTATE(HY013) MAL_MALLOC_FAIL);
999 0 : case -2:
1000 : case -3:
1001 0 : throw(SQL,"sql.drop_func",SQLSTATE(42000) "DROP %s: transaction conflict detected", F);
1002 : default:
1003 : break;
1004 : }
1005 : return MAL_SUCCEED;
1006 : }
1007 :
1008 : static int
1009 6 : args_cmp(sql_arg *a1, sql_arg *a2)
1010 : {
1011 6 : if (a1->inout != a2->inout)
1012 : return -1;
1013 6 : if (strcmp(a1->name, a2->name) != 0)
1014 : return -1;
1015 6 : return subtype_cmp(&a1->type, &a2->type);
1016 : }
1017 :
1018 : static char *
1019 120753 : create_func(mvc *sql, char *sname, char *fname, sql_func *f, int replace)
1020 : {
1021 120753 : sql_func *nf;
1022 120753 : sql_subfunc *sf;
1023 120753 : sql_schema *s = NULL;
1024 120753 : char *F = NULL, *fn = NULL, *base = replace ? "CREATE OR REPLACE" : "CREATE";
1025 :
1026 120753 : FUNC_TYPE_STR(f->type, F, fn)
1027 :
1028 120753 : (void) fn;
1029 120753 : if (!(s = mvc_bind_schema(sql, sname)))
1030 0 : throw(SQL,"sql.create_func", SQLSTATE(3F000) "%s %s: no such schema '%s'", base, F, sname);
1031 120753 : if (!mvc_schema_privs(sql, s))
1032 0 : throw(SQL,"sql.create_func", SQLSTATE(42000) "%s %s: access denied for %s to schema '%s'", base, F, get_string_global_var(sql, "current_user"), s->base.name);
1033 :
1034 120753 : if (replace) {
1035 68 : list *tl = sa_list(sql->sa);
1036 68 : if (!list_empty(f->ops)) {
1037 79 : for (node *n = f->ops->h ; n ; n = n->next ) {
1038 45 : sql_arg *arg = n->data;
1039 :
1040 45 : list_append(tl, &arg->type);
1041 : }
1042 : }
1043 :
1044 68 : if ((sf = sql_bind_func_(sql, s->base.name, fname, tl, f->type, false, true)) != NULL) {
1045 15 : sql_func *sff = sf->func;
1046 :
1047 15 : if (!sff->s || sff->system)
1048 0 : throw(SQL,"sql.create_func", SQLSTATE(42000) "%s %s: not allowed to replace system %s %s;", base, F, fn, sff->base.name);
1049 :
1050 : /* if all function parameters are the same, return */
1051 15 : if (sff->lang == f->lang && sff->type == f->type &&
1052 15 : sff->varres == f->varres && sff->vararg == f->vararg &&
1053 18 : ((!sff->query && !f->query) || (sff->query && f->query && strcmp(sff->query, f->query) == 0)) &&
1054 6 : list_cmp(sff->res, f->res, (fcmp) &args_cmp) == 0 &&
1055 3 : list_cmp(sff->ops, f->ops, (fcmp) &args_cmp) == 0)
1056 : return MAL_SUCCEED;
1057 :
1058 12 : if (mvc_check_dependency(sql, sff->base.id, !IS_PROC(sff) ? FUNC_DEPENDENCY : PROC_DEPENDENCY, NULL))
1059 0 : throw(SQL,"sql.create_func", SQLSTATE(42000) "%s %s: there are database objects dependent on %s %s;", base, F, fn, sff->base.name);
1060 12 : switch (mvc_drop_func(sql, s, sff, 0)) {
1061 0 : case -1:
1062 0 : throw(SQL,"sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1063 1 : case -2:
1064 : case -3:
1065 1 : throw(SQL,"sql.create_func", SQLSTATE(42000) "%s %s: transaction conflict detected", base, F);
1066 : default:
1067 : break;
1068 : }
1069 : } else {
1070 53 : sql->session->status = 0; /* if the function was not found clean the error */
1071 53 : sql->errstr[0] = '\0';
1072 : }
1073 : }
1074 120749 : switch (mvc_create_func(&nf, sql, NULL, s, f->base.name, f->ops, f->res, f->type, f->lang, f->mod, f->imp, f->query, f->varres, f->vararg, f->system, f->side_effect, f->order_required, f->opt_order)) {
1075 0 : case -1:
1076 0 : throw(SQL,"sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1077 1 : case -2:
1078 : case -3:
1079 1 : throw(SQL,"sql.create_func", SQLSTATE(42000) "%s %s: transaction conflict detected", base, F);
1080 : default:
1081 120748 : break;
1082 : }
1083 120748 : switch (nf->lang) {
1084 112940 : case FUNC_LANG_MAL:
1085 112940 : assert(nf->imp);
1086 112940 : nf->instantiated = TRUE; /* MAL functions get instantiated while being created */
1087 : /* fall through */
1088 120519 : case FUNC_LANG_SQL: {
1089 120519 : char *buf;
1090 120519 : sql_rel *r = NULL;
1091 120519 : allocator *sa = sql->sa;
1092 :
1093 120519 : assert(nf->query);
1094 120519 : if (!(sql->sa = sa_create(sql->pa))) {
1095 0 : sql->sa = sa;
1096 0 : throw(SQL, "sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1097 : }
1098 120519 : if (!(buf = sa_strdup(sql->sa, nf->query))) {
1099 0 : sa_destroy(sql->sa);
1100 0 : sql->sa = sa;
1101 0 : throw(SQL, "sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1102 : }
1103 120519 : r = rel_parse(sql, s, buf, m_deps);
1104 120519 : if (r)
1105 120519 : r = sql_processrelation(sql, r, 0, 0, 0, 0);
1106 120519 : if (r) {
1107 120519 : node *n;
1108 120519 : list *blist = rel_dependencies(sql, r);
1109 :
1110 120519 : if (!f->vararg && f->ops) {
1111 309693 : for (n = f->ops->h; n; n = n->next) {
1112 189174 : sql_arg *a = n->data;
1113 :
1114 189174 : if (a->type.type->s && mvc_create_dependency(sql, &a->type.type->base, nf->base.id, TYPE_DEPENDENCY)) {
1115 0 : sa_destroy(sql->sa);
1116 0 : sql->sa = sa;
1117 0 : throw(SQL, "sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1118 : }
1119 : }
1120 : }
1121 120519 : if (!f->varres && f->res) {
1122 258013 : for (n = f->res->h; n; n = n->next) {
1123 156444 : sql_arg *a = n->data;
1124 :
1125 156444 : if (a->type.type->s && mvc_create_dependency(sql, &a->type.type->base, nf->base.id, TYPE_DEPENDENCY)) {
1126 0 : sa_destroy(sql->sa);
1127 0 : sql->sa = sa;
1128 0 : throw(SQL, "sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1129 : }
1130 : }
1131 : }
1132 136106 : if (mvc_create_dependencies(sql, blist, nf->base.id, !IS_PROC(f) ? FUNC_DEPENDENCY : PROC_DEPENDENCY)) {
1133 0 : sa_destroy(sql->sa);
1134 0 : sql->sa = sa;
1135 0 : throw(SQL, "sql.create_func", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1136 : }
1137 : }
1138 120519 : sa_destroy(sql->sa);
1139 120519 : sql->sa = sa;
1140 120519 : if (!r) {
1141 0 : if (strlen(sql->errstr) > 6 && sql->errstr[5] == '!')
1142 0 : throw(SQL, "sql.create_func", "%s", sql->errstr);
1143 : else
1144 0 : throw(SQL, "sql.create_func", SQLSTATE(42000) "%s", sql->errstr);
1145 : }
1146 : }
1147 : default:
1148 : break;
1149 : }
1150 : return MAL_SUCCEED;
1151 : }
1152 :
1153 : str
1154 1369 : alter_table(Client cntxt, mvc *sql, char *sname, sql_table *t)
1155 : {
1156 1369 : sql_schema *s = NULL;
1157 1369 : sql_table *nt = NULL;
1158 1369 : node *n;
1159 :
1160 1369 : if (!(s = mvc_bind_schema(sql, sname)))
1161 0 : throw(SQL,"sql.alter_table",
1162 : SQLSTATE(3F000) "ALTER TABLE: no such schema '%s'", sname);
1163 :
1164 1369 : if (!mvc_schema_privs(sql, s) &&
1165 0 : !(isTempSchema(s) && t->persistence == SQL_LOCAL_TEMP))
1166 0 : throw(SQL,"sql.alter_table",
1167 : SQLSTATE(42000) "ALTER TABLE: insufficient privileges for"
1168 : " user '%s' in schema '%s'",
1169 : get_string_global_var(sql, "current_user"), s->base.name);
1170 :
1171 1369 : if (!(nt = mvc_bind_table(sql, s, t->base.name)))
1172 0 : throw(SQL,"sql.alter_table",
1173 : SQLSTATE(42S02) "ALTER TABLE: no such table '%s'", t->base.name);
1174 :
1175 1369 : sql_table *gt = NULL;
1176 1369 : if (nt && isTempTable(nt)) {
1177 34 : gt = (sql_table*)os_find_id(s->tables, sql->session->tr, nt->base.id);
1178 34 : if (gt)
1179 1369 : nt = gt;
1180 : }
1181 :
1182 : /* First check if all the changes are allowed */
1183 1369 : if (t->idxs) {
1184 : /* only one pkey */
1185 1369 : if (nt->pkey) {
1186 1423 : for (n = ol_first_node(t->idxs); n; n = n->next) {
1187 696 : sql_idx *i = n->data;
1188 696 : if (!i->base.new || i->base.deleted)
1189 0 : continue;
1190 696 : if (i->key && i->key->type == pkey)
1191 3 : throw(SQL,"sql.alter_table",
1192 : SQLSTATE(40000) "CONSTRAINT PRIMARY KEY: a"
1193 : " table can have only one PRIMARY KEY\n");
1194 : }
1195 : }
1196 : }
1197 :
1198 21092 : for (n = ol_first_node(t->columns); n; n = n->next) {
1199 : /* null or default value changes */
1200 19848 : sql_column *c = n->data;
1201 :
1202 19848 : if (c->base.new)
1203 : break;
1204 :
1205 19741 : sql_column *nc = mvc_bind_column(sql, nt, c->base.name);
1206 19741 : if (c->base.deleted) {
1207 68 : switch (mvc_drop_column(sql, nt, nc, c->drop_action)) {
1208 0 : case -1:
1209 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY013) MAL_MALLOC_FAIL);
1210 1 : case -2:
1211 : case -3:
1212 1 : throw(SQL,"sql.alter_table",
1213 : SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
1214 : default:
1215 67 : break;
1216 : }
1217 67 : continue;
1218 : }
1219 19673 : if (c->null != nc->null && isTable(nt)) {
1220 99 : if (c->null && nt->pkey) { /* check for primary keys based on this column */
1221 2 : node *m;
1222 4 : for (m = nt->pkey->k.columns->h; m; m = m->next) {
1223 4 : sql_kc *kc = m->data;
1224 :
1225 4 : if (kc->c->base.id == c->base.id)
1226 2 : throw(SQL,"sql.alter_table", SQLSTATE(40000) "NOT NULL CONSTRAINT: cannot remove NOT NULL CONSTRAINT for column '%s' part of the PRIMARY KEY\n", c->base.name);
1227 : }
1228 : }
1229 97 : switch (mvc_null(sql, nc, c->null)) {
1230 0 : case -1:
1231 0 : throw(SQL,"sql.alter_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1232 1 : case -2:
1233 : case -3:
1234 1 : throw(SQL,"sql.alter_table", SQLSTATE(42000) "NOT NULL CONSTRAINT: transaction conflict detected");
1235 : default:
1236 96 : break;
1237 : }
1238 : /* for non empty check for nulls */
1239 96 : sqlstore *store = sql->session->tr->store;
1240 96 : if (c->null == 0) {
1241 94 : const void *nilptr = ATOMnilptr(c->type.type->localtype);
1242 94 : rids *nils = store->table_api.rids_select(sql->session->tr, nc, nilptr, NULL, NULL);
1243 94 : if (!nils)
1244 0 : throw(SQL,"sql.alter_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1245 94 : int has_nils = !is_oid_nil(store->table_api.rids_next(nils));
1246 :
1247 94 : store->table_api.rids_destroy(nils);
1248 94 : if (has_nils)
1249 11 : throw(SQL,"sql.alter_table", SQLSTATE(40002) "ALTER TABLE: NOT NULL constraint violated for column %s.%s", c->t->base.name, c->base.name);
1250 : }
1251 : }
1252 19659 : if ((c->def || nc->def) && (!c->def || !nc->def || strcmp(c->def, nc->def) != 0)) {
1253 23 : switch (mvc_default(sql, nc, c->def)) {
1254 0 : case -1:
1255 0 : throw(SQL,"sql.alter_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1256 0 : case -2:
1257 : case -3:
1258 0 : throw(SQL,"sql.alter_table", SQLSTATE(42000) "DEFAULT: transaction conflict detected");
1259 : default:
1260 : break;
1261 : }
1262 : }
1263 :
1264 19659 : if ((c->storage_type || nc->storage_type) && (!c->storage_type || !nc->storage_type || strcmp(c->storage_type, nc->storage_type) != 0)) {
1265 0 : if (c->t->access == TABLE_WRITABLE)
1266 0 : throw(SQL,"sql.alter_table", SQLSTATE(40002) "ALTER TABLE: SET STORAGE for column %s.%s only allowed on READ or INSERT ONLY tables", c->t->base.name, c->base.name);
1267 0 : switch (mvc_storage(sql, nc, c->storage_type)) {
1268 0 : case -1:
1269 0 : throw(SQL,"sql.alter_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1270 0 : case -2:
1271 : case -3:
1272 0 : throw(SQL,"sql.alter_table", SQLSTATE(42000) "ALTER TABLE: SET STORAGE transaction conflict detected");
1273 : default:
1274 : break;
1275 : }
1276 : }
1277 : }
1278 : /* handle new columns */
1279 1456 : for (; n; n = n->next) {
1280 : /* propagate alter table .. add column */
1281 107 : sql_column *c = n->data;
1282 :
1283 107 : if (c->base.deleted) /* skip */
1284 0 : continue;
1285 107 : switch (mvc_copy_column(sql, nt, c, NULL)) {
1286 0 : case -1:
1287 0 : throw(SQL,"sql.alter_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1288 2 : case -2:
1289 : case -3:
1290 2 : throw(SQL,"sql.alter_table", SQLSTATE(42000) "ALTER TABLE: %s_%s_%s conflicts with another transaction", s->base.name, t->base.name, c->base.name);
1291 : default:
1292 : break;
1293 : }
1294 : }
1295 1349 : if (t->idxs) {
1296 : /* alter drop index */
1297 1349 : if (t->idxs)
1298 2457 : for (n = ol_first_node(t->idxs); n; n = n->next) {
1299 1108 : sql_idx *i = n->data;
1300 1108 : if (i->base.new || !i->base.deleted)
1301 1108 : continue;
1302 0 : sql_idx *ni = mvc_bind_idx(sql, s, i->base.name);
1303 0 : if (ni == NULL)
1304 0 : throw(SQL, "sql.alter_table", "Couldn't bind index %s", i->base.name);
1305 0 : switch (mvc_drop_idx(sql, s, ni)) {
1306 0 : case -1:
1307 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY013) MAL_MALLOC_FAIL);
1308 0 : case -2:
1309 : case -3:
1310 0 : throw(SQL,"sql.alter_table",SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
1311 : default:
1312 : break;
1313 : }
1314 : }
1315 : /* alter add index */
1316 2440 : for (n = ol_first_node(t->idxs); n; n = n->next) {
1317 1108 : sql_idx *i = n->data;
1318 1108 : BAT *b = NULL, *nb = NULL;
1319 :
1320 1108 : if (!i->base.new || i->base.deleted)
1321 0 : continue;
1322 :
1323 1108 : if (i->type == ordered_idx) {
1324 77 : sql_kc *ic = i->columns->h->data;
1325 77 : if (!(b = mvc_bind(sql, nt->s->base.name, nt->base.name, ic->c->base.name, RDONLY)))
1326 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY005) "Cannot access ordered index %s_%s_%s", s->base.name, t->base.name, i->base.name);
1327 77 : if (VIEWtparent(b)) {
1328 77 : nb = BBP_desc(VIEWtparent(b));
1329 77 : BBPunfix(b->batCacheid);
1330 77 : if (!(b = BATdescriptor(nb->batCacheid)))
1331 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY005) "Cannot access ordered index %s_%s_%s", s->base.name, t->base.name, i->base.name);
1332 : }
1333 77 : char *msg = OIDXcreateImplementation(cntxt, newBatType(b->ttype), b, -1);
1334 77 : BBPunfix(b->batCacheid);
1335 77 : if (msg != MAL_SUCCEED) {
1336 0 : char *smsg = createException(SQL,"sql.alter_table", SQLSTATE(40002) "CREATE ORDERED INDEX: %s", msg);
1337 0 : freeException(msg);
1338 0 : return smsg;
1339 : }
1340 1031 : } else if (i->type == imprints_idx) {
1341 71 : gdk_return r;
1342 71 : sql_kc *ic = i->columns->h->data;
1343 71 : if (!(b = mvc_bind(sql, nt->s->base.name, nt->base.name, ic->c->base.name, RDONLY)))
1344 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY005) "Cannot access imprints index %s_%s_%s", s->base.name, t->base.name, i->base.name);
1345 71 : if (VIEWtparent(b)) {
1346 71 : nb = BBP_desc(VIEWtparent(b));
1347 71 : BBPunfix(b->batCacheid);
1348 71 : if (!(b = BATdescriptor(nb->batCacheid)))
1349 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY005) "Cannot access imprints index %s_%s_%s", s->base.name, t->base.name, i->base.name);
1350 : }
1351 71 : if(b->ttype == TYPE_str) {
1352 11 : if (t->access != TABLE_READONLY) {
1353 5 : BBPunfix(b->batCacheid);
1354 5 : throw(SQL, "sql.alter_TABLE", SQLSTATE(HY005) "Cannot create string imprint index %s on non read only table %s.%s", i->base.name, s->base.name, t->base.name);
1355 : }
1356 :
1357 : /* We signal that we want a strimp on b. It will be created the next time it is needed, i.e. by
1358 : * PCRElikeselect.
1359 : */
1360 6 : r = BATsetstrimps(b);
1361 : } else {
1362 105 : switch (ATOMbasetype(b->ttype)) {
1363 9 : default: {
1364 9 : const char *tp = ATOMname(b->ttype);
1365 9 : BBPunfix(b->batCacheid);
1366 9 : throw(SQL, "sql.alter_table", SQLSTATE(HY005) "Cannot create imprint index %s on type %s", i->base.name, tp);
1367 : }
1368 : case TYPE_bte:
1369 : case TYPE_sht:
1370 : case TYPE_int:
1371 : case TYPE_lng:
1372 : #ifdef HAVE_HGE
1373 : case TYPE_hge:
1374 : #endif
1375 : case TYPE_flt:
1376 : case TYPE_dbl:
1377 : r = GDK_SUCCEED; /* fake imprints creation */
1378 : break;
1379 : }
1380 : }
1381 :
1382 57 : BBPunfix(b->batCacheid);
1383 57 : if (r != GDK_SUCCEED)
1384 0 : throw(SQL, "sql.alter_table", GDK_EXCEPTION);
1385 : }
1386 1094 : switch (mvc_copy_idx(sql, nt, i, NULL)) {
1387 0 : case -1:
1388 0 : throw(SQL,"sql.alter_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1389 3 : case -2:
1390 : case -3:
1391 3 : throw(SQL,"sql.alter_table", SQLSTATE(42000) "ALTER TABLE: %s_%s_%s conflicts with another transaction", s->base.name, t->base.name, i->base.name);
1392 : default:
1393 : break;
1394 : }
1395 : }
1396 : }
1397 1332 : if (t->keys) {
1398 : /* alter drop key */
1399 2117 : for (n = ol_first_node(t->keys); n; n = n->next) {
1400 785 : sql_key *k = n->data;
1401 :
1402 785 : if ((!k->base.new && !k->base.deleted) || (k->base.new && k->base.deleted))
1403 0 : continue;
1404 785 : if (k->base.deleted) {
1405 0 : sql_key *nk = mvc_bind_key(sql, s, k->base.name);
1406 0 : if (nk) {
1407 0 : switch (mvc_drop_key(sql, s, nk, k->drop_action)) {
1408 0 : case -1:
1409 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY013) MAL_MALLOC_FAIL);
1410 0 : case -2:
1411 : case -3:
1412 0 : throw(SQL,"sql.alter_table",SQLSTATE(42000) "ALTER TABLE: %s_%s_%s conflicts with another transaction", s->base.name, t->base.name, k->base.name);
1413 : default:
1414 : break;
1415 : }
1416 : }
1417 : } else { /* new */
1418 785 : str err;
1419 785 : if ((err = sql_partition_validate_key(sql, t, k, "ALTER")))
1420 0 : return err;
1421 785 : switch (mvc_copy_key(sql, nt, k, NULL)) {
1422 0 : case -1:
1423 0 : throw(SQL,"sql.alter_table",SQLSTATE(HY013) MAL_MALLOC_FAIL);
1424 0 : case -2:
1425 : case -3:
1426 0 : throw(SQL,"sql.alter_table",SQLSTATE(42000) "ALTER TABLE: %s_%s_%s conflicts with another transaction", s->base.name, t->base.name, k->base.name);
1427 : default:
1428 : break;
1429 : }
1430 : }
1431 : }
1432 : }
1433 : return MAL_SUCCEED;
1434 : }
1435 :
1436 : /* the MAL wrappers */
1437 : str
1438 313 : SQLcreate_seq(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1439 313 : { mvc *sql = NULL;
1440 313 : str msg;
1441 313 : str sname = *getArgReference_str(stk, pci, 1);
1442 313 : str seqname = *getArgReference_str(stk, pci, 2);
1443 313 : sql_sequence *s = *(sql_sequence **) getArgReference(stk, pci, 3);
1444 :
1445 313 : initcontext();
1446 313 : msg = create_seq(sql, sname, seqname, s);
1447 313 : return msg;
1448 : }
1449 :
1450 : str
1451 46 : SQLalter_seq(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1452 46 : { mvc *sql = NULL;
1453 46 : str msg = MAL_SUCCEED;
1454 46 : str sname = *getArgReference_str(stk, pci, 1);
1455 46 : str seqname = *getArgReference_str(stk, pci, 2);
1456 46 : sql_sequence *s = *(sql_sequence **) getArgReference(stk, pci, 3);
1457 46 : lng *val = NULL;
1458 46 : BAT *b = NULL;
1459 46 : BATiter bi = {0};
1460 :
1461 46 : initcontext();
1462 46 : if (getArgType(mb, pci, 4) == TYPE_lng)
1463 46 : val = getArgReference_lng(stk, pci, 4);
1464 0 : else if (isaBatType(getArgType(mb, pci, 4))) {
1465 0 : bat *bid = getArgReference_bat(stk, pci, 4);
1466 :
1467 0 : if (!(b = BATdescriptor(*bid)))
1468 0 : throw(SQL, "sql.alter_seq", SQLSTATE(HY002) RUNTIME_OBJECT_MISSING);
1469 0 : if (BATcount(b) != 1) {
1470 0 : BBPunfix(b->batCacheid);
1471 0 : throw(SQL, "sql.alter_seq", SQLSTATE(42000) "Only one value allowed to alter a sequence value");
1472 : }
1473 0 : bi = bat_iterator(b);
1474 0 : if (getBatType(getArgType(mb, pci, 4)) == TYPE_lng) {
1475 0 : val = (lng*)bi.base;
1476 : }
1477 : }
1478 :
1479 46 : if (val == NULL || is_lng_nil(*val))
1480 1 : msg = createException(SQL,"sql.alter_seq", SQLSTATE(42M36) "ALTER SEQUENCE: cannot (re)start with NULL");
1481 : else
1482 45 : msg = alter_seq(sql, sname, seqname, s, val);
1483 :
1484 46 : if (b) {
1485 0 : bat_iterator_end(&bi);
1486 0 : BBPunfix(b->batCacheid);
1487 : }
1488 : return msg;
1489 : }
1490 :
1491 : str
1492 32 : SQLdrop_seq(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1493 32 : { mvc *sql = NULL;
1494 32 : str msg = MAL_SUCCEED;
1495 32 : str sname = *getArgReference_str(stk, pci, 1);
1496 32 : str name = *getArgReference_str(stk, pci, 2);
1497 :
1498 32 : initcontext();
1499 32 : msg = drop_seq(sql, sname, name);
1500 32 : return msg;
1501 : }
1502 :
1503 : str
1504 1082 : SQLcreate_schema(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1505 1082 : { mvc *sql = NULL;
1506 1082 : str msg = MAL_SUCCEED;
1507 1082 : str sname = *getArgReference_str(stk, pci, 1);
1508 1082 : str name = SaveArgReference(stk, pci, 2);
1509 1082 : sqlid auth_id;
1510 :
1511 1082 : initcontext();
1512 1082 : auth_id = sql->role_id;
1513 1120 : if (!strNil(name) && (auth_id = sql_find_auth(sql, name)) < 0)
1514 0 : throw(SQL,"sql.create_schema", SQLSTATE(42M32) "CREATE SCHEMA: no such authorization '%s'", name);
1515 1082 : if (sql->user_id != USER_MONETDB && sql->role_id != ROLE_SYSADMIN)
1516 0 : throw(SQL,"sql.create_schema", SQLSTATE(42000) "CREATE SCHEMA: insufficient privileges for user '%s'", get_string_global_var(sql, "current_user"));
1517 1082 : if (mvc_bind_schema(sql, sname))
1518 0 : throw(SQL,"sql.create_schema", SQLSTATE(3F000) "CREATE SCHEMA: name '%s' already in use", sname);
1519 1082 : switch (mvc_create_schema(sql, sname, auth_id, sql->user_id)) {
1520 0 : case -1:
1521 0 : throw(SQL,"sql.create_schema",SQLSTATE(HY013) MAL_MALLOC_FAIL);
1522 1 : case -2:
1523 : case -3:
1524 1 : throw(SQL,"sql.create_schema",SQLSTATE(42000) "CREATE SCHEMA: transaction conflict detected");
1525 : default:
1526 : break;
1527 : }
1528 : return msg;
1529 : }
1530 :
1531 : str
1532 191 : SQLdrop_schema(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1533 : {
1534 191 : mvc *sql = NULL;
1535 191 : str msg = MAL_SUCCEED;
1536 191 : str sname = *getArgReference_str(stk, pci, 1);
1537 191 : int if_exists = *getArgReference_int(stk, pci, 2);
1538 191 : int action = *getArgReference_int(stk, pci, 3);
1539 191 : sql_schema *s;
1540 :
1541 191 : initcontext();
1542 191 : s = mvc_bind_schema(sql, sname);
1543 191 : if (!s) {
1544 12 : if (!if_exists)
1545 8 : throw(SQL,"sql.drop_schema",SQLSTATE(3F000) "DROP SCHEMA: name %s does not exist", sname);
1546 : return MAL_SUCCEED;
1547 : }
1548 179 : sql_trans *tr = sql->session->tr;
1549 179 : sql_schema *cur = cur_schema(sql);
1550 :
1551 179 : if (!mvc_schema_privs(sql, s))
1552 0 : throw(SQL,"sql.drop_schema",SQLSTATE(42000) "DROP SCHEMA: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
1553 179 : if (cur && s->base.id == cur->base.id)
1554 1 : throw(SQL,"sql.drop_schema",SQLSTATE(42000) "DROP SCHEMA: cannot drop current schema");
1555 178 : if (s->system)
1556 8 : throw(SQL,"sql.drop_schema",SQLSTATE(42000) "DROP SCHEMA: access denied for '%s'", sname);
1557 170 : if (sql_schema_has_user(sql, s))
1558 8 : throw(SQL,"sql.drop_schema",SQLSTATE(2BM37) "DROP SCHEMA: unable to drop schema '%s' (there are database users using it as session's default schema)", sname);
1559 243 : if (!action /* RESTRICT */ && (
1560 159 : os_size(s->tables, tr) || os_size(s->types, tr) || os_size(s->funcs, tr) || os_size(s->seqs, tr)))
1561 3 : throw(SQL,"sql.drop_schema",SQLSTATE(2BM37) "DROP SCHEMA: unable to drop schema '%s' (there are database objects which depend on it)", sname);
1562 :
1563 159 : switch (mvc_drop_schema(sql, s, action)) {
1564 0 : case -1:
1565 0 : throw(SQL,"sql.drop_schema",SQLSTATE(HY013) MAL_MALLOC_FAIL);
1566 0 : case -2:
1567 : case -3:
1568 0 : throw(SQL,"sql.drop_schema",SQLSTATE(42000) "DROP SCHEMA: transaction conflict detected");
1569 : default:
1570 : break;
1571 : }
1572 : return MAL_SUCCEED;
1573 : }
1574 :
1575 : str
1576 10099 : SQLcreate_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1577 10099 : { mvc *sql = NULL;
1578 10099 : str msg;
1579 10099 : str sname = *getArgReference_str(stk, pci, 1);
1580 : //str tname = *getArgReference_str(stk, pci, 2);
1581 10099 : sql_table *t = *(sql_table **) getArgReference(stk, pci, 3);
1582 10099 : int temp = *getArgReference_int(stk, pci, 4), remote = (pci->argc == 7);
1583 10099 : int pw_encrypted = temp;
1584 :
1585 10099 : initcontext();
1586 10091 : if (remote)
1587 101 : temp = 0;
1588 10091 : msg = create_table_or_view(sql, sname, t->base.name, t, temp, 0);
1589 10091 : if (!msg && remote) {
1590 101 : str username = *getArgReference_str(stk, pci, 5);
1591 101 : str password = *getArgReference_str(stk, pci, 6);
1592 :
1593 101 : sql_schema *s = mvc_bind_schema(sql, sname);
1594 101 : t = s?mvc_bind_table(sql, s, t->base.name):NULL;
1595 101 : if (t)
1596 101 : return remote_create(sql, t->base.id, username, password, pw_encrypted);
1597 0 : throw(SQL, "sql.create_table", SQLSTATE(3F000) "Internal error");
1598 : }
1599 : return msg;
1600 : }
1601 :
1602 : str
1603 22262 : SQLcreate_view(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1604 22262 : { mvc *sql = NULL;
1605 22262 : str msg;
1606 22262 : str sname = *getArgReference_str(stk, pci, 1);
1607 : //str vname = *getArgReference_str(stk, pci, 2);
1608 22262 : sql_table *t = *(sql_table **) getArgReference(stk, pci, 3);
1609 22262 : int temp = *getArgReference_int(stk, pci, 4);
1610 22262 : int replace = *getArgReference_int(stk, pci, 5);
1611 :
1612 22262 : initcontext();
1613 22261 : msg = create_table_or_view(sql, sname, t->base.name, t, temp, replace);
1614 22261 : return msg;
1615 : }
1616 :
1617 : str
1618 3679 : SQLdrop_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1619 3679 : { mvc *sql = NULL;
1620 3679 : str msg;
1621 3679 : str sname = *getArgReference_str(stk, pci, 1);
1622 3679 : str name = *getArgReference_str(stk, pci, 2);
1623 3679 : int if_exists = *getArgReference_int(stk, pci, 3);
1624 3679 : int action = *getArgReference_int(stk, pci, 4);
1625 :
1626 3679 : initcontext();
1627 3679 : msg = drop_table(sql, sname, name, action, if_exists);
1628 3679 : return msg;
1629 : }
1630 :
1631 : str
1632 218 : SQLdrop_view(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1633 218 : { mvc *sql = NULL;
1634 218 : str msg;
1635 218 : str sname = *getArgReference_str(stk, pci, 1);
1636 218 : str name = *getArgReference_str(stk, pci, 2);
1637 218 : int if_exists = *getArgReference_int(stk, pci, 3);
1638 218 : int action = *getArgReference_int(stk, pci, 4);
1639 :
1640 218 : initcontext();
1641 218 : msg = drop_view(sql, sname, name, action, if_exists);
1642 218 : return msg;
1643 : }
1644 :
1645 : str
1646 150 : SQLdrop_constraint(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1647 150 : { mvc *sql = NULL;
1648 150 : str msg;
1649 150 : str sname = *getArgReference_str(stk, pci, 1);
1650 150 : str tname = *getArgReference_str(stk, pci, 2);
1651 150 : str kname = *getArgReference_str(stk, pci, 3);
1652 150 : int action = *getArgReference_int(stk, pci, 5);
1653 150 : (void) *getArgReference_int(stk, pci, 4); //the if_exists parameter is also passed but not used
1654 :
1655 150 : initcontext();
1656 150 : msg = drop_key(sql, sname, tname, kname, action);
1657 150 : return msg;
1658 : }
1659 :
1660 : str
1661 1369 : SQLalter_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1662 1369 : { mvc *sql = NULL;
1663 1369 : str msg;
1664 1369 : str sname = *getArgReference_str(stk, pci, 1);
1665 1369 : str tname = *getArgReference_str(stk, pci, 2);
1666 1369 : sql_table *t = *(sql_table **) getArgReference(stk, pci, 3);
1667 :
1668 1369 : (void)tname;
1669 1369 : initcontext();
1670 1369 : msg = alter_table(cntxt, sql, sname, t);
1671 1369 : return msg;
1672 : }
1673 :
1674 : str
1675 906 : SQLcreate_type(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1676 906 : { mvc *sql = NULL;
1677 906 : str msg;
1678 906 : str sname = *getArgReference_str(stk, pci, 1);
1679 906 : char *name = *getArgReference_str(stk, pci, 2);
1680 906 : char *impl = *getArgReference_str(stk, pci, 3);
1681 906 : sql_schema *s = NULL;
1682 :
1683 906 : initcontext();
1684 :
1685 906 : if (!(s = mvc_bind_schema(sql, sname)))
1686 0 : throw(SQL,"sql.create_type",SQLSTATE(3F000) "CREATE TYPE: no such schema '%s'", sname);
1687 906 : if (!mvc_schema_privs(sql, s))
1688 0 : throw(SQL,"sql.create_type", SQLSTATE(42000) "CREATE TYPE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
1689 906 : if (schema_bind_type(sql, s, name))
1690 0 : throw(SQL,"sql.create_type", SQLSTATE(42S02) "CREATE TYPE: type '%s' already exists", name);
1691 906 : switch (mvc_create_type(sql, s, name, 0, 0, 0, impl)) {
1692 0 : case -1:
1693 0 : throw(SQL,"sql.create_type", SQLSTATE(HY013) MAL_MALLOC_FAIL);
1694 1 : case -2:
1695 : case -3:
1696 1 : throw(SQL,"sql.create_type", SQLSTATE(42000) "CREATE TYPE: transaction conflict detected");
1697 0 : case -4:
1698 0 : throw(SQL,"sql.create_type", SQLSTATE(0D000) "CREATE TYPE: unknown external type '%s'", impl);
1699 : default:
1700 : break;
1701 : }
1702 : return msg;
1703 : }
1704 :
1705 : str
1706 4 : SQLdrop_type(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1707 4 : { mvc *sql = NULL;
1708 4 : str msg;
1709 4 : str sname = *getArgReference_str(stk, pci, 1);
1710 4 : char *name = *getArgReference_str(stk, pci, 2);
1711 4 : int drop_action = *getArgReference_int(stk, pci, 3);
1712 4 : sql_schema *s = NULL;
1713 4 : sql_type *t;
1714 :
1715 4 : initcontext();
1716 :
1717 4 : if (!(s = mvc_bind_schema(sql, sname)))
1718 0 : throw(SQL,"sql.drop_type",SQLSTATE(3F000) "DROP TYPE: no such schema '%s'", sname);
1719 4 : if (!mvc_schema_privs(sql, s))
1720 0 : throw(SQL,"sql.drop_type", SQLSTATE(42000) "DROP TYPE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), s->base.name);
1721 4 : if (!(t = schema_bind_type(sql, s, name)))
1722 0 : throw(SQL,"sql.drop_type", SQLSTATE(3F000) "DROP TYPE: type '%s' does not exist", name);
1723 4 : if (!drop_action && mvc_check_dependency(sql, t->base.id, TYPE_DEPENDENCY, NULL))
1724 1 : throw(SQL,"sql.drop_type", SQLSTATE(42000) "DROP TYPE: unable to drop type %s (there are database objects which depend on it)\n", name);
1725 3 : switch (mvc_drop_type(sql, s, t, drop_action)) {
1726 0 : case -1:
1727 0 : throw(SQL,"sql.drop_type",SQLSTATE(HY013) MAL_MALLOC_FAIL);
1728 0 : case -2:
1729 : case -3:
1730 0 : throw(SQL,"sql.drop_type",SQLSTATE(42000) "DROP TYPE: transaction conflict detected");
1731 : default:
1732 : break;
1733 : }
1734 : return msg;
1735 : }
1736 :
1737 : str
1738 40 : SQLgrant_roles(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1739 40 : { mvc *sql = NULL;
1740 40 : str msg;
1741 40 : str sname = *getArgReference_str(stk, pci, 1);
1742 40 : char *auth = SaveArgReference(stk, pci, 2);
1743 40 : sqlid grantor = (sqlid) *getArgReference_int(stk, pci, 3);
1744 40 : int admin = *getArgReference_int(stk, pci, 4);
1745 :
1746 40 : initcontext();
1747 40 : msg = sql_grant_role(sql, sname /*grantee */ , auth, grantor, admin);
1748 40 : return msg;
1749 : }
1750 :
1751 : str
1752 10 : SQLrevoke_roles(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1753 10 : { mvc *sql = NULL;
1754 10 : str msg;
1755 10 : str sname = *getArgReference_str(stk, pci, 1);
1756 10 : char *auth = SaveArgReference(stk, pci, 2);
1757 10 : sqlid grantor = (sqlid) *getArgReference_int(stk, pci, 3);
1758 10 : int admin = *getArgReference_int(stk, pci, 4);
1759 :
1760 10 : initcontext();
1761 10 : msg = sql_revoke_role(sql, sname /*grantee */ , auth, grantor, admin);
1762 10 : return msg;
1763 : }
1764 :
1765 : str
1766 18374 : SQLgrant(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1767 18374 : { mvc *sql = NULL;
1768 18374 : str msg;
1769 18374 : str sname = *getArgReference_str(stk, pci, 1);
1770 18374 : char *tname = *getArgReference_str(stk, pci, 2);
1771 18374 : char *grantee = *getArgReference_str(stk, pci, 3);
1772 18374 : int privs = *getArgReference_int(stk, pci, 4);
1773 18374 : char *cname = SaveArgReference(stk, pci, 5);
1774 18374 : int grant = *getArgReference_int(stk, pci, 6);
1775 18374 : sqlid grantor = (sqlid) *getArgReference_int(stk, pci, 7);
1776 :
1777 18374 : initcontext();
1778 18374 : if (strNil(tname))
1779 10 : msg = sql_grant_global_privs(sql, grantee, privs, grant, grantor);
1780 : else
1781 18364 : msg = sql_grant_table_privs(sql, grantee, privs, sname, tname, cname, grant, grantor);
1782 : return msg;
1783 : }
1784 :
1785 15 : str SQLrevoke(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1786 15 : { mvc *sql = NULL;
1787 15 : str msg;
1788 15 : str sname = *getArgReference_str(stk, pci, 1);
1789 15 : char *tname = *getArgReference_str(stk, pci, 2);
1790 15 : char *grantee = *getArgReference_str(stk, pci, 3);
1791 15 : int privs = *getArgReference_int(stk, pci, 4);
1792 15 : char *cname = SaveArgReference(stk, pci, 5);
1793 15 : int grant = *getArgReference_int(stk, pci, 6);
1794 15 : sqlid grantor = (sqlid) *getArgReference_int(stk, pci, 7);
1795 :
1796 15 : initcontext();
1797 15 : if (strNil(tname))
1798 2 : msg = sql_revoke_global_privs(sql, grantee, privs, grant, grantor);
1799 : else
1800 13 : msg = sql_revoke_table_privs(sql, grantee, privs, sname, tname, cname, grant, grantor);
1801 : return msg;
1802 : }
1803 :
1804 : str
1805 98731 : SQLgrant_function(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1806 98731 : { mvc *sql = NULL;
1807 98731 : str msg;
1808 98731 : str sname = *getArgReference_str(stk, pci, 1);
1809 98731 : sqlid func_id = (sqlid) *getArgReference_int(stk, pci, 2);
1810 98731 : char *grantee = *getArgReference_str(stk, pci, 3);
1811 98731 : int privs = *getArgReference_int(stk, pci, 4);
1812 98731 : int grant = *getArgReference_int(stk, pci, 5);
1813 98731 : sqlid grantor = (sqlid) *getArgReference_int(stk, pci, 6);
1814 :
1815 98731 : initcontext();
1816 98731 : msg = sql_grant_func_privs(sql, grantee, privs, sname, func_id, grant, grantor);
1817 98731 : return msg;
1818 : }
1819 :
1820 : str
1821 1 : SQLrevoke_function(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1822 1 : { mvc *sql = NULL;
1823 1 : str msg;
1824 1 : str sname = *getArgReference_str(stk, pci, 1);
1825 1 : sqlid func_id = (sqlid) *getArgReference_int(stk, pci, 2);
1826 1 : char *grantee = *getArgReference_str(stk, pci, 3);
1827 1 : int privs = *getArgReference_int(stk, pci, 4);
1828 1 : int grant = *getArgReference_int(stk, pci, 5);
1829 1 : sqlid grantor = (sqlid) *getArgReference_int(stk, pci, 6);
1830 :
1831 1 : initcontext();
1832 1 : msg = sql_revoke_func_privs(sql, grantee, privs, sname, func_id, grant, grantor);
1833 1 : return msg;
1834 : }
1835 :
1836 : str
1837 358 : SQLcreate_user(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1838 358 : { mvc *sql = NULL;
1839 358 : str msg;
1840 358 : str sname = *getArgReference_str(stk, pci, 1);
1841 358 : char *passwd = *getArgReference_str(stk, pci, 2);
1842 358 : int enc = *getArgReference_int(stk, pci, 3);
1843 358 : char *schema = SaveArgReference(stk, pci, 4);
1844 358 : char *schema_path = SaveArgReference(stk, pci, 5);
1845 358 : char *fullname = SaveArgReference(stk, pci, 6);
1846 358 : lng max_memory = *getArgReference_lng(stk, pci, 7);
1847 358 : int max_workers = *getArgReference_int(stk, pci, 8);
1848 358 : char *optimizer = SaveArgReference(stk, pci, 9);
1849 358 : char *default_role = SaveArgReference(stk, pci, 10);
1850 :
1851 358 : initcontext();
1852 358 : msg = sql_create_user(sql, sname, passwd, enc, fullname, schema, schema_path, max_memory, max_workers, optimizer, default_role);
1853 358 : return msg;
1854 : }
1855 :
1856 : str
1857 107 : SQLdrop_user(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1858 107 : { mvc *sql = NULL;
1859 107 : str msg;
1860 107 : str sname = *getArgReference_str(stk, pci, 1);
1861 :
1862 107 : initcontext();
1863 107 : msg = sql_drop_user(sql, sname);
1864 107 : return msg;
1865 : }
1866 :
1867 : str
1868 83 : SQLalter_user(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1869 83 : { mvc *sql = NULL;
1870 83 : str msg;
1871 83 : str sname = *getArgReference_str(stk, pci, 1);
1872 83 : char *passwd = SaveArgReference(stk, pci, 2);
1873 83 : int enc = *getArgReference_int(stk, pci, 3);
1874 83 : char *schema = SaveArgReference(stk, pci, 4);
1875 83 : char *schema_path = SaveArgReference(stk, pci, 5);
1876 83 : char *oldpasswd = SaveArgReference(stk, pci, 6);
1877 83 : char *role = SaveArgReference(stk, pci, 7);
1878 83 : lng max_memory = *getArgReference_lng(stk, pci, 8);
1879 83 : int max_workers = *getArgReference_int(stk, pci, 9);
1880 :
1881 83 : initcontext();
1882 83 : msg = sql_alter_user(sql, sname, passwd, enc, schema, schema_path, oldpasswd, role, max_memory, max_workers);
1883 :
1884 83 : return msg;
1885 : }
1886 :
1887 : str
1888 5 : SQLrename_user(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1889 5 : { mvc *sql = NULL;
1890 5 : str msg;
1891 5 : str sname = *getArgReference_str(stk, pci, 1);
1892 5 : char *newuser = *getArgReference_str(stk, pci, 2);
1893 :
1894 5 : initcontext();
1895 5 : msg = sql_rename_user(sql, sname, newuser);
1896 5 : return msg;
1897 : }
1898 :
1899 : str
1900 26 : SQLcreate_role(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1901 26 : { mvc *sql = NULL;
1902 26 : str msg;
1903 26 : str sname = *getArgReference_str(stk, pci, 1);
1904 26 : char *role = sname;
1905 26 : sqlid grantor = (sqlid)*getArgReference_int(stk, pci, 3);
1906 :
1907 26 : initcontext();
1908 26 : msg = sql_create_role(sql, role, grantor);
1909 26 : return msg;
1910 : }
1911 :
1912 : str
1913 19 : SQLdrop_role(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1914 19 : { mvc *sql = NULL;
1915 19 : str msg;
1916 19 : str sname = *getArgReference_str(stk, pci, 1);
1917 19 : char *role = sname;
1918 :
1919 19 : initcontext();
1920 19 : msg = sql_drop_role(sql, role);
1921 19 : return msg;
1922 : }
1923 :
1924 : str
1925 160 : SQLdrop_index(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1926 160 : { mvc *sql = NULL;
1927 160 : str msg;
1928 160 : str sname = *getArgReference_str(stk, pci, 1);
1929 160 : char *iname = *getArgReference_str(stk, pci, 2);
1930 :
1931 160 : initcontext();
1932 160 : msg = drop_index(sql, sname, iname);
1933 160 : return msg;
1934 : }
1935 :
1936 : str
1937 568 : SQLdrop_function(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1938 568 : { mvc *sql = NULL;
1939 568 : str msg;
1940 568 : str sname = *getArgReference_str(stk, pci, 1);
1941 568 : char *fname = *getArgReference_str(stk, pci, 2);
1942 568 : sqlid fid = (sqlid)*getArgReference_int(stk, pci, 3);
1943 568 : sql_ftype type = (sql_ftype) *getArgReference_int(stk, pci, 4);
1944 568 : int action = *getArgReference_int(stk, pci, 5);
1945 :
1946 568 : initcontext();
1947 568 : msg = drop_func(sql, sname, fname, fid, type, action);
1948 568 : return msg;
1949 : }
1950 :
1951 : str
1952 120753 : SQLcreate_function(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1953 120753 : { mvc *sql = NULL;
1954 120753 : str msg;
1955 120753 : str sname = *getArgReference_str(stk, pci, 1);
1956 120753 : str fname = *getArgReference_str(stk, pci, 2);
1957 120753 : sql_func *f = *(sql_func **) getArgReference(stk, pci, 3);
1958 120753 : int replace = *getArgReference_int(stk, pci, 4);
1959 :
1960 120753 : initcontext();
1961 120753 : msg = create_func(sql, sname, fname, f, replace);
1962 120753 : return msg;
1963 : }
1964 :
1965 : str
1966 345 : SQLcreate_trigger(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1967 345 : { mvc *sql = NULL;
1968 345 : str msg;
1969 345 : str sname = *getArgReference_str(stk, pci, 1);
1970 345 : char *tname = *getArgReference_str(stk, pci, 2);
1971 345 : char *triggername = *getArgReference_str(stk, pci, 3);
1972 345 : int time = *getArgReference_int(stk, pci, 4);
1973 345 : int orientation = *getArgReference_int(stk, pci, 5);
1974 345 : int event = *getArgReference_int(stk, pci, 6);
1975 345 : char *old_name = *getArgReference_str(stk, pci, 7);
1976 345 : char *new_name = *getArgReference_str(stk, pci, 8);
1977 345 : char *condition = *getArgReference_str(stk, pci, 9);
1978 345 : char *query = *getArgReference_str(stk, pci, 10);
1979 345 : int replace = *getArgReference_int(stk, pci, 11);
1980 :
1981 345 : initcontext();
1982 374 : old_name=(strNil(old_name))?NULL:old_name;
1983 385 : new_name=(strNil(new_name))?NULL:new_name;
1984 345 : condition=(strNil(condition))?NULL:condition;
1985 345 : msg = create_trigger(sql, sname, tname, triggername, time, orientation, event, old_name, new_name, condition, query, replace);
1986 345 : return msg;
1987 : }
1988 :
1989 : str
1990 84 : SQLdrop_trigger(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
1991 84 : { mvc *sql = NULL;
1992 84 : str msg;
1993 84 : str sname = *getArgReference_str(stk, pci, 1);
1994 84 : char *triggername = *getArgReference_str(stk, pci, 2);
1995 84 : int if_exists = *getArgReference_int(stk, pci, 3);
1996 :
1997 84 : initcontext();
1998 84 : msg = drop_trigger(sql, sname, triggername, if_exists);
1999 84 : return msg;
2000 : }
2001 :
2002 : str
2003 312 : SQLalter_add_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2004 312 : { mvc *sql = NULL;
2005 312 : str msg;
2006 312 : str sname = *getArgReference_str(stk, pci, 1);
2007 312 : char *mtname = SaveArgReference(stk, pci, 2);
2008 312 : char *psname = SaveArgReference(stk, pci, 3);
2009 312 : char *ptname = SaveArgReference(stk, pci, 4);
2010 :
2011 312 : initcontext();
2012 312 : msg = alter_table_add_table(sql, sname, mtname, psname, ptname);
2013 312 : return msg;
2014 : }
2015 :
2016 : str
2017 224 : SQLalter_add_range_partition(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2018 224 : { mvc *sql = NULL;
2019 224 : str msg;
2020 224 : str sname = *getArgReference_str(stk, pci, 1);
2021 224 : char *mtname = SaveArgReference(stk, pci, 2);
2022 224 : char *psname = SaveArgReference(stk, pci, 3);
2023 224 : char *ptname = SaveArgReference(stk, pci, 4);
2024 224 : ValRecord *min = &(stk)->stk[(pci)->argv[5]];
2025 224 : ValRecord *max = &(stk)->stk[(pci)->argv[6]];
2026 224 : bit with_nills = *getArgReference_bit(stk, pci, 7);
2027 224 : int update = *getArgReference_int(stk, pci, 8);
2028 224 : lng cnt = 0;
2029 :
2030 224 : if (getArgType(mb, pci, 9) == TYPE_lng) {
2031 222 : cnt = *getArgReference_lng(stk, pci, 9);
2032 : } else {
2033 2 : BAT *c = BATdescriptor(*getArgReference_bat(stk, pci, 9));
2034 2 : if (c && BATcount(c) == 1)
2035 2 : cnt = *(lng*)Tloc(c, 0);
2036 2 : if (c)
2037 2 : BBPunfix(c->batCacheid);
2038 : }
2039 :
2040 224 : initcontext();
2041 224 : msg = alter_table_add_range_partition(sql, sname, mtname, psname, ptname, VALget(min), VALget(max), with_nills, update, cnt);
2042 224 : return msg;
2043 : }
2044 :
2045 : str
2046 59 : SQLalter_add_value_partition(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2047 59 : { mvc *sql = NULL;
2048 59 : str msg;
2049 59 : str sname = *getArgReference_str(stk, pci, 1);
2050 59 : char *mtname = SaveArgReference(stk, pci, 2);
2051 59 : char *psname = SaveArgReference(stk, pci, 3);
2052 59 : char *ptname = SaveArgReference(stk, pci, 4);
2053 59 : bit with_nills = *getArgReference_bit(stk, pci, 5);
2054 59 : int update = *getArgReference_int(stk, pci, 6);
2055 59 : lng cnt = 0;
2056 :
2057 59 : if (getArgType(mb, pci, 7) == TYPE_lng) {
2058 59 : cnt = *getArgReference_lng(stk, pci, 7);
2059 : } else {
2060 0 : BAT *c = BATdescriptor(*getArgReference_bat(stk, pci, 7));
2061 0 : if (c && BATcount(c) == 1)
2062 0 : cnt = *(lng*)Tloc(c, 0);
2063 0 : if (c)
2064 0 : BBPunfix(c->batCacheid);
2065 : }
2066 :
2067 59 : initcontext();
2068 59 : msg = alter_table_add_value_partition(sql, stk, pci, sname, mtname, psname, ptname, with_nills, update, cnt);
2069 59 : return msg;
2070 : }
2071 :
2072 : str
2073 180 : SQLalter_del_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2074 180 : { mvc *sql = NULL;
2075 180 : str msg;
2076 180 : str sname = *getArgReference_str(stk, pci, 1);
2077 180 : char *mtname = SaveArgReference(stk, pci, 2);
2078 180 : char *psname = SaveArgReference(stk, pci, 3);
2079 180 : char *ptname = SaveArgReference(stk, pci, 4);
2080 180 : int drop_action = *getArgReference_int(stk, pci, 5);
2081 :
2082 180 : initcontext();
2083 180 : msg= alter_table_del_table(sql, sname, mtname, psname, ptname, drop_action);
2084 180 : return msg;
2085 : }
2086 :
2087 : str
2088 2294 : SQLalter_set_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2089 2294 : { mvc *sql = NULL;
2090 2294 : str msg;
2091 2294 : str sname = *getArgReference_str(stk, pci, 1);
2092 2294 : char *tname = SaveArgReference(stk, pci, 2);
2093 2294 : int access = *getArgReference_int(stk, pci, 3);
2094 :
2095 2294 : initcontext();
2096 2294 : msg = alter_table_set_access(sql, sname, tname, access);
2097 :
2098 2294 : return msg;
2099 : }
2100 :
2101 : str
2102 354 : SQLcomment_on(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2103 : {
2104 354 : mvc *sql = NULL;
2105 354 : str msg;
2106 354 : sqlid objid = (sqlid) *getArgReference_int(stk, pci, 1);
2107 354 : char *remark = *getArgReference_str(stk, pci, 2);
2108 354 : sql_trans *tx;
2109 354 : sql_schema *sys;
2110 354 : sql_table *comments;
2111 354 : sql_column *id_col, *remark_col;
2112 354 : oid rid;
2113 354 : int ok = LOG_OK;
2114 :
2115 354 : initcontext();
2116 :
2117 : // Manually insert the rows to circumvent permission checks.
2118 354 : tx = sql->session->tr;
2119 354 : sys = mvc_bind_schema(sql, "sys");
2120 354 : if (!sys)
2121 0 : throw(SQL, "sql.comment_on", SQLSTATE(3F000) "Internal error");
2122 354 : comments = mvc_bind_table(sql, sys, "comments");
2123 354 : if (!comments)
2124 0 : throw(SQL, "sql.comment_on", SQLSTATE(3F000) "no table sys.comments");
2125 354 : id_col = mvc_bind_column(sql, comments, "id");
2126 354 : remark_col = find_sql_column(comments, "remark");
2127 354 : if (!id_col || !remark_col)
2128 0 : throw(SQL, "sql.comment_on", SQLSTATE(3F000) "no table sys.comments");
2129 354 : sqlstore *store = tx->store;
2130 354 : rid = store->table_api.column_find_row(tx, id_col, &objid, NULL);
2131 708 : if (!strNil(remark) && *remark) {
2132 345 : if (!is_oid_nil(rid)) {
2133 : // have new remark and found old one, so update field
2134 : /* UPDATE sys.comments SET remark = %s WHERE id = %d */
2135 4 : ok = store->table_api.column_update_value(tx, remark_col, rid, remark);
2136 : } else {
2137 : // have new remark but found none so insert row
2138 : /* INSERT INTO sys.comments (id, remark) VALUES (%d, %s) */
2139 341 : ok = store->table_api.table_insert(tx, comments, &objid, &remark);
2140 : }
2141 345 : if (ok != LOG_OK)
2142 1 : throw(SQL, "sql.comment_on", SQLSTATE(42000) "Comment on failed%s", ok == LOG_CONFLICT ? " due to conflict with another transaction" : "");
2143 344 : if ((ok = sql_trans_add_dependency(tx, objid, ddl)) != LOG_OK) /* At the moment this adds dependencies for old objects :( */
2144 0 : throw(SQL, "sql.comment_on", SQLSTATE(HY013) MAL_MALLOC_FAIL);
2145 : } else {
2146 9 : if (!is_oid_nil(rid)) {
2147 : // have no remark but found one, so delete row
2148 : /* DELETE FROM sys.comments WHERE id = %d */
2149 7 : if ((ok = store->table_api.table_delete(tx, comments, rid)) != LOG_OK)
2150 0 : throw(SQL, "sql.comment_on", SQLSTATE(42000) "Comment on failed%s", ok == LOG_CONFLICT ? " due to conflict with another transaction" : "");
2151 : }
2152 : }
2153 : return MAL_SUCCEED;
2154 : }
2155 :
2156 : str
2157 8 : SQLrename_schema(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2158 : {
2159 8 : mvc *sql = NULL;
2160 8 : str msg = MAL_SUCCEED;
2161 8 : str old_name = *getArgReference_str(stk, pci, 1);
2162 8 : str new_name = *getArgReference_str(stk, pci, 2);
2163 8 : sql_schema *s;
2164 :
2165 8 : initcontext();
2166 8 : sql_schema *cur = cur_schema(sql);
2167 :
2168 8 : if (!(s = mvc_bind_schema(sql, old_name)))
2169 0 : throw(SQL, "sql.rename_schema", SQLSTATE(42S02)
2170 : "ALTER SCHEMA: no such schema '%s'", old_name);
2171 :
2172 8 : if (!mvc_schema_privs(sql, s))
2173 0 : throw(SQL, "sql.rename_schema", SQLSTATE(42000)
2174 : "ALTER SCHEMA: access denied for %s to schema '%s'",
2175 : get_string_global_var(sql, "current_user"), old_name);
2176 :
2177 8 : if (s->system)
2178 0 : throw(SQL, "sql.rename_schema", SQLSTATE(3F000)
2179 : "ALTER SCHEMA: cannot rename a system schema");
2180 :
2181 16 : if (strNil(new_name) || *new_name == '\0')
2182 0 : throw(SQL, "sql.rename_schema", SQLSTATE(3F000)
2183 : "ALTER SCHEMA: invalid new schema name");
2184 :
2185 8 : if (mvc_bind_schema(sql, new_name))
2186 0 : throw(SQL, "sql.rename_schema", SQLSTATE(3F000)
2187 : "ALTER SCHEMA: there is a schema named '%s' in the database", new_name);
2188 :
2189 8 : if (mvc_check_dependency(sql, s->base.id, SCHEMA_DEPENDENCY, NULL) == HAS_DEPENDENCY) {
2190 0 : throw(SQL, "sql.rename_schema", "ALTER SCHEMA: unable to"
2191 : " rename schema '%s', there are database objects"
2192 : " which depend on it", old_name);
2193 : }
2194 :
2195 8 : switch (sql_trans_rename_schema(sql->session->tr, s->base.id, new_name)) {
2196 0 : case -1:
2197 0 : throw(SQL,"sql.rename_schema", SQLSTATE(HY013) MAL_MALLOC_FAIL);
2198 0 : case -2:
2199 : case -3:
2200 0 : throw(SQL,"sql.rename_schema", SQLSTATE(42000)
2201 : "ALTER SCHEMA: transaction conflict detected");
2202 : default:
2203 8 : break;
2204 : }
2205 :
2206 8 : if (cur && s->base.id == cur->base.id) {
2207 1 : if (!mvc_set_schema(sql, new_name))
2208 0 : throw(SQL, "sql.rename_schema",SQLSTATE(HY013) MAL_MALLOC_FAIL);
2209 :
2210 1 : s = mvc_bind_schema(sql, "sys");
2211 1 : assert(s);
2212 :
2213 1 : if (!sqlvar_set_string(find_global_var(sql, s, "current_schema"), new_name))
2214 0 : throw(SQL, "sql.setVariable", SQLSTATE(HY013) MAL_MALLOC_FAIL);
2215 : }
2216 :
2217 : return msg;
2218 : }
2219 :
2220 : str
2221 45 : SQLrename_table(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2222 : {
2223 45 : mvc *sql = NULL;
2224 45 : str msg = MAL_SUCCEED;
2225 45 : str oschema_name = *getArgReference_str(stk, pci, 1);
2226 45 : str nschema_name = *getArgReference_str(stk, pci, 2);
2227 45 : str otable_name = *getArgReference_str(stk, pci, 3);
2228 45 : str ntable_name = *getArgReference_str(stk, pci, 4);
2229 45 : sql_schema *o, *s;
2230 45 : sql_table *t;
2231 :
2232 45 : initcontext();
2233 :
2234 45 : if (strcmp(oschema_name, nschema_name) == 0) { //renaming the table itself
2235 19 : if (!(s = mvc_bind_schema(sql, oschema_name)))
2236 0 : throw(SQL, "sql.rename_table", SQLSTATE(42S02) "ALTER TABLE: no such schema '%s'", oschema_name);
2237 19 : if (!mvc_schema_privs(sql, s))
2238 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), oschema_name);
2239 19 : if (!(t = mvc_bind_table(sql, s, otable_name)))
2240 0 : throw(SQL, "sql.rename_table", SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", otable_name, oschema_name);
2241 19 : if (t->system)
2242 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: cannot rename a system table");
2243 19 : if (isView(t))
2244 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: cannot rename a view");
2245 19 : if (isDeclaredTable(t))
2246 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: cannot rename a declared table");
2247 19 : if (mvc_check_dependency(sql, t->base.id, TABLE_DEPENDENCY, NULL))
2248 0 : throw (SQL,"sql.rename_table", SQLSTATE(2BM37) "ALTER TABLE: unable to rename table '%s' (there are database objects which depend on it)", otable_name);
2249 38 : if (strNil(ntable_name) || *ntable_name == '\0')
2250 0 : throw(SQL, "sql.rename_table", SQLSTATE(3F000) "ALTER TABLE: invalid new table name");
2251 19 : if (mvc_bind_table(sql, s, ntable_name))
2252 0 : throw(SQL, "sql.rename_table", SQLSTATE(3F000) "ALTER TABLE: there is a table named '%s' in schema '%s'", ntable_name, oschema_name);
2253 :
2254 19 : switch (sql_trans_rename_table(sql->session->tr, s, t->base.id, ntable_name)) {
2255 0 : case -1:
2256 0 : throw(SQL,"sql.rename_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
2257 3 : case -2:
2258 : case -3:
2259 3 : throw(SQL,"sql.rename_table", SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
2260 : default:
2261 : break;
2262 : }
2263 : } else { //changing the schema of the table
2264 26 : assert(strcmp(otable_name, ntable_name) == 0);
2265 :
2266 26 : if (!(o = mvc_bind_schema(sql, oschema_name)))
2267 0 : throw(SQL, "sql.rename_table", SQLSTATE(42S02) "ALTER TABLE: no such schema '%s'", oschema_name);
2268 26 : if (!mvc_schema_privs(sql, o))
2269 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), oschema_name);
2270 26 : if (!(t = mvc_bind_table(sql, o, otable_name)))
2271 0 : throw(SQL, "sql.rename_table", SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", otable_name, oschema_name);
2272 26 : if (t->system)
2273 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: cannot set schema of a system table");
2274 26 : if (isTempSchema(o))
2275 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: not possible to change a temporary table schema");
2276 26 : if (isView(t))
2277 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: not possible to change schema of a view");
2278 26 : if (isDeclaredTable(t))
2279 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: not possible to change schema of a declared table");
2280 26 : if (mvc_check_dependency(sql, t->base.id, TABLE_DEPENDENCY, NULL) || list_length(t->members) || ol_length(t->triggers))
2281 0 : throw(SQL, "sql.rename_table", SQLSTATE(2BM37) "ALTER TABLE: unable to set schema of table '%s' (there are database objects which depend on it)", otable_name);
2282 26 : if (!(s = mvc_bind_schema(sql, nschema_name)))
2283 0 : throw(SQL, "sql.rename_table", SQLSTATE(42S02) "ALTER TABLE: no such schema '%s'", nschema_name);
2284 26 : if (!mvc_schema_privs(sql, s))
2285 0 : throw(SQL, "sql.rename_table", SQLSTATE(42000) "ALTER TABLE: access denied for '%s' to schema '%s'", get_string_global_var(sql, "current_user"), nschema_name);
2286 26 : if (isTempSchema(s))
2287 0 : throw(SQL, "sql.rename_table", SQLSTATE(3F000) "ALTER TABLE: not possible to change table's schema to temporary");
2288 26 : if (mvc_bind_table(sql, s, otable_name))
2289 0 : throw(SQL, "sql.rename_table", SQLSTATE(42S02) "ALTER TABLE: table '%s' on schema '%s' already exists", otable_name, nschema_name);
2290 :
2291 26 : switch (sql_trans_set_table_schema(sql->session->tr, t->base.id, o, s)) {
2292 0 : case -1:
2293 0 : throw(SQL,"sql.rename_table", SQLSTATE(HY013) MAL_MALLOC_FAIL);
2294 1 : case -2:
2295 : case -3:
2296 1 : throw(SQL,"sql.rename_table", SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
2297 : default:
2298 : break;
2299 : }
2300 : }
2301 :
2302 : return msg;
2303 : }
2304 :
2305 : str
2306 13 : SQLrename_column(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
2307 : {
2308 13 : mvc *sql = NULL;
2309 13 : str msg = MAL_SUCCEED;
2310 13 : str schema_name = *getArgReference_str(stk, pci, 1);
2311 13 : str table_name = *getArgReference_str(stk, pci, 2);
2312 13 : str old_name = *getArgReference_str(stk, pci, 3);
2313 13 : str new_name = *getArgReference_str(stk, pci, 4);
2314 13 : sql_schema *s;
2315 13 : sql_table *t;
2316 13 : sql_column *col;
2317 :
2318 13 : initcontext();
2319 13 : if (!(s = mvc_bind_schema(sql, schema_name)))
2320 0 : throw(SQL, "sql.rename_column", SQLSTATE(42S02) "ALTER TABLE: no such schema '%s'", schema_name);
2321 13 : if (!mvc_schema_privs(sql, s))
2322 0 : throw(SQL, "sql.rename_column", SQLSTATE(42000) "ALTER TABLE: access denied for %s to schema '%s'", get_string_global_var(sql, "current_user"), schema_name);
2323 13 : if (!(t = mvc_bind_table(sql, s, table_name)))
2324 0 : throw(SQL, "sql.rename_column", SQLSTATE(42S02) "ALTER TABLE: no such table '%s' in schema '%s'", table_name, schema_name);
2325 13 : if (t->system)
2326 0 : throw(SQL, "sql.rename_column", SQLSTATE(42000) "ALTER TABLE: cannot rename a column in a system table");
2327 13 : if (isView(t))
2328 0 : throw(SQL, "sql.rename_column", SQLSTATE(42000) "ALTER TABLE: cannot rename column '%s': '%s' is a view", old_name, table_name);
2329 13 : if (isDeclaredTable(t))
2330 0 : throw(SQL, "sql.rename_column", SQLSTATE(42000) "ALTER TABLE: cannot rename column in a declared table");
2331 13 : if (!(col = mvc_bind_column(sql, t, old_name)))
2332 0 : throw(SQL, "sql.rename_column", SQLSTATE(42S22) "ALTER TABLE: no such column '%s' in table '%s'", old_name, table_name);
2333 13 : if (mvc_check_dependency(sql, col->base.id, COLUMN_DEPENDENCY, NULL))
2334 0 : throw(SQL, "sql.rename_column", SQLSTATE(2BM37) "ALTER TABLE: cannot rename column '%s' (there are database objects which depend on it)", old_name);
2335 26 : if (strNil(new_name) || *new_name == '\0')
2336 0 : throw(SQL, "sql.rename_column", SQLSTATE(3F000) "ALTER TABLE: invalid new column name");
2337 13 : if (mvc_bind_column(sql, t, new_name))
2338 0 : throw(SQL, "sql.rename_column", SQLSTATE(3F000) "ALTER TABLE: there is a column named '%s' in table '%s'", new_name, table_name);
2339 :
2340 13 : switch (sql_trans_rename_column(sql->session->tr, t, col->base.id, old_name, new_name)) {
2341 0 : case -1:
2342 0 : throw(SQL,"sql.rename_column", SQLSTATE(HY013) MAL_MALLOC_FAIL);
2343 0 : case -2:
2344 : case -3:
2345 0 : throw(SQL,"sql.rename_column", SQLSTATE(42000) "ALTER TABLE: transaction conflict detected");
2346 : default:
2347 : break;
2348 : }
2349 : return msg;
2350 : }
|