aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2017-12-24 00:18:47 +0000
committerdrh <drh@noemail.net>2017-12-24 00:18:47 +0000
commit1be266ba089bf463f1b0a5ea2839b7a1341d91ab (patch)
tree5dce4dc6834328c050928c7046a813d9472f4f07
parent88a921ce602c7d940a0ba4ed3eeeef31a4ce1455 (diff)
downloadsqlite-1be266ba089bf463f1b0a5ea2839b7a1341d91ab.tar.gz
sqlite-1be266ba089bf463f1b0a5ea2839b7a1341d91ab.zip
Remove the ExprSpan object. Instead, keep track of the test of subphrases in
the parse using the "scanpt" non-terminal. FossilOrigin-Name: 3eab7bdc44e0878b83dc86f27058a40c2ffafeacadc566f03693f6dc7e40a504
-rw-r--r--manifest21
-rw-r--r--manifest.uuid2
-rw-r--r--src/build.c23
-rw-r--r--src/expr.c11
-rw-r--r--src/parse.y410
-rw-r--r--src/sqliteInt.h16
6 files changed, 208 insertions, 275 deletions
diff --git a/manifest b/manifest
index f187cc029..3cc840deb 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Simplification\sto\sthe\serror\shandling\slogic\sin\sthe\sextension\sloader.
-D 2017-12-23T14:39:36.160
+C Remove\sthe\sExprSpan\sobject.\sInstead,\skeep\strack\sof\sthe\stest\sof\ssubphrases\sin\nthe\sparse\susing\sthe\s"scanpt"\snon-terminal.
+D 2017-12-24T00:18:47.740
F Makefile.in ceb40bfcb30ebba8e1202b34c56ff7e13e112f9809e2381d99be32c2726058f5
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 6480671f7c129e61208d69492b3c71ce4310d49fceac83cfb17f1c081e242b69
@@ -423,7 +423,7 @@ F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca
F src/btree.c b83a6b03f160528020bb965f0c3a40af5286cd4923c3870fd218177f03a120a7
F src/btree.h 32ef5d3f25dc70ef1ee9cecf84a023c21378f06a57cd701d2e866e141b150f09
F src/btreeInt.h 55b702efce17e5d1941865464227d3802cfc9c7c832fac81d4c94dced47a71fc
-F src/build.c ed567f088edbc305dad33a6b14e08f8216a3860f6bad1d180450d5a5414bf346
+F src/build.c d3d2feeeee9c6b41a0bc7a00e4803724780f29f27ef16633b6e32aa0901c7994
F src/callback.c fe677cb5f5abb02f7a772a62a98c2f516426081df68856e8f2d5f950929b966a
F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
F src/ctime.c ff1be3eed7bdd75aaca61ca8dc848f7c9f850ef2fb9cb56f2734e922a098f9c0
@@ -431,7 +431,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
F src/dbpage.c 8db4c97f630e7d83f884ea75caf1ffd0988c160e9d530194d93721c80821e0f6
F src/dbstat.c 7a4ba8518b6369ef3600c49cf9c918ad979acba610b2aebef1b656d649b96720
F src/delete.c 74667ad914ac143731a444a1bacf29ceb18f6eded8a0dd17aafae80baa07f8bb
-F src/expr.c fe11b91bb65b869143bd42023427c4429778ae42c0a0db7762f68f75b347a958
+F src/expr.c 04188faa71b86bff3a1de46d92f41b9ec2b18fa1bbbdbf683cfff657fe803f3d
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c d617daf66b5515e2b42c1405b2b4984c30ca50fb705ab164271a9bf66c69e331
F src/func.c 0fb9a2d678d3c8aba89b46468b309cd7e8fa9806a369a30aa89024660845bb13
@@ -467,7 +467,7 @@ F src/os_win.c 0a4afa35cc8e812000df3ea2f64b476131b39e29e75d8007d0504726e4761de4
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c 07cf850241667874fcce9d7d924c814305e499b26c804322e2261247b5921903
F src/pager.h 581698f2177e8bd4008fe4760898ce20b6133d1df22139b9101b5155f900df7a
-F src/parse.y d79001da275bfe344b409006b85e81e486a0f6afc3762fdf0944f000f4aa0111
+F src/parse.y 1e29222ba074fea8d84438098e00812071d4cfd34c8620f34accab7cd523a276
F src/pcache.c 7ae91a4557a43d77d449accbfdc68846e6516f8e2eda46e8bbe4536fb669b201
F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170
F src/pcache1.c 716975564c15eb6679e97f734cec1bfd6c16ac3d4010f05f1f8e509fc7d19880
@@ -483,7 +483,7 @@ F src/shell.c.in 339169a3d1307b5566ebe9ce15832d03439206106724c78cc3d9125a7b85179
F src/sqlite.h.in 2126192945019d4cdce335cb236b440a05ec75c93e4cd94c9c6d6e7fcc654cc4
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h c02d628cca67f3889c689d82d25c3eb45e2c155db08e4c6089b5840d64687d34
-F src/sqliteInt.h 003b78433baae4e5c997f99f2f9cf98d90754f256baeacb32f8189569a48251f
+F src/sqliteInt.h 124be5e9bacd2a356ba17875bbaddf5f25aa1ba8a292233210ba8141ecc58316
F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b
F src/status.c 9737ed017279a9e0c5da748701c3c7bf1e8ae0dae459aad20dd64fcff97a7e35
F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34
@@ -1687,7 +1687,10 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 05fee1a21ea398f1e4d6f1cf361657eff25ed6cd8f85ab398262dcfd30da57e9
-R 7fbfe3e61eca395fa5baf5f121a4d2ad
+P 07c773148d8db185fa54991df09298b64f4fef28879e6c9395759265e8183977
+R 1cdf837f203b6ea58ba0352a2b260bed
+T *branch * span-refactor
+T *sym-span-refactor *
+T -sym-trunk *
U drh
-Z d82d9c01768cefc5beb206b92e1398bf
+Z 03a6ffebedfd10412e429ce17606ec66
diff --git a/manifest.uuid b/manifest.uuid
index 8454418cd..512e59124 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-07c773148d8db185fa54991df09298b64f4fef28879e6c9395759265e8183977 \ No newline at end of file
+3eab7bdc44e0878b83dc86f27058a40c2ffafeacadc566f03693f6dc7e40a504 \ No newline at end of file
diff --git a/src/build.c b/src/build.c
index 01d897241..edf300628 100644
--- a/src/build.c
+++ b/src/build.c
@@ -1221,34 +1221,41 @@ char sqlite3AffinityType(const char *zIn, u8 *pszEst){
** This routine is called by the parser while in the middle of
** parsing a CREATE TABLE statement.
*/
-void sqlite3AddDefaultValue(Parse *pParse, ExprSpan *pSpan){
+void sqlite3AddDefaultValue(
+ Parse *pParse, /* Parsing context */
+ Expr *pExpr, /* The parsed expression of the default value */
+ const char *zStart, /* Start of the default value text */
+ const char *zEnd /* First character past end of defaut value text */
+){
Table *p;
Column *pCol;
sqlite3 *db = pParse->db;
p = pParse->pNewTable;
if( p!=0 ){
pCol = &(p->aCol[p->nCol-1]);
- if( !sqlite3ExprIsConstantOrFunction(pSpan->pExpr, db->init.busy) ){
+ if( !sqlite3ExprIsConstantOrFunction(pExpr, db->init.busy) ){
sqlite3ErrorMsg(pParse, "default value of column [%s] is not constant",
pCol->zName);
}else{
/* A copy of pExpr is used instead of the original, as pExpr contains
- ** tokens that point to volatile memory. The 'span' of the expression
- ** is required by pragma table_info.
+ ** tokens that point to volatile memory.
*/
Expr x;
+ int n;
sqlite3ExprDelete(db, pCol->pDflt);
memset(&x, 0, sizeof(x));
x.op = TK_SPAN;
- x.u.zToken = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
- x.pLeft = pSpan->pExpr;
+ while( sqlite3Isspace(zStart[0]) ) zStart++;
+ n = (int)(zEnd - zStart);
+ while( n>0 && sqlite3Isspace(zStart[n-1]) ) n--;
+ x.u.zToken = sqlite3DbStrNDup(db, zStart, n);
+ x.pLeft = pExpr;
x.flags = EP_Skip;
pCol->pDflt = sqlite3ExprDup(db, &x, EXPRDUP_REDUCE);
sqlite3DbFree(db, x.u.zToken);
}
}
- sqlite3ExprDelete(db, pSpan->pExpr);
+ sqlite3ExprDelete(db, pExpr);
}
/*
diff --git a/src/expr.c b/src/expr.c
index 524e53934..129c1299b 100644
--- a/src/expr.c
+++ b/src/expr.c
@@ -1654,17 +1654,20 @@ void sqlite3ExprListSetName(
void sqlite3ExprListSetSpan(
Parse *pParse, /* Parsing context */
ExprList *pList, /* List to which to add the span. */
- ExprSpan *pSpan /* The span to be added */
+ const char *zStart, /* Start of the span */
+ const char *zEnd /* End of the span */
){
sqlite3 *db = pParse->db;
assert( pList!=0 || db->mallocFailed!=0 );
if( pList ){
struct ExprList_item *pItem = &pList->a[pList->nExpr-1];
+ int n;
assert( pList->nExpr>0 );
- assert( db->mallocFailed || pItem->pExpr==pSpan->pExpr );
sqlite3DbFree(db, pItem->zSpan);
- pItem->zSpan = sqlite3DbStrNDup(db, (char*)pSpan->zStart,
- (int)(pSpan->zEnd - pSpan->zStart));
+ while( sqlite3Isspace(zStart[0]) ) zStart++;
+ n = (int)(zEnd - zStart);
+ while( n>0 && sqlite3Isspace(zStart[n-1]) ) n--;
+ pItem->zSpan = sqlite3DbStrNDup(db, zStart, n);
}
}
diff --git a/src/parse.y b/src/parse.y
index 0867d1e0c..d59426409 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -273,26 +273,47 @@ typename(A) ::= typename(A) ids(Y). {A.n=Y.n+(int)(Y.z-A.z);}
signed ::= plus_num.
signed ::= minus_num.
+// The scanpt non-terminal takes a value which is a pointer to the
+// input text just past the last token that has been shifted into
+// the parser. By surrounding some phrase in the grammar with two
+// scanpt non-terminals, we can capture the input text for that phrase.
+// For example:
+//
+// something ::= .... scanpt(A) phrase scanpt(Z).
+//
+// The text that is parsed as "phrase" is a string starting at A
+// and containing (int)(Z-A) characters. There might be some extra
+// whitespace on either end of the text, but that can be removed in
+// post-processing, if needed.
+//
+%type scanpt {const char*}
+scanpt(A) ::= . {
+ if( yyLookahead!=YYNOCODE ){
+ A = yyLookaheadToken.z;
+ }else{
+ A = pParse->sLastToken.z + pParse->sLastToken.n;
+ }
+}
+
// "carglist" is a list of additional constraints that come after the
// column name and column type in a CREATE TABLE statement.
//
carglist ::= carglist ccons.
carglist ::= .
ccons ::= CONSTRAINT nm(X). {pParse->constraintName = X;}
-ccons ::= DEFAULT term(X). {sqlite3AddDefaultValue(pParse,&X);}
-ccons ::= DEFAULT LP expr(X) RP. {sqlite3AddDefaultValue(pParse,&X);}
-ccons ::= DEFAULT PLUS term(X). {sqlite3AddDefaultValue(pParse,&X);}
-ccons ::= DEFAULT MINUS(A) term(X). {
- ExprSpan v;
- v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, X.pExpr, 0);
- v.zStart = A.z;
- v.zEnd = X.zEnd;
- sqlite3AddDefaultValue(pParse,&v);
-}
-ccons ::= DEFAULT id(X). {
- ExprSpan v;
- spanExpr(&v, pParse, TK_STRING, X);
- sqlite3AddDefaultValue(pParse,&v);
+ccons ::= DEFAULT scanpt(A) term(X) scanpt(Z).
+ {sqlite3AddDefaultValue(pParse,X,A,Z);}
+ccons ::= DEFAULT LP(A) expr(X) RP(Z).
+ {sqlite3AddDefaultValue(pParse,X,A.z+1,Z.z);}
+ccons ::= DEFAULT PLUS(A) term(X) scanpt(Z).
+ {sqlite3AddDefaultValue(pParse,X,A.z,Z);}
+ccons ::= DEFAULT MINUS(A) term(X) scanpt(Z). {
+ Expr *p = sqlite3PExpr(pParse, TK_UMINUS, X, 0);
+ sqlite3AddDefaultValue(pParse,p,A.z,Z);
+}
+ccons ::= DEFAULT scanpt id(X). {
+ Expr *p = tokenExpr(pParse, TK_STRING, X);
+ sqlite3AddDefaultValue(pParse,p,X.z,X.z+X.n);
}
// In addition to the type name, we also care about the primary key and
@@ -304,7 +325,7 @@ ccons ::= PRIMARY KEY sortorder(Z) onconf(R) autoinc(I).
{sqlite3AddPrimaryKey(pParse,0,R,I,Z);}
ccons ::= UNIQUE onconf(R). {sqlite3CreateIndex(pParse,0,0,0,0,R,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
-ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X.pExpr);}
+ccons ::= CHECK LP expr(X) RP. {sqlite3AddCheckConstraint(pParse,X);}
ccons ::= REFERENCES nm(T) eidlist_opt(TA) refargs(R).
{sqlite3CreateForeignKey(pParse,0,&T,TA,R);}
ccons ::= defer_subclause(D). {sqlite3DeferForeignKey(pParse,D);}
@@ -355,7 +376,7 @@ tcons ::= UNIQUE LP sortlist(X) RP onconf(R).
{sqlite3CreateIndex(pParse,0,0,0,X,R,0,0,0,0,
SQLITE_IDXTYPE_UNIQUE);}
tcons ::= CHECK LP expr(E) RP onconf.
- {sqlite3AddCheckConstraint(pParse,E.pExpr);}
+ {sqlite3AddCheckConstraint(pParse,E);}
tcons ::= FOREIGN KEY LP eidlist(FA) RP
REFERENCES nm(T) eidlist_opt(TA) refargs(R) defer_subclause_opt(D). {
sqlite3CreateForeignKey(pParse, FA, &T, TA, R);
@@ -549,16 +570,16 @@ distinct(A) ::= . {A = 0;}
%destructor sclp {sqlite3ExprListDelete(pParse->db, $$);}
sclp(A) ::= selcollist(A) COMMA.
sclp(A) ::= . {A = 0;}
-selcollist(A) ::= sclp(A) expr(X) as(Y). {
- A = sqlite3ExprListAppend(pParse, A, X.pExpr);
+selcollist(A) ::= sclp(A) scanpt(B) expr(X) scanpt(Z) as(Y). {
+ A = sqlite3ExprListAppend(pParse, A, X);
if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1);
- sqlite3ExprListSetSpan(pParse,A,&X);
+ sqlite3ExprListSetSpan(pParse,A,B,Z);
}
selcollist(A) ::= sclp(A) STAR. {
Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0);
A = sqlite3ExprListAppend(pParse, A, p);
}
-selcollist(A) ::= sclp(A) nm(X) DOT STAR. {
+selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. {
Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0);
Expr *pLeft = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
@@ -656,7 +677,7 @@ joinop(X) ::= JOIN_KW(A) nm(B) nm(C) JOIN.
%type on_opt {Expr*}
%destructor on_opt {sqlite3ExprDelete(pParse->db, $$);}
-on_opt(N) ::= ON expr(E). {N = E.pExpr;}
+on_opt(N) ::= ON expr(E). {N = E;}
on_opt(N) ::= . {N = 0;}
// Note that this block abuses the Token type just a little. If there is
@@ -693,11 +714,11 @@ using_opt(U) ::= . {U = 0;}
orderby_opt(A) ::= . {A = 0;}
orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;}
sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). {
- A = sqlite3ExprListAppend(pParse,A,Y.pExpr);
+ A = sqlite3ExprListAppend(pParse,A,Y);
sqlite3ExprListSetSortOrder(A,Z);
}
sortlist(A) ::= expr(Y) sortorder(Z). {
- A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/
+ A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/
sqlite3ExprListSetSortOrder(A,Z);
}
@@ -715,7 +736,7 @@ groupby_opt(A) ::= GROUP BY nexprlist(X). {A = X;}
%type having_opt {Expr*}
%destructor having_opt {sqlite3ExprDelete(pParse->db, $$);}
having_opt(A) ::= . {A = 0;}
-having_opt(A) ::= HAVING expr(X). {A = X.pExpr;}
+having_opt(A) ::= HAVING expr(X). {A = X;}
%type limit_opt {Expr*}
@@ -729,11 +750,11 @@ having_opt(A) ::= HAVING expr(X). {A = X.pExpr;}
//%destructor limit_opt {sqlite3ExprDelete(pParse->db, $$);}
limit_opt(A) ::= . {A = 0;}
limit_opt(A) ::= LIMIT expr(X).
- {A = sqlite3PExpr(pParse,TK_LIMIT,X.pExpr,0);}
+ {A = sqlite3PExpr(pParse,TK_LIMIT,X,0);}
limit_opt(A) ::= LIMIT expr(X) OFFSET expr(Y).
- {A = sqlite3PExpr(pParse,TK_LIMIT,X.pExpr,Y.pExpr);}
+ {A = sqlite3PExpr(pParse,TK_LIMIT,X,Y);}
limit_opt(A) ::= LIMIT expr(X) COMMA expr(Y).
- {A = sqlite3PExpr(pParse,TK_LIMIT,Y.pExpr,X.pExpr);}
+ {A = sqlite3PExpr(pParse,TK_LIMIT,Y,X);}
/////////////////////////// The DELETE statement /////////////////////////////
//
@@ -757,7 +778,7 @@ cmd ::= with(C) DELETE FROM fullname(X) indexed_opt(I) where_opt(W). {
%destructor where_opt {sqlite3ExprDelete(pParse->db, $$);}
where_opt(A) ::= . {A = 0;}
-where_opt(A) ::= WHERE expr(X). {A = X.pExpr;}
+where_opt(A) ::= WHERE expr(X). {A = X;}
////////////////////////// The UPDATE command ////////////////////////////////
//
@@ -784,18 +805,18 @@ cmd ::= with(C) UPDATE orconf(R) fullname(X) indexed_opt(I) SET setlist(Y)
%destructor setlist {sqlite3ExprListDelete(pParse->db, $$);}
setlist(A) ::= setlist(A) COMMA nm(X) EQ expr(Y). {
- A = sqlite3ExprListAppend(pParse, A, Y.pExpr);
+ A = sqlite3ExprListAppend(pParse, A, Y);
sqlite3ExprListSetName(pParse, A, &X, 1);
}
setlist(A) ::= setlist(A) COMMA LP idlist(X) RP EQ expr(Y). {
- A = sqlite3ExprListAppendVector(pParse, A, X, Y.pExpr);
+ A = sqlite3ExprListAppendVector(pParse, A, X, Y);
}
setlist(A) ::= nm(X) EQ expr(Y). {
- A = sqlite3ExprListAppend(pParse, 0, Y.pExpr);
+ A = sqlite3ExprListAppend(pParse, 0, Y);
sqlite3ExprListSetName(pParse, A, &X, 1);
}
setlist(A) ::= LP idlist(X) RP EQ expr(Y). {
- A = sqlite3ExprListAppendVector(pParse, 0, X, Y.pExpr);
+ A = sqlite3ExprListAppendVector(pParse, 0, X, Y);
}
////////////////////////// The INSERT command /////////////////////////////////
@@ -829,26 +850,18 @@ idlist(A) ::= nm(Y).
/////////////////////////// Expression Processing /////////////////////////////
//
-%type expr {ExprSpan}
-%destructor expr {sqlite3ExprDelete(pParse->db, $$.pExpr);}
-%type term {ExprSpan}
-%destructor term {sqlite3ExprDelete(pParse->db, $$.pExpr);}
+%type expr {Expr*}
+%destructor expr {sqlite3ExprDelete(pParse->db, $$);}
+%type term {Expr*}
+%destructor term {sqlite3ExprDelete(pParse->db, $$);}
%include {
- /* This is a utility routine used to set the ExprSpan.zStart and
- ** ExprSpan.zEnd values of pOut so that the span covers the complete
- ** range of text beginning with pStart and going to the end of pEnd.
- */
- static void spanSet(ExprSpan *pOut, Token *pStart, Token *pEnd){
- pOut->zStart = pStart->z;
- pOut->zEnd = &pEnd->z[pEnd->n];
- }
/* Construct a new Expr object from a single identifier. Use the
** new Expr to populate pOut. Set the span of pOut to be the identifier
** that created the expression.
*/
- static void spanExpr(ExprSpan *pOut, Parse *pParse, int op, Token t){
+ static Expr *tokenExpr(Parse *pParse, int op, Token t){
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
if( p ){
memset(p, 0, sizeof(Expr));
@@ -866,136 +879,98 @@ idlist(A) ::= nm(Y).
p->nHeight = 1;
#endif
}
- pOut->pExpr = p;
- pOut->zStart = t.z;
- pOut->zEnd = &t.z[t.n];
+ return p;
}
}
expr(A) ::= term(A).
-expr(A) ::= LP(B) expr(X) RP(E).
- {spanSet(&A,&B,&E); /*A-overwrites-B*/ A.pExpr = X.pExpr;}
-expr(A) ::= id(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
-expr(A) ::= JOIN_KW(X). {spanExpr(&A,pParse,TK_ID,X); /*A-overwrites-X*/}
+expr(A) ::= LP expr(X) RP. {A = X;}
+expr(A) ::= id(X). {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/}
+expr(A) ::= JOIN_KW(X). {A=tokenExpr(pParse,TK_ID,X); /*A-overwrites-X*/}
expr(A) ::= nm(X) DOT nm(Y). {
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1);
- spanSet(&A,&X,&Y); /*A-overwrites-X*/
- A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
+ A = sqlite3PExpr(pParse, TK_DOT, temp1, temp2);
}
expr(A) ::= nm(X) DOT nm(Y) DOT nm(Z). {
Expr *temp1 = sqlite3ExprAlloc(pParse->db, TK_ID, &X, 1);
Expr *temp2 = sqlite3ExprAlloc(pParse->db, TK_ID, &Y, 1);
Expr *temp3 = sqlite3ExprAlloc(pParse->db, TK_ID, &Z, 1);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
- spanSet(&A,&X,&Z); /*A-overwrites-X*/
- A.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
+ A = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
-term(A) ::= NULL|FLOAT|BLOB(X). {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/}
-term(A) ::= STRING(X). {spanExpr(&A,pParse,@X,X); /*A-overwrites-X*/}
+term(A) ::= NULL|FLOAT|BLOB(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
+term(A) ::= STRING(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
term(A) ::= INTEGER(X). {
- A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
- A.zStart = X.z;
- A.zEnd = X.z + X.n;
+ A = sqlite3ExprAlloc(pParse->db, TK_INTEGER, &X, 1);
}
expr(A) ::= VARIABLE(X). {
if( !(X.z[0]=='#' && sqlite3Isdigit(X.z[1])) ){
u32 n = X.n;
- spanExpr(&A, pParse, TK_VARIABLE, X);
- sqlite3ExprAssignVarNumber(pParse, A.pExpr, n);
+ A = tokenExpr(pParse, TK_VARIABLE, X);
+ sqlite3ExprAssignVarNumber(pParse, A, n);
}else{
/* When doing a nested parse, one can include terms in an expression
** that look like this: #1 #2 ... These terms refer to registers
** in the virtual machine. #N is the N-th register. */
Token t = X; /*A-overwrites-X*/
assert( t.n>=2 );
- spanSet(&A, &t, &t);
if( pParse->nested==0 ){
sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &t);
- A.pExpr = 0;
+ A = 0;
}else{
- A.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
- if( A.pExpr ) sqlite3GetInt32(&t.z[1], &A.pExpr->iTable);
+ A = sqlite3PExpr(pParse, TK_REGISTER, 0, 0);
+ if( A ) sqlite3GetInt32(&t.z[1], &A->iTable);
}
}
}
expr(A) ::= expr(A) COLLATE ids(C). {
- A.pExpr = sqlite3ExprAddCollateToken(pParse, A.pExpr, &C, 1);
- A.zEnd = &C.z[C.n];
+ A = sqlite3ExprAddCollateToken(pParse, A, &C, 1);
}
%ifndef SQLITE_OMIT_CAST
-expr(A) ::= CAST(X) LP expr(E) AS typetoken(T) RP(Y). {
- spanSet(&A,&X,&Y); /*A-overwrites-X*/
- A.pExpr = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1);
- sqlite3ExprAttachSubtrees(pParse->db, A.pExpr, E.pExpr, 0);
+expr(A) ::= CAST LP expr(E) AS typetoken(T) RP. {
+ A = sqlite3ExprAlloc(pParse->db, TK_CAST, &T, 1);
+ sqlite3ExprAttachSubtrees(pParse->db, A, E, 0);
}
%endif SQLITE_OMIT_CAST
-expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP(E). {
+expr(A) ::= id(X) LP distinct(D) exprlist(Y) RP. {
if( Y && Y->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){
sqlite3ErrorMsg(pParse, "too many arguments on function %T", &X);
}
- A.pExpr = sqlite3ExprFunction(pParse, Y, &X);
- spanSet(&A,&X,&E);
- if( D==SF_Distinct && A.pExpr ){
- A.pExpr->flags |= EP_Distinct;
+ A = sqlite3ExprFunction(pParse, Y, &X);
+ if( D==SF_Distinct && A ){
+ A->flags |= EP_Distinct;
}
}
-expr(A) ::= id(X) LP STAR RP(E). {
- A.pExpr = sqlite3ExprFunction(pParse, 0, &X);
- spanSet(&A,&X,&E);
+expr(A) ::= id(X) LP STAR RP. {
+ A = sqlite3ExprFunction(pParse, 0, &X);
}
term(A) ::= CTIME_KW(OP). {
- A.pExpr = sqlite3ExprFunction(pParse, 0, &OP);
- spanSet(&A, &OP, &OP);
+ A = sqlite3ExprFunction(pParse, 0, &OP);
}
-%include {
- /* This routine constructs a binary expression node out of two ExprSpan
- ** objects and uses the result to populate a new ExprSpan object.
- */
- static void spanBinaryExpr(
- Parse *pParse, /* The parsing context. Errors accumulate here */
- int op, /* The binary operation */
- ExprSpan *pLeft, /* The left operand, and output */
- ExprSpan *pRight /* The right operand */
- ){
- pLeft->pExpr = sqlite3PExpr(pParse, op, pLeft->pExpr, pRight->pExpr);
- pLeft->zEnd = pRight->zEnd;
- }
-
- /* If doNot is true, then add a TK_NOT Expr-node wrapper around the
- ** outside of *ppExpr.
- */
- static void exprNot(Parse *pParse, int doNot, ExprSpan *pSpan){
- if( doNot ){
- pSpan->pExpr = sqlite3PExpr(pParse, TK_NOT, pSpan->pExpr, 0);
- }
- }
-}
-
-expr(A) ::= LP(L) nexprlist(X) COMMA expr(Y) RP(R). {
- ExprList *pList = sqlite3ExprListAppend(pParse, X, Y.pExpr);
- A.pExpr = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
- if( A.pExpr ){
- A.pExpr->x.pList = pList;
- spanSet(&A, &L, &R);
+expr(A) ::= LP nexprlist(X) COMMA expr(Y) RP. {
+ ExprList *pList = sqlite3ExprListAppend(pParse, X, Y);
+ A = sqlite3PExpr(pParse, TK_VECTOR, 0, 0);
+ if( A ){
+ A->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
}
-expr(A) ::= expr(A) AND(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
-expr(A) ::= expr(A) OR(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+expr(A) ::= expr(A) AND(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
+expr(A) ::= expr(A) OR(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) LT|GT|GE|LE(OP) expr(Y).
- {spanBinaryExpr(pParse,@OP,&A,&Y);}
-expr(A) ::= expr(A) EQ|NE(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+ {A=sqlite3PExpr(pParse,@OP,A,Y);}
+expr(A) ::= expr(A) EQ|NE(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) BITAND|BITOR|LSHIFT|RSHIFT(OP) expr(Y).
- {spanBinaryExpr(pParse,@OP,&A,&Y);}
+ {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) PLUS|MINUS(OP) expr(Y).
- {spanBinaryExpr(pParse,@OP,&A,&Y);}
+ {A=sqlite3PExpr(pParse,@OP,A,Y);}
expr(A) ::= expr(A) STAR|SLASH|REM(OP) expr(Y).
- {spanBinaryExpr(pParse,@OP,&A,&Y);}
-expr(A) ::= expr(A) CONCAT(OP) expr(Y). {spanBinaryExpr(pParse,@OP,&A,&Y);}
+ {A=sqlite3PExpr(pParse,@OP,A,Y);}
+expr(A) ::= expr(A) CONCAT(OP) expr(Y). {A=sqlite3PExpr(pParse,@OP,A,Y);}
%type likeop {Token}
likeop(A) ::= LIKE_KW|MATCH(A).
likeop(A) ::= NOT LIKE_KW|MATCH(X). {A=X; A.n|=0x80000000; /*A-overwrite-X*/}
@@ -1003,42 +978,26 @@ expr(A) ::= expr(A) likeop(OP) expr(Y). [LIKE_KW] {
ExprList *pList;
int bNot = OP.n & 0x80000000;
OP.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, A.pExpr);
- A.pExpr = sqlite3ExprFunction(pParse, pList, &OP);
- exprNot(pParse, bNot, &A);
- A.zEnd = Y.zEnd;
- if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, Y);
+ pList = sqlite3ExprListAppend(pParse,pList, A);
+ A = sqlite3ExprFunction(pParse, pList, &OP);
+ if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
+ if( A ) A->flags |= EP_InfixFunc;
}
expr(A) ::= expr(A) likeop(OP) expr(Y) ESCAPE expr(E). [LIKE_KW] {
ExprList *pList;
int bNot = OP.n & 0x80000000;
OP.n &= 0x7fffffff;
- pList = sqlite3ExprListAppend(pParse,0, Y.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, A.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, E.pExpr);
- A.pExpr = sqlite3ExprFunction(pParse, pList, &OP);
- exprNot(pParse, bNot, &A);
- A.zEnd = E.zEnd;
- if( A.pExpr ) A.pExpr->flags |= EP_InfixFunc;
+ pList = sqlite3ExprListAppend(pParse,0, Y);
+ pList = sqlite3ExprListAppend(pParse,pList, A);
+ pList = sqlite3ExprListAppend(pParse,pList, E);
+ A = sqlite3ExprFunction(pParse, pList, &OP);
+ if( bNot ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
+ if( A ) A->flags |= EP_InfixFunc;
}
-%include {
- /* Construct an expression node for a unary postfix operator
- */
- static void spanUnaryPostfix(
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand, and output */
- Token *pPostOp /* The operand token for setting the span */
- ){
- pOperand->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
- pOperand->zEnd = &pPostOp->z[pPostOp->n];
- }
-}
-
-expr(A) ::= expr(A) ISNULL|NOTNULL(E). {spanUnaryPostfix(pParse,@E,&A,&E);}
-expr(A) ::= expr(A) NOT NULL(E). {spanUnaryPostfix(pParse,TK_NOTNULL,&A,&E);}
+expr(A) ::= expr(A) ISNULL|NOTNULL(E). {A = sqlite3PExpr(pParse,@E,A,0);}
+expr(A) ::= expr(A) NOT NULL. {A = sqlite3PExpr(pParse,TK_NOTNULL,A,0);}
%include {
/* A routine to convert a binary TK_IS or TK_ISNOT expression into a
@@ -1060,61 +1019,42 @@ expr(A) ::= expr(A) NOT NULL(E). {spanUnaryPostfix(pParse,TK_NOTNULL,&A,&E);}
// is any other expression, code as TK_IS or TK_ISNOT.
//
expr(A) ::= expr(A) IS expr(Y). {
- spanBinaryExpr(pParse,TK_IS,&A,&Y);
- binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_ISNULL);
+ A = sqlite3PExpr(pParse,TK_IS,A,Y);
+ binaryToUnaryIfNull(pParse, Y, A, TK_ISNULL);
}
expr(A) ::= expr(A) IS NOT expr(Y). {
- spanBinaryExpr(pParse,TK_ISNOT,&A,&Y);
- binaryToUnaryIfNull(pParse, Y.pExpr, A.pExpr, TK_NOTNULL);
+ A = sqlite3PExpr(pParse,TK_ISNOT,A,Y);
+ binaryToUnaryIfNull(pParse, Y, A, TK_NOTNULL);
}
-%include {
- /* Construct an expression node for a unary prefix operator
- */
- static void spanUnaryPrefix(
- ExprSpan *pOut, /* Write the new expression node here */
- Parse *pParse, /* Parsing context to record errors */
- int op, /* The operator */
- ExprSpan *pOperand, /* The operand */
- Token *pPreOp /* The operand token for setting the span */
- ){
- pOut->zStart = pPreOp->z;
- pOut->pExpr = sqlite3PExpr(pParse, op, pOperand->pExpr, 0);
- pOut->zEnd = pOperand->zEnd;
- }
-}
-
-
-
expr(A) ::= NOT(B) expr(X).
- {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/}
+ {A = sqlite3PExpr(pParse, @B, X, 0);/*A-overwrites-B*/}
expr(A) ::= BITNOT(B) expr(X).
- {spanUnaryPrefix(&A,pParse,@B,&X,&B);/*A-overwrites-B*/}
-expr(A) ::= MINUS(B) expr(X). [BITNOT]
- {spanUnaryPrefix(&A,pParse,TK_UMINUS,&X,&B);/*A-overwrites-B*/}
-expr(A) ::= PLUS(B) expr(X). [BITNOT]
- {spanUnaryPrefix(&A,pParse,TK_UPLUS,&X,&B);/*A-overwrites-B*/}
+ {A = sqlite3PExpr(pParse, @B, X, 0);/*A-overwrites-B*/}
+expr(A) ::= MINUS expr(X). [BITNOT]
+ {A = sqlite3PExpr(pParse, TK_UMINUS, X, 0);}
+expr(A) ::= PLUS expr(X). [BITNOT]
+ {A = sqlite3PExpr(pParse, TK_UPLUS, X, 0);}
%type between_op {int}
between_op(A) ::= BETWEEN. {A = 0;}
between_op(A) ::= NOT BETWEEN. {A = 1;}
expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
- ExprList *pList = sqlite3ExprListAppend(pParse,0, X.pExpr);
- pList = sqlite3ExprListAppend(pParse,pList, Y.pExpr);
- A.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, A.pExpr, 0);
- if( A.pExpr ){
- A.pExpr->x.pList = pList;
+ ExprList *pList = sqlite3ExprListAppend(pParse,0, X);
+ pList = sqlite3ExprListAppend(pParse,pList, Y);
+ A = sqlite3PExpr(pParse, TK_BETWEEN, A, 0);
+ if( A ){
+ A->x.pList = pList;
}else{
sqlite3ExprListDelete(pParse->db, pList);
}
- exprNot(pParse, N, &A);
- A.zEnd = Y.zEnd;
+ if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
}
%ifndef SQLITE_OMIT_SUBQUERY
%type in_op {int}
in_op(A) ::= IN. {A = 0;}
in_op(A) ::= NOT IN. {A = 1;}
- expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP(E). [IN] {
+ expr(A) ::= expr(A) in_op(N) LP exprlist(Y) RP. [IN] {
if( Y==0 ){
/* Expressions of the form
**
@@ -1124,8 +1064,8 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
** simplify to constants 0 (false) and 1 (true), respectively,
** regardless of the value of expr1.
*/
- sqlite3ExprDelete(pParse->db, A.pExpr);
- A.pExpr = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
+ sqlite3ExprDelete(pParse->db, A);
+ A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1);
}else if( Y->nExpr==1 ){
/* Expressions of the form:
**
@@ -1152,54 +1092,48 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] {
pRHS->flags &= ~EP_Collate;
pRHS->flags |= EP_Generic;
}
- A.pExpr = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A.pExpr, pRHS);
+ A = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A, pRHS);
}else{
- A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0);
- if( A.pExpr ){
- A.pExpr->x.pList = Y;
- sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
+ A = sqlite3PExpr(pParse, TK_IN, A, 0);
+ if( A ){
+ A->x.pList = Y;
+ sqlite3ExprSetHeightAndFlags(pParse, A);
}else{
sqlite3ExprListDelete(pParse->db, Y);
}
- exprNot(pParse, N, &A);
+ if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
}
- A.zEnd = &E.z[E.n];
}
- expr(A) ::= LP(B) select(X) RP(E). {
- spanSet(&A,&B,&E); /*A-overwrites-B*/
- A.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
- sqlite3PExprAddSelect(pParse, A.pExpr, X);
+ expr(A) ::= LP select(X) RP. {
+ A = sqlite3PExpr(pParse, TK_SELECT, 0, 0);
+ sqlite3PExprAddSelect(pParse, A, X);
}
- expr(A) ::= expr(A) in_op(N) LP select(Y) RP(E). [IN] {
- A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0);
- sqlite3PExprAddSelect(pParse, A.pExpr, Y);
- exprNot(pParse, N, &A);
- A.zEnd = &E.z[E.n];
+ expr(A) ::= expr(A) in_op(N) LP select(Y) RP. [IN] {
+ A = sqlite3PExpr(pParse, TK_IN, A, 0);
+ sqlite3PExprAddSelect(pParse, A, Y);
+ if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
}
expr(A) ::= expr(A) in_op(N) nm(Y) dbnm(Z) paren_exprlist(E). [IN] {
SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&Y,&Z);
Select *pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0);
if( E ) sqlite3SrcListFuncArgs(pParse, pSelect ? pSrc : 0, E);
- A.pExpr = sqlite3PExpr(pParse, TK_IN, A.pExpr, 0);
- sqlite3PExprAddSelect(pParse, A.pExpr, pSelect);
- exprNot(pParse, N, &A);
- A.zEnd = Z.z ? &Z.z[Z.n] : &Y.z[Y.n];
+ A = sqlite3PExpr(pParse, TK_IN, A, 0);
+ sqlite3PExprAddSelect(pParse, A, pSelect);
+ if( N ) A = sqlite3PExpr(pParse, TK_NOT, A, 0);
}
- expr(A) ::= EXISTS(B) LP select(Y) RP(E). {
+ expr(A) ::= EXISTS LP select(Y) RP. {
Expr *p;
- spanSet(&A,&B,&E); /*A-overwrites-B*/
- p = A.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
+ p = A = sqlite3PExpr(pParse, TK_EXISTS, 0, 0);
sqlite3PExprAddSelect(pParse, p, Y);
}
%endif SQLITE_OMIT_SUBQUERY
/* CASE expressions */
-expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
- spanSet(&A,&C,&E); /*A-overwrites-C*/
- A.pExpr = sqlite3PExpr(pParse, TK_CASE, X, 0);
- if( A.pExpr ){
- A.pExpr->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
- sqlite3ExprSetHeightAndFlags(pParse, A.pExpr);
+expr(A) ::= CASE case_operand(X) case_exprlist(Y) case_else(Z) END. {
+ A = sqlite3PExpr(pParse, TK_CASE, X, 0);
+ if( A ){
+ A->x.pList = Z ? sqlite3ExprListAppend(pParse,Y,Z) : Y;
+ sqlite3ExprSetHeightAndFlags(pParse, A);
}else{
sqlite3ExprListDelete(pParse->db, Y);
sqlite3ExprDelete(pParse->db, Z);
@@ -1208,20 +1142,20 @@ expr(A) ::= CASE(C) case_operand(X) case_exprlist(Y) case_else(Z) END(E). {
%type case_exprlist {ExprList*}
%destructor case_exprlist {sqlite3ExprListDelete(pParse->db, $$);}
case_exprlist(A) ::= case_exprlist(A) WHEN expr(Y) THEN expr(Z). {
- A = sqlite3ExprListAppend(pParse,A, Y.pExpr);
- A = sqlite3ExprListAppend(pParse,A, Z.pExpr);
+ A = sqlite3ExprListAppend(pParse,A, Y);
+ A = sqlite3ExprListAppend(pParse,A, Z);
}
case_exprlist(A) ::= WHEN expr(Y) THEN expr(Z). {
- A = sqlite3ExprListAppend(pParse,0, Y.pExpr);
- A = sqlite3ExprListAppend(pParse,A, Z.pExpr);
+ A = sqlite3ExprListAppend(pParse,0, Y);
+ A = sqlite3ExprListAppend(pParse,A, Z);
}
%type case_else {Expr*}
%destructor case_else {sqlite3ExprDelete(pParse->db, $$);}
-case_else(A) ::= ELSE expr(X). {A = X.pExpr;}
+case_else(A) ::= ELSE expr(X). {A = X;}
case_else(A) ::= . {A = 0;}
%type case_operand {Expr*}
%destructor case_operand {sqlite3ExprDelete(pParse->db, $$);}
-case_operand(A) ::= expr(X). {A = X.pExpr; /*A-overwrites-X*/}
+case_operand(A) ::= expr(X). {A = X; /*A-overwrites-X*/}
case_operand(A) ::= . {A = 0;}
%type exprlist {ExprList*}
@@ -1232,9 +1166,9 @@ case_operand(A) ::= . {A = 0;}
exprlist(A) ::= nexprlist(A).
exprlist(A) ::= . {A = 0;}
nexprlist(A) ::= nexprlist(A) COMMA expr(Y).
- {A = sqlite3ExprListAppend(pParse,A,Y.pExpr);}
+ {A = sqlite3ExprListAppend(pParse,A,Y);}
nexprlist(A) ::= expr(Y).
- {A = sqlite3ExprListAppend(pParse,0,Y.pExpr); /*A-overwrites-Y*/}
+ {A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/}
%ifndef SQLITE_OMIT_SUBQUERY
/* A paren_exprlist is an optional expression list contained inside
@@ -1388,7 +1322,7 @@ foreach_clause ::= FOR EACH ROW.
%type when_clause {Expr*}
%destructor when_clause {sqlite3ExprDelete(pParse->db, $$);}
when_clause(A) ::= . { A = 0; }
-when_clause(A) ::= WHEN expr(X). { A = X.pExpr; }
+when_clause(A) ::= WHEN expr(X). { A = X; }
%type trigger_cmd_list {TriggerStep*}
%destructor trigger_cmd_list {sqlite3DeleteTriggerStep(pParse->db, $$);}
@@ -1453,18 +1387,16 @@ trigger_cmd(A) ::= select(X).
{A = sqlite3TriggerSelectStep(pParse->db, X); /*A-overwrites-X*/}
// The special RAISE expression that may occur in trigger programs
-expr(A) ::= RAISE(X) LP IGNORE RP(Y). {
- spanSet(&A,&X,&Y); /*A-overwrites-X*/
- A.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
- if( A.pExpr ){
- A.pExpr->affinity = OE_Ignore;
+expr(A) ::= RAISE LP IGNORE RP. {
+ A = sqlite3PExpr(pParse, TK_RAISE, 0, 0);
+ if( A ){
+ A->affinity = OE_Ignore;
}
}
-expr(A) ::= RAISE(X) LP raisetype(T) COMMA nm(Z) RP(Y). {
- spanSet(&A,&X,&Y); /*A-overwrites-X*/
- A.pExpr = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
- if( A.pExpr ) {
- A.pExpr->affinity = (char)T;
+expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. {
+ A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
+ if( A ) {
+ A->affinity = (char)T;
}
}
%endif !SQLITE_OMIT_TRIGGER
@@ -1485,16 +1417,16 @@ cmd ::= DROP TRIGGER ifexists(NOERR) fullname(X). {
//////////////////////// ATTACH DATABASE file AS name /////////////////////////
%ifndef SQLITE_OMIT_ATTACH
cmd ::= ATTACH database_kw_opt expr(F) AS expr(D) key_opt(K). {
- sqlite3Attach(pParse, F.pExpr, D.pExpr, K);
+ sqlite3Attach(pParse, F, D, K);
}
cmd ::= DETACH database_kw_opt expr(D). {
- sqlite3Detach(pParse, D.pExpr);
+ sqlite3Detach(pParse, D);
}
%type key_opt {Expr*}
%destructor key_opt {sqlite3ExprDelete(pParse->db, $$);}
key_opt(A) ::= . { A = 0; }
-key_opt(A) ::= KEY expr(X). { A = X.pExpr; }
+key_opt(A) ::= KEY expr(X). { A = X; }
database_kw_opt ::= DATABASE.
database_kw_opt ::= .
diff --git a/src/sqliteInt.h b/src/sqliteInt.h
index b0c4711b0..93099ca1d 100644
--- a/src/sqliteInt.h
+++ b/src/sqliteInt.h
@@ -1063,7 +1063,6 @@ typedef struct Db Db;
typedef struct Schema Schema;
typedef struct Expr Expr;
typedef struct ExprList ExprList;
-typedef struct ExprSpan ExprSpan;
typedef struct FKey FKey;
typedef struct FuncDestructor FuncDestructor;
typedef struct FuncDef FuncDef;
@@ -2505,17 +2504,6 @@ struct ExprList {
};
/*
-** An instance of this structure is used by the parser to record both
-** the parse tree for an expression and the span of input text for an
-** expression.
-*/
-struct ExprSpan {
- Expr *pExpr; /* The expression parse tree */
- const char *zStart; /* First character of input text */
- const char *zEnd; /* One character past the end of input text */
-};
-
-/*
** An instance of this structure can hold a simple list of identifiers,
** such as the list "a,b,c" in the following statements:
**
@@ -3663,7 +3651,7 @@ ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
void sqlite3ExprListSetSortOrder(ExprList*,int);
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
-void sqlite3ExprListSetSpan(Parse*,ExprList*,ExprSpan*);
+void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
void sqlite3ExprListDelete(sqlite3*, ExprList*);
u32 sqlite3ExprListFlags(const ExprList*);
int sqlite3Init(sqlite3*, char**);
@@ -3693,7 +3681,7 @@ void sqlite3AddColumn(Parse*,Token*,Token*);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*);
-void sqlite3AddDefaultValue(Parse*,ExprSpan*);
+void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
void sqlite3AddCollateType(Parse*, Token*);
void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
int sqlite3ParseUri(const char*,const char*,unsigned int*,