From aca19e19a8934b9d2d237d183b389dad5e519361 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Apr 2017 19:41:31 +0000 Subject: [PATCH 01/12] Proof of concept for the ability to use the expression columns in an index on expressions in place of equivalent expressions in the result set or in the WHERE clause. This check-in compiles but is mostly untested. FossilOrigin-Name: a52ef2ad7c0e14b78b801f16a1f6ea8d8fa9ae5d7d810e18dd24c600b662a312 --- manifest | 29 ++++++++++++---------- manifest.uuid | 2 +- src/expr.c | 4 +++ src/select.c | 2 +- src/sqliteInt.h | 1 + src/where.c | 1 + src/whereInt.h | 1 + src/wherecode.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ tool/addopcodes.tcl | 1 + 9 files changed, 85 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 50c2d8faef..4c47ee7fcd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\s".lint\sfkey"\sshell\scommand\sfor\scases\swhere\sthe\schild\skey\sis\salso\san\nINTEGER\sPRIMARY\sKEY. -D 2017-04-06T14:56:26.887 +C Proof\sof\sconcept\sfor\sthe\sability\sto\suse\sthe\sexpression\scolumns\sin\san\sindex\non\sexpressions\sin\splace\sof\sequivalent\sexpressions\sin\sthe\sresult\sset\sor\sin\nthe\sWHERE\sclause.\s\sThis\scheck-in\scompiles\sbut\sis\smostly\suntested. +D 2017-04-07T19:41:31.032 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -354,7 +354,7 @@ F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 6bce2cbdd822963cf28e782938a96274cc37f18ac28dec7a4e35ccac09f66ce8 +F src/expr.c 8fd6b7bc10c2c33e017b0f2715efdc83c01e348be27797022ed9eaa3002ca720 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 @@ -401,12 +401,12 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 +F src/select.c b24e628a2b76800171f4c86e38b5d93e27f2c40e603b24733aa8e471029e6ecd F src/shell.c e9fede684f847402c0373fe5e270918e6ef47f51e57ba5aebff121d8c2bc1ea8 F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 -F src/sqliteInt.h 6cf244eb06119b44e155717708e54f0638c35e9bd8ef59ea570eb1f093f0da44 +F src/sqliteInt.h 9affb53bb405dcea1d86e85198ebaf6232a684cc2b2af6b3c181869f1c8f3e93 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c a9e66593dfb28a9e746cba7153f84d49c1ddc4b1 F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -482,9 +482,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c 40c543f0a2195d1b0dc88ef12142bea690009344 F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 -F src/where.c 49b48b720184fdde747c468d7270feeb1b88c6a71092cea3a1aa168dc8ac0b0f -F src/whereInt.h 2d50c2b74a33be44cb68fdecee30b4d93552f1f4 -F src/wherecode.c 677e95413c472c0b413023b6b69a47f40fce1b04 +F src/where.c 1d14e18f32231fa7969e718e7b60ef749b0065e2a7e1b6b00883b20732d280f1 +F src/whereInt.h 7a21ef633e26acbf46df04add2eba6e0a2100c78dc5879049e93f981fc3344df +F src/wherecode.c 38d171e309c7b54d5bdc7d8b663ec16249ad8888e01a77f6c55e9350de8e8349 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1482,7 +1482,7 @@ F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 -F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 +F tool/addopcodes.tcl ffa614f3eac5bd6672a5ca7c936500645e01d3a9f8329ab7cbf86582dd17f936 F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x @@ -1570,7 +1570,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 327eff25ba2420267cc8dc49dd3c3aab45f4bf9e060d1ad480e25d016d21f3ba -R 260410c30d599e0993c58e23cef69640 -U dan -Z 25db1dc906fb1b522f7b655980ddd579 +P 48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 +R c609ef75ab8f5bb5565771cdc08e2586 +T *branch * covering-index-on-expr +T *sym-covering-index-on-expr * +T -sym-trunk * +U drh +Z 9d990a9e03df0f0f8f16d32c22292949 diff --git a/manifest.uuid b/manifest.uuid index 3814e9cddf..26e5bb9e68 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 \ No newline at end of file +a52ef2ad7c0e14b78b801f16a1f6ea8d8fa9ae5d7d810e18dd24c600b662a312 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e3db59732e..afdbbb1275 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3192,6 +3192,10 @@ void sqlite3ExprCodeGetColumnOfTable( int iCol, /* Index of the column to extract */ int regOut /* Extract the value into this register */ ){ + if( pTab==0 ){ + sqlite3VdbeAddOp3(v, OP_Column, iTabCur, iCol, regOut); + return; + } if( iCol<0 || iCol==pTab->iPKey ){ sqlite3VdbeAddOp2(v, OP_Rowid, iTabCur, regOut); }else{ diff --git a/src/select.c b/src/select.c index 334307cce7..55d2584fbe 100644 --- a/src/select.c +++ b/src/select.c @@ -3147,7 +3147,7 @@ static void substSelect(Parse*, Select *, int, ExprList*, int); ** This routine is part of the flattening procedure. A subquery ** whose result set is defined by pEList appears as entry in the ** FROM clause of a SELECT such that the VDBE cursor assigned to that -** FORM clause entry is iTable. This routine make the necessary +** FORM clause entry is iTable. This routine makes the necessary ** changes to pExpr so that it refers directly to the source table ** of the subquery rather the result set of the subquery. */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 2b3c934ecd..40660aed99 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3324,6 +3324,7 @@ struct Walker { struct CCurHint *pCCurHint; /* Used by codeCursorHint() */ int *aiCol; /* array of column indexes */ struct IdxCover *pIdxCover; /* Check for index coverage */ + struct IdxExprTrans *pIdxTrans; /* Convert indexed expr to column */ } u; }; diff --git a/src/where.c b/src/where.c index 5a0b35bdf1..38183d6849 100644 --- a/src/where.c +++ b/src/where.c @@ -4447,6 +4447,7 @@ WhereInfo *sqlite3WhereBegin( pWInfo->pParse = pParse; pWInfo->pTabList = pTabList; pWInfo->pOrderBy = pOrderBy; + pWInfo->pWhere = pWhere; pWInfo->pResultSet = pResultSet; pWInfo->aiCurOnePass[0] = pWInfo->aiCurOnePass[1] = -1; pWInfo->nLevel = nTabList; diff --git a/src/whereInt.h b/src/whereInt.h index f065fae6ba..6bd4aab2b0 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -417,6 +417,7 @@ struct WhereInfo { SrcList *pTabList; /* List of tables in the join */ ExprList *pOrderBy; /* The ORDER BY clause or NULL */ ExprList *pResultSet; /* Result set of the query */ + Expr *pWhere; /* The complete WHERE clause */ LogEst iLimit; /* LIMIT if wctrlFlags has WHERE_USE_LIMIT */ int aiCurOnePass[2]; /* OP_OpenWrite cursors for the ONEPASS opt */ int iContinue; /* Jump here to continue with next record */ diff --git a/src/wherecode.c b/src/wherecode.c index 4fd5e16fac..bdf732755e 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1039,6 +1039,61 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ } } +#if 1 /* INDEXEXPRTRANS */ +typedef struct IdxExprTrans { + Expr *pIdxExpr; /* The index expression */ + int iTabCur; /* The cursor of the corresponding table */ + int iIdxCur; /* The cursor for the index */ + int iIdxCol; /* The column for the index */ +} IdxExprTrans; + +static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ + IdxExprTrans *pX = p->u.pIdxTrans; + if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr->op = TK_COLUMN; + pExpr->iTable = pX->iIdxCur; + pExpr->iColumn = pX->iIdxCol; + pExpr->pTab = 0; + return WRC_Prune; + }else{ + return WRC_Continue; + } +} + +/* +** For an indexes on expression X, locate every instance of expression X in pExpr +** and change that subexpression into a reference to the appropriate column of +** the index. +*/ +static void whereIndexExprTrans( + Index *pIdx, /* The Index */ + int iTabCur, /* Cursor of the table that is being indexed */ + int iIdxCur, /* Cursor of the index itself */ + WhereInfo *pWInfo /* Transform expressions in this WHERE clause */ +){ + int iIdxCol; /* Column number of the index */ + ExprList *aColExpr; /* Expressions that are indexed */ + Walker w; + IdxExprTrans x; + aColExpr = pIdx->aColExpr; + if( aColExpr==0 ) return; /* Not an index on expressions */ + memset(&w, 0, sizeof(w)); + w.xExprCallback = whereIndexExprTransNode; + w.u.pIdxTrans = &x; + x.iTabCur = iTabCur; + x.iIdxCur = iIdxCur; + for(iIdxCol=0; iIdxColnExpr; iIdxCol++){ + if( pIdx->aiColumn[iIdxCol]!=XN_EXPR ) continue; + assert( aColExpr->a[iIdxCol].pExpr!=0 ); + x.iIdxCol = iIdxCol; + x.pIdxExpr = aColExpr->a[iIdxCol].pExpr; + sqlite3WalkExpr(&w, pWInfo->pWhere); + sqlite3WalkExprList(&w, pWInfo->pOrderBy); + sqlite3WalkExprList(&w, pWInfo->pResultSet); + } +} +#endif + /* ** Generate code for the start of the iLevel-th loop in the WHERE clause ** implementation described by pWInfo. @@ -1620,6 +1675,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } +#if 1 /* INDEXEXPRTANS */ + whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); +#endif + /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ pLevel->op = OP_Noop; diff --git a/tool/addopcodes.tcl b/tool/addopcodes.tcl index a6c58f1a25..dc96f2cfbe 100644 --- a/tool/addopcodes.tcl +++ b/tool/addopcodes.tcl @@ -32,6 +32,7 @@ set extras { UNCLOSED_STRING FUNCTION COLUMN + IDXCOLUMN AGG_FUNCTION AGG_COLUMN UMINUS From f1824a77b0d68537831a8b82f08b1d27be389d75 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 7 Apr 2017 19:52:13 +0000 Subject: [PATCH 02/12] Remove an unused token type. FossilOrigin-Name: 13a422230dcf4a8a80434af97434d57e456dcaa6bf0c41e6859f37ded6fa96ca --- manifest | 15 ++++++--------- manifest.uuid | 2 +- tool/addopcodes.tcl | 1 - 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 4c47ee7fcd..99232c34c4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Proof\sof\sconcept\sfor\sthe\sability\sto\suse\sthe\sexpression\scolumns\sin\san\sindex\non\sexpressions\sin\splace\sof\sequivalent\sexpressions\sin\sthe\sresult\sset\sor\sin\nthe\sWHERE\sclause.\s\sThis\scheck-in\scompiles\sbut\sis\smostly\suntested. -D 2017-04-07T19:41:31.032 +C Remove\san\sunused\stoken\stype. +D 2017-04-07T19:52:13.781 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -1482,7 +1482,7 @@ F test/zerodamage.test e59a56443d6298ecf7435f618f0b27654f0c849e F tool/GetFile.cs a15e08acb5dd7539b75ba23501581d7c2b462cb5 F tool/GetTclKit.bat 6afa640edc7810725aec61c3076ac617c4aaf0b7 F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 -F tool/addopcodes.tcl ffa614f3eac5bd6672a5ca7c936500645e01d3a9f8329ab7cbf86582dd17f936 +F tool/addopcodes.tcl 10c889c4a65ec6c5604e4a47306fa77ff57ae189 F tool/build-all-msvc.bat c12328d06c45fec8baada5949e3d5af54bf8c887 x F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 F tool/cg_anno.tcl f95b0006c52cf7f0496b506343415b6ee3cdcdd3 x @@ -1570,10 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48826b222c110a90996a84605318ea6b1e502b8c5129f4d561f8350dbdbcd264 -R c609ef75ab8f5bb5565771cdc08e2586 -T *branch * covering-index-on-expr -T *sym-covering-index-on-expr * -T -sym-trunk * +P a52ef2ad7c0e14b78b801f16a1f6ea8d8fa9ae5d7d810e18dd24c600b662a312 +R ffc8fa52d9e0cf4a5ba4590fbfff02cc U drh -Z 9d990a9e03df0f0f8f16d32c22292949 +Z e6d170fd55537b8013050239f469d07c diff --git a/manifest.uuid b/manifest.uuid index 26e5bb9e68..4bd060a2aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a52ef2ad7c0e14b78b801f16a1f6ea8d8fa9ae5d7d810e18dd24c600b662a312 \ No newline at end of file +13a422230dcf4a8a80434af97434d57e456dcaa6bf0c41e6859f37ded6fa96ca \ No newline at end of file diff --git a/tool/addopcodes.tcl b/tool/addopcodes.tcl index dc96f2cfbe..a6c58f1a25 100644 --- a/tool/addopcodes.tcl +++ b/tool/addopcodes.tcl @@ -32,7 +32,6 @@ set extras { UNCLOSED_STRING FUNCTION COLUMN - IDXCOLUMN AGG_FUNCTION AGG_COLUMN UMINUS From 7a6ea93fd88248a3b602df1418d409c7116fe981 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 9 Apr 2017 19:23:55 +0000 Subject: [PATCH 03/12] Do not expose the name of the internal Mem object in the public interface defined by sqlite3.h. FossilOrigin-Name: 19dd753f9e50fee247b1ab141669817c7e88bc3f6d6065dba6c731db9f7a2409 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/btree.h | 2 +- src/sqlite.h.in | 2 +- src/vdbe.h | 2 +- src/vdbeInt.h | 2 +- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index 2b13eab25a..e5b43e782e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disallow\sleading\szeros\son\snumeric\sconstants\sin\sJSON.\nFix\sfor\sticket\s[b93be8729a895a528e2] -D 2017-04-08T18:18:22.572 +C Do\snot\sexpose\sthe\sname\sof\sthe\sinternal\sMem\sobject\sin\sthe\spublic\sinterface\ndefined\sby\ssqlite3.h. +D 2017-04-09T19:23:55.530 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -345,7 +345,7 @@ F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca F src/btree.c 24ae5472bd0b53b4130ecdda389deb621af721d1fcb50890b878102b00bd10fa -F src/btree.h bf64dfeeddeebdb775a5eba0098bbc00d073290d +F src/btree.h 80f518c0788be6cec8d9f8e13bd8e380df299d2b5e4ac340dc887b0642647cfc F src/btreeInt.h a392d353104b4add58b4a59cb185f5d5693dde832c565b77d8d4c343ed98f610 F src/build.c 4026a9c554b233e50c5e9ad46963e676cf54dd2306d952aa1eaa07a1bc9ce14f F src/callback.c 2e76147783386374bf01b227f752c81ec872d730 @@ -403,7 +403,7 @@ F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac F src/select.c afcf31d8ed7c890328a31d3f350467ccd273af345b24562382b398d6d9cd0664 F src/shell.c 70f4957b988572315e97c56941fdc81fd35907fee36b7b2e7be5ec4c7e9d065d -F src/sqlite.h.in ab77e511620eebbd4ed7e4f52fae697b6870dda66c945acd2d3066f99c98e17e +F src/sqlite.h.in 40233103e3e4e10f8a63523498d0259d232e42aba478e2d3fb914799185aced6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 58fd0676d3111d02e62e5a35992a7d3da5d3f88753acc174f2d37b774fbbdd28 F src/sqliteInt.h 6cf244eb06119b44e155717708e54f0638c35e9bd8ef59ea570eb1f093f0da44 @@ -469,8 +469,8 @@ F src/utf.c 699001c79f28e48e9bcdf8a463da029ea660540c F src/util.c ca8440ede81e155d15cff7c101654f60b55a9ae6 F src/vacuum.c 1fe4555cd8c9b263afb85b5b4ee3a4a4181ad569 F src/vdbe.c 808fda3d50f544120d27c731449b524b4ec8f8b0f734b228831078f0ba53ecb9 -F src/vdbe.h caa5346d52bae2a3c8c1dcfa60a7a4dc878a9e3865cb8239da55808b316c8158 -F src/vdbeInt.h 5db089ce18c4feff8820ec6e4cac2d2c82e03d4b1d96f10a6e43832147b8dffe +F src/vdbe.h f7d1456e28875c2dcb964056589b5b7149ab7edf39edeca801596a39bb3d3848 +F src/vdbeInt.h c070bc5c8b913bda0ceaa995cd4d939ded5e4fc96cf7c3c1c602d41b871f8ade F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 F src/vdbeaux.c 0ecacf8c7ca93e430b30819b8fc9b2c1ffe88202d1437e88c08a1f0b6159c58c F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P b9a8c2b9bec9f537b2d5aff6659a5748b1f70b53519a1f9dfceb5209154eca8e -R 670b9d233206c31ff293234250b6b1b3 +P 204e72f0080e8f08f99978870bd3cb9d59b068ecffee82192d707c650548b43b +R 4aadeea99512ebde70036e66f3a8d746 U drh -Z 7379463864511f4d80e83d3921199e22 +Z d0890c6128b3b61f6503cc6c672cce64 diff --git a/manifest.uuid b/manifest.uuid index 149c2506cf..a6f6c0a5e4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -204e72f0080e8f08f99978870bd3cb9d59b068ecffee82192d707c650548b43b \ No newline at end of file +19dd753f9e50fee247b1ab141669817c7e88bc3f6d6065dba6c731db9f7a2409 \ No newline at end of file diff --git a/src/btree.h b/src/btree.h index 0e017f5300..6bd90455a8 100644 --- a/src/btree.h +++ b/src/btree.h @@ -276,7 +276,7 @@ struct BtreePayload { const void *pKey; /* Key content for indexes. NULL for tables */ sqlite3_int64 nKey; /* Size of pKey for indexes. PRIMARY KEY for tabs */ const void *pData; /* Data for tables. NULL for indexes */ - struct Mem *aMem; /* First of nMem value in the unpacked pKey */ + sqlite3_value *aMem; /* First of nMem value in the unpacked pKey */ u16 nMem; /* Number of aMem[] value. Might be zero */ int nData; /* Size of pData. 0 if none. */ int nZero; /* Extra zero data appended after pData,nData */ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d12da51444..99d381d9d0 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -3702,7 +3702,7 @@ int sqlite3_stmt_busy(sqlite3_stmt*); ** The [sqlite3_value_blob | sqlite3_value_type()] family of ** interfaces require protected sqlite3_value objects. */ -typedef struct Mem sqlite3_value; +typedef struct sqlite3_value sqlite3_value; /* ** CAPI3REF: SQL Function Context Object diff --git a/src/vdbe.h b/src/vdbe.h index be19bc5316..651810d4a4 100644 --- a/src/vdbe.h +++ b/src/vdbe.h @@ -30,7 +30,7 @@ typedef struct Vdbe Vdbe; ** The names of the following types declared in vdbeInt.h are required ** for the VdbeOp definition. */ -typedef struct Mem Mem; +typedef struct sqlite3_value Mem; typedef struct SubProgram SubProgram; /* diff --git a/src/vdbeInt.h b/src/vdbeInt.h index c0435a5a79..6ef155b5c3 100644 --- a/src/vdbeInt.h +++ b/src/vdbeInt.h @@ -185,7 +185,7 @@ struct VdbeFrame { ** structures. Each Mem struct may cache multiple representations (string, ** integer etc.) of the same value. */ -struct Mem { +struct sqlite3_value { union MemValue { double r; /* Real value used when MEM_Real is set in flags */ i64 i; /* Integer value used when MEM_Int is set in flags */ From e12e24ded81798d8580fbf527c6adcb3b7be3f7c Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Apr 2017 12:25:05 +0000 Subject: [PATCH 04/12] Change the JSON extension so that it disallows control characters inside of strings. Fix for ticket [6c9b5514077fed34551f98e64c09a10dc2fc8e16]. FossilOrigin-Name: 475d8f82ec61a4ff3e6a7650731230ccecb6cc580d1397d189d0ba479d9bad4d --- ext/misc/json1.c | 2 +- manifest | 14 +++++++------- manifest.uuid | 2 +- test/json102.test | 11 +++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index b12964ba4d..0d1b9a4642 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -785,7 +785,7 @@ static int jsonParseValue(JsonParse *pParse, u32 i){ j = i+1; for(;;){ c = z[j]; - if( c==0 ) return -1; + if( c<=0x1f ) return -1; /* Control characters not allowed in strings */ if( c=='\\' ){ c = z[++j]; if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' diff --git a/manifest b/manifest index e5b43e782e..8aad80974e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\sexpose\sthe\sname\sof\sthe\sinternal\sMem\sobject\sin\sthe\spublic\sinterface\ndefined\sby\ssqlite3.h. -D 2017-04-09T19:23:55.530 +C Change\sthe\sJSON\sextension\sso\sthat\sit\sdisallows\scontrol\scharacters\sinside\sof\nstrings.\s\sFix\sfor\sticket\s[6c9b5514077fed34551f98e64c09a10dc2fc8e16]. +D 2017-04-10T12:25:05.724 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -218,7 +218,7 @@ F ext/misc/eval.c f971962e92ebb8b0a4e6b62949463ee454d88fa2 F ext/misc/fileio.c d4171c815d6543a9edef8308aab2951413cd8d0f F ext/misc/fuzzer.c 7c64b8197bb77b7d64eff7cac7848870235d4c25 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 312b4ddf4c7399dcbd2189f492e8ca92a872c2df7347473bfb38854f9d60c06a +F ext/misc/json1.c 70d49f69ce61e54a83a29e425e704ca3e7e42e6bd9a7cf3c112d0ad995f6560b F ext/misc/memvfs.c e5225bc22e79dde6b28380f3a068ddf600683a33 F ext/misc/nextchar.c 35c8b8baacb96d92abbb34a83a997b797075b342 F ext/misc/percentile.c 92699c8cd7d517ff610e6037e56506f8904dae2e @@ -911,7 +911,7 @@ F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac -F test/json102.test de1728e8ffde4a57cbc77b6815a60ccb82a6c759967be44e71952757e7d7947b +F test/json102.test 0eacdde66991e9afd3f2a010fa97e9843de55b84297982875a017c3dc8aaec7e F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 204e72f0080e8f08f99978870bd3cb9d59b068ecffee82192d707c650548b43b -R 4aadeea99512ebde70036e66f3a8d746 +P 19dd753f9e50fee247b1ab141669817c7e88bc3f6d6065dba6c731db9f7a2409 +R 4d25d4996adadb5793b8d9872a867cae U drh -Z d0890c6128b3b61f6503cc6c672cce64 +Z 90838f4be97951a4a7983906c4e90eed diff --git a/manifest.uuid b/manifest.uuid index a6f6c0a5e4..d2945c983f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -19dd753f9e50fee247b1ab141669817c7e88bc3f6d6065dba6c731db9f7a2409 \ No newline at end of file +475d8f82ec61a4ff3e6a7650731230ccecb6cc580d1397d189d0ba479d9bad4d \ No newline at end of file diff --git a/test/json102.test b/test/json102.test index d1f2a4d36d..5c7866391f 100644 --- a/test/json102.test +++ b/test/json102.test @@ -319,4 +319,15 @@ do_execsql_test json102-1410 { SELECT json_valid('{"x":-01.5}') } 0 do_execsql_test json102-1411 { SELECT json_valid('{"x":00}') } 0 do_execsql_test json102-1412 { SELECT json_valid('{"x":-00}') } 0 +#------------------------------------------------------------------------ +# 2017-04-10 ticket 6c9b5514077fed34551f98e64c09a10dc2fc8e16 +# JSON extension accepts strings containing control characters. +# +# The JSON spec requires that all control characters be escaped. +# +do_execsql_test json102-1500 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<0x20) + SELECT x FROM c WHERE json_valid(printf('{"a":"x%sz"}', char(x))) ORDER BY x; +} {32} + finish_test From 2ac702d8c04451bc1ea4672c8b3e41c13bf30ae3 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Apr 2017 12:31:15 +0000 Subject: [PATCH 05/12] Add a new JSON test case to verify that all control characters are escaped in the json_quote() function. FossilOrigin-Name: 6ee12221fa252784c897a24ae8cff64dfe6149cbc9020abe14539df33202d892 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/json102.test | 7 +++++++ 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 8aad80974e..9e00749dd3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Change\sthe\sJSON\sextension\sso\sthat\sit\sdisallows\scontrol\scharacters\sinside\sof\nstrings.\s\sFix\sfor\sticket\s[6c9b5514077fed34551f98e64c09a10dc2fc8e16]. -D 2017-04-10T12:25:05.724 +C Add\sa\snew\sJSON\stest\scase\sto\sverify\sthat\sall\scontrol\scharacters\sare\sescaped\nin\sthe\sjson_quote()\sfunction. +D 2017-04-10T12:31:15.817 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -911,7 +911,7 @@ F test/jrnlmode.test 7864d59cf7f6e552b9b99ba0f38acd167edc10fa F test/jrnlmode2.test 81610545a4e6ed239ea8fa661891893385e23a1d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa F test/json101.test c0897616f32d95431f37fd291cb78742181980ac -F test/json102.test 0eacdde66991e9afd3f2a010fa97e9843de55b84297982875a017c3dc8aaec7e +F test/json102.test eeb54efa221e50b74a2d6fb9259963b48d7414dca3ce2fdfdeed45cb28487bc1 F test/json103.test c5f6b85e69de05f6b3195f9f9d5ce9cd179099a0 F test/json104.test 877d5845f6303899b7889ea5dd1bea99076e3100574d5c536082245c5805dcaa F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 19dd753f9e50fee247b1ab141669817c7e88bc3f6d6065dba6c731db9f7a2409 -R 4d25d4996adadb5793b8d9872a867cae +P 475d8f82ec61a4ff3e6a7650731230ccecb6cc580d1397d189d0ba479d9bad4d +R e695ac710cfefacf863281e0b95431be U drh -Z 90838f4be97951a4a7983906c4e90eed +Z 55d7fe0aa816bb30b53d727ea413a3ad diff --git a/manifest.uuid b/manifest.uuid index d2945c983f..841a70c05c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -475d8f82ec61a4ff3e6a7650731230ccecb6cc580d1397d189d0ba479d9bad4d \ No newline at end of file +6ee12221fa252784c897a24ae8cff64dfe6149cbc9020abe14539df33202d892 \ No newline at end of file diff --git a/test/json102.test b/test/json102.test index 5c7866391f..18a6bbf5cc 100644 --- a/test/json102.test +++ b/test/json102.test @@ -330,4 +330,11 @@ do_execsql_test json102-1500 { SELECT x FROM c WHERE json_valid(printf('{"a":"x%sz"}', char(x))) ORDER BY x; } {32} +# All control characters are escaped +# +do_execsql_test json102-1501 { + WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<0x1f) + SELECT sum(json_valid(json_quote('a'||char(x)||'z'))) FROM c ORDER BY x; +} {31} + finish_test From 4c6463cc29ba5fb3efa6c609e99e4c7258145f8e Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Apr 2017 20:27:54 +0000 Subject: [PATCH 06/12] Slightly smaller and faster sqlite3VdbeMemGrow(). FossilOrigin-Name: efd1702ae8da8e0dd3d2ee7bd5a1bd8aeff2b370498e404041fcb406fdaf72e4 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbemem.c | 32 +++++++++++++++----------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 9e00749dd3..da40325b79 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\snew\sJSON\stest\scase\sto\sverify\sthat\sall\scontrol\scharacters\sare\sescaped\nin\sthe\sjson_quote()\sfunction. -D 2017-04-10T12:31:15.817 +C Slightly\ssmaller\sand\sfaster\ssqlite3VdbeMemGrow(). +D 2017-04-10T20:27:54.806 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -474,7 +474,7 @@ F src/vdbeInt.h c070bc5c8b913bda0ceaa995cd4d939ded5e4fc96cf7c3c1c602d41b871f8ade F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 F src/vdbeaux.c 0ecacf8c7ca93e430b30819b8fc9b2c1ffe88202d1437e88c08a1f0b6159c58c F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 -F src/vdbemem.c 8bb4dd22837da969bfda25ef3f92d41aaad192328f89a0951290d5e26ad7dbc4 +F src/vdbemem.c 934f9bce97228df9d2ae7f094e1ffcd5ada8fe9c0b13cf5c3978c4b7e64f1087 F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 475d8f82ec61a4ff3e6a7650731230ccecb6cc580d1397d189d0ba479d9bad4d -R e695ac710cfefacf863281e0b95431be +P 6ee12221fa252784c897a24ae8cff64dfe6149cbc9020abe14539df33202d892 +R ae61a98584e297a339cd6bce47824c4a U drh -Z 55d7fe0aa816bb30b53d727ea413a3ad +Z 28f2e38050d0b016e3e15bd91aa46f28 diff --git a/manifest.uuid b/manifest.uuid index 841a70c05c..850654a2c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6ee12221fa252784c897a24ae8cff64dfe6149cbc9020abe14539df33202d892 \ No newline at end of file +efd1702ae8da8e0dd3d2ee7bd5a1bd8aeff2b370498e404041fcb406fdaf72e4 \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index d7963cb7e7..e5890d2940 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -125,23 +125,21 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ assert( pMem->szMalloc==0 || pMem->szMalloc==sqlite3DbMallocSize(pMem->db, pMem->zMalloc) ); - if( pMem->szMallocszMalloc>0 && pMem->z==pMem->zMalloc ){ - pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); - bPreserve = 0; - }else{ - if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); - pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); - } - if( pMem->zMalloc==0 ){ - sqlite3VdbeMemSetNull(pMem); - pMem->z = 0; - pMem->szMalloc = 0; - return SQLITE_NOMEM_BKPT; - }else{ - pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); - } + if( n<32 ) n = 32; + if( bPreserve && pMem->szMalloc>0 && pMem->z==pMem->zMalloc ){ + pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n); + bPreserve = 0; + }else{ + if( pMem->szMalloc>0 ) sqlite3DbFreeNN(pMem->db, pMem->zMalloc); + pMem->zMalloc = sqlite3DbMallocRaw(pMem->db, n); + } + if( pMem->zMalloc==0 ){ + sqlite3VdbeMemSetNull(pMem); + pMem->z = 0; + pMem->szMalloc = 0; + return SQLITE_NOMEM_BKPT; + }else{ + pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); } if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){ From 0415d826c08f9acdca57ebb860862bea3b932087 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 10 Apr 2017 20:51:21 +0000 Subject: [PATCH 07/12] Smaller and faster vdbeFreeOpArray() FossilOrigin-Name: e052436d9f54b785facd661adc648512356b831c0547aa8f347ebf4bd8ef1254 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbeaux.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index da40325b79..ce780fd179 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Slightly\ssmaller\sand\sfaster\ssqlite3VdbeMemGrow(). -D 2017-04-10T20:27:54.806 +C Smaller\sand\sfaster\svdbeFreeOpArray() +D 2017-04-10T20:51:21.112 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -472,7 +472,7 @@ F src/vdbe.c 808fda3d50f544120d27c731449b524b4ec8f8b0f734b228831078f0ba53ecb9 F src/vdbe.h f7d1456e28875c2dcb964056589b5b7149ab7edf39edeca801596a39bb3d3848 F src/vdbeInt.h c070bc5c8b913bda0ceaa995cd4d939ded5e4fc96cf7c3c1c602d41b871f8ade F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 -F src/vdbeaux.c 0ecacf8c7ca93e430b30819b8fc9b2c1ffe88202d1437e88c08a1f0b6159c58c +F src/vdbeaux.c 6b3f6ce909e206d4c918988b13b7fa687e92b4471d137e0f2a37edac80ec60be F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 F src/vdbemem.c 934f9bce97228df9d2ae7f094e1ffcd5ada8fe9c0b13cf5c3978c4b7e64f1087 F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570c @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6ee12221fa252784c897a24ae8cff64dfe6149cbc9020abe14539df33202d892 -R ae61a98584e297a339cd6bce47824c4a +P efd1702ae8da8e0dd3d2ee7bd5a1bd8aeff2b370498e404041fcb406fdaf72e4 +R 08e07e2df33f53e5c795c66423297623 U drh -Z 28f2e38050d0b016e3e15bd91aa46f28 +Z fe1f0eec29c92bb8a2e730e35a741ada diff --git a/manifest.uuid b/manifest.uuid index 850654a2c8..bbd127fb57 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -efd1702ae8da8e0dd3d2ee7bd5a1bd8aeff2b370498e404041fcb406fdaf72e4 \ No newline at end of file +e052436d9f54b785facd661adc648512356b831c0547aa8f347ebf4bd8ef1254 \ No newline at end of file diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 3fcfb681d1..00a5ec91a9 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -879,7 +879,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ if( aOp ){ Op *pOp; - for(pOp=aOp; pOp<&aOp[nOp]; pOp++){ + for(pOp=&aOp[nOp-1]; pOp>=aOp; pOp--){ if( pOp->p4type ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS sqlite3DbFree(db, pOp->zComment); From eac5fc047622aa8d72005b1b3f99968bd14c62e1 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Apr 2017 01:01:27 +0000 Subject: [PATCH 08/12] Improved comments. Fix a problem when an indexed expression is used in an ORDER BY clause. FossilOrigin-Name: c59eaf2b7cd2596733f349fc0fe979f71fd29bd73152a0c57066e0b69d5b7a4a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/select.c | 27 +++++++++++++++++++-------- src/wherecode.c | 19 +++++++++++++++---- 4 files changed, 42 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 45c8bc8233..09a2684db4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\schanges\sfrom\strunk. -D 2017-04-10T23:42:04.790 +C Improved\scomments.\s\sFix\sa\sproblem\swhen\san\sindexed\sexpression\sis\sused\sin\san\nORDER\sBY\sclause. +D 2017-04-11T01:01:27.332 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -401,7 +401,7 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c b24e628a2b76800171f4c86e38b5d93e27f2c40e603b24733aa8e471029e6ecd +F src/select.c 9228235fdefe6de138ac01c4c68d07fd95d78780ef85112a76e63e260a6f5897 F src/shell.c 70f4957b988572315e97c56941fdc81fd35907fee36b7b2e7be5ec4c7e9d065d F src/sqlite.h.in 40233103e3e4e10f8a63523498d0259d232e42aba478e2d3fb914799185aced6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -484,7 +484,7 @@ F src/wal.h 06b2a0b599cc0f53ea97f497cf8c6b758c999f71 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 F src/where.c 1d14e18f32231fa7969e718e7b60ef749b0065e2a7e1b6b00883b20732d280f1 F src/whereInt.h 7a21ef633e26acbf46df04add2eba6e0a2100c78dc5879049e93f981fc3344df -F src/wherecode.c 38d171e309c7b54d5bdc7d8b663ec16249ad8888e01a77f6c55e9350de8e8349 +F src/wherecode.c 943e32e9dccd0af802e0683ae11071c8bd808364e5908a5fb66758bd404c8681 F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd @@ -1570,7 +1570,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 13a422230dcf4a8a80434af97434d57e456dcaa6bf0c41e6859f37ded6fa96ca e052436d9f54b785facd661adc648512356b831c0547aa8f347ebf4bd8ef1254 -R a0a3c2f64645982d19356fee9ed1bee3 +P 8978465f335925378d3aa99df6190ce6a1ee6b130205ccc493f2399803844760 +R 1b0a9c05391f59848f876fd33c1876bb U drh -Z 41de53ab744a90538b62b8272746f983 +Z 21e604ae631dfab7b9082f6214d51689 diff --git a/manifest.uuid b/manifest.uuid index 68ee565894..f5bcb5c58b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8978465f335925378d3aa99df6190ce6a1ee6b130205ccc493f2399803844760 \ No newline at end of file +c59eaf2b7cd2596733f349fc0fe979f71fd29bd73152a0c57066e0b69d5b7a4a \ No newline at end of file diff --git a/src/select.c b/src/select.c index 55d2584fbe..10519b44ac 100644 --- a/src/select.c +++ b/src/select.c @@ -1530,6 +1530,7 @@ static void generateColumnTypes( NameContext sNC; sNC.pSrcList = pTabList; sNC.pParse = pParse; + sNC.pNext = 0; for(i=0; inExpr; i++){ Expr *p = pEList->a[i].pExpr; const char *zType; @@ -1554,6 +1555,19 @@ static void generateColumnTypes( #endif /* !defined(SQLITE_OMIT_DECLTYPE) */ } +/* +** Return the Table objecct in the SrcList that has cursor iCursor. +** Or return NULL if no such Table object exists in the SrcList. +*/ +static Table *tableWithCursor(SrcList *pList, int iCursor){ + int j; + for(j=0; jnSrc; j++){ + if( pList->a[j].iCursor==iCursor ) return pList->a[j].pTab; + } + return 0; +} + + /* ** Generate code that will tell the VDBE the names of columns ** in the result set. This information is used to provide the @@ -1565,7 +1579,8 @@ static void generateColumnNames( ExprList *pEList /* Expressions defining the result set */ ){ Vdbe *v = pParse->pVdbe; - int i, j; + int i; + Table *pTab; sqlite3 *db = pParse->db; int fullNames, shortNames; @@ -1590,15 +1605,11 @@ static void generateColumnNames( if( pEList->a[i].zName ){ char *zName = pEList->a[i].zName; sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, SQLITE_TRANSIENT); - }else if( p->op==TK_COLUMN || p->op==TK_AGG_COLUMN ){ - Table *pTab; + }else if( (p->op==TK_COLUMN || p->op==TK_AGG_COLUMN) + && (pTab = tableWithCursor(pTabList, p->iTable))!=0 + ){ char *zCol; int iCol = p->iColumn; - for(j=0; ALWAYS(jnSrc); j++){ - if( pTabList->a[j].iCursor==p->iTable ) break; - } - assert( jnSrc ); - pTab = pTabList->a[j].pTab; if( iCol<0 ) iCol = pTab->iPKey; assert( iCol==-1 || (iCol>=0 && iColnCol) ); if( iCol<0 ){ diff --git a/src/wherecode.c b/src/wherecode.c index bdf732755e..d429fbb523 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1039,7 +1039,10 @@ static void codeExprOrVector(Parse *pParse, Expr *p, int iReg, int nReg){ } } -#if 1 /* INDEXEXPRTRANS */ +/* An instance of the IdxExprTrans object carries information about a +** mapping from an expression on table columns into a column in an index +** down through the Walker. +*/ typedef struct IdxExprTrans { Expr *pIdxExpr; /* The index expression */ int iTabCur; /* The cursor of the corresponding table */ @@ -1047,6 +1050,12 @@ typedef struct IdxExprTrans { int iIdxCol; /* The column for the index */ } IdxExprTrans; +/* The walker node callback used to transform matching expressions into +** a reference to an index column for an index on an expression. +** +** If pExpr matches, then transform it into a reference to the index column +** that contains the value of pExpr. +*/ static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ @@ -1092,7 +1101,6 @@ static void whereIndexExprTrans( sqlite3WalkExprList(&w, pWInfo->pResultSet); } } -#endif /* ** Generate code for the start of the iLevel-th loop in the WHERE clause @@ -1675,9 +1683,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( iRowidReg, pPk->nKeyCol); VdbeCoverage(v); } -#if 1 /* INDEXEXPRTANS */ + /* If pIdx is an index on one or more expressions, then look through + ** all the expressions in pWInfo and try to transform matching expressions + ** into reference to index columns. + */ whereIndexExprTrans(pIdx, iCur, iIdxCur, pWInfo); -#endif + /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ From b8d29c2f75ec3ab56e6cc7be47646d5151dea86f Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 11 Apr 2017 11:52:25 +0000 Subject: [PATCH 09/12] Fix a segfault that could occur if an indexed expression was used in a comparison operation within the result-set of a SELECT statement. FossilOrigin-Name: d6bb7c42ff6309ce168ccdcf03b4cdabfccfc9e2a911d254ac7dc4fea4aa2bc1 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- test/indexexpr2.test | 36 ++++++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) create mode 100644 test/indexexpr2.test diff --git a/manifest b/manifest index 944af9d4e5..9c3dec2998 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\susing\san\sindex\son\san\sexpression,\stry\sto\suse\sthe\scolumns\sof\sthe\sindex\nrather\sthan\spulling\scolumns\sfrom\sthe\stable\sand\sreevaluating\sthe\sexpression. -D 2017-04-11T01:30:42.675 +C Fix\sa\ssegfault\sthat\scould\soccur\sif\san\sindexed\sexpression\swas\sused\sin\sa\ncomparison\soperation\swithin\sthe\sresult-set\sof\sa\sSELECT\sstatement. +D 2017-04-11T11:52:25.960 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -354,7 +354,7 @@ F src/ctime.c 47d91a25ad8f199a71a5b1b7b169d6dd0d6e98c5719eca801568798743d1161c F src/date.c ee676e7694dfadbdd2fde1a258a71be8360ba5ae F src/dbstat.c 19ee7a4e89979d4df8e44cfac7a8f905ec89b77d F src/delete.c 0d9d5549d42e79ce4d82ff1db1e6c81e36d2f67c -F src/expr.c 8fd6b7bc10c2c33e017b0f2715efdc83c01e348be27797022ed9eaa3002ca720 +F src/expr.c f6572c7690fa619e85b1192b683ccc30cd123363415963c061ada3770b18f6a7 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 2e9aabe1aee76273aff8a84ee92c464e095400ae F src/func.c 9d52522cc8ae7f5cdadfe14594262f1618bc1f86083c4cd6da861b4cf5af6174 @@ -878,6 +878,7 @@ F test/index7.test 7feababe16f2091b229c22aff2bcc1d4d6b9d2bb F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/indexedby.test 9c4cd331224e57f79fbf411ae245e6272d415985 F test/indexexpr1.test 038b3befa74e5a75126b6e9dd2ae5df61c1c7cf7 +F test/indexexpr2.test bcf694ae72efaaeb97691b990b61e39bf233884e27b9cc6b845a1f0c6bc9f0bb F test/indexfault.test 31d4ab9a7d2f6e9616933eb079722362a883eb1d F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 38742b5e9601c8f8d76e9b7555f7270288c2d371 @@ -1570,8 +1571,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e052436d9f54b785facd661adc648512356b831c0547aa8f347ebf4bd8ef1254 c59eaf2b7cd2596733f349fc0fe979f71fd29bd73152a0c57066e0b69d5b7a4a -R 1b0a9c05391f59848f876fd33c1876bb -T +closed c59eaf2b7cd2596733f349fc0fe979f71fd29bd73152a0c57066e0b69d5b7a4a -U drh -Z d8fc420323e8e66f4fe145abb4c72eca +P a47efb7c8520a01110ce3b3531ebe1bab6720780d67fba001992c44c5807d332 +R 23a3a6c1f1b033d4a8710b18c262d91a +U dan +Z ab01f2cb6410fac9d35417473ab077a6 diff --git a/manifest.uuid b/manifest.uuid index 5aefa94528..c52fa5cd85 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a47efb7c8520a01110ce3b3531ebe1bab6720780d67fba001992c44c5807d332 \ No newline at end of file +d6bb7c42ff6309ce168ccdcf03b4cdabfccfc9e2a911d254ac7dc4fea4aa2bc1 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index afdbbb1275..f3135ccaa9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -58,7 +58,7 @@ char sqlite3ExprAffinity(Expr *pExpr){ return sqlite3AffinityType(pExpr->u.zToken, 0); } #endif - if( op==TK_AGG_COLUMN || op==TK_COLUMN ){ + if( (op==TK_AGG_COLUMN || op==TK_COLUMN) && pExpr->pTab ){ return sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn); } if( op==TK_SELECT_COLUMN ){ diff --git a/test/indexexpr2.test b/test/indexexpr2.test new file mode 100644 index 0000000000..140498b124 --- /dev/null +++ b/test/indexexpr2.test @@ -0,0 +1,36 @@ +# 2017 April 11 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix indexexpr2 + +do_execsql_test 1 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + + CREATE INDEX i1 ON t1(b || 'x'); +} + +do_execsql_test 1.1 { + SELECT 'TWOX' == (b || 'x') FROM t1 WHERE (b || 'x')>'onex' +} {0 0} + +do_execsql_test 1.2 { + SELECT 'TWOX' == (b || 'x') COLLATE nocase FROM t1 WHERE (b || 'x')>'onex' +} {0 1} + +finish_test + From cbae543a5c38d6328aef03391f57ada19da1cdc9 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Apr 2017 12:20:54 +0000 Subject: [PATCH 10/12] Add an ALWAYS() around an unreachable condition in sqlite3VdbeMemGrow(). FossilOrigin-Name: 0f3eb61f44c94234ffc14c3a493a27ec62c0d1e2bb62798f36eafa98ddcdc58e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbemem.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 9c3dec2998..d9e49b0e04 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sthat\scould\soccur\sif\san\sindexed\sexpression\swas\sused\sin\sa\ncomparison\soperation\swithin\sthe\sresult-set\sof\sa\sSELECT\sstatement. -D 2017-04-11T11:52:25.960 +C Add\san\sALWAYS()\saround\san\sunreachable\scondition\sin\ssqlite3VdbeMemGrow(). +D 2017-04-11T12:20:54.451 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -474,7 +474,7 @@ F src/vdbeInt.h c070bc5c8b913bda0ceaa995cd4d939ded5e4fc96cf7c3c1c602d41b871f8ade F src/vdbeapi.c 5b08d82592bcff4470601fe78aaabebd50837860 F src/vdbeaux.c 6b3f6ce909e206d4c918988b13b7fa687e92b4471d137e0f2a37edac80ec60be F src/vdbeblob.c 359891617358deefc85bef7bcf787fa6b77facb9 -F src/vdbemem.c 934f9bce97228df9d2ae7f094e1ffcd5ada8fe9c0b13cf5c3978c4b7e64f1087 +F src/vdbemem.c 3122f5a21064198c10ee1b4686937aab27d5395712d9af905b7fa1affc47a453 F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570c F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834 F src/vtab.c 007513c2ef52472fcdea6a741683d50662e82790 @@ -1571,7 +1571,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P a47efb7c8520a01110ce3b3531ebe1bab6720780d67fba001992c44c5807d332 -R 23a3a6c1f1b033d4a8710b18c262d91a -U dan -Z ab01f2cb6410fac9d35417473ab077a6 +P d6bb7c42ff6309ce168ccdcf03b4cdabfccfc9e2a911d254ac7dc4fea4aa2bc1 +R 3ed33f6a8cc3dac4cc6e300fdc5f3bb6 +U drh +Z 9f3e0bc1025e624bd24df215db691169 diff --git a/manifest.uuid b/manifest.uuid index c52fa5cd85..55c3bcd3f4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d6bb7c42ff6309ce168ccdcf03b4cdabfccfc9e2a911d254ac7dc4fea4aa2bc1 \ No newline at end of file +0f3eb61f44c94234ffc14c3a493a27ec62c0d1e2bb62798f36eafa98ddcdc58e \ No newline at end of file diff --git a/src/vdbemem.c b/src/vdbemem.c index e5890d2940..4f57893767 100644 --- a/src/vdbemem.c +++ b/src/vdbemem.c @@ -142,7 +142,7 @@ SQLITE_NOINLINE int sqlite3VdbeMemGrow(Mem *pMem, int n, int bPreserve){ pMem->szMalloc = sqlite3DbMallocSize(pMem->db, pMem->zMalloc); } - if( bPreserve && pMem->z && pMem->z!=pMem->zMalloc ){ + if( bPreserve && pMem->z && ALWAYS(pMem->z!=pMem->zMalloc) ){ memcpy(pMem->zMalloc, pMem->z, pMem->n); } if( (pMem->flags&MEM_Dyn)!=0 ){ From ef90a6b8dd49a9a676df8ea4b3bfec028d977c8a Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Apr 2017 16:44:39 +0000 Subject: [PATCH 11/12] Very slight smaller and faster sqlite3SelectNew() FossilOrigin-Name: 4143650c4ce32289d2301cdfc69bb10877246420f656bed122886f6803fc956a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/select.c | 15 +++++++-------- 3 files changed, 14 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index d9e49b0e04..94fb9ee84b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\san\sALWAYS()\saround\san\sunreachable\scondition\sin\ssqlite3VdbeMemGrow(). -D 2017-04-11T12:20:54.451 +C Very\sslight\ssmaller\sand\sfaster\ssqlite3SelectNew() +D 2017-04-11T16:44:39.910 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -401,7 +401,7 @@ F src/printf.c 8757834f1b54dae512fb25eb1acc8e94a0d15dd2290b58f2563f65973265adb2 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac -F src/select.c 9228235fdefe6de138ac01c4c68d07fd95d78780ef85112a76e63e260a6f5897 +F src/select.c e6f9afd8a5ef35bd186e51a6bea6d3d46bc93a530f26a21fe8a0a43dbeca9415 F src/shell.c 70f4957b988572315e97c56941fdc81fd35907fee36b7b2e7be5ec4c7e9d065d F src/sqlite.h.in 40233103e3e4e10f8a63523498d0259d232e42aba478e2d3fb914799185aced6 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1571,7 +1571,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P d6bb7c42ff6309ce168ccdcf03b4cdabfccfc9e2a911d254ac7dc4fea4aa2bc1 -R 3ed33f6a8cc3dac4cc6e300fdc5f3bb6 +P 0f3eb61f44c94234ffc14c3a493a27ec62c0d1e2bb62798f36eafa98ddcdc58e +R 5f2f74eb29544d7d3c639e823e92116e U drh -Z 9f3e0bc1025e624bd24df215db691169 +Z 7231f0f16860dcf4ac8b22d5fa5d18a1 diff --git a/manifest.uuid b/manifest.uuid index 55c3bcd3f4..8095499f96 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0f3eb61f44c94234ffc14c3a493a27ec62c0d1e2bb62798f36eafa98ddcdc58e \ No newline at end of file +4143650c4ce32289d2301cdfc69bb10877246420f656bed122886f6803fc956a \ No newline at end of file diff --git a/src/select.c b/src/select.c index 10519b44ac..54265ab2a9 100644 --- a/src/select.c +++ b/src/select.c @@ -112,14 +112,13 @@ Select *sqlite3SelectNew( ){ Select *pNew; Select standin; - sqlite3 *db = pParse->db; - pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) ); + pNew = sqlite3DbMallocRawNN(pParse->db, sizeof(*pNew) ); if( pNew==0 ){ - assert( db->mallocFailed ); + assert( pParse->db->mallocFailed ); pNew = &standin; } if( pEList==0 ){ - pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db,TK_ASTERISK,0)); + pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(pParse->db,TK_ASTERISK,0)); } pNew->pEList = pEList; pNew->op = TK_SELECT; @@ -132,7 +131,7 @@ Select *sqlite3SelectNew( pNew->addrOpenEphm[0] = -1; pNew->addrOpenEphm[1] = -1; pNew->nSelectRow = 0; - if( pSrc==0 ) pSrc = sqlite3DbMallocZero(db, sizeof(*pSrc)); + if( pSrc==0 ) pSrc = sqlite3DbMallocZero(pParse->db, sizeof(*pSrc)); pNew->pSrc = pSrc; pNew->pWhere = pWhere; pNew->pGroupBy = pGroupBy; @@ -143,9 +142,9 @@ Select *sqlite3SelectNew( pNew->pLimit = pLimit; pNew->pOffset = pOffset; pNew->pWith = 0; - assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || db->mallocFailed!=0 ); - if( db->mallocFailed ) { - clearSelect(db, pNew, pNew!=&standin); + assert( pOffset==0 || pLimit!=0 || pParse->nErr>0 || pParse->db->mallocFailed!=0 ); + if( pParse->db->mallocFailed ) { + clearSelect(pParse->db, pNew, pNew!=&standin); pNew = 0; }else{ assert( pNew->pSrc!=0 || pParse->nErr>0 ); From e97c9ff49adaa4906f935f2e52e355110c806218 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 11 Apr 2017 18:06:48 +0000 Subject: [PATCH 12/12] Smaller and faster implementation of exprMightBeIndexed(). FossilOrigin-Name: 76cd611d41465fcec61c21520d55172cb236530f38386b7d4a5544ba87de2353 --- manifest | 12 ++++----- manifest.uuid | 2 +- src/whereexpr.c | 68 +++++++++++++++++++++++++++---------------------- 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/manifest b/manifest index 94fb9ee84b..24cef3a8e4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Very\sslight\ssmaller\sand\sfaster\ssqlite3SelectNew() -D 2017-04-11T16:44:39.910 +C Smaller\sand\sfaster\simplementation\sof\sexprMightBeIndexed(). +D 2017-04-11T18:06:48.387 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 F Makefile.msc a4c0613a18663bda56d8cf76079ab6590a7c3602e54befb4bbdef76bcaa38b6a @@ -485,7 +485,7 @@ F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791 F src/where.c 1d14e18f32231fa7969e718e7b60ef749b0065e2a7e1b6b00883b20732d280f1 F src/whereInt.h 7a21ef633e26acbf46df04add2eba6e0a2100c78dc5879049e93f981fc3344df F src/wherecode.c 943e32e9dccd0af802e0683ae11071c8bd808364e5908a5fb66758bd404c8681 -F src/whereexpr.c 130cdd1a43af71b19755270fb1224874cf55158c +F src/whereexpr.c e913aaa7b73ffcce66abcea5f197e2c538d48b5df78d0b7bba8ff4d73cc2e745 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1571,7 +1571,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 0f3eb61f44c94234ffc14c3a493a27ec62c0d1e2bb62798f36eafa98ddcdc58e -R 5f2f74eb29544d7d3c639e823e92116e +P 4143650c4ce32289d2301cdfc69bb10877246420f656bed122886f6803fc956a +R 1aa45dcbe6873a793fc57d44af855002 U drh -Z 7231f0f16860dcf4ac8b22d5fa5d18a1 +Z c24847878c6bf2e9fe8bedbea41e582e diff --git a/manifest.uuid b/manifest.uuid index 8095499f96..a6b9476e65 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4143650c4ce32289d2301cdfc69bb10877246420f656bed122886f6803fc956a \ No newline at end of file +76cd611d41465fcec61c21520d55172cb236530f38386b7d4a5544ba87de2353 \ No newline at end of file diff --git a/src/whereexpr.c b/src/whereexpr.c index 248b5349db..22dfa6d9b1 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -830,8 +830,8 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ ** Expression pExpr is one operand of a comparison operator that might ** be useful for indexing. This routine checks to see if pExpr appears ** in any index. Return TRUE (1) if pExpr is an indexed term and return -** FALSE (0) if not. If TRUE is returned, also set *piCur to the cursor -** number of the table that is indexed and *piColumn to the column number +** FALSE (0) if not. If TRUE is returned, also set aiCurCol[0] to the cursor +** number of the table that is indexed and aiCurCol[1] to the column number ** of the column that is indexed, or XN_EXPR (-2) if an expression is being ** indexed. ** @@ -839,18 +839,37 @@ static Bitmask exprSelectUsage(WhereMaskSet *pMaskSet, Select *pS){ ** true even if that particular column is not indexed, because the column ** might be added to an automatic index later. */ -static int exprMightBeIndexed( +static SQLITE_NOINLINE int exprMightBeIndexed2( SrcList *pFrom, /* The FROM clause */ - int op, /* The specific comparison operator */ Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ - Expr *pExpr, /* An operand of a comparison operator */ - int *piCur, /* Write the referenced table cursor number here */ - int *piColumn /* Write the referenced table column number here */ + int *aiCurCol, /* Write the referenced table cursor and column here */ + Expr *pExpr /* An operand of a comparison operator */ ){ Index *pIdx; int i; int iCur; - + for(i=0; mPrereq>1; i++, mPrereq>>=1){} + iCur = pFrom->a[i].iCursor; + for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->aColExpr==0 ) continue; + for(i=0; inKeyCol; i++){ + if( pIdx->aiColumn[i]!=XN_EXPR ) continue; + if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ + aiCurCol[0] = iCur; + aiCurCol[1] = XN_EXPR; + return 1; + } + } + } + return 0; +} +static int exprMightBeIndexed( + SrcList *pFrom, /* The FROM clause */ + Bitmask mPrereq, /* Bitmask of FROM clause terms referenced by pExpr */ + int *aiCurCol, /* Write the referenced table cursor & column here */ + Expr *pExpr, /* An operand of a comparison operator */ + int op /* The specific comparison operator */ +){ /* If this expression is a vector to the left or right of a ** inequality constraint (>, <, >= or <=), perform the processing ** on the first element of the vector. */ @@ -862,26 +881,13 @@ static int exprMightBeIndexed( } if( pExpr->op==TK_COLUMN ){ - *piCur = pExpr->iTable; - *piColumn = pExpr->iColumn; + aiCurCol[0] = pExpr->iTable; + aiCurCol[1] = pExpr->iColumn; return 1; } if( mPrereq==0 ) return 0; /* No table references */ if( (mPrereq&(mPrereq-1))!=0 ) return 0; /* Refs more than one table */ - for(i=0; mPrereq>1; i++, mPrereq>>=1){} - iCur = pFrom->a[i].iCursor; - for(pIdx=pFrom->a[i].pTab->pIndex; pIdx; pIdx=pIdx->pNext){ - if( pIdx->aColExpr==0 ) continue; - for(i=0; inKeyCol; i++){ - if( pIdx->aiColumn[i]!=XN_EXPR ) continue; - if( sqlite3ExprCompareSkip(pExpr, pIdx->aColExpr->a[i].pExpr, iCur)==0 ){ - *piCur = iCur; - *piColumn = XN_EXPR; - return 1; - } - } - } - return 0; + return exprMightBeIndexed2(pFrom,mPrereq,aiCurCol,pExpr); } /* @@ -961,7 +967,7 @@ static void exprAnalyze( pTerm->iParent = -1; pTerm->eOperator = 0; if( allowedOp(op) ){ - int iCur, iColumn; + int aiCurCol[2]; Expr *pLeft = sqlite3ExprSkipCollate(pExpr->pLeft); Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); u16 opMask = (pTerm->prereqRight & prereqLeft)==0 ? WO_ALL : WO_EQUIV; @@ -972,14 +978,14 @@ static void exprAnalyze( pLeft = pLeft->x.pList->a[pTerm->iField-1].pExpr; } - if( exprMightBeIndexed(pSrc, op, prereqLeft, pLeft, &iCur, &iColumn) ){ - pTerm->leftCursor = iCur; - pTerm->u.leftColumn = iColumn; + if( exprMightBeIndexed(pSrc, prereqLeft, aiCurCol, pLeft, op) ){ + pTerm->leftCursor = aiCurCol[0]; + pTerm->u.leftColumn = aiCurCol[1]; pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; if( pRight - && exprMightBeIndexed(pSrc, op, pTerm->prereqRight, pRight, &iCur,&iColumn) + && exprMightBeIndexed(pSrc, pTerm->prereqRight, aiCurCol, pRight, op) ){ WhereTerm *pNew; Expr *pDup; @@ -1009,8 +1015,8 @@ static void exprAnalyze( pNew = pTerm; } exprCommute(pParse, pDup); - pNew->leftCursor = iCur; - pNew->u.leftColumn = iColumn; + pNew->leftCursor = aiCurCol[0]; + pNew->u.leftColumn = aiCurCol[1]; testcase( (prereqLeft | extraRight) != prereqLeft ); pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll;