Record the position of many identifiers in the parse using the new

Expr.w.iOfst field.  This is done with the idea of providing offset
results for sqlite3_error_offset() for a more kinds of errors, though that
part is not yet implemented.

FossilOrigin-Name: 32a3a53b62ab09ac2212905e7f42fe6f1b09d891e015203e5caf4cb16262f18e
This commit is contained in:
drh 2022-02-05 21:49:47 +00:00
parent 4734b3f9b7
commit 796588ae07
9 changed files with 48 additions and 53 deletions

View File

@ -1,5 +1,5 @@
C Update\sstale\sevidence\smarks\son\ssqlite3_vtab_rhs_value()\stest\scases.
D 2022-02-05T13:27:52.187
C Record\sthe\sposition\sof\smany\sidentifiers\sin\sthe\sparse\susing\sthe\snew\nExpr.w.iOfst\sfield.\s\sThis\sis\sdone\swith\sthe\sidea\sof\sproviding\soffset\nresults\sfor\ssqlite3_error_offset()\sfor\sa\smore\skinds\sof\serrors,\sthough\sthat\npart\sis\snot\syet\simplemented.
D 2022-02-05T21:49:47.746
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@ -541,7 +541,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c f6183fb7370425cd8642759693d9994649217cf7111caef89bc2c4946afbc36d
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
F src/parse.y 04f61db1cdd7036c6d74baad1c342d3e3110cb0765c48fcfd3bdf4e974a1e5bb
F src/parse.y 0b8d621453e18ac2ea15c237c14bd5451478b3f4e13a5a4020153bbb14ec34ee
F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
@ -552,12 +552,12 @@ F src/printf.c 975f1f5417f2526365b6e6d7f22332e3e11806dad844701d92846292b654ba9a
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c 0dd8e23fda88411d63b2e6650f2380fdb08e88112e9a095fc23d5a08de4b2641
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c a6d2d4bed279d7fe4fcedaf297eaf6441e8e17c6e3947a32d24d23be52ac02f2
F src/select.c 3baa9dd8cf240654773c7974e2bcce398ac9dd24419c36684156963defe43b35
F src/shell.c.in 2f58e6aa6b3d2012db32f1c5fa4591e9d12fd582904632b4fc8f57a382b98fd3
F src/sqlite.h.in 800d6509517d383d38188e71bb5f1802c7db097a1282af7bf5d6c9a6da5a15ed
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h a95cb9ed106e3d39e2118e4dcc15a14faec3fa50d0093425083d340d9dfd96e6
F src/sqliteInt.h 838df3e9ba9390058076d2f50c7efde9e0e8747303e788cf5bbe05402ab10924
F src/sqliteInt.h 763162b933c7498d3bd9181688957ca6e7bdd37c5f2000bc08e2ef1c4a2f68a3
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@ -617,7 +617,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c b74d878aa7c82ec8460779468061a96185e22257f68ab785b69abce354b70446
F src/treeview.c 9dfdb7ff7f6645d0a6458dbdf4ffac041c071c4533a6db8bb6e502b979ac67bc
F src/treeview.c a84b57d15e46007d8b1ae249344b3f0b7f3c62def908b98baaa54935a57c8476
F src/trigger.c 692972e4393dfc8017a1a527c1ea1b96ce3d101e84584cd832fcfb83d22b50b2
F src/update.c f875b0d59da5c3055a0b2ac20560e1650229c6787e78de5e9836267b5cbb8359
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
@ -639,10 +639,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
F src/where.c 31bc1f43b0bf679e93c3e7a7d67cbcaddc7ae746694b149b282427d337b06caa
F src/where.c 4e8f27c9829818a3210e8c97b5c23f7c2fb67e68a5750a3e40384bbed24ce69e
F src/whereInt.h 15d2975c3b4c193c78c26674400a840da8647fe1777ae3b026e2d15937b38a03
F src/wherecode.c 4a0dd0403e1c9b628a420eefbe1d60da0003356de6ee18e6707480c9b995bae7
F src/whereexpr.c 2da56404a024dc8dc41a31d8b498eed2c7c6b0bb412150d88cb3327516aa3b9f
F src/wherecode.c 6150f51c0368be941fad90a736ce37cc1e2a719876750a3183a516ed256a4cbb
F src/whereexpr.c ee4b962c8f8613afb8cd656b3a470130c42c952dd4af2ad1d2294d37a47bb1f1
F src/window.c dfaec4abc6012cbc18e4a202ca3a5d5a0efcc4011d86a06d882ddaab8aedee4d
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
@ -1943,8 +1943,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P fc4c82e5694cbdae13f2cb90e5368ba9f6b826a220a81de32ead2ffe1bc5f31f
R 77f0ae55ad3d60a43a54eedbd1ba900e
P 46744b83d5e1335bcbc59f9625e8ade3f360469d17f34e8d996f077ba9afa89e
R 0a4aa7afd9e04bf279efc53c3cded45e
U drh
Z 7f71ba7f9f59dcc236766823f2cedb34
Z 533fa15e28ce8e0df54f074f779eaaaf
# Remove this line to create a well-formed Fossil manifest.

