mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-21 09:00:59 +03:00
Update the parser so that sub-queries and CTEs may have WITH clauses.
FossilOrigin-Name: 704d3931b855562a619769955969d439c42ca406
This commit is contained in:
18
src/build.c
18
src/build.c
@@ -4200,22 +4200,26 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){
|
||||
}
|
||||
|
||||
#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) */
|
||||
|
||||
30
src/parse.y
30
src/parse.y
@@ -396,7 +396,7 @@ cmd ::= DROP VIEW ifexists(E) fullname(X). {
|
||||
|
||||
//////////////////////// 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);
|
||||
@@ -407,12 +407,16 @@ cmd ::= with select(X). {
|
||||
|
||||
%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;
|
||||
@@ -1365,13 +1369,19 @@ anylist ::= anylist ANY.
|
||||
|
||||
|
||||
//////////////////////// 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
|
||||
|
||||
@@ -760,6 +760,7 @@ typedef struct VTable VTable;
|
||||
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
|
||||
@@ -2631,6 +2632,19 @@ int sqlite3WalkSelectFrom(Walker*, Select*);
|
||||
#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.
|
||||
@@ -3330,8 +3344,8 @@ const char *sqlite3JournalModename(int);
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user