engine/sqlite/src/alter.cpp
author Lars Persson <lars.persson@embeddev.se>
Wed, 31 Mar 2010 18:09:02 +0200
changeset 64 b52f6033af15
parent 2 29cda98b007e
permissions -rw-r--r--
Add so image conversion is done in feedinfo if image already exist. Check in feedengine if image exist from previous database(files might exist, even though the db is corrupt.
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 */