-C Parse\scommon\stable\sexpressions.\s\sBut\sdo\snot\sdo\sanything\swith\sthem\s(yet).
-D 2014-01-11T13:22:17.016
+C Update\sthe\sparser\sso\sthat\ssub-queries\sand\sCTEs\smay\shave\sWITH\sclauses.
+D 2014-01-11T19:19:36.147
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df
F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
-F src/build.c 198670a78fe748b6e60d6345a8aa1db57794511a
+F src/build.c 1da29e4e93d9774599f1f791d011ba46d841000c
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07
F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
-F src/parse.y 0ccd364dd3670ad5763a5e94dd11196ddc10927a
+F src/parse.y 1e3fd22fc82930d0cce01f2ab90616100c59ee0c
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b
F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h bb093076ba1eb956330cca0ca2a206c91facab4b
+F src/sqliteInt.h 2710b3a6c66edda9f193453268f6fe878ff5a0ca
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F test/win32heap.test ea19770974795cff26e11575e12d422dbd16893c
F test/win32lock.test 7a6bd73a5dcdee39b5bb93e92395e1773a194361
F test/win32longpath.test 169c75a3b2e43481f4a62122510210c67b08f26d
+F test/with1.test e8146198319c3627bb21ef085c58a827f35686a7
F test/without_rowid1.test aaa26da19d543cd8d3d2d0e686dfa255556c15c8
F test/without_rowid2.test af260339f79d13cb220288b67cd287fbcf81ad99
F test/without_rowid3.test eac3d5c8a1924725b58503a368f2cbd24fd6c8a0
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P 29ba458d849ad8864711cbe59fb10447a947e06a
-R b8f42a0591e43b680c1e09056e8afd6e
-T *branch * common-table-expr
-T *sym-common-table-expr *
-T -sym-trunk *
-U drh
-Z 9a38087dfe69ad33926bbf7c01c0b22a
+P da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5
+R bbb9d541af414d7b8bb3f418deb50875
+U dan
+Z a973a84816d55810384771a899b1092b
-da98b7205eb3d7ec2ddbf8a8e24eee0b2ff499a5
\ No newline at end of file
+704d3931b855562a619769955969d439c42ca406
\ No newline at end of file
}
#ifndef SQLITE_OMIT_CTE
-/* This routine is invoked when a single with_query of a
-** common-table-expression has been parsed. Record the query.
+/*
+** This routine is invoked once per CTE by the parser while parsing a
+** WITH clause.
*/
-void sqlite3CteAdd(
+With *sqlite3WithAdd(
Parse *pParse, /* Parsing context */
+ With *pWith, /* Existing WITH clause, or NULL */
Token *pName, /* Name of the common-table */
- ExprList *pArgList, /* Optional column name list for the table */
+ IdList *pArglist, /* Optional column name list for the table */
Select *pQuery /* Query used to initialize the table */
){
- sqlite3ExprListDelete(pParse->db, pArgList);
+ sqlite3IdListDelete(pParse->db, pArglist);
sqlite3SelectDelete(pParse->db, pQuery);
+ return 0;
}
-/* This routine is invoked at the end of the entire WITH clause.
+/*
+** Free the contents of the With object passed as the second argument.
*/
-void sqlite3CteFinish(Parse *pParse, int isRecursive){
+void sqlite3WithDelete(sqlite3 *db, With *pWith){
/* TBD */
}
#endif /* !defined(SQLITE_OMIT_CTE) */
//////////////////////// The SELECT statement /////////////////////////////////
//
-cmd ::= with select(X). {
+cmd ::= select(X). {
SelectDest dest = {SRT_Output, 0, 0, 0, 0};
sqlite3Select(pParse, X, &dest);
sqlite3ExplainBegin(pParse->pVdbe);
%type select {Select*}
%destructor select {sqlite3SelectDelete(pParse->db, $$);}
+%type selectnowith {Select*}
+%destructor selectnowith {sqlite3SelectDelete(pParse->db, $$);}
%type oneselect {Select*}
%destructor oneselect {sqlite3SelectDelete(pParse->db, $$);}
-select(A) ::= oneselect(X). {A = X;}
+select(A) ::= with selectnowith(X). {A = X;}
+
+selectnowith(A) ::= oneselect(X). {A = X;}
%ifndef SQLITE_OMIT_COMPOUND_SELECT
-select(A) ::= select(X) multiselect_op(Y) oneselect(Z). {
+selectnowith(A) ::= selectnowith(X) multiselect_op(Y) oneselect(Z). {
if( Z ){
Z->op = (u8)Y;
Z->pPrior = X;
//////////////////////// COMMON TABLE EXPRESSIONS ////////////////////////////
-with ::= .
+%type with {With*}
+%type wqlist {With*}
+%destructor with {sqlite3WithDelete(pParse->db, $$);}
+
+with(A) ::= . {A = 0;}
%ifndef SQLITE_OMIT_CTE
-with ::= WITH wqlist. {sqlite3CteFinish(pParse, 0);}
-with ::= WITH RECURSIVE wqlist. {sqlite3CteFinish(pParse, 1);}
-wqlist ::= with_query.
-wqlist ::= wqlist COMMA with_query.
-with_query ::= nm(X) idxlist_opt(Y) AS LP select(Z) RP. {
- sqlite3CteAdd(pParse, &X, Y, Z);
+with(A) ::= WITH wqlist(W). { A = W; }
+with(A) ::= WITH RECURSIVE wqlist(W). { A = W; }
+
+wqlist(A) ::= nm(X) inscollist_opt(Y) AS LP select(Z) RP. {
+ A = sqlite3WithAdd(pParse, 0, &X, Y, Z);
+}
+wqlist(A) ::= wqlist(W) COMMA nm(X) inscollist_opt(Y) AS LP select(Z) RP. {
+ A = sqlite3WithAdd(pParse, W, &X, Y, Z);
}
%endif SQLITE_OMIT_CTE
typedef struct VtabCtx VtabCtx;
typedef struct Walker Walker;
typedef struct WhereInfo WhereInfo;
+typedef struct With With;
/*
** Defer sourcing vdbe.h and btree.h until after the "u8" and
#define WRC_Prune 1 /* Omit children but continue walking siblings */
#define WRC_Abort 2 /* Abandon the tree walk */
+/*
+** An instance of this structure represents a set of CTEs (common table
+** expressions) created by a single WITH clause.
+*/
+struct With {
+ int nCte; /* Number of CTEs */
+ struct Cte {
+ const char *zName; /* Name of this CTE */
+ IdList *pCol; /* List of explicit column names, or NULL */
+ Select *pSelect; /* The contents of the CTE */
+ } a[1];
+};
+
/*
** Assuming zIn points to the first byte of a UTF-8 character,
** advance zIn to point to the first byte of the next UTF-8 character.
int sqlite3WalDefaultHook(void*,sqlite3*,const char*,int);
#endif
#ifndef SQLITE_OMIT_CTE
- void sqlite3CteAdd(Parse*,Token*,ExprList*,Select*);
- void sqlite3CteFinish(Parse*,int);
+ With *sqlite3WithAdd(Parse*,With*,Token*,IdList*,Select*);
+ void sqlite3WithDelete(sqlite3*,With*);
#endif
/* Declarations for functions in fkey.c. All of these are replaced by
--- /dev/null
+# 2014 January 11
+#
+# The author disclaims copyright to this source code. In place of
+# a legal notice, here is a blessing:
+#
+# May you do good and not evil.
+# May you find forgiveness for yourself and forgive others.
+# May you share freely, never taking more than you give.
+#
+#***********************************************************************
+# This file implements regression tests for SQLite library. The
+# focus of this file is testing the WITH clause.
+#
+
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+set ::testprefix with1
+
+do_execsql_test 1.0 {
+ CREATE TABLE t1(x INTEGER, y INTEGER);
+ WITH x(a) AS ( SELECT * FROM t1) SELECT 10
+} {10}
+
+do_execsql_test 1.1 {
+ SELECT * FROM ( WITH x AS ( SELECT * FROM t1) SELECT 10 );
+} {10}
+
+do_execsql_test 1.2 {
+ WITH x(a) AS ( SELECT * FROM t1) INSERT INTO t1 VALUES(1,2);
+} {}
+
+do_execsql_test 1.3 {
+ WITH x(a) AS ( SELECT * FROM t1) DELETE FROM t1;
+} {}
+
+do_execsql_test 1.4 {
+ WITH x(a) AS ( SELECT * FROM t1) UPDATE t1 SET x = y;
+} {}
+
+finish_test