View File

@ -1 +1 @@
46744b83d5e1335bcbc59f9625e8ade3f360469d17f34e8d996f077ba9afa89e
32a3a53b62ab09ac2212905e7f42fe6f1b09d891e015203e5caf4cb16262f18e

View File

@ -659,7 +659,7 @@ selcollist(A) ::= sclp(A) scanpt 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 *pLeft = tokenExpr(pParse, TK_ID, X);
Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight);
A = sqlite3ExprListAppend(pParse,A, pDot);
}
@ -1025,10 +1025,7 @@ idlist(A) ::= nm(Y).
%include {
/* 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.
*/
/* Construct a new Expr object from a single token */
static Expr *tokenExpr(Parse *pParse, int op, Token t){
Expr *p = sqlite3DbMallocRawNN(pParse->db, sizeof(Expr)+t.n+1);
if( p ){
@ -1048,6 +1045,7 @@ idlist(A) ::= nm(Y).
p->u.zToken = (char*)&p[1];
memcpy(p->u.zToken, t.z, t.n);
p->u.zToken[t.n] = 0;
p->w.iOfst = (int)(t.z - pParse->zTail);
if( sqlite3Isquote(p->u.zToken[0]) ){
sqlite3DequoteExpr(p);
}
@ -1068,23 +1066,15 @@ 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);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (void*)temp2, &Y);
sqlite3RenameTokenMap(pParse, (void*)temp1, &X);
}
Expr *temp1 = tokenExpr(pParse,TK_ID,X);
Expr *temp2 = tokenExpr(pParse,TK_ID,Y);
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 *temp1 = tokenExpr(pParse,TK_ID,X);
Expr *temp2 = tokenExpr(pParse,TK_ID,Y);
Expr *temp3 = tokenExpr(pParse,TK_ID,Z);
Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3);
if( IN_RENAME_OBJECT ){
sqlite3RenameTokenMap(pParse, (void*)temp3, &Z);
sqlite3RenameTokenMap(pParse, (void*)temp2, &Y);
}
A = sqlite3PExpr(pParse, TK_DOT, temp1, temp4);
}
term(A) ::= NULL|FLOAT|BLOB(X). {A=tokenExpr(pParse,@X,X); /*A-overwrites-X*/}
@ -1593,7 +1583,7 @@ expr(A) ::= RAISE LP IGNORE RP. {
}
}
expr(A) ::= RAISE LP raisetype(T) COMMA nm(Z) RP. {
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
A = sqlite3ExprAlloc(pParse->db, TK_RAISE, &Z, 1);
if( A ) {
A->affExpr = (char)T;
}

View File

@ -354,14 +354,14 @@ static void addWhereTerm(
ExprSetProperty(pEq, EP_FromJoin);
assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(pEq, EP_NoReduce);
pEq->iRightJoinTable = pE2->iTable;
pEq->w.iRightJoinTable = pE2->iTable;
}
*ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
}
/*
** Set the EP_FromJoin property on all terms of the given expression.
** And set the Expr.iRightJoinTable to iTable for every term in the
** And set the Expr.w.iRightJoinTable to iTable for every term in the
** expression.
**
** The EP_FromJoin property is used on terms of an expression to tell
@ -371,8 +371,8 @@ static void addWhereTerm(
** WHERE clause during join processing but we need to remember that they
** originated in the ON or USING clause.
**
** The Expr.iRightJoinTable tells the WHERE clause processing that the
** expression depends on table iRightJoinTable even if that table is not
** The Expr.w.iRightJoinTable tells the WHERE clause processing that the
** expression depends on table w.iRightJoinTable even if that table is not
** explicitly mentioned in the expression. That information is needed
** for cases like this:
**
@ -390,7 +390,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){
ExprSetProperty(p, EP_FromJoin);
assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) );
ExprSetVVAProperty(p, EP_NoReduce);
p->iRightJoinTable = iTable;
p->w.iRightJoinTable = iTable;
if( p->op==TK_FUNCTION ){
assert( ExprUseXList(p) );
if( p->x.pList ){
@ -406,7 +406,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){
}
/* Undo the work of sqlite3SetJoinExpr(). In the expression p, convert every
** term that is marked with EP_FromJoin and iRightJoinTable==iTable into
** term that is marked with EP_FromJoin and w.iRightJoinTable==iTable into
** an ordinary term that omits the EP_FromJoin mark.
**
** This happens when a LEFT JOIN is simplified into an ordinary JOIN.
@ -414,7 +414,7 @@ void sqlite3SetJoinExpr(Expr *p, int iTable){
static void unsetJoinExpr(Expr *p, int iTable){
while( p ){
if( ExprHasProperty(p, EP_FromJoin)
&& (iTable<0 || p->iRightJoinTable==iTable) ){
&& (iTable<0 || p->w.iRightJoinTable==iTable) ){
ExprClearProperty(p, EP_FromJoin);
}
if( p->op==TK_COLUMN && p->iTable==iTable ){
@ -3648,9 +3648,9 @@ static Expr *substExpr(
){
if( pExpr==0 ) return 0;
if( ExprHasProperty(pExpr, EP_FromJoin)
&& pExpr->iRightJoinTable==pSubst->iTable
&& pExpr->w.iRightJoinTable==pSubst->iTable
){
pExpr->iRightJoinTable = pSubst->iNewTable;
pExpr->w.iRightJoinTable = pSubst->iNewTable;
}
if( pExpr->op==TK_COLUMN
&& pExpr->iTable==pSubst->iTable
@ -3689,7 +3689,7 @@ static Expr *substExpr(
ExprSetProperty(pNew, EP_CanBeNull);
}
if( ExprHasProperty(pExpr,EP_FromJoin) ){
sqlite3SetJoinExpr(pNew, pExpr->iRightJoinTable);
sqlite3SetJoinExpr(pNew, pExpr->w.iRightJoinTable);
}
sqlite3ExprDelete(db, pExpr);
pExpr = pNew;
@ -3854,7 +3854,7 @@ static int renumberCursorsCb(Walker *pWalker, Expr *pExpr){
renumberCursorDoMapping(pWalker, &pExpr->iTable);
}
if( ExprHasProperty(pExpr, EP_FromJoin) ){
renumberCursorDoMapping(pWalker, &pExpr->iRightJoinTable);
renumberCursorDoMapping(pWalker, &pExpr->w.iRightJoinTable);
}
return WRC_Continue;
}
@ -4864,11 +4864,13 @@ static int pushDownWhereTerms(
}
if( isLeftJoin
&& (ExprHasProperty(pWhere,EP_FromJoin)==0
|| pWhere->iRightJoinTable!=iCursor)
|| pWhere->w.iRightJoinTable!=iCursor)
){
return 0; /* restriction (4) */
}
if( ExprHasProperty(pWhere,EP_FromJoin) && pWhere->iRightJoinTable!=iCursor ){
if( ExprHasProperty(pWhere,EP_FromJoin)
&& pWhere->w.iRightJoinTable!=iCursor
){
return 0; /* restriction (5) */
}
if( sqlite3ExprIsTableConstant(pWhere, iCursor) ){

View File

@ -2824,7 +2824,10 @@ struct Expr {
** TK_VARIABLE: variable number (always >= 1).
** TK_SELECT_COLUMN: column of the result vector */
i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */
int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
union {
int iRightJoinTable; /* If EP_FromJoin, the right table of the join */
int iOfst; /* else: start of token from start of statement */
} w;
AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */
union {
Table *pTab; /* TK_COLUMN: Table containing column. Can be NULL

View File

@ -412,7 +412,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
sqlite3_str_appendf(&x, " fg.af=%x.%c",
pExpr->flags, pExpr->affExpr ? pExpr->affExpr : 'n');
if( ExprHasProperty(pExpr, EP_FromJoin) ){
sqlite3_str_appendf(&x, " iRJT=%d", pExpr->iRightJoinTable);
sqlite3_str_appendf(&x, " iRJT=%d", pExpr->w.iRightJoinTable);
}
if( ExprHasProperty(pExpr, EP_FromDDL) ){
sqlite3_str_appendf(&x, " DDL");

View File

@ -3166,7 +3166,7 @@ static int whereUsablePartialIndex(
for(i=0, pTerm=pWC->a; i<pWC->nTerm; i++, pTerm++){
Expr *pExpr;
pExpr = pTerm->pExpr;
if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab)
if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->w.iRightJoinTable==iTab)
&& (isLeft==0 || ExprHasProperty(pExpr, EP_FromJoin))
&& sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab)
&& (pTerm->wtFlags & TERM_VNULL)==0
@ -5146,7 +5146,7 @@ static SQLITE_NOINLINE Bitmask whereOmitNoopJoin(
for(pTerm=pWInfo->sWC.a; pTerm<pEnd; pTerm++){
if( (pTerm->prereqAll & pLoop->maskSelf)!=0 ){
if( !ExprHasProperty(pTerm->pExpr, EP_FromJoin)
|| pTerm->pExpr->iRightJoinTable!=pItem->iCursor
|| pTerm->pExpr->w.iRightJoinTable!=pItem->iCursor
){
break;
}

View File

@ -1062,7 +1062,7 @@ static void codeCursorHint(
if( pTabItem->fg.jointype & JT_LEFT ){
Expr *pExpr = pTerm->pExpr;
if( !ExprHasProperty(pExpr, EP_FromJoin)
|| pExpr->iRightJoinTable!=pTabItem->iCursor
|| pExpr->w.iRightJoinTable!=pTabItem->iCursor
){
sWalker.eCode = 0;
sWalker.xExprCallback = codeCursorHintIsOrFunction;

View File

@ -466,7 +466,7 @@ static int isAuxiliaryVtabOperator(
static void transferJoinMarkings(Expr *pDerived, Expr *pBase){
if( pDerived ){
pDerived->flags |= pBase->flags & EP_FromJoin;
pDerived->iRightJoinTable = pBase->iRightJoinTable;
pDerived->w.iRightJoinTable = pBase->w.iRightJoinTable;
}
}
@ -1111,7 +1111,7 @@ static void exprAnalyze(
#endif
if( ExprHasProperty(pExpr, EP_FromJoin) ){
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->iRightJoinTable);
Bitmask x = sqlite3WhereGetMask(pMaskSet, pExpr->w.iRightJoinTable);
prereqAll |= x;
extraRight = x-1; /* ON clause terms may not be used with an index
** on left table of a LEFT JOIN. Ticket #3015 */
@ -1462,7 +1462,7 @@ static void exprAnalyze(
0, sqlite3ExprDup(db, pRight, 0));
if( ExprHasProperty(pExpr, EP_FromJoin) && pNewExpr ){
ExprSetProperty(pNewExpr, EP_FromJoin);
pNewExpr->iRightJoinTable = pExpr->iRightJoinTable;
pNewExpr->w.iRightJoinTable = pExpr->w.iRightJoinTable;
}
idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC);
testcase( idxNew==0 );