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