engine/sqlite/src/alter.cpp
author Sebastian Brannstrom <sebastianb@symbian.org>
Sat, 23 Oct 2010 17:11:38 +0100
branch3rded
changeset 278 e6aa20533d01
parent 2 29cda98b007e
permissions -rw-r--r--
Merged fix for 3843
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     1
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     2
** 2005 February 15
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     3
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     4
** The author disclaims copyright to this source code.  In place of
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     5
** a legal notice, here is a blessing:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     6
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     7
**    May you do good and not evil.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     8
**    May you find forgiveness for yourself and forgive others.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
     9
**    May you share freely, never taking more than you give.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    10
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    11
*************************************************************************
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    12
** This file contains C code routines that used to generate VDBE code
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    13
** that implements the ALTER TABLE command.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    14
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    15
** $Id: alter.cpp 1282 2008-11-13 09:31:33Z LarsPson $
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    16
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    17
#include "sqliteInt.h"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    18
#include <ctype.h>
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    19
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    20
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    21
** The code in this file only exists if we are not omitting the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    22
** ALTER TABLE logic from the build.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    23
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    24
#ifndef SQLITE_OMIT_ALTERTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    25
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    26
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    27
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    28
** This function is used by SQL generated to implement the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    29
** ALTER TABLE command. The first argument is the text of a CREATE TABLE or
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    30
** CREATE INDEX command. The second is a table name. The table name in 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    31
** the CREATE TABLE or CREATE INDEX statement is replaced with the third
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    32
** argument and the result returned. Examples:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    33
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    34
** sqlite_rename_table('CREATE TABLE abc(a, b, c)', 'def')
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    35
**     -> 'CREATE TABLE def(a, b, c)'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    36
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    37
** sqlite_rename_table('CREATE INDEX i ON abc(a)', 'def')
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    38
**     -> 'CREATE INDEX i ON def(a, b, c)'
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    39
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    40
static void renameTableFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    41
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    42
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    43
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    44
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    45
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    46
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    47
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    48
  int token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    49
  Token tname;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    50
  unsigned char const *zCsr = zSql;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    51
  int len = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    52
  char *zRet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    53
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    54
  sqlite3 *db = (sqlite3 *)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    55
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    56
  /* The principle used to locate the table name in the CREATE TABLE 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    57
  ** statement is that the table name is the first token that is immediatedly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    58
  ** followed by a left parenthesis - TK_LP - or "USING" TK_USING.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    59
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    60
  if( zSql ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    61
    do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    62
      if( !*zCsr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    63
        /* Ran out of input before finding an opening bracket. Return NULL. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    64
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    65
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    66
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    67
      /* Store the token that zCsr points to in tname. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    68
      tname.z = zCsr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    69
      tname.n = len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    70
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    71
      /* Advance zCsr to the next token. Store that token type in 'token',
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    72
      ** and its length in 'len' (to be used next iteration of this loop).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    73
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    74
      do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    75
        zCsr += len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    76
        len = sqlite3GetToken(zCsr, &token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    77
      } while( token==TK_SPACE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    78
      assert( len>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    79
    } while( token!=TK_LP && token!=TK_USING );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    80
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    81
    zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    82
       zTableName, tname.z+tname.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    83
    sqlite3_result_text(context, zRet, -1, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    84
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    85
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    86
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    87
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    88
/* This function is used by SQL generated to implement the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    89
** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    90
** statement. The second is a table name. The table name in the CREATE 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    91
** TRIGGER statement is replaced with the third argument and the result 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    92
** returned. This is analagous to renameTableFunc() above, except for CREATE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    93
** TRIGGER, not CREATE INDEX and CREATE TABLE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    94
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    95
static void renameTriggerFunc(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    96
  sqlite3_context *context,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    97
  int argc,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    98
  sqlite3_value **argv
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
    99
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   100
  unsigned char const *zSql = sqlite3_value_text(argv[0]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   101
  unsigned char const *zTableName = sqlite3_value_text(argv[1]);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   102
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   103
  int token;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   104
  Token tname;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   105
  int dist = 3;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   106
  unsigned char const *zCsr = zSql;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   107
  int len = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   108
  char *zRet;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   109
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   110
  sqlite3 *db = (sqlite3 *)sqlite3_user_data(context);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   111
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   112
  /* The principle used to locate the table name in the CREATE TRIGGER 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   113
  ** statement is that the table name is the first token that is immediatedly
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   114
  ** preceded by either TK_ON or TK_DOT and immediatedly followed by one
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   115
  ** of TK_WHEN, TK_BEGIN or TK_FOR.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   116
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   117
  if( zSql ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   118
    do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   119
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   120
      if( !*zCsr ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   121
        /* Ran out of input before finding the table name. Return NULL. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   122
        return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   123
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   124
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   125
      /* Store the token that zCsr points to in tname. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   126
      tname.z = zCsr;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   127
      tname.n = len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   128
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   129
      /* Advance zCsr to the next token. Store that token type in 'token',
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   130
      ** and its length in 'len' (to be used next iteration of this loop).
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   131
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   132
      do {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   133
        zCsr += len;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   134
        len = sqlite3GetToken(zCsr, &token);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   135
      }while( token==TK_SPACE );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   136
      assert( len>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   137
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   138
      /* Variable 'dist' stores the number of tokens read since the most
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   139
      ** recent TK_DOT or TK_ON. This means that when a WHEN, FOR or BEGIN 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   140
      ** token is read and 'dist' equals 2, the condition stated above
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   141
      ** to be met.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   142
      **
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   143
      ** Note that ON cannot be a database, table or column name, so
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   144
      ** there is no need to worry about syntax like 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   145
      ** "CREATE TRIGGER ... ON ON.ON BEGIN ..." etc.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   146
      */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   147
      dist++;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   148
      if( token==TK_DOT || token==TK_ON ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   149
        dist = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   150
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   151
    } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   152
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   153
    /* Variable tname now contains the token that is the old table-name
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   154
    ** in the CREATE TRIGGER statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   155
    */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   156
    zRet = sqlite3MPrintf(db, "%.*s%Q%s", tname.z - zSql, zSql, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   157
       zTableName, tname.z+tname.n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   158
    sqlite3_result_text(context, zRet, -1, sqlite3_free);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   159
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   160
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   161
#endif   /* !SQLITE_OMIT_TRIGGER */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   162
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   163
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   164
** Register built-in functions used to help implement ALTER TABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   165
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   166
void sqlite3AlterFunctions(sqlite3 *db){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   167
  static const struct {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   168
     char *zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   169
     signed char nArg;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   170
     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   171
  } aFuncs[] = {
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   172
    { "sqlite_rename_table",    2, renameTableFunc},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   173
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   174
    { "sqlite_rename_trigger",  2, renameTriggerFunc},
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   175
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   176
  };
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   177
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   178
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   179
  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   180
    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   181
        SQLITE_UTF8, (void *)db, aFuncs[i].xFunc, 0, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   182
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   183
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   184
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   185
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   186
** Generate the text of a WHERE expression which can be used to select all
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   187
** temporary triggers on table pTab from the sqlite_temp_master table. If
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   188
** table pTab has no temporary triggers, or is itself stored in the 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   189
** temporary database, NULL is returned.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   190
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   191
static char *whereTempTriggers(Parse *pParse, Table *pTab){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   192
  Trigger *pTrig;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   193
  char *zWhere = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   194
  char *tmp = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   195
  const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   196
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   197
  /* If the table is not located in the temp-db (in which case NULL is 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   198
  ** returned, loop through the tables list of triggers. For each trigger
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   199
  ** that is not part of the temp-db schema, add a clause to the WHERE 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   200
  ** expression being built up in zWhere.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   201
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   202
  if( pTab->pSchema!=pTempSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   203
    sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   204
    for( pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   205
      if( pTrig->pSchema==pTempSchema ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   206
        if( !zWhere ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   207
          zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->name);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   208
        }else{
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   209
          tmp = zWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   210
          zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   211
          sqlite3_free(tmp);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   212
        }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   213
      }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   214
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   215
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   216
  return zWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   217
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   218
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   219
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   220
** Generate code to drop and reload the internal representation of table
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   221
** pTab from the database, including triggers and temporary triggers.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   222
** Argument zName is the name of the table in the database schema at
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   223
** the time the generated code is executed. This can be different from
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   224
** pTab->zName if this function is being called to code part of an 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   225
** "ALTER TABLE RENAME TO" statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   226
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   227
static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   228
  Vdbe *v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   229
  char *zWhere;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   230
  int iDb;                   /* Index of database containing pTab */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   231
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   232
  Trigger *pTrig;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   233
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   234
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   235
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   236
  if( !v ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   237
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   238
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   239
  assert( iDb>=0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   240
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   241
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   242
  /* Drop any table triggers from the internal schema. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   243
  for(pTrig=pTab->pTrigger; pTrig; pTrig=pTrig->pNext){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   244
    int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   245
    assert( iTrigDb==iDb || iTrigDb==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   246
    sqlite3VdbeOp3(v, OP_DropTrigger, iTrigDb, 0, pTrig->name, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   247
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   248
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   249
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   250
  /* Drop the table and index from the internal schema */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   251
  sqlite3VdbeOp3(v, OP_DropTable, iDb, 0, pTab->zName, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   252
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   253
  /* Reload the table, index and permanent trigger schemas. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   254
  zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   255
  if( !zWhere ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   256
  sqlite3VdbeOp3(v, OP_ParseSchema, iDb, 0, zWhere, P3_DYNAMIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   257
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   258
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   259
  /* Now, if the table is not stored in the temp database, reload any temp 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   260
  ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   261
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   262
  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   263
    sqlite3VdbeOp3(v, OP_ParseSchema, 1, 0, zWhere, P3_DYNAMIC);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   264
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   265
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   266
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   267
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   268
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   269
** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   270
** command. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   271
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   272
void sqlite3AlterRenameTable(
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   273
  Parse *pParse,            /* Parser context. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   274
  SrcList *pSrc,            /* The table to rename. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   275
  Token *pName              /* The new table name. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   276
){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   277
  int iDb;                  /* Database that contains the table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   278
  char *zDb;                /* Name of database iDb */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   279
  Table *pTab;              /* Table being renamed */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   280
  char *zName = 0;          /* NULL-terminated version of pName */ 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   281
  sqlite3 *db = pParse->db; /* Database connection */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   282
  int nTabName;             /* Number of UTF-8 characters in zTabName */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   283
  const char *zTabName;     /* Original name of the table */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   284
  Vdbe *v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   285
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   286
  char *zWhere = 0;         /* Where clause to locate temp triggers */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   287
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   288
  int isVirtualRename = 0;  /* True if this is a v-table with an xRename() */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   289
  
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   290
  if( db->mallocFailed ) goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   291
  assert( pSrc->nSrc==1 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   292
  assert( sqlite3BtreeHoldsAllMutexes(pParse->db) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   293
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   294
  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   295
  if( !pTab ) goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   296
  iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   297
  zDb = db->aDb[iDb].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   298
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   299
  /* Get a NULL terminated version of the new table name. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   300
  zName = sqlite3NameFromToken(db, pName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   301
  if( !zName ) goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   302
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   303
  /* Check that a table or index named 'zName' does not already exist
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   304
  ** in database iDb. If so, this is an error.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   305
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   306
  if( sqlite3FindTable(db, zName, zDb) || sqlite3FindIndex(db, zName, zDb) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   307
    sqlite3ErrorMsg(pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   308
        "there is already another table or index with this name: %s", zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   309
    goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   310
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   311
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   312
  /* Make sure it is not a system table being altered, or a reserved name
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   313
  ** that the table is being renamed to.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   314
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   315
  if( strlen(pTab->zName)>6 && 0==sqlite3StrNICmp(pTab->zName, "sqlite_", 7) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   316
    sqlite3ErrorMsg(pParse, "table %s may not be altered", pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   317
    goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   318
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   319
  if( SQLITE_OK!=sqlite3CheckObjectName(pParse, zName) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   320
    goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   321
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   322
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   323
#ifndef SQLITE_OMIT_VIEW
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   324
  if( pTab->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   325
    sqlite3ErrorMsg(pParse, "view %s may not be altered", pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   326
    goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   327
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   328
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   329
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   330
#ifndef SQLITE_OMIT_AUTHORIZATION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   331
  /* Invoke the authorization callback. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   332
  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   333
    goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   334
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   335
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   336
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   337
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   338
  if( sqlite3ViewGetColumnNames(pParse, pTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   339
    goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   340
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   341
  if( IsVirtual(pTab) && pTab->pMod->pModule->xRename ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   342
    isVirtualRename = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   343
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   344
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   345
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   346
  /* Begin a transaction and code the VerifyCookie for database iDb. 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   347
  ** Then modify the schema cookie (since the ALTER TABLE modifies the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   348
  ** schema). Open a statement transaction if the table is a virtual
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   349
  ** table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   350
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   351
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   352
  if( v==0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   353
    goto exit_rename_table;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   354
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   355
  sqlite3BeginWriteOperation(pParse, isVirtualRename, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   356
  sqlite3ChangeCookie(db, v, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   357
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   358
  /* If this is a virtual table, invoke the xRename() function if
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   359
  ** one is defined. The xRename() callback will modify the names
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   360
  ** of any resources used by the v-table implementation (including other
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   361
  ** SQLite tables) that are identified by the name of the virtual table.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   362
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   363
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   364
  if( isVirtualRename ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   365
    sqlite3VdbeOp3(v, OP_String8, 0, 0, zName, 0);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   366
    sqlite3VdbeOp3(v, OP_VRename, 0, 0, (const char*)pTab->pVtab, P3_VTAB);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   367
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   368
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   369
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   370
  /* figure out how many UTF-8 characters are in zName */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   371
  zTabName = pTab->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   372
  nTabName = sqlite3Utf8CharLen(zTabName, -1);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   373
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   374
  /* Modify the sqlite_master table to use the new table name. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   375
  sqlite3NestedParse(pParse,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   376
      "UPDATE %Q.%s SET "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   377
#ifdef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   378
          "sql = sqlite_rename_table(sql, %Q), "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   379
#else
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   380
          "sql = CASE "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   381
            "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)"
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   382
            "ELSE sqlite_rename_table(sql, %Q) END, "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   383
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   384
          "tbl_name = %Q, "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   385
          "name = CASE "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   386
            "WHEN type='table' THEN %Q "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   387
            "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   388
             "'sqlite_autoindex_' || %Q || substr(name,%d+18) "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   389
            "ELSE name END "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   390
      "WHERE tbl_name=%Q AND "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   391
          "(type='table' OR type='index' OR type='trigger');", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   392
      zDb, SCHEMA_TABLE(iDb), zName, zName, zName, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   393
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   394
      zName,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   395
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   396
      zName, nTabName, zTabName
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   397
  );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   398
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   399
#ifndef SQLITE_OMIT_AUTOINCREMENT
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   400
  /* If the sqlite_sequence table exists in this database, then update 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   401
  ** it with the new table name.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   402
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   403
  if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   404
    sqlite3NestedParse(pParse,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   405
        "UPDATE %Q.sqlite_sequence set name = %Q WHERE name = %Q",
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   406
        zDb, zName, pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   407
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   408
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   409
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   410
#ifndef SQLITE_OMIT_TRIGGER
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   411
  /* If there are TEMP triggers on this table, modify the sqlite_temp_master
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   412
  ** table. Don't do this if the table being ALTERed is itself located in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   413
  ** the temp database.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   414
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   415
  if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   416
    sqlite3NestedParse(pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   417
        "UPDATE sqlite_temp_master SET "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   418
            "sql = sqlite_rename_trigger(sql, %Q), "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   419
            "tbl_name = %Q "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   420
            "WHERE %s;", zName, zName, zWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   421
    sqlite3_free(zWhere);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   422
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   423
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   424
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   425
  /* Drop and reload the internal table schema. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   426
  reloadTableSchema(pParse, pTab, zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   427
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   428
exit_rename_table:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   429
  sqlite3SrcListDelete(pSrc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   430
  sqlite3_free(zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   431
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   432
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   433
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   434
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   435
** This function is called after an "ALTER TABLE ... ADD" statement
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   436
** has been parsed. Argument pColDef contains the text of the new
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   437
** column definition.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   438
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   439
** The Table structure pParse->pNewTable was extended to include
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   440
** the new column during parsing.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   441
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   442
void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   443
  Table *pNew;              /* Copy of pParse->pNewTable */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   444
  Table *pTab;              /* Table being altered */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   445
  int iDb;                  /* Database number */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   446
  const char *zDb;          /* Database name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   447
  const char *zTab;         /* Table name */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   448
  char *zCol;               /* Null-terminated column definition */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   449
  Column *pCol;             /* The new column */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   450
  Expr *pDflt;              /* Default value for the new column */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   451
  sqlite3 *db;              /* The database connection; */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   452
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   453
  if( pParse->nErr ) return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   454
  pNew = pParse->pNewTable;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   455
  assert( pNew );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   456
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   457
  db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   458
  assert( sqlite3BtreeHoldsAllMutexes(db) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   459
  iDb = sqlite3SchemaToIndex(db, pNew->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   460
  zDb = db->aDb[iDb].zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   461
  zTab = pNew->zName;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   462
  pCol = &pNew->aCol[pNew->nCol-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   463
  pDflt = pCol->pDflt;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   464
  pTab = sqlite3FindTable(db, zTab, zDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   465
  assert( pTab );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   466
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   467
#ifndef SQLITE_OMIT_AUTHORIZATION
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   468
  /* Invoke the authorization callback. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   469
  if( sqlite3AuthCheck(pParse, SQLITE_ALTER_TABLE, zDb, pTab->zName, 0) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   470
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   471
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   472
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   473
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   474
  /* If the default value for the new column was specified with a 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   475
  ** literal NULL, then set pDflt to 0. This simplifies checking
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   476
  ** for an SQL NULL default below.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   477
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   478
  if( pDflt && pDflt->op==TK_NULL ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   479
    pDflt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   480
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   481
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   482
  /* Check that the new column is not specified as PRIMARY KEY or UNIQUE.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   483
  ** If there is a NOT NULL constraint, then the default value for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   484
  ** column must not be NULL.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   485
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   486
  if( pCol->isPrimKey ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   487
    sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   488
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   489
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   490
  if( pNew->pIndex ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   491
    sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   492
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   493
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   494
  if( pCol->notNull && !pDflt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   495
    sqlite3ErrorMsg(pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   496
        "Cannot add a NOT NULL column with default value NULL");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   497
    return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   498
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   499
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   500
  /* Ensure the default expression is something that sqlite3ValueFromExpr()
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   501
  ** can handle (i.e. not CURRENT_TIME etc.)
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   502
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   503
  if( pDflt ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   504
    sqlite3_value *pVal;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   505
    if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   506
      db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   507
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   508
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   509
    if( !pVal ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   510
      sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   511
      return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   512
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   513
    sqlite3ValueFree(pVal);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   514
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   515
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   516
  /* Modify the CREATE TABLE statement. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   517
  zCol = sqlite3DbStrNDup(db, (char*)pColDef->z, pColDef->n);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   518
  if( zCol ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   519
    char *zEnd = &zCol[pColDef->n-1];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   520
    while( (zEnd>zCol && *zEnd==';') || isspace(*(unsigned char *)zEnd) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   521
      *zEnd-- = '\0';
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   522
    }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   523
    sqlite3NestedParse(pParse, 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   524
        "UPDATE %Q.%s SET "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   525
          "sql = substr(sql,1,%d) || ', ' || %Q || substr(sql,%d) "
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   526
        "WHERE type = 'table' AND name = %Q", 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   527
      zDb, SCHEMA_TABLE(iDb), pNew->addColOffset, zCol, pNew->addColOffset+1,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   528
      zTab
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   529
    );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   530
    sqlite3_free(zCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   531
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   532
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   533
  /* If the default value of the new column is NULL, then set the file
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   534
  ** format to 2. If the default value of the new column is not NULL,
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   535
  ** the file format becomes 3.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   536
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   537
  sqlite3MinimumFileFormat(pParse, iDb, pDflt ? 3 : 2);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   538
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   539
  /* Reload the schema of the modified table. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   540
  reloadTableSchema(pParse, pTab, pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   541
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   542
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   543
/*
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   544
** This function is called by the parser after the table-name in
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   545
** an "ALTER TABLE <table-name> ADD" statement is parsed. Argument 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   546
** pSrc is the full-name of the table being altered.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   547
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   548
** This routine makes a (partial) copy of the Table structure
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   549
** for the table being altered and sets Parse.pNewTable to point
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   550
** to it. Routines called by the parser as the column definition
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   551
** is parsed (i.e. sqlite3AddColumn()) add the new Column data to 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   552
** the copy. The copy of the Table structure is deleted by tokenize.c 
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   553
** after parsing is finished.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   554
**
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   555
** Routine sqlite3AlterFinishAddColumn() will be called to complete
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   556
** coding the "ALTER TABLE ... ADD" statement.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   557
*/
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   558
void sqlite3AlterBeginAddColumn(Parse *pParse, SrcList *pSrc){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   559
  Table *pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   560
  Table *pTab;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   561
  Vdbe *v;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   562
  int iDb;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   563
  int i;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   564
  int nAlloc;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   565
  sqlite3 *db = pParse->db;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   566
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   567
  /* Look up the table being altered. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   568
  assert( pParse->pNewTable==0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   569
  assert( sqlite3BtreeHoldsAllMutexes(db) );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   570
  if( db->mallocFailed ) goto exit_begin_add_column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   571
  pTab = sqlite3LocateTable(pParse, pSrc->a[0].zName, pSrc->a[0].zDatabase);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   572
  if( !pTab ) goto exit_begin_add_column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   573
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   574
#ifndef SQLITE_OMIT_VIRTUALTABLE
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   575
  if( IsVirtual(pTab) ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   576
    sqlite3ErrorMsg(pParse, "virtual tables may not be altered");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   577
    goto exit_begin_add_column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   578
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   579
#endif
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   580
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   581
  /* Make sure this is not an attempt to ALTER a view. */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   582
  if( pTab->pSelect ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   583
    sqlite3ErrorMsg(pParse, "Cannot add a column to a view");
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   584
    goto exit_begin_add_column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   585
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   586
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   587
  assert( pTab->addColOffset>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   588
  iDb = sqlite3SchemaToIndex(db, pTab->pSchema);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   589
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   590
  /* Put a copy of the Table struct in Parse.pNewTable for the
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   591
  ** sqlite3AddColumn() function and friends to modify.
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   592
  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   593
  pNew = (Table*)sqlite3DbMallocZero(db, sizeof(Table));
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   594
  if( !pNew ) goto exit_begin_add_column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   595
  pParse->pNewTable = pNew;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   596
  pNew->nRef = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   597
  pNew->nCol = pTab->nCol;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   598
  assert( pNew->nCol>0 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   599
  nAlloc = (((pNew->nCol-1)/8)*8)+8;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   600
  assert( nAlloc>=pNew->nCol && nAlloc%8==0 && nAlloc-pNew->nCol<8 );
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   601
  pNew->aCol = (Column*)sqlite3DbMallocZero(db, sizeof(Column)*nAlloc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   602
  pNew->zName = sqlite3DbStrDup(db, pTab->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   603
  if( !pNew->aCol || !pNew->zName ){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   604
    db->mallocFailed = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   605
    goto exit_begin_add_column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   606
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   607
  memcpy(pNew->aCol, pTab->aCol, sizeof(Column)*pNew->nCol);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   608
  for(i=0; i<pNew->nCol; i++){
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   609
    Column *pCol = &pNew->aCol[i];
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   610
    pCol->zName = sqlite3DbStrDup(db, pCol->zName);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   611
    pCol->zColl = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   612
    pCol->zType = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   613
    pCol->pDflt = 0;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   614
  }
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   615
  pNew->pSchema = db->aDb[iDb].pSchema;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   616
  pNew->addColOffset = pTab->addColOffset;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   617
  pNew->nRef = 1;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   618
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   619
  /* Begin a transaction and increment the schema cookie.  */
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   620
  sqlite3BeginWriteOperation(pParse, 0, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   621
  v = sqlite3GetVdbe(pParse);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   622
  if( !v ) goto exit_begin_add_column;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   623
  sqlite3ChangeCookie(db, v, iDb);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   624
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   625
exit_begin_add_column:
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   626
  sqlite3SrcListDelete(pSrc);
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   627
  return;
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   628
}
29cda98b007e Initial import of Podcatcher from the Bergamot project
skip
parents:
diff changeset
   629
#endif  /* SQLITE_ALTER_TABLE */