1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Protect access to the Expr.y union using nearby assert()s and branches.

FossilOrigin-Name: 87e2f5eb436fc448427b0e24fb70f29688796b513b8c7b12f1a21540dae1e56d
This commit is contained in:
drh
2021-10-07 20:46:29 +00:00
parent 867bc4de2e
commit 477572b9f1
13 changed files with 131 additions and 78 deletions

View File

@@ -1,5 +1,5 @@
C Break\sthe\stcl\srelease\stests\sinto\ssmaller\sunits\sto\sbetter\stake\sadvantage\sof\smulti-processor\ssystems. C Protect\saccess\sto\sthe\sExpr.y\sunion\susing\snearby\sassert()s\sand\sbranches.
D 2021-10-07T19:27:17.394 D 2021-10-07T20:46:29.719
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -483,7 +483,7 @@ F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca
F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b
F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c c3ef7565031b96f70c6d240929052cc2603e54df4a48025e2387104c804b2de6 F src/alter.c 9578c5a54027166688ec3e679ed10e85a3d08b986210e98d736f57aacc63335a
F src/analyze.c 979b6d2cdaca992a9c9f0818de55d08fb9a4e52929a509752b52d9fd23bb86d3 F src/analyze.c 979b6d2cdaca992a9c9f0818de55d08fb9a4e52929a509752b52d9fd23bb86d3
F src/attach.c e3f9d9a2a4a844750f3f348f37afb244535f21382cbfcd840152cb21cb41cfaf F src/attach.c e3f9d9a2a4a844750f3f348f37afb244535f21382cbfcd840152cb21cb41cfaf
F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf
@@ -501,9 +501,9 @@ F src/date.c fa928630fecf1d436cdc7a7a5c950c781709023ca782c21b7a43cc7361a9451e
F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a F src/dbpage.c 8a01e865bf8bc6d7b1844b4314443a6436c07c3efe1d488ed89e81719047833a
F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d F src/dbstat.c 861e08690fcb0f2ee1165eff0060ea8d4f3e2ea10f80dab7d32ad70443a6ff2d
F src/delete.c 3ce6af6b64c8b476de51ccc32da0cb3142d42e65754e1d8118addf65b8bcba15 F src/delete.c 3ce6af6b64c8b476de51ccc32da0cb3142d42e65754e1d8118addf65b8bcba15
F src/expr.c 19c0b5c7afaf6a305274b7de312f319bd86e802383f08ef6633f0752f51d96a8 F src/expr.c 529f7eca2821e874a375b1b318e697d62cb28f56069677c93f587f2de5dceb54
F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
F src/fkey.c 0c57a9cd2a0ecd04dde0c06e41df46959526f52a68c4409591e0f8c41a577042 F src/fkey.c 187b67af20c5795953a592832c5d985e4313fe503ebd8f95e3e9e9ad5a730bb5
F src/func.c 9577175a1459f65c9e3c4bbe7ed0bdf97ee928f693c81ee9f61e2642414c917c F src/func.c 9577175a1459f65c9e3c4bbe7ed0bdf97ee928f693c81ee9f61e2642414c917c
F src/global.c 612ea60c9acbcb45754c2ed659b4a56936a06814718e969636fedc7e3b889808 F src/global.c 612ea60c9acbcb45754c2ed659b4a56936a06814718e969636fedc7e3b889808
F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19
@@ -538,7 +538,7 @@ F src/os_win.c 77d39873836f1831a9b0b91894fec45ab0e9ca8e067dc8c549e1d1eca1566fe9
F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
F src/pager.c e20778eee03916035f5fb861bab7edb894779b1c448c3725fd4cde5f6a3edc6d F src/pager.c e20778eee03916035f5fb861bab7edb894779b1c448c3725fd4cde5f6a3edc6d
F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f F src/pager.h 4bf9b3213a4b2bebbced5eaa8b219cf25d4a82f385d093cd64b7e93e5285f66f
F src/parse.y 82bdd593c50bddcc285a173e9788a20296103217f5f5290c9122abf8af71af62 F src/parse.y 0bd7971a7489bbf6c3726f1b50da6e508bdff8fa493e9cc3f5a96b12cbb2361e
F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b F src/pcache.c 084e638432c610f95aea72b8509f0845d2791293f39d1b82f0c0a7e089c3bb6b
F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65 F src/pcache1.c 54881292a9a5db202b2c0ac541c5e3ef9a5e8c4f1c1383adb2601d5499a60e65
@@ -547,14 +547,14 @@ F src/pragma.h 87330ed2fbfa2a1274de93ca0ab850fba336189228cb256089202c3b52766fad
F src/prepare.c 8f07616db04337057b8498b72d051ee90f73c54615c2e908c05404cef1e060b7 F src/prepare.c 8f07616db04337057b8498b72d051ee90f73c54615c2e908c05404cef1e060b7
F src/printf.c 5901672228f305f7d493cbc4e7d76a61a5caecdbc1cd06b1f9ec42ea4265cf8d F src/printf.c 5901672228f305f7d493cbc4e7d76a61a5caecdbc1cd06b1f9ec42ea4265cf8d
F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c F src/random.c 097dc8b31b8fba5a9aca1697aeb9fd82078ec91be734c16bffda620ced7ab83c
F src/resolve.c 7f8954f49ddf18d16a13866593eb4f51a6deba8b30b2d877e27ef1b385cd94db F src/resolve.c ae65c88f5d0d4bc0052b203773d407efa2387c2bd6b202f87178006c7bb8632c
F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92
F src/select.c 6164779bdafadf23f506e87224095b73f27be519b242579bd9d24a6d6a53d9fb F src/select.c 56069fb5fae836179ffb58e8c4a2723a8c4e146abf7892472fbc5534a86e353f
F src/shell.c.in ac685e63c506fb2e39375c83347c88bff84dc48fa5d6a59f508d7d67951693a0 F src/shell.c.in ac685e63c506fb2e39375c83347c88bff84dc48fa5d6a59f508d7d67951693a0
F src/sqlite.h.in 4e977a5e2ed1a9e8987ff65a2cab5f99a4298ebf040ea5ff636e1753339ff45a F src/sqlite.h.in 4e977a5e2ed1a9e8987ff65a2cab5f99a4298ebf040ea5ff636e1753339ff45a
F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510 F src/sqlite3ext.h e97f4e9b509408fea4c4e9bef5a41608dfac343b4d3c7a990dedde1e19af9510
F src/sqliteInt.h e62e6eab356e01a8cf1c88d0a2ec7e403e5d3b141b4816ec0b5ea23acd1fcd14 F src/sqliteInt.h 62fad2ae3aaf94a9398d031dc20bd147e2954a93e3d85455f3d999bebed48121
F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1 F src/status.c 4b8bc2a6905163a38b739854a35b826c737333fab5b1f8e03fa7eb9a4799c4c1
F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -614,7 +614,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c
F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e F src/tokenize.c bae853ad129d1129c063de8630a3e99e306283bc40146f359b1bb91be2c08f1e
F src/treeview.c e80a6126f82c0cd0a939aa617c428329c6e2c3351b7d4dabb8b8a83c9b4e7696 F src/treeview.c 9dfdb7ff7f6645d0a6458dbdf4ffac041c071c4533a6db8bb6e502b979ac67bc
F src/trigger.c 3f612ce5f0858b6c23460a3c799d01f408b49b0b29d931d8b8e6fc224a8667de F src/trigger.c 3f612ce5f0858b6c23460a3c799d01f408b49b0b29d931d8b8e6fc224a8667de
F src/update.c 69c4c10bc6873a80c0a77cb578f9fc60ee90003d03f9530bc3370fa24615772d F src/update.c 69c4c10bc6873a80c0a77cb578f9fc60ee90003d03f9530bc3370fa24615772d
F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937 F src/upsert.c 8789047a8f0a601ea42fa0256d1ba3190c13746b6ba940fe2d25643a7e991937
@@ -631,15 +631,15 @@ F src/vdbemem.c 8be0af1060012520381d3296fcb1718e80cd5b99ce04f51f7e1c4dba4072caac
F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2 F src/vdbesort.c cd5130f683706c1a43e165a74187745fb3351cb56052cf9dc91de820634bbde2
F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823
F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c F src/vdbevtab.c f99b275366c5fc5e2d99f734729880994ab9500bdafde7fae3b02d562b9d323c
F src/vtab.c 3a6640d86d5dfae8f69715a1ee7405bb96d8982b39655b91c1f3648baae476a8 F src/vtab.c d07cc24dd84b0b51bf05adb187b0d2e6b0cac56cfbc0197995a26d4f8fa5c7e2
F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c F src/wal.c 2be08331d798237ad5d7ae0b252700ffb2b63189cb18d993496d009a93e2f81c
F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
F src/where.c 56e1902e9b91fb1fe159181a21c34abd59a01e2cb8f5ef4c3e478d32c5d838df F src/where.c 56e1902e9b91fb1fe159181a21c34abd59a01e2cb8f5ef4c3e478d32c5d838df
F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b F src/whereInt.h 9248161dd004f625ce5d3841ca9b99fed3fc8d61522cf76340fc5217dbe1375b
F src/wherecode.c 6721f5de1d74d952b473c3f2473ea36b4a3aafed2c0ae0edb02c7e8a6b908d43 F src/wherecode.c 0bb4a2a82fc9ccfce105fb2ff2921de373c62aa60c770029f95bd8b685f3498a
F src/whereexpr.c 01d87dc0d5fb0a18100a65ba5466e399f2b8d96b3ec8a6056cf2aac10436afa5 F src/whereexpr.c 4514a162d878b6523a698fac1d760991b5728be0d7e2b2b0687aa175144dcf15
F src/window.c 0dff6fedf61493490d21ced5d7a7b4321d4c0db6c8123f0179c46080a860850a F src/window.c 0dff6fedf61493490d21ced5d7a7b4321d4c0db6c8123f0179c46080a860850a
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627
@@ -1928,7 +1928,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
P 8eaa1d4a98b24adf245bbd2fe9212aa6a924a0f09c445906d7f87574f36a7423 P 03cef1c30d96cd42682f57667bb3072c7643ef43fe05eda2d8b82c30789234af
R 5eb83fb05c47023834fe1cae6d00b957 R 06b773afbf19fb9230871daeb2e22572
U dan U drh
Z 9054f47cc6bebbf9ed5d65ed018c55d7 Z 58c40dd2d56708967ad96d2415e961d1

