| OLD | NEW |
| 1 /* | 1 /* |
| 2 ** 2005 February 15 | 2 ** 2005 February 15 |
| 3 ** | 3 ** |
| 4 ** The author disclaims copyright to this source code. In place of | 4 ** The author disclaims copyright to this source code. In place of |
| 5 ** a legal notice, here is a blessing: | 5 ** a legal notice, here is a blessing: |
| 6 ** | 6 ** |
| 7 ** May you do good and not evil. | 7 ** May you do good and not evil. |
| 8 ** May you find forgiveness for yourself and forgive others. | 8 ** May you find forgiveness for yourself and forgive others. |
| 9 ** May you share freely, never taking more than you give. | 9 ** May you share freely, never taking more than you give. |
| 10 ** | 10 ** |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 70 /* Advance zCsr to the next token. Store that token type in 'token', | 70 /* Advance zCsr to the next token. Store that token type in 'token', |
| 71 ** and its length in 'len' (to be used next iteration of this loop). | 71 ** and its length in 'len' (to be used next iteration of this loop). |
| 72 */ | 72 */ |
| 73 do { | 73 do { |
| 74 zCsr += len; | 74 zCsr += len; |
| 75 len = sqlite3GetToken(zCsr, &token); | 75 len = sqlite3GetToken(zCsr, &token); |
| 76 } while( token==TK_SPACE ); | 76 } while( token==TK_SPACE ); |
| 77 assert( len>0 ); | 77 assert( len>0 ); |
| 78 } while( token!=TK_LP && token!=TK_USING ); | 78 } while( token!=TK_LP && token!=TK_USING ); |
| 79 | 79 |
| 80 zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, | 80 zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), |
| 81 zTableName, tname.z+tname.n); | 81 zSql, zTableName, tname.z+tname.n); |
| 82 sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); | 82 sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); |
| 83 } | 83 } |
| 84 } | 84 } |
| 85 | 85 |
| 86 /* | 86 /* |
| 87 ** This C function implements an SQL user function that is used by SQL code | 87 ** This C function implements an SQL user function that is used by SQL code |
| 88 ** generated by the ALTER TABLE ... RENAME command to modify the definition | 88 ** generated by the ALTER TABLE ... RENAME command to modify the definition |
| 89 ** of any foreign key constraints that use the table being renamed as the | 89 ** of any foreign key constraints that use the table being renamed as the |
| 90 ** parent table. It is passed three arguments: | 90 ** parent table. It is passed three arguments: |
| 91 ** | 91 ** |
| (...skipping 17 matching lines...) Expand all Loading... |
| 109 char *zResult; | 109 char *zResult; |
| 110 unsigned char const *zInput = sqlite3_value_text(argv[0]); | 110 unsigned char const *zInput = sqlite3_value_text(argv[0]); |
| 111 unsigned char const *zOld = sqlite3_value_text(argv[1]); | 111 unsigned char const *zOld = sqlite3_value_text(argv[1]); |
| 112 unsigned char const *zNew = sqlite3_value_text(argv[2]); | 112 unsigned char const *zNew = sqlite3_value_text(argv[2]); |
| 113 | 113 |
| 114 unsigned const char *z; /* Pointer to token */ | 114 unsigned const char *z; /* Pointer to token */ |
| 115 int n; /* Length of token z */ | 115 int n; /* Length of token z */ |
| 116 int token; /* Type of token */ | 116 int token; /* Type of token */ |
| 117 | 117 |
| 118 UNUSED_PARAMETER(NotUsed); | 118 UNUSED_PARAMETER(NotUsed); |
| 119 if( zInput==0 || zOld==0 ) return; |
| 119 for(z=zInput; *z; z=z+n){ | 120 for(z=zInput; *z; z=z+n){ |
| 120 n = sqlite3GetToken(z, &token); | 121 n = sqlite3GetToken(z, &token); |
| 121 if( token==TK_REFERENCES ){ | 122 if( token==TK_REFERENCES ){ |
| 122 char *zParent; | 123 char *zParent; |
| 123 do { | 124 do { |
| 124 z += n; | 125 z += n; |
| 125 n = sqlite3GetToken(z, &token); | 126 n = sqlite3GetToken(z, &token); |
| 126 }while( token==TK_SPACE ); | 127 }while( token==TK_SPACE ); |
| 127 | 128 |
| 128 zParent = sqlite3DbStrNDup(db, (const char *)z, n); | 129 zParent = sqlite3DbStrNDup(db, (const char *)z, n); |
| 129 if( zParent==0 ) break; | 130 if( zParent==0 ) break; |
| 130 sqlite3Dequote(zParent); | 131 sqlite3Dequote(zParent); |
| 131 if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ | 132 if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ |
| 132 char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", | 133 char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", |
| 133 (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew | 134 (zOutput?zOutput:""), (int)(z-zInput), zInput, (const char *)zNew |
| 134 ); | 135 ); |
| 135 sqlite3DbFree(db, zOutput); | 136 sqlite3DbFree(db, zOutput); |
| 136 zOutput = zOut; | 137 zOutput = zOut; |
| 137 zInput = &z[n]; | 138 zInput = &z[n]; |
| 138 } | 139 } |
| 139 sqlite3DbFree(db, zParent); | 140 sqlite3DbFree(db, zParent); |
| 140 } | 141 } |
| 141 } | 142 } |
| 142 | 143 |
| 143 zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), | 144 zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), |
| (...skipping 22 matching lines...) Expand all Loading... |
| 166 Token tname; | 167 Token tname; |
| 167 int dist = 3; | 168 int dist = 3; |
| 168 unsigned char const *zCsr = zSql; | 169 unsigned char const *zCsr = zSql; |
| 169 int len = 0; | 170 int len = 0; |
| 170 char *zRet; | 171 char *zRet; |
| 171 sqlite3 *db = sqlite3_context_db_handle(context); | 172 sqlite3 *db = sqlite3_context_db_handle(context); |
| 172 | 173 |
| 173 UNUSED_PARAMETER(NotUsed); | 174 UNUSED_PARAMETER(NotUsed); |
| 174 | 175 |
| 175 /* The principle used to locate the table name in the CREATE TRIGGER | 176 /* The principle used to locate the table name in the CREATE TRIGGER |
| 176 ** statement is that the table name is the first token that is immediatedly | 177 ** statement is that the table name is the first token that is immediately |
| 177 ** preceded by either TK_ON or TK_DOT and immediatedly followed by one | 178 ** preceded by either TK_ON or TK_DOT and immediately followed by one |
| 178 ** of TK_WHEN, TK_BEGIN or TK_FOR. | 179 ** of TK_WHEN, TK_BEGIN or TK_FOR. |
| 179 */ | 180 */ |
| 180 if( zSql ){ | 181 if( zSql ){ |
| 181 do { | 182 do { |
| 182 | 183 |
| 183 if( !*zCsr ){ | 184 if( !*zCsr ){ |
| 184 /* Ran out of input before finding the table name. Return NULL. */ | 185 /* Ran out of input before finding the table name. Return NULL. */ |
| 185 return; | 186 return; |
| 186 } | 187 } |
| 187 | 188 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 209 */ | 210 */ |
| 210 dist++; | 211 dist++; |
| 211 if( token==TK_DOT || token==TK_ON ){ | 212 if( token==TK_DOT || token==TK_ON ){ |
| 212 dist = 0; | 213 dist = 0; |
| 213 } | 214 } |
| 214 } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); | 215 } while( dist!=2 || (token!=TK_WHEN && token!=TK_FOR && token!=TK_BEGIN) ); |
| 215 | 216 |
| 216 /* Variable tname now contains the token that is the old table-name | 217 /* Variable tname now contains the token that is the old table-name |
| 217 ** in the CREATE TRIGGER statement. | 218 ** in the CREATE TRIGGER statement. |
| 218 */ | 219 */ |
| 219 zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", ((u8*)tname.z) - zSql, zSql, | 220 zRet = sqlite3MPrintf(db, "%.*s\"%w\"%s", (int)(((u8*)tname.z) - zSql), |
| 220 zTableName, tname.z+tname.n); | 221 zSql, zTableName, tname.z+tname.n); |
| 221 sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); | 222 sqlite3_result_text(context, zRet, -1, SQLITE_DYNAMIC); |
| 222 } | 223 } |
| 223 } | 224 } |
| 224 #endif /* !SQLITE_OMIT_TRIGGER */ | 225 #endif /* !SQLITE_OMIT_TRIGGER */ |
| 225 | 226 |
| 226 /* | 227 /* |
| 227 ** Register built-in functions used to help implement ALTER TABLE | 228 ** Register built-in functions used to help implement ALTER TABLE |
| 228 */ | 229 */ |
| 229 void sqlite3AlterFunctions(void){ | 230 void sqlite3AlterFunctions(void){ |
| 230 static SQLITE_WSD FuncDef aAlterTableFuncs[] = { | 231 static SQLITE_WSD FuncDef aAlterTableFuncs[] = { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); | 352 sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); |
| 352 } | 353 } |
| 353 #endif | 354 #endif |
| 354 | 355 |
| 355 /* Drop the table and index from the internal schema. */ | 356 /* Drop the table and index from the internal schema. */ |
| 356 sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); | 357 sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); |
| 357 | 358 |
| 358 /* Reload the table, index and permanent trigger schemas. */ | 359 /* Reload the table, index and permanent trigger schemas. */ |
| 359 zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); | 360 zWhere = sqlite3MPrintf(pParse->db, "tbl_name=%Q", zName); |
| 360 if( !zWhere ) return; | 361 if( !zWhere ) return; |
| 361 sqlite3VdbeAddOp4(v, OP_ParseSchema, iDb, 0, 0, zWhere, P4_DYNAMIC); | 362 sqlite3VdbeAddParseSchemaOp(v, iDb, zWhere); |
| 362 | 363 |
| 363 #ifndef SQLITE_OMIT_TRIGGER | 364 #ifndef SQLITE_OMIT_TRIGGER |
| 364 /* Now, if the table is not stored in the temp database, reload any temp | 365 /* Now, if the table is not stored in the temp database, reload any temp |
| 365 ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. | 366 ** triggers. Don't use IN(...) in case SQLITE_OMIT_SUBQUERY is defined. |
| 366 */ | 367 */ |
| 367 if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ | 368 if( (zWhere=whereTempTriggers(pParse, pTab))!=0 ){ |
| 368 sqlite3VdbeAddOp4(v, OP_ParseSchema, 1, 0, 0, zWhere, P4_DYNAMIC); | 369 sqlite3VdbeAddParseSchemaOp(v, 1, zWhere); |
| 369 } | 370 } |
| 370 #endif | 371 #endif |
| 371 } | 372 } |
| 372 | 373 |
| 373 /* | 374 /* |
| 374 ** Parameter zName is the name of a table that is about to be altered | 375 ** Parameter zName is the name of a table that is about to be altered |
| 375 ** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). | 376 ** (either with ALTER TABLE ... RENAME TO or ALTER TABLE ... ADD COLUMN). |
| 376 ** If the table is a system table, this function leaves an error message | 377 ** If the table is a system table, this function leaves an error message |
| 377 ** in pParse->zErr (system tables may not be altered) and returns non-zero. | 378 ** in pParse->zErr (system tables may not be altered) and returns non-zero. |
| 378 ** | 379 ** |
| (...skipping 28 matching lines...) Expand all Loading... |
| 407 char *zWhere = 0; /* Where clause to locate temp triggers */ | 408 char *zWhere = 0; /* Where clause to locate temp triggers */ |
| 408 #endif | 409 #endif |
| 409 VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ | 410 VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ |
| 410 int savedDbFlags; /* Saved value of db->flags */ | 411 int savedDbFlags; /* Saved value of db->flags */ |
| 411 | 412 |
| 412 savedDbFlags = db->flags; | 413 savedDbFlags = db->flags; |
| 413 if( NEVER(db->mallocFailed) ) goto exit_rename_table; | 414 if( NEVER(db->mallocFailed) ) goto exit_rename_table; |
| 414 assert( pSrc->nSrc==1 ); | 415 assert( pSrc->nSrc==1 ); |
| 415 assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); | 416 assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); |
| 416 | 417 |
| 417 pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); | 418 pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); |
| 418 if( !pTab ) goto exit_rename_table; | 419 if( !pTab ) goto exit_rename_table; |
| 419 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); | 420 iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); |
| 420 zDb = db->aDb[iDb].zName; | 421 zDb = db->aDb[iDb].zName; |
| 421 db->flags |= SQLITE_PreferBuiltin; | 422 db->flags |= SQLITE_PreferBuiltin; |
| 422 | 423 |
| 423 /* Get a NULL terminated version of the new table name. */ | 424 /* Get a NULL terminated version of the new table name. */ |
| 424 zName = sqlite3NameFromToken(db, pName); | 425 zName = sqlite3NameFromToken(db, pName); |
| 425 if( !zName ) goto exit_rename_table; | 426 if( !zName ) goto exit_rename_table; |
| 426 | 427 |
| 427 /* Check that a table or index named 'zName' does not already exist | 428 /* Check that a table or index named 'zName' does not already exist |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 goto exit_rename_table; | 463 goto exit_rename_table; |
| 463 } | 464 } |
| 464 if( IsVirtual(pTab) ){ | 465 if( IsVirtual(pTab) ){ |
| 465 pVTab = sqlite3GetVTable(db, pTab); | 466 pVTab = sqlite3GetVTable(db, pTab); |
| 466 if( pVTab->pVtab->pModule->xRename==0 ){ | 467 if( pVTab->pVtab->pModule->xRename==0 ){ |
| 467 pVTab = 0; | 468 pVTab = 0; |
| 468 } | 469 } |
| 469 } | 470 } |
| 470 #endif | 471 #endif |
| 471 | 472 |
| 472 /* Begin a transaction and code the VerifyCookie for database iDb. | 473 /* Begin a transaction for database iDb. |
| 473 ** Then modify the schema cookie (since the ALTER TABLE modifies the | 474 ** Then modify the schema cookie (since the ALTER TABLE modifies the |
| 474 ** schema). Open a statement transaction if the table is a virtual | 475 ** schema). Open a statement transaction if the table is a virtual |
| 475 ** table. | 476 ** table. |
| 476 */ | 477 */ |
| 477 v = sqlite3GetVdbe(pParse); | 478 v = sqlite3GetVdbe(pParse); |
| 478 if( v==0 ){ | 479 if( v==0 ){ |
| 479 goto exit_rename_table; | 480 goto exit_rename_table; |
| 480 } | 481 } |
| 481 sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); | 482 sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); |
| 482 sqlite3ChangeCookie(pParse, iDb); | 483 sqlite3ChangeCookie(pParse, iDb); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 523 "sql = CASE " | 524 "sql = CASE " |
| 524 "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" | 525 "WHEN type = 'trigger' THEN sqlite_rename_trigger(sql, %Q)" |
| 525 "ELSE sqlite_rename_table(sql, %Q) END, " | 526 "ELSE sqlite_rename_table(sql, %Q) END, " |
| 526 #endif | 527 #endif |
| 527 "tbl_name = %Q, " | 528 "tbl_name = %Q, " |
| 528 "name = CASE " | 529 "name = CASE " |
| 529 "WHEN type='table' THEN %Q " | 530 "WHEN type='table' THEN %Q " |
| 530 "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " | 531 "WHEN name LIKE 'sqlite_autoindex%%' AND type='index' THEN " |
| 531 "'sqlite_autoindex_' || %Q || substr(name,%d+18) " | 532 "'sqlite_autoindex_' || %Q || substr(name,%d+18) " |
| 532 "ELSE name END " | 533 "ELSE name END " |
| 533 "WHERE tbl_name=%Q AND " | 534 "WHERE tbl_name=%Q COLLATE nocase AND " |
| 534 "(type='table' OR type='index' OR type='trigger');", | 535 "(type='table' OR type='index' OR type='trigger');", |
| 535 zDb, SCHEMA_TABLE(iDb), zName, zName, zName, | 536 zDb, SCHEMA_TABLE(iDb), zName, zName, zName, |
| 536 #ifndef SQLITE_OMIT_TRIGGER | 537 #ifndef SQLITE_OMIT_TRIGGER |
| 537 zName, | 538 zName, |
| 538 #endif | 539 #endif |
| 539 zName, nTabName, zTabName | 540 zName, nTabName, zTabName |
| 540 ); | 541 ); |
| 541 | 542 |
| 542 #ifndef SQLITE_OMIT_AUTOINCREMENT | 543 #ifndef SQLITE_OMIT_AUTOINCREMENT |
| 543 /* If the sqlite_sequence table exists in this database, then update | 544 /* If the sqlite_sequence table exists in this database, then update |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 ** If that allocation failed, we would have quit before reaching this | 599 ** If that allocation failed, we would have quit before reaching this |
| 599 ** point */ | 600 ** point */ |
| 600 if( ALWAYS(v) ){ | 601 if( ALWAYS(v) ){ |
| 601 int r1 = sqlite3GetTempReg(pParse); | 602 int r1 = sqlite3GetTempReg(pParse); |
| 602 int r2 = sqlite3GetTempReg(pParse); | 603 int r2 = sqlite3GetTempReg(pParse); |
| 603 int j1; | 604 int j1; |
| 604 sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); | 605 sqlite3VdbeAddOp3(v, OP_ReadCookie, iDb, r1, BTREE_FILE_FORMAT); |
| 605 sqlite3VdbeUsesBtree(v, iDb); | 606 sqlite3VdbeUsesBtree(v, iDb); |
| 606 sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); | 607 sqlite3VdbeAddOp2(v, OP_Integer, minFormat, r2); |
| 607 j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); | 608 j1 = sqlite3VdbeAddOp3(v, OP_Ge, r2, 0, r1); |
| 609 sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); VdbeCoverage(v); |
| 608 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); | 610 sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_FILE_FORMAT, r2); |
| 609 sqlite3VdbeJumpHere(v, j1); | 611 sqlite3VdbeJumpHere(v, j1); |
| 610 sqlite3ReleaseTempReg(pParse, r1); | 612 sqlite3ReleaseTempReg(pParse, r1); |
| 611 sqlite3ReleaseTempReg(pParse, r2); | 613 sqlite3ReleaseTempReg(pParse, r2); |
| 612 } | 614 } |
| 613 } | 615 } |
| 614 | 616 |
| 615 /* | 617 /* |
| 616 ** This function is called after an "ALTER TABLE ... ADD" statement | 618 ** This function is called after an "ALTER TABLE ... ADD" statement |
| 617 ** has been parsed. Argument pColDef contains the text of the new | 619 ** has been parsed. Argument pColDef contains the text of the new |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 ** for an SQL NULL default below. | 659 ** for an SQL NULL default below. |
| 658 */ | 660 */ |
| 659 if( pDflt && pDflt->op==TK_NULL ){ | 661 if( pDflt && pDflt->op==TK_NULL ){ |
| 660 pDflt = 0; | 662 pDflt = 0; |
| 661 } | 663 } |
| 662 | 664 |
| 663 /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. | 665 /* Check that the new column is not specified as PRIMARY KEY or UNIQUE. |
| 664 ** If there is a NOT NULL constraint, then the default value for the | 666 ** If there is a NOT NULL constraint, then the default value for the |
| 665 ** column must not be NULL. | 667 ** column must not be NULL. |
| 666 */ | 668 */ |
| 667 if( pCol->isPrimKey ){ | 669 if( pCol->colFlags & COLFLAG_PRIMKEY ){ |
| 668 sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); | 670 sqlite3ErrorMsg(pParse, "Cannot add a PRIMARY KEY column"); |
| 669 return; | 671 return; |
| 670 } | 672 } |
| 671 if( pNew->pIndex ){ | 673 if( pNew->pIndex ){ |
| 672 sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); | 674 sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); |
| 673 return; | 675 return; |
| 674 } | 676 } |
| 675 if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ | 677 if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ |
| 676 sqlite3ErrorMsg(pParse, | 678 sqlite3ErrorMsg(pParse, |
| 677 "Cannot add a REFERENCES column with non-NULL default value"); | 679 "Cannot add a REFERENCES column with non-NULL default value"); |
| 678 return; | 680 return; |
| 679 } | 681 } |
| 680 if( pCol->notNull && !pDflt ){ | 682 if( pCol->notNull && !pDflt ){ |
| 681 sqlite3ErrorMsg(pParse, | 683 sqlite3ErrorMsg(pParse, |
| 682 "Cannot add a NOT NULL column with default value NULL"); | 684 "Cannot add a NOT NULL column with default value NULL"); |
| 683 return; | 685 return; |
| 684 } | 686 } |
| 685 | 687 |
| 686 /* Ensure the default expression is something that sqlite3ValueFromExpr() | 688 /* Ensure the default expression is something that sqlite3ValueFromExpr() |
| 687 ** can handle (i.e. not CURRENT_TIME etc.) | 689 ** can handle (i.e. not CURRENT_TIME etc.) |
| 688 */ | 690 */ |
| 689 if( pDflt ){ | 691 if( pDflt ){ |
| 690 sqlite3_value *pVal; | 692 sqlite3_value *pVal = 0; |
| 691 if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ | 693 if( sqlite3ValueFromExpr(db, pDflt, SQLITE_UTF8, SQLITE_AFF_NONE, &pVal) ){ |
| 692 db->mallocFailed = 1; | 694 db->mallocFailed = 1; |
| 693 return; | 695 return; |
| 694 } | 696 } |
| 695 if( !pVal ){ | 697 if( !pVal ){ |
| 696 sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); | 698 sqlite3ErrorMsg(pParse, "Cannot add a column with non-constant default"); |
| 697 return; | 699 return; |
| 698 } | 700 } |
| 699 sqlite3ValueFree(pVal); | 701 sqlite3ValueFree(pVal); |
| 700 } | 702 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 750 Vdbe *v; | 752 Vdbe *v; |
| 751 int iDb; | 753 int iDb; |
| 752 int i; | 754 int i; |
| 753 int nAlloc; | 755 int nAlloc; |
| 754 sqlite3 *db = pParse->db; | 756 sqlite3 *db = pParse->db; |
| 755 | 757 |
| 756 /* Look up the table being altered. */ | 758 /* Look up the table being altered. */ |
| 757 assert( pParse->pNewTable==0 ); | 759 assert( pParse->pNewTable==0 ); |
| 758 assert( sqlite3BtreeHoldsAllMutexes(db) ); | 760 assert( sqlite3BtreeHoldsAllMutexes(db) ); |
| 759 if( db->mallocFailed ) goto exit_begin_add_column; | 761 if( db->mallocFailed ) goto exit_begin_add_column; |
| 760 pTab = sqlite3LocateTable(pParse, 0, pSrc->a[0].zName, pSrc->a[0].zDatabase); | 762 pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); |
| 761 if( !pTab ) goto exit_begin_add_column; | 763 if( !pTab ) goto exit_begin_add_column; |
| 762 | 764 |
| 763 #ifndef SQLITE_OMIT_VIRTUALTABLE | 765 #ifndef SQLITE_OMIT_VIRTUALTABLE |
| 764 if( IsVirtual(pTab) ){ | 766 if( IsVirtual(pTab) ){ |
| 765 sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); | 767 sqlite3ErrorMsg(pParse, "virtual tables may not be altered"); |
| 766 goto exit_begin_add_column; | 768 goto exit_begin_add_column; |
| 767 } | 769 } |
| 768 #endif | 770 #endif |
| 769 | 771 |
| 770 /* Make sure this is not an attempt to ALTER a view. */ | 772 /* Make sure this is not an attempt to ALTER a view. */ |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 sqlite3BeginWriteOperation(pParse, 0, iDb); | 819 sqlite3BeginWriteOperation(pParse, 0, iDb); |
| 818 v = sqlite3GetVdbe(pParse); | 820 v = sqlite3GetVdbe(pParse); |
| 819 if( !v ) goto exit_begin_add_column; | 821 if( !v ) goto exit_begin_add_column; |
| 820 sqlite3ChangeCookie(pParse, iDb); | 822 sqlite3ChangeCookie(pParse, iDb); |
| 821 | 823 |
| 822 exit_begin_add_column: | 824 exit_begin_add_column: |
| 823 sqlite3SrcListDelete(db, pSrc); | 825 sqlite3SrcListDelete(db, pSrc); |
| 824 return; | 826 return; |
| 825 } | 827 } |
| 826 #endif /* SQLITE_ALTER_TABLE */ | 828 #endif /* SQLITE_ALTER_TABLE */ |
| OLD | NEW |