-C When\sparsing\sthe\sschema,\signore\sany\sSQL\sthat\sdoes\snot\sbegin\nwith\s"CREATE".\sCherrypick\sof\s[d3c00d61581c]\swith\sadditional\schanges.
-D 2015-05-21T02:07:56.469
+C Ensure\sthat\stables\snames\sare\sdequoted\sexactly\sonce\sby\sthe\strigger\slogic.\nCherrypick\s[59e92bd9521f1e8]\sand\s[9d887b92f8086961e].
+D 2015-05-21T02:20:47.492
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2f37e468503dbe79d35c9f6dffcf3fae1ae9ec20
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/delete.c 51d32f0a9c880663e54ce309f52e40c325d5e112
F src/expr.c 00675123e0beec98f999aa4594d2cbe1fec33c1b
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
-F src/fkey.c 657212460bf5cfd3ae607d12ea62092844c227b5
+F src/fkey.c 46f9dc13b4f3e8f9659d31e71cd5f76c8ae465cc
F src/func.c e75f41c421f00762ab9da7dc8fb90af3972cf99f
F src/global.c 4cfdca5cb0edd33c4d021baec4ede958cb2c793b
F src/hash.c 458488dcc159c301b8e7686280ab209f1fb915af
F src/shell.c a31c37ed0959173dce7a565359e6372c68aa0268
F src/sqlite.h.in 6af2d92925bfed3dfd2c022fef48469762ccd435
F src/sqlite3ext.h 6904f4aadf976f95241311fbffb00823075d9477
-F src/sqliteInt.h e65429a6f19b41720561b9434b2192574a91cfa2
+F src/sqliteInt.h ce9a4d64a183a0d3500123445a905607abaeb0a1
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 4568e72dfd36b6a5911f93457364deb072e0b03a
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/test_wholenumber.c 6129adfbe7c7444f2e60cc785927f3aa74e12290
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c 1e86210d3976717a19238ea7b047fac481fe8c12
-F src/trigger.c ee7e178fb9188f44b532cebd449a7c1df90fb684
+F src/trigger.c bc7f94ec7a5e0067846acb0691996812a00336ca
F src/update.c d3076782c887c10e882996550345da9c4c9f9dea
F src/utf.c 890c67dcfcc7a74623c95baac7535aadfe265e84
F src/util.c 4f6cfad661b2e3454b0cdd5b1b9d39a54942d0e3
F test/fallocate.test b5d34437bd7ab01d41b1464b8117aefd4d32160e
F test/filectrl.test f0327bd804d9c7bd048fa7a151c5eab8e27df42b
F test/filefmt.test ffa17b5aebc3eb4b1e3be1ccb5ee906ffbd97f6e
-F test/fkey1.test 01c7de578e11747e720c2d9aeef27f239853c4da
+F test/fkey1.test fcaff62ae3c4322ba39bf01ee07944b72bccc76b
F test/fkey2.test 080969fe219b3b082b0e097ac18c6af2e5b0631f
F test/fkey3.test 5ec899d12b13bcf1e9ef40eff7fb692fdb91392e
F test/fkey4.test c6c8f9f9be885f95c85c7bceb26f243ad906fd49
F test/trigger9.test 5b0789f1c5c4600961f8e68511b825b87be53e31
F test/triggerA.test e0aaba16d3547193d36bbd82a1b0ed75e9c88d40
F test/triggerB.test 56780c031b454abac2340dbb3b71ac5c56c3d7fe
-F test/triggerC.test 4d4bdaf0230c206b50d350330107ef9802bc2d4f
+F test/triggerC.test a8fad3c4c87beb69c4e73497f8bde7285af9285f
F test/triggerD.test 8e7f3921a92a5797d472732108109e44575fa650
F test/tt3_checkpoint.c 415eccce672d681b297485fc20f44cdf0eac93af
F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
F tool/warnings-clang.sh 9f406d66e750e8ac031c63a9ef3248aaa347ef2a
F tool/warnings.sh fbc018d67fd7395f440c28f33ef0f94420226381
-P 0f0694e4245083f6abb4ce104c39add45f2eb71a
-Q +2c649cdf7e058cf490597ffbddd5dc1eb5c3b346
-Q +d3c00d61581c8ba6dce5618391432d3af8d324d4
-R d9dd499bc0772f79ea4a61d9b9920aea
+P 09784f376b47b6ca539a5106dfa65d8abebe1ef2
+Q +59e92bd9521f1e8315a9a7e7fd3d63b0c75eaf0e
+Q +9d887b92f8086961e045f8acb9ee7a443796d411
+R 8b9677253ae83c017d7457a710552396
U drh
-Z 50e7ee5eace512a88d2256e7d4efb230
+Z 94b5f3dbcf1046c08af07824e7389b9d
-09784f376b47b6ca539a5106dfa65d8abebe1ef2
\ No newline at end of file
+9e3f64a4f4182ad80e82edb53095ed508e8b1d13
\ No newline at end of file
** parent table are used for the comparison. */
pEq = sqlite3PExpr(pParse, TK_EQ,
sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol)
+ sqlite3ExprAlloc(db, TK_ID, &tFromCol, 0)
, 0);
pWhere = sqlite3ExprAnd(db, pWhere, pEq);
if( pChanges ){
pEq = sqlite3PExpr(pParse, TK_IS,
sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+ sqlite3ExprAlloc(db, TK_ID, &tOld, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol),
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0),
0),
0);
pWhen = sqlite3ExprAnd(db, pWhen, pEq);
Expr *pNew;
if( action==OE_Cascade ){
pNew = sqlite3PExpr(pParse, TK_DOT,
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew),
- sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol)
+ sqlite3ExprAlloc(db, TK_ID, &tNew, 0),
+ sqlite3ExprAlloc(db, TK_ID, &tToCol, 0)
, 0);
}else if( action==OE_SetDflt ){
Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt;
pTrigger = (Trigger *)sqlite3DbMallocZero(db,
sizeof(Trigger) + /* struct Trigger */
sizeof(TriggerStep) + /* Single step in trigger program */
- nFrom + 1 /* Space for pStep->target.z */
+ nFrom + 1 /* Space for pStep->zTarget */
);
if( pTrigger ){
pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1];
- pStep->target.z = (char *)&pStep[1];
- pStep->target.n = nFrom;
- memcpy((char *)pStep->target.z, zFrom, nFrom);
+ pStep->zTarget = (char *)&pStep[1];
+ memcpy((char *)pStep->zTarget, zFrom, nFrom);
pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE);
pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE);
* orconf -> stores the ON CONFLICT algorithm
* pSelect -> If this is an INSERT INTO ... SELECT ... statement, then
* this stores a pointer to the SELECT statement. Otherwise NULL.
- * target -> A token holding the quoted name of the table to insert into.
+ * zTarget -> Dequoted name of the table to insert into.
* pExprList -> If this is an INSERT INTO ... VALUES ... statement, then
* this stores values to be inserted. Otherwise NULL.
* pIdList -> If this is an INSERT INTO ... (<column-names>) VALUES ...
* inserted into.
*
* (op == TK_DELETE)
- * target -> A token holding the quoted name of the table to delete from.
+ * zTarget -> Dequoted name of the table to delete from.
* pWhere -> The WHERE clause of the DELETE statement if one is specified.
* Otherwise NULL.
*
* (op == TK_UPDATE)
- * target -> A token holding the quoted name of the table to update rows of.
+ * zTarget -> Dequoted name of the table to update.
* pWhere -> The WHERE clause of the UPDATE statement if one is specified.
* Otherwise NULL.
* pExprList -> A list of the columns to update and the expressions to update
u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */
u8 orconf; /* OE_Rollback etc. */
Trigger *pTrig; /* The trigger that this step is a part of */
- Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
- Token target; /* Target table for DELETE, UPDATE, INSERT */
+ Select *pSelect; /* SELECT statement or RHS of INSERT INTO SELECT ... */
+ char *zTarget; /* Target table for DELETE, UPDATE, INSERT */
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */
IdList *pIdList; /* Column names for INSERT */
){
TriggerStep *pTriggerStep;
- pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n);
+ pTriggerStep = sqlite3DbMallocZero(db, sizeof(TriggerStep) + pName->n + 1);
if( pTriggerStep ){
char *z = (char*)&pTriggerStep[1];
memcpy(z, pName->z, pName->n);
- pTriggerStep->target.z = z;
- pTriggerStep->target.n = pName->n;
+ sqlite3Dequote(z);
+ pTriggerStep->zTarget = z;
pTriggerStep->op = op;
}
return pTriggerStep;
}
/*
-** Convert the pStep->target token into a SrcList and return a pointer
+** Convert the pStep->zTarget string into a SrcList and return a pointer
** to that SrcList.
**
** This routine adds a specific database name, if needed, to the target when
Parse *pParse, /* The parsing context */
TriggerStep *pStep /* The trigger containing the target token */
){
+ sqlite3 *db = pParse->db;
int iDb; /* Index of the database to use */
SrcList *pSrc; /* SrcList to be returned */
- pSrc = sqlite3SrcListAppend(pParse->db, 0, &pStep->target, 0);
+ pSrc = sqlite3SrcListAppend(db, 0, 0, 0);
if( pSrc ){
assert( pSrc->nSrc>0 );
- assert( pSrc->a!=0 );
- iDb = sqlite3SchemaToIndex(pParse->db, pStep->pTrig->pSchema);
+ pSrc->a[pSrc->nSrc-1].zName = sqlite3DbStrDup(db, pStep->zTarget);
+ iDb = sqlite3SchemaToIndex(db, pStep->pTrig->pSchema);
if( iDb==0 || iDb>=2 ){
- sqlite3 *db = pParse->db;
- assert( iDb<pParse->db->nDb );
+ assert( iDb<db->nDb );
pSrc->a[pSrc->nSrc-1].zDatabase = sqlite3DbStrDup(db, db->aDb[iDb].zName);
}
}
{0 1 t5 e {} {SET DEFAULT} CASCADE NONE} \
]
+# Stress the dequoting logic. The first test is not so bad.
+do_execsql_test fkey1-4.0 {
+ PRAGMA foreign_keys=ON;
+ CREATE TABLE "xx1"("xx2" TEXT PRIMARY KEY, "xx3" TEXT);
+ INSERT INTO "xx1"("xx2","xx3") VALUES('abc','def');
+ CREATE TABLE "xx4"("xx5" TEXT REFERENCES "xx1" ON DELETE CASCADE);
+ INSERT INTO "xx4"("xx5") VALUES('abc');
+ INSERT INTO "xx1"("xx2","xx3") VALUES('uvw','xyz');
+ SELECT 1, "xx5" FROM "xx4";
+ DELETE FROM "xx1";
+ SELECT 2, "xx5" FROM "xx4";
+} {1 abc}
+
+# This case is identical to the previous except the "xx" in each name
+# is changed to a single escaped double-quote character.
+do_execsql_test fkey1-4.1 {
+ PRAGMA foreign_keys=ON;
+ CREATE TABLE """1"("""2" TEXT PRIMARY KEY, """3" TEXT);
+ INSERT INTO """1"("""2","""3") VALUES('abc','def');
+ CREATE TABLE """4"("""5" TEXT REFERENCES """1" ON DELETE CASCADE);
+ INSERT INTO """4"("""5") VALUES('abc');
+ INSERT INTO """1"("""2","""3") VALUES('uvw','xyz');
+ SELECT 1, """5" FROM """4";
+ DELETE FROM """1";
+ SELECT 2, """5" FROM """4";
+} {1 abc}
+do_execsql_test fkey1-4.2 {
+ PRAGMA table_info="""1";
+} {0 {"2} TEXT 0 {} 1 1 {"3} TEXT 0 {} 0}
+
finish_test
set testdir [file dirname $argv0]
source $testdir/tester.tcl
+set testprefix triggerC
ifcapable {!trigger} {
finish_test
return
+#-------------------------------------------------------------------------
+# Check that table names used by trigger programs are dequoted exactly
+# once.
+#
+do_execsql_test 15.1.1 {
+ PRAGMA recursive_triggers = 1;
+ CREATE TABLE node(
+ id int not null primary key,
+ pid int not null default 0 references node,
+ key varchar not null,
+ path varchar default '',
+ unique(pid, key)
+ );
+ CREATE TRIGGER node_delete_referencing AFTER DELETE ON "node"
+ BEGIN
+ DELETE FROM "node" WHERE pid = old."id";
+ END;
+}
+do_execsql_test 15.1.2 {
+ INSERT INTO node(id, pid, key) VALUES(9, 0, 'test');
+ INSERT INTO node(id, pid, key) VALUES(90, 9, 'test1');
+ INSERT INTO node(id, pid, key) VALUES(900, 90, 'test2');
+ DELETE FROM node WHERE id=9;
+ SELECT * FROM node;
+}
+
+do_execsql_test 15.2.1 {
+ CREATE TABLE x1 (x);
+
+ CREATE TABLE x2 (a, b);
+ CREATE TABLE '"x2"'(a, b);
+
+ INSERT INTO x2 VALUES(1, 2);
+ INSERT INTO x2 VALUES(3, 4);
+ INSERT INTO '"x2"' SELECT * FROM x2;
+
+ CREATE TRIGGER x1ai AFTER INSERT ON x1 BEGIN
+ INSERT INTO """x2""" VALUES('x', 'y');
+ DELETE FROM """x2""" WHERE a=1;
+ UPDATE """x2""" SET b = 11 WHERE a = 3;
+ END;
+
+ INSERT INTO x1 VALUES('go!');
+}
+
+do_execsql_test 15.2.2 { SELECT * FROM x2; } {1 2 3 4}
+do_execsql_test 15.2.3 { SELECT * FROM """x2"""; } {3 11 x y}
+
finish_test