View File

@@ -1 +1 @@
03cef1c30d96cd42682f57667bb3072c7643ef43fe05eda2d8b82c30789234af 87e2f5eb436fc448427b0e24fb70f29688796b513b8c7b12f1a21540dae1e56d

View File

@@ -805,7 +805,9 @@ void sqlite3RenameTokenRemap(Parse *pParse, const void *pTo, const void *pFrom){
static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){ static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
Parse *pParse = pWalker->pParse; Parse *pParse = pWalker->pParse;
sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr); sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr);
if( ExprUseYTab(pExpr) ){
sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab); sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab);
}
return WRC_Continue; return WRC_Continue;
} }
@@ -1004,6 +1006,7 @@ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){
renameTokenFind(pWalker->pParse, p, (void*)pExpr); renameTokenFind(pWalker->pParse, p, (void*)pExpr);
}else if( pExpr->op==TK_COLUMN }else if( pExpr->op==TK_COLUMN
&& pExpr->iColumn==p->iCol && pExpr->iColumn==p->iCol
&& ALWAYS(ExprUseYTab(pExpr))
&& p->pTab==pExpr->y.pTab && p->pTab==pExpr->y.pTab
){ ){
renameTokenFind(pWalker->pParse, p, (void*)pExpr); renameTokenFind(pWalker->pParse, p, (void*)pExpr);
@@ -1606,7 +1609,10 @@ renameColumnFunc_done:
*/ */
static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ static int renameTableExprCb(Walker *pWalker, Expr *pExpr){
RenameCtx *p = pWalker->u.pRename; RenameCtx *p = pWalker->u.pRename;
if( pExpr->op==TK_COLUMN && p->pTab==pExpr->y.pTab ){ if( pExpr->op==TK_COLUMN
&& ALWAYS(ExprUseYTab(pExpr))
&& p->pTab==pExpr->y.pTab
){
renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab); renameTokenFind(pWalker->pParse, p, (void*)&pExpr->y.pTab);
} }
return WRC_Continue; return WRC_Continue;

View File

@@ -53,9 +53,12 @@ char sqlite3ExprAffinity(const Expr *pExpr){
} }
op = pExpr->op; op = pExpr->op;
if( op==TK_REGISTER ) op = pExpr->op2; if( op==TK_REGISTER ) op = pExpr->op2;
if( (op==TK_COLUMN || op==TK_AGG_COLUMN) && pExpr->y.pTab ){ if( op==TK_COLUMN || op==TK_AGG_COLUMN ){
assert( ExprUseYTab(pExpr) );
if( pExpr->y.pTab ){
return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); return sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
} }
}
if( op==TK_SELECT ){ if( op==TK_SELECT ){
assert( ExprUseXSelect(pExpr) ); assert( ExprUseXSelect(pExpr) );
assert( pExpr->x.pSelect!=0 ); assert( pExpr->x.pSelect!=0 );
@@ -171,9 +174,9 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
while( p ){ while( p ){
int op = p->op; int op = p->op;
if( op==TK_REGISTER ) op = p->op2; if( op==TK_REGISTER ) op = p->op2;
if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER) if( op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER ){
&& p->y.pTab!=0 assert( ExprUseYTab(p) );
){ if( p->y.pTab!=0 ){
/* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally /* op==TK_REGISTER && p->y.pTab!=0 happens when pExpr was originally
** a TK_COLUMN but was previously evaluated and cached in a register */ ** a TK_COLUMN but was previously evaluated and cached in a register */
int j = p->iColumn; int j = p->iColumn;
@@ -183,6 +186,7 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr){
} }
break; break;
} }
}
if( op==TK_CAST || op==TK_UPLUS ){ if( op==TK_CAST || op==TK_UPLUS ){
p = p->pLeft; p = p->pLeft;
continue; continue;
@@ -1200,12 +1204,10 @@ void sqlite3ExprAssignVarNumber(Parse *pParse, Expr *pExpr, u32 n){
*/ */
static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){ static SQLITE_NOINLINE void sqlite3ExprDeleteNN(sqlite3 *db, Expr *p){
assert( p!=0 ); assert( p!=0 );
/* Sanity check: Assert that the IntValue is non-negative if it exists */ assert( !ExprUseUValue(p) || p->u.iValue>=0 );
assert( !ExprHasProperty(p, EP_IntValue) || p->u.iValue>=0 ); assert( !ExprUseYWin(p) || !ExprUseYSub(p) );
assert( !ExprUseYWin(p) || p->y.pWin!=0 || db->mallocFailed );
assert( !ExprHasProperty(p, EP_WinFunc) || p->y.pWin!=0 || db->mallocFailed ); assert( p->op!=TK_FUNCTION || !ExprUseYSub(p) );
assert( p->op!=TK_FUNCTION || ExprHasProperty(p, EP_TokenOnly|EP_Reduced)
|| p->y.pWin==0 || ExprHasProperty(p, EP_WinFunc) );
#ifdef SQLITE_DEBUG #ifdef SQLITE_DEBUG
if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){ if( ExprHasProperty(p, EP_Leaf) && !ExprHasProperty(p, EP_TokenOnly) ){
assert( p->pLeft==0 ); assert( p->pLeft==0 );
@@ -2451,6 +2453,7 @@ int sqlite3ExprCanBeNull(const Expr *p){
case TK_BLOB: case TK_BLOB:
return 0; return 0;
case TK_COLUMN: case TK_COLUMN:
assert( ExprUseYTab(p) );
return ExprHasProperty(p, EP_CanBeNull) || return ExprHasProperty(p, EP_CanBeNull) ||
p->y.pTab==0 || /* Reference to column of index on expression */ p->y.pTab==0 || /* Reference to column of index on expression */
(p->iColumn>=0 (p->iColumn>=0
@@ -3021,6 +3024,7 @@ void sqlite3CodeRhsOfIN(
ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d", ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
pExpr->x.pSelect->selId)); pExpr->x.pSelect->selId));
} }
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr); pExpr->y.sub.iAddr);
sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable); sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
@@ -3029,6 +3033,7 @@ void sqlite3CodeRhsOfIN(
} }
/* Begin coding the subroutine */ /* Begin coding the subroutine */
assert( !ExprUseYWin(pExpr) );
ExprSetProperty(pExpr, EP_Subrtn); ExprSetProperty(pExpr, EP_Subrtn);
assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) ); assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.regReturn = ++pParse->nMem;
@@ -3155,6 +3160,7 @@ void sqlite3CodeRhsOfIN(
if( addrOnce ){ if( addrOnce ){
sqlite3VdbeJumpHere(v, addrOnce); sqlite3VdbeJumpHere(v, addrOnce);
/* Subroutine return */ /* Subroutine return */
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse); sqlite3ClearTempRegCache(pParse);
@@ -3198,12 +3204,15 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
** subroutine. */ ** subroutine. */
if( ExprHasProperty(pExpr, EP_Subrtn) ){ if( ExprHasProperty(pExpr, EP_Subrtn) ){
ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId)); ExplainQueryPlan((pParse, 0, "REUSE SUBQUERY %d", pSel->selId));
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn, sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
pExpr->y.sub.iAddr); pExpr->y.sub.iAddr);
return pExpr->iTable; return pExpr->iTable;
} }
/* Begin coding the subroutine */ /* Begin coding the subroutine */
assert( !ExprUseYWin(pExpr) );
assert( !ExprHasProperty(pExpr, EP_Reduced|EP_TokenOnly) );
ExprSetProperty(pExpr, EP_Subrtn); ExprSetProperty(pExpr, EP_Subrtn);
pExpr->y.sub.regReturn = ++pParse->nMem; pExpr->y.sub.regReturn = ++pParse->nMem;
pExpr->y.sub.iAddr = pExpr->y.sub.iAddr =
@@ -3283,6 +3292,7 @@ int sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
} }
/* Subroutine return */ /* Subroutine return */
assert( ExprUseYSub(pExpr) );
sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn); sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1); sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
sqlite3ClearTempRegCache(pParse); sqlite3ClearTempRegCache(pParse);
@@ -4026,6 +4036,7 @@ expr_code_doover:
*/ */
int aff; int aff;
iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target); iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
assert( ExprUseYTab(pExpr) );
if( pExpr->y.pTab ){ if( pExpr->y.pTab ){
aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn); aff = sqlite3TableColumnAffinity(pExpr->y.pTab, pExpr->iColumn);
}else{ }else{
@@ -4049,9 +4060,11 @@ expr_code_doover:
** immediately prior to the first column. ** immediately prior to the first column.
*/ */
Column *pCol; Column *pCol;
Table *pTab = pExpr->y.pTab; Table *pTab;
int iSrc; int iSrc;
int iCol = pExpr->iColumn; int iCol = pExpr->iColumn;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab;
assert( pTab!=0 ); assert( pTab!=0 );
assert( iCol>=XN_ROWID ); assert( iCol>=XN_ROWID );
assert( iCol<pTab->nCol ); assert( iCol<pTab->nCol );
@@ -4089,6 +4102,7 @@ expr_code_doover:
iTab = pParse->iSelfTab - 1; iTab = pParse->iSelfTab - 1;
} }
} }
assert( ExprUseYTab(pExpr) );
iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab,
pExpr->iColumn, iTab, target, pExpr->iColumn, iTab, target,
pExpr->op2); pExpr->op2);
@@ -4539,9 +4553,14 @@ expr_code_doover:
** p1==1 -> old.a p1==4 -> new.a ** p1==1 -> old.a p1==4 -> new.a
** p1==2 -> old.b p1==5 -> new.b ** p1==2 -> old.b p1==5 -> new.b
*/ */
Table *pTab = pExpr->y.pTab; Table *pTab;
int iCol = pExpr->iColumn; int iCol;
int p1 = pExpr->iTable * (pTab->nCol+1) + 1 int p1;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab;
iCol = pExpr->iColumn;
p1 = pExpr->iTable * (pTab->nCol+1) + 1
+ sqlite3TableColumnToStorage(pTab, iCol); + sqlite3TableColumnToStorage(pTab, iCol);
assert( pExpr->iTable==0 || pExpr->iTable==1 ); assert( pExpr->iTable==0 || pExpr->iTable==1 );
@@ -5744,9 +5763,13 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){
testcase( pExpr->op==TK_GE ); testcase( pExpr->op==TK_GE );
/* The y.pTab=0 assignment in wherecode.c always happens after the /* The y.pTab=0 assignment in wherecode.c always happens after the
** impliesNotNullRow() test */ ** impliesNotNullRow() test */
if( (pLeft->op==TK_COLUMN && pLeft->y.pTab!=0 assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
assert( pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
if( (pLeft->op==TK_COLUMN
&& pLeft->y.pTab!=0
&& IsVirtual(pLeft->y.pTab)) && IsVirtual(pLeft->y.pTab))
|| (pRight->op==TK_COLUMN && pRight->y.pTab!=0 || (pRight->op==TK_COLUMN
&& pRight->y.pTab!=0
&& IsVirtual(pRight->y.pTab)) && IsVirtual(pRight->y.pTab))
){ ){
return WRC_Prune; return WRC_Prune;
@@ -6073,6 +6096,7 @@ static int analyzeAggregate(Walker *pWalker, Expr *pExpr){
&& (k = addAggInfoColumn(pParse->db, pAggInfo))>=0 && (k = addAggInfoColumn(pParse->db, pAggInfo))>=0
){ ){
pCol = &pAggInfo->aCol[k]; pCol = &pAggInfo->aCol[k];
assert( ExprUseYTab(pExpr) );
pCol->pTab = pExpr->y.pTab; pCol->pTab = pExpr->y.pTab;
pCol->iTable = pExpr->iTable; pCol->iTable = pExpr->iTable;
pCol->iColumn = pExpr->iColumn; pCol->iColumn = pExpr->iColumn;

View File

@@ -510,6 +510,7 @@ static Expr *exprTableColumn(
){ ){
Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0); Expr *pExpr = sqlite3Expr(db, TK_COLUMN, 0);
if( pExpr ){ if( pExpr ){
assert( ExprUseYTab(pExpr) );
pExpr->y.pTab = pTab; pExpr->y.pTab = pTab;
pExpr->iTable = iCursor; pExpr->iTable = iCursor;
pExpr->iColumn = iCol; pExpr->iColumn = iCol;

View File

@@ -1039,9 +1039,9 @@ idlist(A) ::= nm(Y).
ExprClearVVAProperties(p); ExprClearVVAProperties(p);
p->iAgg = -1; p->iAgg = -1;
p->pLeft = p->pRight = 0; p->pLeft = p->pRight = 0;
p->x.pList = 0;
p->pAggInfo = 0; p->pAggInfo = 0;
p->y.pTab = 0; memset(&p->x, 0, sizeof(p->x));
memset(&p->y, 0, sizeof(p->y));
p->op2 = 0; p->op2 = 0;
p->iTable = 0; p->iTable = 0;
p->iColumn = 0; p->iColumn = 0;

View File

@@ -191,6 +191,7 @@ Bitmask sqlite3ExprColUsed(Expr *pExpr){
Table *pExTab; Table *pExTab;
n = pExpr->iColumn; n = pExpr->iColumn;
assert( ExprUseYTab(pExpr) );
pExTab = pExpr->y.pTab; pExTab = pExpr->y.pTab;
assert( pExTab!=0 ); assert( pExTab!=0 );
if( (pExTab->tabFlags & TF_HasGenerated)!=0 if( (pExTab->tabFlags & TF_HasGenerated)!=0
@@ -328,6 +329,7 @@ static int lookupName(
if( sqlite3StrICmp(zTabName, zTab)!=0 ){ if( sqlite3StrICmp(zTabName, zTab)!=0 ){
continue; continue;
} }
assert( ExprUseYTab(pExpr) );
if( IN_RENAME_OBJECT && pItem->zAlias ){ if( IN_RENAME_OBJECT && pItem->zAlias ){
sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab); sqlite3RenameTokenRemap(pParse, 0, (void*)&pExpr->y.pTab);
} }
@@ -359,6 +361,7 @@ static int lookupName(
} }
if( pMatch ){ if( pMatch ){
pExpr->iTable = pMatch->iCursor; pExpr->iTable = pMatch->iCursor;
assert( ExprUseYTab(pExpr) );
pExpr->y.pTab = pMatch->pTab; pExpr->y.pTab = pMatch->pTab;
/* RIGHT JOIN not (yet) supported */ /* RIGHT JOIN not (yet) supported */
assert( (pMatch->fg.jointype & JT_RIGHT)==0 ); assert( (pMatch->fg.jointype & JT_RIGHT)==0 );
@@ -432,6 +435,7 @@ static int lookupName(
#ifndef SQLITE_OMIT_UPSERT #ifndef SQLITE_OMIT_UPSERT
if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){ if( pExpr->iTable==EXCLUDED_TABLE_NUMBER ){
testcase( iCol==(-1) ); testcase( iCol==(-1) );
assert( ExprUseYTab(pExpr) );
if( IN_RENAME_OBJECT ){ if( IN_RENAME_OBJECT ){
pExpr->iColumn = iCol; pExpr->iColumn = iCol;
pExpr->y.pTab = pTab; pExpr->y.pTab = pTab;
@@ -444,6 +448,7 @@ static int lookupName(
}else }else
#endif /* SQLITE_OMIT_UPSERT */ #endif /* SQLITE_OMIT_UPSERT */
{ {
assert( ExprUseYTab(pExpr) );
pExpr->y.pTab = pTab; pExpr->y.pTab = pTab;
if( pParse->bReturning ){ if( pParse->bReturning ){
eNewExprOp = TK_REGISTER; eNewExprOp = TK_REGISTER;
@@ -591,7 +596,7 @@ static int lookupName(
sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol); sqlite3VdbeAddDblquoteStr(db, pParse->pVdbe, zCol);
#endif #endif
pExpr->op = TK_STRING; pExpr->op = TK_STRING;
pExpr->y.pTab = 0; memset(&pExpr->y, 0, sizeof(pExpr->y));
return WRC_Prune; return WRC_Prune;
} }
if( sqlite3ExprIdToTrueFalse(pExpr) ){ if( sqlite3ExprIdToTrueFalse(pExpr) ){
@@ -677,7 +682,9 @@ Expr *sqlite3CreateColumnExpr(sqlite3 *db, SrcList *pSrc, int iSrc, int iCol){
Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0); Expr *p = sqlite3ExprAlloc(db, TK_COLUMN, 0, 0);
if( p ){ if( p ){
SrcItem *pItem = &pSrc->a[iSrc]; SrcItem *pItem = &pSrc->a[iSrc];
Table *pTab = p->y.pTab = pItem->pTab; Table *pTab;
assert( ExprUseYTab(p) );
pTab = p->y.pTab = pItem->pTab;
p->iTable = pItem->iCursor; p->iTable = pItem->iCursor;
if( p->y.pTab->iPKey==iCol ){ if( p->y.pTab->iPKey==iCol ){
p->iColumn = -1; p->iColumn = -1;
@@ -793,6 +800,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
assert( pSrcList && pSrcList->nSrc>=1 ); assert( pSrcList && pSrcList->nSrc>=1 );
pItem = pSrcList->a; pItem = pSrcList->a;
pExpr->op = TK_COLUMN; pExpr->op = TK_COLUMN;
assert( ExprUseYTab(pExpr) );
pExpr->y.pTab = pItem->pTab; pExpr->y.pTab = pItem->pTab;
pExpr->iTable = pItem->iCursor; pExpr->iTable = pItem->iCursor;
pExpr->iColumn--; pExpr->iColumn--;
@@ -879,10 +887,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
pLeft = pRight->pLeft; pLeft = pRight->pLeft;
pRight = pRight->pRight; pRight = pRight->pRight;
} }
assert( !ExprHasProperty(pLeft, EP_IntValue) ); assert( ExprUseUToken(pLeft) && ExprUseUToken(pRight) );
zTable = pLeft->u.zToken; zTable = pLeft->u.zToken;
assert( !ExprHasProperty(pRight, EP_IntValue) );
zColumn = pRight->u.zToken; zColumn = pRight->u.zToken;
assert( ExprUseYTab(pExpr) );
if( IN_RENAME_OBJECT ){ if( IN_RENAME_OBJECT ){
sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight); sqlite3RenameTokenRemap(pParse, (void*)pExpr, (void*)pRight);
sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft); sqlite3RenameTokenRemap(pParse, (void*)&pExpr->y.pTab, (void*)pLeft);
@@ -1071,7 +1079,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
#ifndef SQLITE_OMIT_WINDOWFUNC #ifndef SQLITE_OMIT_WINDOWFUNC
if( pWin ){ if( pWin ){
Select *pSel = pNC->pWinSelect; Select *pSel = pNC->pWinSelect;
assert( pWin==pExpr->y.pWin ); assert( pWin==0 || (ExprUseYWin(pExpr) && pWin==pExpr->y.pWin) );
if( IN_RENAME_OBJECT==0 ){ if( IN_RENAME_OBJECT==0 ){
sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef); sqlite3WindowUpdate(pParse, pSel ? pSel->pWinDefn : 0, pWin, pDef);
if( pParse->db->mallocFailed ) break; if( pParse->db->mallocFailed ) break;

View File

@@ -941,7 +941,9 @@ static void selectExprDefer(
struct ExprList_item *pItem = &pEList->a[i]; struct ExprList_item *pItem = &pEList->a[i];
if( pItem->u.x.iOrderByCol==0 ){ if( pItem->u.x.iOrderByCol==0 ){
Expr *pExpr = pItem->pExpr; Expr *pExpr = pItem->pExpr;
Table *pTab = pExpr->y.pTab; Table *pTab;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab;
if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab) if( pExpr->op==TK_COLUMN && pExpr->iColumn>=0 && pTab && !IsVirtual(pTab)
&& (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF) && (pTab->aCol[pExpr->iColumn].colFlags & COLFLAG_SORTERREF)
){ ){
@@ -964,6 +966,7 @@ static void selectExprDefer(
Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0); Expr *pNew = sqlite3PExpr(pParse, TK_COLUMN, 0, 0);
if( pNew ){ if( pNew ){
pNew->iTable = pExpr->iTable; pNew->iTable = pExpr->iTable;
assert( ExprUseYTab(pNew) );
pNew->y.pTab = pExpr->y.pTab; pNew->y.pTab = pExpr->y.pTab;
pNew->iColumn = pPk ? pPk->aiColumn[k] : -1; pNew->iColumn = pPk ? pPk->aiColumn[k] : -1;
pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew); pExtra = sqlite3ExprListAppend(pParse, pExtra, pNew);
@@ -1812,7 +1815,7 @@ static const char *columnTypeImpl(
break; break;
} }
assert( pTab && pExpr->y.pTab==pTab ); assert( pTab && ExprUseYTab(pExpr) && pExpr->y.pTab==pTab );
if( pS ){ if( pS ){
/* The "table" is actually a sub-select or a view in the FROM clause /* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin ** of the SELECT statement. Return the declaration type and origin
@@ -2005,7 +2008,8 @@ void sqlite3GenerateColumnNames(
assert( p!=0 ); assert( p!=0 );
assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */ assert( p->op!=TK_AGG_COLUMN ); /* Agg processing has not run yet */
assert( p->op!=TK_COLUMN || p->y.pTab!=0 ); /* Covering idx not yet coded */ assert( p->op!=TK_COLUMN
|| (ExprUseYTab(p) && p->y.pTab!=0) ); /* Covering idx not yet coded */
if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){ if( pEList->a[i].zEName && pEList->a[i].eEName==ENAME_NAME ){
/* An AS clause always takes first priority */ /* An AS clause always takes first priority */
char *zName = pEList->a[i].zEName; char *zName = pEList->a[i].zEName;
@@ -2101,7 +2105,10 @@ int sqlite3ColumnsFromExprList(
pColExpr = pColExpr->pRight; pColExpr = pColExpr->pRight;
assert( pColExpr!=0 ); assert( pColExpr!=0 );
} }
if( pColExpr->op==TK_COLUMN && (pTab = pColExpr->y.pTab)!=0 ){ if( pColExpr->op==TK_COLUMN
&& ALWAYS( ExprUseYTab(pColExpr) )
&& (pTab = pColExpr->y.pTab)!=0
){
/* For columns use the column name name */ /* For columns use the column name name */
int iCol = pColExpr->iColumn; int iCol = pColExpr->iColumn;
if( iCol<0 ) iCol = pTab->iPKey; if( iCol<0 ) iCol = pTab->iPKey;

View File

@@ -2829,8 +2829,7 @@ struct Expr {
} y; } y;
}; };
/* /* The following are the meanings of bits in the Expr.flags field.
** The following are the meanings of bits in the Expr.flags field.
** Value restrictions: ** Value restrictions:
** **
** EP_Agg == NC_HasAgg == SF_HasAgg ** EP_Agg == NC_HasAgg == SF_HasAgg
@@ -2869,14 +2868,12 @@ struct Expr {
#define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */ #define EP_FromDDL 0x40000000 /* Originates from sqlite_schema */
/* 0x80000000 // Available */ /* 0x80000000 // Available */
/* /* The EP_Propagate mask is a set of properties that automatically propagate
** The EP_Propagate mask is a set of properties that automatically propagate
** upwards into parent nodes. ** upwards into parent nodes.
*/ */
#define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc) #define EP_Propagate (EP_Collate|EP_Subquery|EP_HasFunc)
/* /* Macros can be used to test, set, or clear bits in the
** These macros can be used to test, set, or clear bits in the
** Expr.flags field. ** Expr.flags field.
*/ */
#define ExprHasProperty(E,P) (((E)->flags&(P))!=0) #define ExprHasProperty(E,P) (((E)->flags&(P))!=0)
@@ -2886,16 +2883,16 @@ struct Expr {
#define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysTrue(E) (((E)->flags&(EP_FromJoin|EP_IsTrue))==EP_IsTrue)
#define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse) #define ExprAlwaysFalse(E) (((E)->flags&(EP_FromJoin|EP_IsFalse))==EP_IsFalse)
/* /* Macros used to ensure that the correct members of unions are accessed
** Macros used to ensure that the correct members of unions are accessed. ** in Expr.
*/ */
#define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0)
#define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) #define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0)
#define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) #define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0)
#define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) #define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0)
#define ExprUseYTab(E) ((E)->op==TK_COLUMN) #define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0)
#define ExprUseYWin(E) ((E)->flags&EP_WinFunc)!=0) #define ExprUseYWin(E) (((E)->flags&EP_WinFunc)!=0)
#define ExprUseYSub(E) ((E)->op==TK_IN||(E)->op==TK_SELECT||(E)->op==TK_EXISTS) #define ExprUseYSub(E) (((E)->flags&EP_Subrtn)!=0)
/* Flags for use with Expr.vvaFlags /* Flags for use with Expr.vvaFlags
*/ */

View File

@@ -442,6 +442,7 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){
sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s", sqlite3TreeViewLine(pView, "COLUMN(%d)%s%s",
pExpr->iColumn, zFlgs, zOp2); pExpr->iColumn, zFlgs, zOp2);
}else{ }else{
assert( ExprUseYTab(pExpr) );
sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s", sqlite3TreeViewLine(pView, "{%d:%d} pTab=%p%s",
pExpr->iTable, pExpr->iColumn, pExpr->iTable, pExpr->iColumn,
pExpr->y.pTab, zFlgs); pExpr->y.pTab, zFlgs);

View File

@@ -1137,6 +1137,7 @@ FuncDef *sqlite3VtabOverloadFunction(
/* Check to see the left operand is a column in a virtual table */ /* Check to see the left operand is a column in a virtual table */
if( NEVER(pExpr==0) ) return pDef; if( NEVER(pExpr==0) ) return pDef;
if( pExpr->op!=TK_COLUMN ) return pDef; if( pExpr->op!=TK_COLUMN ) return pDef;
assert( ExprUseYTab(pExpr) );
pTab = pExpr->y.pTab; pTab = pExpr->y.pTab;
if( pTab==0 ) return pDef; if( pTab==0 ) return pDef;
if( !IsVirtual(pTab) ) return pDef; if( !IsVirtual(pTab) ) return pDef;

View File

@@ -1175,10 +1175,10 @@ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){
pExpr->op = TK_COLUMN; pExpr->op = TK_COLUMN;
pExpr->iTable = pX->iIdxCur; pExpr->iTable = pX->iIdxCur;
pExpr->iColumn = pX->iIdxCol; pExpr->iColumn = pX->iIdxCol;
pExpr->y.pTab = 0;
testcase( ExprHasProperty(pExpr, EP_Skip) ); testcase( ExprHasProperty(pExpr, EP_Skip) );
testcase( ExprHasProperty(pExpr, EP_Unlikely) ); testcase( ExprHasProperty(pExpr, EP_Unlikely) );
ExprClearProperty(pExpr, EP_Skip|EP_Unlikely); ExprClearProperty(pExpr, EP_Skip|EP_Unlikely|EP_WinFunc|EP_Subrtn);
pExpr->y.pTab = 0;
return WRC_Prune; return WRC_Prune;
}else{ }else{
return WRC_Continue; return WRC_Continue;
@@ -1193,7 +1193,7 @@ static int whereIndexExprTransColumn(Walker *p, Expr *pExpr){
if( pExpr->op==TK_COLUMN ){ if( pExpr->op==TK_COLUMN ){
IdxExprTrans *pX = p->u.pIdxTrans; IdxExprTrans *pX = p->u.pIdxTrans;
if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){ if( pExpr->iTable==pX->iTabCur && pExpr->iColumn==pX->iTabCol ){
assert( pExpr->y.pTab!=0 ); assert( ExprUseYTab(pExpr) && pExpr->y.pTab!=0 );
preserveExpr(pX, pExpr); preserveExpr(pX, pExpr);
pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn); pExpr->affExpr = sqlite3TableColumnAffinity(pExpr->y.pTab,pExpr->iColumn);
pExpr->iTable = pX->iIdxCur; pExpr->iTable = pX->iIdxCur;

View File

@@ -267,7 +267,9 @@ static int isLikeOrGlob(
*/ */
if( pLeft->op!=TK_COLUMN if( pLeft->op!=TK_COLUMN
|| sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT
|| (pLeft->y.pTab && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ || (ALWAYS( ExprUseYTab(pLeft) )
&& pLeft->y.pTab
&& IsVirtual(pLeft->y.pTab)) /* Might be numeric */
){ ){
int isNum; int isNum;
double rDummy; double rDummy;
@@ -383,6 +385,7 @@ static int isAuxiliaryVtabOperator(
** MATCH(expression,vtab_column) ** MATCH(expression,vtab_column)
*/ */
pCol = pList->a[1].pExpr; pCol = pList->a[1].pExpr;
assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) );
testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
if( ExprIsVtab(pCol) ){ if( ExprIsVtab(pCol) ){
for(i=0; i<ArraySize(aOp); i++){ for(i=0; i<ArraySize(aOp); i++){
@@ -407,6 +410,7 @@ static int isAuxiliaryVtabOperator(
** with function names in an arbitrary case. ** with function names in an arbitrary case.
*/ */
pCol = pList->a[0].pExpr; pCol = pList->a[0].pExpr;
assert( pCol->op!=TK_COLUMN || ExprUseYTab(pCol) );
testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 ); testcase( pCol->op==TK_COLUMN && pCol->y.pTab==0 );
if( ExprIsVtab(pCol) ){ if( ExprIsVtab(pCol) ){
sqlite3_vtab *pVtab; sqlite3_vtab *pVtab;
@@ -432,10 +436,12 @@ static int isAuxiliaryVtabOperator(
int res = 0; int res = 0;
Expr *pLeft = pExpr->pLeft; Expr *pLeft = pExpr->pLeft;
Expr *pRight = pExpr->pRight; Expr *pRight = pExpr->pRight;
assert( pLeft->op!=TK_COLUMN || ExprUseYTab(pLeft) );
testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 ); testcase( pLeft->op==TK_COLUMN && pLeft->y.pTab==0 );
if( ExprIsVtab(pLeft) ){ if( ExprIsVtab(pLeft) ){
res++; res++;
} }
assert( pRight==0 || pRight->op!=TK_COLUMN || ExprUseYTab(pRight) );
testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 ); testcase( pRight && pRight->op==TK_COLUMN && pRight->y.pTab==0 );
if( pRight && ExprIsVtab(pRight) ){ if( pRight && ExprIsVtab(pRight) ){
res++; res++;
@@ -1558,7 +1564,8 @@ Bitmask sqlite3WhereExprUsageNN(WhereMaskSet *pMaskSet, Expr *p){
mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList); mask |= sqlite3WhereExprListUsage(pMaskSet, p->x.pList);
} }
#ifndef SQLITE_OMIT_WINDOWFUNC #ifndef SQLITE_OMIT_WINDOWFUNC
if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && p->y.pWin ){ if( (p->op==TK_FUNCTION || p->op==TK_AGG_FUNCTION) && ExprUseYWin(p) ){
assert( p->y.pWin!=0 );
mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition); mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pPartition);
mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy); mask |= sqlite3WhereExprListUsage(pMaskSet, p->y.pWin->pOrderBy);
mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter); mask |= sqlite3WhereExprUsage(pMaskSet, p->y.pWin->pFilter);
@@ -1633,6 +1640,7 @@ void sqlite3WhereTabFuncArgs(
if( pColRef==0 ) return; if( pColRef==0 ) return;
pColRef->iTable = pItem->iCursor; pColRef->iTable = pItem->iCursor;
pColRef->iColumn = k++; pColRef->iColumn = k++;
assert( ExprUseYTab(pColRef) );
pColRef->y.pTab = pTab; pColRef->y.pTab = pTab;
pRhs = sqlite3PExpr(pParse, TK_UPLUS, pRhs = sqlite3PExpr(pParse, TK_UPLUS,
sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0);