-C Fix\svarious\sharmless\scompiler\swarnings.
-D 2022-02-04T13:15:01.508
+C Allow\sALTER\sTABLE\sRENAME\sCOLUMN\sto\sproceed\seven\sif\sthere\sare\serrors\sin\nthe\sschema,\sas\slong\sas\sPRAGMA\swritable_schema=ON\sis\sactive.
+D 2022-02-04T16:43:30.569
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
-F src/alter.c e8ac1df663bf4ec74920edd1299435f2a616d2404de0ac4013c151ea4e7a11f2
+F src/alter.c 11c8e4d382632a024c19fa09131d271c8c36f5b520023066e08408973a20e82d
F src/analyze.c 7518b99e07c5494111fe3bd867f28f804b6c5c1ad0703ec3d116de9bab3fa516
F src/attach.c f26d400f3ffe2cdca01406bca70e5f58c5488bf165b4fc37c228136dfcf1b583
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707
F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959
F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc
-F test/altercol.test 9471187fe155d9c4211ae185e104ff48ce8f114262ee1256cf1e110b339c725f
+F test/altercol.test d4f25038a7a72c38267f99ff7c0153d720c0a908321bbbf0639c301e6ea1c57c
F test/altercorrupt.test 2e1d705342cf9d7de884518ddbb053fd52d7e60d2b8869b7b63b2fda68435c12
F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e
F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9f67ad00cd38b7c5ec6d14b379e1a611777bbdf6901d843a80712ba7d94d6d33
-R ed2fd6b08e6120318ad847a61dee5a51
+P 70049342d5ad57ea3e863bba19253934b868bacdd1c26c9371bac024a829badf
+R ade5a35b1c4e6334138f31a1e28c7fb0
+T *branch * relaxed-alter-table
+T *sym-relaxed-alter-table *
+T -sym-trunk *
U drh
-Z 871646465b8062211df8c4f3cf586a8c
+Z 7858525677fe7d863fef5513c510c7f5
# Remove this line to create a well-formed Fossil manifest.
-70049342d5ad57ea3e863bba19253934b868bacdd1c26c9371bac024a829badf
\ No newline at end of file
+197cbabf1767d0603928462fb75cf8100f6999f725e0db60d096c7ca20e3da28
\ No newline at end of file
/*
** 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.)
**
** 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,
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);
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:
**
** 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,
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);
}
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
** 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,
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 && !sqlite3WritableSchema(db) ){
+ /* Output case A */
renameColumnParseError(context, zWhen, argv[2], argv[3],&sParse);
}
renameParseCleanup(&sParse);
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 {
} {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 {
} {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 {
} {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}
+
finish_test