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