When PRAGMA writable_schema=ON, allow ALTER TABLE to proceed even if there
are entries in the sqlite_schema table that do not parse. FossilOrigin-Name: fc4c82e5694cbdae13f2cb90e5368ba9f6b826a220a81de32ead2ffe1bc5f31f
This commit is contained in:
commit
dfce5b6dd5
15
manifest
15
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\sdocumentation\stypo.
|
||||
D 2022-02-05T11:13:26.863
|
||||
C When\sPRAGMA\swritable_schema=ON,\sallow\sALTER\sTABLE\sto\sproceed\seven\sif\sthere\nare\sentries\sin\sthe\ssqlite_schema\stable\sthat\sdo\snot\sparse.
|
||||
D 2022-02-05T12:39:17.862
|
||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||
@ -485,7 +485,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
|
||||
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
|
||||
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
|
||||
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
|
||||
F src/alter.c e8ac1df663bf4ec74920edd1299435f2a616d2404de0ac4013c151ea4e7a11f2
|
||||
F src/alter.c af5606a4d7f35a13ce577d96f222d5e6a3c0c23de5b903dd53f28f5a4f57a064
|
||||
F src/analyze.c 7518b99e07c5494111fe3bd867f28f804b6c5c1ad0703ec3d116de9bab3fa516
|
||||
F src/attach.c f26d400f3ffe2cdca01406bca70e5f58c5488bf165b4fc37c228136dfcf1b583
|
||||
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
|
||||
@ -657,7 +657,7 @@ F test/alter3.test ffc4ab29ce78a3517a66afd69b2730667e3471622509c283b2bd4c46f680f
|
||||
F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707
|
||||
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
|
||||
F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc
|
||||
F test/altercol.test 9471187fe155d9c4211ae185e104ff48ce8f114262ee1256cf1e110b339c725f
|
||||
F test/altercol.test 8465ca659c2c55a359cf16cc261df4fcb5c45a5f104a50827c337ae66c09dc15
|
||||
F test/altercorrupt.test 2e1d705342cf9d7de884518ddbb053fd52d7e60d2b8869b7b63b2fda68435c12
|
||||
F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e
|
||||
F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41
|
||||
@ -1943,8 +1943,9 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||
P 1ec747d1c34ced9877709dd306e674376e79145de08b9c316d12bc5e06efc03e
|
||||
R 95f25f88b2d33e679a50c06f4f2d2bb8
|
||||
P 1a7d8bb5ea0d0e0c250312f89a701c0274cfbcaef9cd71995fb83bf939668504 d4e6b9f0f7567b76760a667a701bca4d6158ade39f9a69d205b583c5a1c0c7f4
|
||||
R d0cb6fe0638aaa24f3c3d36cba7c33ac
|
||||
T +closed d4e6b9f0f7567b76760a667a701bca4d6158ade39f9a69d205b583c5a1c0c7f4
|
||||
U drh
|
||||
Z 3c08ad79df7ce58c2d82d934ab4c1b9f
|
||||
Z 7b88963ec7e0e977f5bbe33c546cedf5
|
||||
# Remove this line to create a well-formed Fossil manifest.
|
||||
|
@ -1 +1 @@
|
||||
1a7d8bb5ea0d0e0c250312f89a701c0274cfbcaef9cd71995fb83bf939668504
|
||||
fc4c82e5694cbdae13f2cb90e5368ba9f6b826a220a81de32ead2ffe1bc5f31f
|
52
src/alter.c
52
src/alter.c
@ -1427,7 +1427,7 @@ static void renameParseCleanup(Parse *pParse){
|
||||
/*
|
||||
** SQL function:
|
||||
**
|
||||
** sqlite_rename_column(zSql, iCol, bQuote, zNew, zTable, zOld)
|
||||
** sqlite_rename_column(SQL,TYPE,OBJ,DB,TABLE,COL,NEWNAME,QUOTE,TEMP)
|
||||
**
|
||||
** 0. zSql: SQL statement to rewrite
|
||||
** 1. type: Type of object ("table", "view" etc.)
|
||||
@ -1445,7 +1445,8 @@ static void renameParseCleanup(Parse *pParse){
|
||||
**
|
||||
** This function is used internally by the ALTER TABLE RENAME COLUMN command.
|
||||
** It is only accessible to SQL created using sqlite3NestedParse(). It is
|
||||
** not reachable from ordinary SQL passed into sqlite3_prepare().
|
||||
** not reachable from ordinary SQL passed into sqlite3_prepare() unless the
|
||||
** SQLITE_TESTCTRL_INTERNAL_FUNCTIONS test setting is enabled.
|
||||
*/
|
||||
static void renameColumnFunc(
|
||||
sqlite3_context *context,
|
||||
@ -1594,7 +1595,9 @@ static void renameColumnFunc(
|
||||
|
||||
renameColumnFunc_done:
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( sParse.zErrMsg ){
|
||||
if( sqlite3WritableSchema(db) ){
|
||||
sqlite3_result_value(context, argv[0]);
|
||||
}else if( sParse.zErrMsg ){
|
||||
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
|
||||
}else{
|
||||
sqlite3_result_error_code(context, rc);
|
||||
@ -1793,7 +1796,9 @@ static void renameTableFunc(
|
||||
rc = renameEditSql(context, &sCtx, zInput, zNew, bQuote);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
if( sParse.zErrMsg ){
|
||||
if( sqlite3WritableSchema(db) ){
|
||||
sqlite3_result_value(context, argv[3]);
|
||||
}else if( sParse.zErrMsg ){
|
||||
renameColumnParseError(context, "", argv[1], argv[2], &sParse);
|
||||
}else{
|
||||
sqlite3_result_error_code(context, rc);
|
||||
@ -1818,10 +1823,10 @@ static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){
|
||||
return WRC_Continue;
|
||||
}
|
||||
|
||||
/*
|
||||
** The implementation of an SQL scalar function that rewrites DDL statements
|
||||
** so that any string literals that use double-quotes are modified so that
|
||||
** they use single quotes.
|
||||
/* SQL function: sqlite_rename_quotefix(DB,SQL)
|
||||
**
|
||||
** Rewrite the DDL statement "SQL" so that any string literals that use
|
||||
** double-quotes use single quotes instead.
|
||||
**
|
||||
** Two arguments must be passed:
|
||||
**
|
||||
@ -1840,6 +1845,10 @@ static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){
|
||||
** returns the string:
|
||||
**
|
||||
** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1
|
||||
**
|
||||
** If there is a error in the input SQL, then raise an error, except
|
||||
** if PRAGMA writable_schema=ON, then just return the input string
|
||||
** unmodified following an error.
|
||||
*/
|
||||
static void renameQuotefixFunc(
|
||||
sqlite3_context *context,
|
||||
@ -1914,7 +1923,11 @@ static void renameQuotefixFunc(
|
||||
renameTokenFree(db, sCtx.pList);
|
||||
}
|
||||
if( rc!=SQLITE_OK ){
|
||||
sqlite3_result_error_code(context, rc);
|
||||
if( sqlite3WritableSchema(db) ){
|
||||
sqlite3_result_value(context, argv[1]);
|
||||
}else{
|
||||
sqlite3_result_error_code(context, rc);
|
||||
}
|
||||
}
|
||||
renameParseCleanup(&sParse);
|
||||
}
|
||||
@ -1926,7 +1939,8 @@ static void renameQuotefixFunc(
|
||||
sqlite3BtreeLeaveAll(db);
|
||||
}
|
||||
|
||||
/*
|
||||
/* Function: sqlite_rename_test(DB,SQL,TYPE,NAME,ISTEMP,WHEN,DQS)
|
||||
**
|
||||
** An SQL user function that checks that there are no parse or symbol
|
||||
** resolution problems in a CREATE TRIGGER|TABLE|VIEW|INDEX statement.
|
||||
** After an ALTER TABLE .. RENAME operation is performed and the schema
|
||||
@ -1941,11 +1955,13 @@ static void renameQuotefixFunc(
|
||||
** 5: "when" part of error message.
|
||||
** 6: True to disable the DQS quirk when parsing SQL.
|
||||
**
|
||||
** Unless it finds an error, this function normally returns NULL. However, it
|
||||
** returns integer value 1 if:
|
||||
** The return value is computed as follows:
|
||||
**
|
||||
** * the SQL argument creates a trigger, and
|
||||
** * the table that the trigger is attached to is in database zDb.
|
||||
** A. If an error is seen and not in PRAGMA writable_schema=ON mode,
|
||||
** then raise the error.
|
||||
** B. Else if a trigger is created and the the table that the trigger is
|
||||
** attached to is in database zDb, then return 1.
|
||||
** C. Otherwise return NULL.
|
||||
*/
|
||||
static void renameTableTest(
|
||||
sqlite3_context *context,
|
||||
@ -1990,12 +2006,16 @@ static void renameTableTest(
|
||||
if( rc==SQLITE_OK ){
|
||||
int i1 = sqlite3SchemaToIndex(db, sParse.pNewTrigger->pTabSchema);
|
||||
int i2 = sqlite3FindDbName(db, zDb);
|
||||
if( i1==i2 ) sqlite3_result_int(context, 1);
|
||||
if( i1==i2 ){
|
||||
/* Handle output case B */
|
||||
sqlite3_result_int(context, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK && zWhen ){
|
||||
if( rc!=SQLITE_OK && zWhen && !sqlite3WritableSchema(db) ){
|
||||
/* Output case A */
|
||||
renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
|
||||
}
|
||||
renameParseCleanup(&sParse);
|
||||
|
@ -553,8 +553,9 @@ do_execsql_test 13.1.3 {
|
||||
|
||||
sqlite3_db_config db DEFENSIVE 0
|
||||
do_execsql_test 13.1.4 {
|
||||
PRAGMA writable_schema = 1;
|
||||
PRAGMA writable_schema = ON;
|
||||
UPDATE sqlite_master SET sql = 'CREATE INDEX x1i ON x1(j)' WHERE name='x1i';
|
||||
PRAGMA writable_schema = OFF;
|
||||
} {}
|
||||
|
||||
do_catchsql_test 13.1.5 {
|
||||
@ -562,7 +563,9 @@ do_catchsql_test 13.1.5 {
|
||||
} {1 {error in index x1i: no such column: j}}
|
||||
|
||||
do_execsql_test 13.1.6 {
|
||||
PRAGMA writable_schema = ON;
|
||||
UPDATE sqlite_master SET sql = '' WHERE name='x1i';
|
||||
PRAGMA writable_schema = OFF;
|
||||
} {}
|
||||
|
||||
do_catchsql_test 13.1.7 {
|
||||
@ -570,7 +573,9 @@ do_catchsql_test 13.1.7 {
|
||||
} {1 {error in index x1i: }}
|
||||
|
||||
do_execsql_test 13.1.8 {
|
||||
PRAGMA writable_schema = ON;
|
||||
DELETE FROM sqlite_master WHERE name = 'x1i';
|
||||
PRAGMA writable_schema = OFF;
|
||||
}
|
||||
|
||||
do_execsql_test 13.2.0 {
|
||||
@ -861,5 +866,69 @@ do_execsql_test 23.0 {
|
||||
|
||||
} {ok {CREATE TABLE t1("x" "b",c)}}
|
||||
|
||||
# 2022-02-04
|
||||
# Do not complain about syntax errors in the schema if
|
||||
# in PRAGMA writable_schema=ON mode.
|
||||
#
|
||||
reset_db
|
||||
do_execsql_test 23.0 {
|
||||
CREATE TABLE t1(a INT, b REAL, c TEXT, d BLOB, e ANY);
|
||||
CREATE INDEX t1abx ON t1(a, b, a+b) WHERE c IS NOT NULL;
|
||||
CREATE VIEW t2 AS SELECT a+10, b*5.0, xyz FROM t1; -- unknown column "xyz"
|
||||
CREATE TABLE schema_copy(name TEXT, sql TEXT);
|
||||
INSERT INTO schema_copy(name,sql) SELECT name, sql FROM sqlite_schema WHERE sql IS NOT NULL;
|
||||
} {}
|
||||
do_catchsql_test 23.1 {
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
} {1 {error in view t2: no such column: xyz}}
|
||||
do_execsql_test 23.2 {
|
||||
SELECT name, sql FROM sqlite_master
|
||||
EXCEPT SELECT name, sql FROM schema_copy;
|
||||
} {}
|
||||
do_execsql_test 23.3 {
|
||||
BEGIN;
|
||||
PRAGMA writable_schema=ON;
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
PRAGMA writable_schema=OFF;
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE (name, sql) NOT IN (SELECT name, sql FROM schema_copy);
|
||||
ROLLBACK;
|
||||
} {t1}
|
||||
do_execsql_test 23.10 {
|
||||
DROP VIEW t2;
|
||||
CREATE TRIGGER r3 AFTER INSERT ON t1 BEGIN
|
||||
INSERT INTO t3(x,y) VALUES(new.a, new.b);
|
||||
INSERT INTO t4(p) VALUES(new.c); -- no such table "t4"
|
||||
END;
|
||||
DELETE FROM schema_copy;
|
||||
INSERT INTO schema_copy(name,sql) SELECT name, sql FROM sqlite_schema WHERE sql IS NOT NULL;
|
||||
} {}
|
||||
do_catchsql_test 23.11 {
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
} {1 {error in trigger r3: no such table: main.t3}}
|
||||
do_execsql_test 23.12 {
|
||||
SELECT name, sql FROM sqlite_master
|
||||
EXCEPT SELECT name, sql FROM schema_copy;
|
||||
} {}
|
||||
do_execsql_test 23.13 {
|
||||
BEGIN;
|
||||
PRAGMA writable_schema=ON;
|
||||
ALTER TABLE t1 RENAME COLUMN e TO eeee;
|
||||
PRAGMA writable_schema=OFF;
|
||||
SELECT name FROM sqlite_master
|
||||
WHERE (name, sql) NOT IN (SELECT name, sql FROM schema_copy);
|
||||
ROLLBACK;
|
||||
} {t1}
|
||||
do_execsql_test 23.20 {
|
||||
CREATE TABLE t4(id INTEGER PRIMARY KEY, c1 INT, c2 INT);
|
||||
CREATE VIEW t4v1 AS SELECT id, c1, c99 FROM t4;
|
||||
DELETE FROM schema_copy;
|
||||
INSERT INTO schema_copy SELECT name, sql FROM sqlite_schema;
|
||||
BEGIN;
|
||||
PRAGMA writable_schema=ON;
|
||||
ALTER TABLE t4 RENAME to t4new;
|
||||
SELECT name FROM sqlite_schema WHERE (name,sql) NOT IN (SELECT * FROM schema_copy);
|
||||
ROLLBACK;
|
||||
} {t4new}
|
||||
|
||||
finish_test
|
||||
|
Loading…
Reference in New Issue
Block a user