LCOV - code coverage report
Current view: top level - sql/backends/monet5 - sql_cat.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 960 1312 73.2 %
Date: 2021-10-13 02:24:04 Functions: 61 61 100.0 %

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

Generated by: LCOV version 1.14