From 6e11892db8919592352b20228b9c9c36f31bf1a8 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 12 Aug 2019 16:36:38 +0000 Subject: [PATCH 001/112] Experimental implementation of NULLS FIRST/LAST. This branch still has problems - the most significant of which is that ORDER BY clauses with a non-default NULLS FIRST/LAST qualifier can never use an index. FossilOrigin-Name: 07babb0f897fc8c9cb5b30481899c32fdd743f3f3ca508d8d957826252107dd5 --- manifest | 39 ++++++++++++++++++-------------- manifest.uuid | 2 +- src/build.c | 11 ++++----- src/expr.c | 26 +++++++++++++++------- src/parse.y | 14 ++++++++---- src/select.c | 12 +++++----- src/sqliteInt.h | 9 +++++--- src/vdbe.c | 7 +++++- src/vdbeaux.c | 36 +++++++++++++++++++++--------- src/vdbesort.c | 7 ++++-- src/where.c | 8 ++++--- src/window.c | 8 +++---- test/nulls1.test | 53 ++++++++++++++++++++++++++++++++++++++++++++ tool/mkkeywordhash.c | 3 +++ 14 files changed, 171 insertions(+), 64 deletions(-) create mode 100644 test/nulls1.test diff --git a/manifest b/manifest index 89ec0e6944..168990dfe6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C For\sthe\s".testctrl\sprng_seed"\scommand\sin\sthe\sCLI,\sif\sthe\sargument\sis\s"random"\nthen\sselect\sa\srandom\sinteger\sseed\sand\sprint\sthe\sseed\svalue\son\sstdout. -D 2019-08-12T16:25:11.731 +C Experimental\simplementation\sof\sNULLS\sFIRST/LAST.\sThis\sbranch\sstill\shas\sproblems\s-\sthe\smost\ssignificant\sof\swhich\sis\sthat\sORDER\sBY\sclauses\swith\sa\snon-default\sNULLS\sFIRST/LAST\squalifier\scan\snever\suse\san\sindex. +D 2019-08-12T16:36:38.041 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -467,7 +467,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 781e4594098dca97db672e52ed17c7f063b5b65db144c0c1bf1e9818e7be1ad4 F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556 +F src/build.c 3584e598dd232b182bb657576a4b7ee0c2bd20afa59ad2fe0c4e65ed74e57b64 F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 85239130e25f54279b1dfb3641984a335ce5a38709af29f9b62b555ed1459d07 +F src/expr.c 7cc60cb97c0ddda825cc8bd2de4d3f51f183e894316c74225729ecfa8823aa05 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -512,7 +512,7 @@ F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3 -F src/parse.y 6d03a24bc0dcd15b93c480ea8a87f7ccd25313fe826485726d9ef13b82f2378d +F src/parse.y 61e979ce7f860df902b21b16ed40504ddd58fe4546fb15908a51538b3062e8e0 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848 @@ -523,12 +523,12 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c d49679d55d3cf529bbdff8734c4ac02cedfb2fc785545b89815ddb79680b9198 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117 +F src/select.c a8f5a4993c4ca59c68c55717f7f41e89cff6084b368f33cfd284dcf78262b9ad F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 0598c87a995d63b09bcc408552bf38205cd902b577e74b7c3237bde71093c28b +F src/sqliteInt.h f1ee0017108d34ecccd30301415be7861816877e3e9a01088df081fbcfbf908c F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -595,25 +595,25 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 1041610254502572bcc79ce6f61d9364fb93c154a4935fbaeaa7fd2e158e5205 +F src/vdbe.c bc43c994a18290b4022eb3751d510df1e070d92fa669e51de515fdd529ef105e F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6 F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e -F src/vdbeaux.c 8eeb9799d80bc6b37f2bcb23b3519234b596c530046c2cd0261f9ef1a1ba6c37 +F src/vdbeaux.c 68fd90976d0550bd9ab9ba03befba1f182aadce8bfca7d4b4eb33a2587c925bd F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b1 F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75 -F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2 +F src/vdbesort.c da75f505aba230060ce6472605a4aa6494f73eeb1071e1cc2643c3d4035e671b F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 90cb93dc8eb9383e72f661b2074551d47ff21e5379f7167f7e078bed436989e9 +F src/where.c 83fc2acadfbb1c86501fc0847fd068040ecd9a250a2fc0b81bab5698aa4bc72d F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc -F src/window.c 98b2571c66246bddadf42e76da45ed970fe7518a4c9c1ccc8cdace0711bfabba +F src/window.c 4d56fc1e3dbd3a4fa0653b3f48a3ad7066d0da91d0273cff8bab13c3412ddaf5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1182,6 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 +F test/nulls1.test eac9f46d9bf7a3883700bbc063e8a64fa2f4677ea64f12e173d3052d635f6b23 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1764,7 +1765,7 @@ F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/mkautoconfamal.sh 422fc365358a2e92876ffc62971a0ff28ed472fc8bcf9de0df921c736fdeca5e F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x F tool/mkctimec.tcl dd183b73ae1c28249669741c250525f0407e579a70482371668fd5f130d9feb3 -F tool/mkkeywordhash.c 537b1a11ec1829b51b633da3ba2cc889b4a3f7356b06a07423b6d4cce92c2350 +F tool/mkkeywordhash.c bc5bcc92ebcaf15345346be7cf2204b83ed649b5208234adb5e543c061209bbf F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6a13ea F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 @@ -1836,7 +1837,11 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 48d9b48ab4ace234eb1a055cf33cb533a1c3aa82d0a6e086d96226bd9474ceca -R 5a141faa1c39cc955778f126f1aabd0f -U drh -Z 779c2cf81842090ecdd5432af318ddb5 +P 636ca4472c9f41eb3989f28854d4968867837399a2092f389d1b814d98cccbae +R 6d8a33d8edc53ea630705f876c1c3795 +T *branch * nulls-last +T *sym-nulls-last * +T +closed 8174b2ca587e87083950ab21a47b4b4fe4bf309a8e16a82d4dc26d2c471e28cc +T -sym-trunk * +U dan +Z 02a41ef53191d3d08ca3291791a40934 diff --git a/manifest.uuid b/manifest.uuid index 74af8f947f..3ff2df6757 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -636ca4472c9f41eb3989f28854d4968867837399a2092f389d1b814d98cccbae \ No newline at end of file +07babb0f897fc8c9cb5b30481899c32fdd743f3f3ca508d8d957826252107dd5 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 1c8ef33c9c..71c04299b6 100644 --- a/src/build.c +++ b/src/build.c @@ -1443,7 +1443,7 @@ void sqlite3AddPrimaryKey( pTab->keyConf = (u8)onError; assert( autoInc==0 || autoInc==1 ); pTab->tabFlags |= autoInc*TF_Autoincrement; - if( pList ) pParse->iPkSortOrder = pList->a[0].sortOrder; + if( pList ) pParse->iPkSortOrder = pList->a[0].sortFlags; }else if( autoInc ){ #ifndef SQLITE_OMIT_AUTOINCREMENT sqlite3ErrorMsg(pParse, "AUTOINCREMENT is only allowed on an " @@ -1894,7 +1894,7 @@ static void convertToWithoutRowidTable(Parse *pParse, Table *pTab){ if( IN_RENAME_OBJECT ){ sqlite3RenameTokenRemap(pParse, pList->a[0].pExpr, &pTab->iPKey); } - pList->a[0].sortOrder = pParse->iPkSortOrder; + pList->a[0].sortFlags = pParse->iPkSortOrder; assert( pParse->pNewTable==pTab ); pTab->iPKey = -1; sqlite3CreateIndex(pParse, 0, 0, 0, pList, pTab->keyConf, 0, 0, 0, 0, @@ -3368,7 +3368,7 @@ void sqlite3CreateIndex( sqlite3ExprAlloc(db, TK_ID, &prevCol, 0)); if( pList==0 ) goto exit_create_index; assert( pList->nExpr==1 ); - sqlite3ExprListSetSortOrder(pList, sortOrder); + sqlite3ExprListSetSortOrder(pList, sortOrder, 0); }else{ sqlite3ExprListCheckLength(pParse, pList, "index"); if( pParse->nErr ) goto exit_create_index; @@ -3486,7 +3486,7 @@ void sqlite3CreateIndex( goto exit_create_index; } pIndex->azColl[i] = zColl; - requestedSortOrder = pListItem->sortOrder & sortOrderMask; + requestedSortOrder = pListItem->sortFlags & sortOrderMask; pIndex->aSortOrder[i] = (u8)requestedSortOrder; } @@ -4704,7 +4704,8 @@ KeyInfo *sqlite3KeyInfoOfIndex(Parse *pParse, Index *pIdx){ const char *zColl = pIdx->azColl[i]; pKey->aColl[i] = zColl==sqlite3StrBINARY ? 0 : sqlite3LocateCollSeq(pParse, zColl); - pKey->aSortOrder[i] = pIdx->aSortOrder[i]; + pKey->aSortFlags[i] = pIdx->aSortOrder[i]; + assert( 0==(pKey->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) ); } if( pParse->nErr ){ assert( pParse->rc==SQLITE_ERROR_MISSING_COLLSEQ ); diff --git a/src/expr.c b/src/expr.c index e00b319ed2..4307c08daa 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1404,7 +1404,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ } pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); - pItem->sortOrder = pOldItem->sortOrder; + pItem->sortFlags = pOldItem->sortFlags; pItem->done = 0; pItem->bSpanIsTab = pOldItem->bSpanIsTab; pItem->bSorterRef = pOldItem->bSorterRef; @@ -1657,15 +1657,25 @@ vector_append_error: /* ** Set the sort order for the last element on the given ExprList. */ -void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder){ +void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ if( p==0 ) return; - assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC>=0 && SQLITE_SO_DESC>0 ); assert( p->nExpr>0 ); - if( iSortOrder<0 ){ - assert( p->a[p->nExpr-1].sortOrder==SQLITE_SO_ASC ); - return; + + assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 ); + assert( iSortOrder==SQLITE_SO_UNDEFINED + || iSortOrder==SQLITE_SO_ASC + || iSortOrder==SQLITE_SO_DESC + ); + assert( eNulls==SQLITE_SO_UNDEFINED + || eNulls==SQLITE_SO_ASC + || eNulls==SQLITE_SO_DESC + ); + + if( iSortOrder==SQLITE_SO_UNDEFINED ) iSortOrder = SQLITE_SO_ASC; + p->a[p->nExpr-1].sortFlags = (u8)iSortOrder; + if( eNulls!=SQLITE_SO_UNDEFINED && iSortOrder!=eNulls ){ + p->a[p->nExpr-1].sortFlags |= KEYINFO_ORDER_BIGNULL; } - p->a[p->nExpr-1].sortOrder = (u8)iSortOrder; } /* @@ -4909,7 +4919,7 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ for(i=0; inExpr; i++){ Expr *pExprA = pA->a[i].pExpr; Expr *pExprB = pB->a[i].pExpr; - if( pA->a[i].sortOrder!=pB->a[i].sortOrder ) return 1; + if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1; if( sqlite3ExprCompare(0, pExprA, pExprB, iTab) ) return 1; } return 0; diff --git a/src/parse.y b/src/parse.y index 648e79d9e3..a919c41175 100644 --- a/src/parse.y +++ b/src/parse.y @@ -211,6 +211,7 @@ columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,&A,&Y);} IGNORE IMMEDIATE INITIALLY INSTEAD LIKE_KW MATCH NO PLAN QUERY KEY OF OFFSET PRAGMA RAISE RECURSIVE RELEASE REPLACE RESTRICT ROW ROWS ROLLBACK SAVEPOINT TEMP TRIGGER VACUUM VIEW VIRTUAL WITH WITHOUT + NULLS FIRST LAST %ifdef SQLITE_OMIT_COMPOUND_SELECT EXCEPT INTERSECT UNION %endif SQLITE_OMIT_COMPOUND_SELECT @@ -781,13 +782,13 @@ using_opt(U) ::= . {U = 0;} orderby_opt(A) ::= . {A = 0;} orderby_opt(A) ::= ORDER BY sortlist(X). {A = X;} -sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z). { +sortlist(A) ::= sortlist(A) COMMA expr(Y) sortorder(Z) nulls(X). { A = sqlite3ExprListAppend(pParse,A,Y); - sqlite3ExprListSetSortOrder(A,Z); + sqlite3ExprListSetSortOrder(A,Z,X); } -sortlist(A) ::= expr(Y) sortorder(Z). { +sortlist(A) ::= expr(Y) sortorder(Z) nulls(X). { A = sqlite3ExprListAppend(pParse,0,Y); /*A-overwrites-Y*/ - sqlite3ExprListSetSortOrder(A,Z); + sqlite3ExprListSetSortOrder(A,Z,X); } %type sortorder {int} @@ -796,6 +797,11 @@ sortorder(A) ::= ASC. {A = SQLITE_SO_ASC;} sortorder(A) ::= DESC. {A = SQLITE_SO_DESC;} sortorder(A) ::= . {A = SQLITE_SO_UNDEFINED;} +%type nulls {int} +nulls(A) ::= NULLS FIRST. {A = SQLITE_SO_ASC;} +nulls(A) ::= NULLS LAST. {A = SQLITE_SO_DESC;} +nulls(A) ::= . {A = SQLITE_SO_UNDEFINED;} + %type groupby_opt {ExprList*} %destructor groupby_opt {sqlite3ExprListDelete(pParse->db, $$);} groupby_opt(A) ::= . {A = 0;} diff --git a/src/select.c b/src/select.c index ca1256d160..db2667e2ab 100644 --- a/src/select.c +++ b/src/select.c @@ -664,7 +664,7 @@ static void pushOntoSorter( if( pParse->db->mallocFailed ) return; pOp->p2 = nKey + nData; pKI = pOp->p4.pKeyInfo; - memset(pKI->aSortOrder, 0, pKI->nKeyField); /* Makes OP_Jump testable */ + memset(pKI->aSortFlags, 0, pKI->nKeyField); /* Makes OP_Jump testable */ sqlite3VdbeChangeP4(v, -1, (char*)pKI, P4_KEYINFO); testcase( pKI->nAllField > pKI->nKeyField+2 ); pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, @@ -1275,7 +1275,7 @@ KeyInfo *sqlite3KeyInfoAlloc(sqlite3 *db, int N, int X){ int nExtra = (N+X)*(sizeof(CollSeq*)+1) - sizeof(CollSeq*); KeyInfo *p = sqlite3DbMallocRawNN(db, sizeof(KeyInfo) + nExtra); if( p ){ - p->aSortOrder = (u8*)&p->aColl[N+X]; + p->aSortFlags = (u8*)&p->aColl[N+X]; p->nKeyField = (u16)N; p->nAllField = (u16)(N+X); p->enc = ENC(db); @@ -1352,7 +1352,7 @@ KeyInfo *sqlite3KeyInfoFromExprList( assert( sqlite3KeyInfoIsWriteable(pInfo) ); for(i=iStart, pItem=pList->a+iStart; iaColl[i-iStart] = sqlite3ExprNNCollSeq(pParse, pItem->pExpr); - pInfo->aSortOrder[i-iStart] = pItem->sortOrder; + pInfo->aSortFlags[i-iStart] = pItem->sortFlags; } } return pInfo; @@ -2253,7 +2253,7 @@ static KeyInfo *multiSelectOrderByKeyInfo(Parse *pParse, Select *p, int nExtra){ } assert( sqlite3KeyInfoIsWriteable(pRet) ); pRet->aColl[i] = pColl; - pRet->aSortOrder[i] = pOrderBy->a[i].sortOrder; + pRet->aSortFlags[i] = pOrderBy->a[i].sortFlags; } } @@ -3228,7 +3228,7 @@ static int multiSelectOrderBy( assert( sqlite3KeyInfoIsWriteable(pKeyDup) ); for(i=0; iaColl[i] = multiSelectCollSeq(pParse, p, i); - pKeyDup->aSortOrder[i] = 0; + pKeyDup->aSortFlags[i] = 0; } } } @@ -4425,7 +4425,7 @@ static u8 minMaxQuery(sqlite3 *db, Expr *pFunc, ExprList **ppMinMax){ } *ppMinMax = pOrderBy = sqlite3ExprListDup(db, pEList, 0); assert( pOrderBy!=0 || db->mallocFailed ); - if( pOrderBy ) pOrderBy->a[0].sortOrder = sortOrder; + if( pOrderBy ) pOrderBy->a[0].sortFlags = sortOrder; return eRet; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1104b771f3..f036092bad 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2134,10 +2134,13 @@ struct KeyInfo { u16 nKeyField; /* Number of key columns in the index */ u16 nAllField; /* Total columns, including key plus others */ sqlite3 *db; /* The database connection */ - u8 *aSortOrder; /* Sort order for each column. */ + u8 *aSortFlags; /* Sort order for each column. */ CollSeq *aColl[1]; /* Collating sequence for each term of the key */ }; +#define KEYINFO_ORDER_DESC 0x01 +#define KEYINFO_ORDER_BIGNULL 0x02 + /* ** This object holds a record which has been parsed out into individual ** fields, for the purposes of doing a comparison. @@ -2597,7 +2600,7 @@ struct ExprList { Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ - u8 sortOrder; /* 1 for DESC or 0 for ASC */ + u8 sortFlags; /* 1 for DESC or 0 for ASC */ unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ unsigned reusable :1; /* Constant expression is reusable */ @@ -3881,7 +3884,7 @@ void sqlite3ExprDelete(sqlite3*, Expr*); void sqlite3ExprUnmapAndDelete(Parse*, Expr*); ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*); ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*); -void sqlite3ExprListSetSortOrder(ExprList*,int); +void sqlite3ExprListSetSortOrder(ExprList*,int,int); void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int); void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*); void sqlite3ExprListDelete(sqlite3*, ExprList*); diff --git a/src/vdbe.c b/src/vdbe.c index 0bba39a667..de9c24bef7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2227,9 +2227,14 @@ case OP_Compare: { REGISTER_TRACE(p2+idx, &aMem[p2+idx]); assert( inKeyField ); pColl = pKeyInfo->aColl[i]; - bRev = pKeyInfo->aSortOrder[i]; + bRev = (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC); iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); if( iCompare ){ + if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) + && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) + ){ + iCompare = -iCompare; + } if( bRev ) iCompare = -iCompare; break; } diff --git a/src/vdbeaux.c b/src/vdbeaux.c index 2e9fcc1250..6b1f34fb71 100644 --- a/src/vdbeaux.c +++ b/src/vdbeaux.c @@ -1493,14 +1493,16 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ case P4_KEYINFO: { int j; KeyInfo *pKeyInfo = pOp->p4.pKeyInfo; - assert( pKeyInfo->aSortOrder!=0 ); + assert( pKeyInfo->aSortFlags!=0 ); sqlite3_str_appendf(&x, "k(%d", pKeyInfo->nKeyField); for(j=0; jnKeyField; j++){ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : ""; if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; - sqlite3_str_appendf(&x, ",%s%s", - pKeyInfo->aSortOrder[j] ? "-" : "", zColl); + sqlite3_str_appendf(&x, ",%s%s%s", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", + zColl); } sqlite3_str_append(&x, ")", 1); break; @@ -3813,7 +3815,7 @@ UnpackedRecord *sqlite3VdbeAllocUnpackedRecord( p = (UnpackedRecord *)sqlite3DbMallocRaw(pKeyInfo->db, nByte); if( !p ) return 0; p->aMem = (Mem*)&((char*)p)[ROUND8(sizeof(UnpackedRecord))]; - assert( pKeyInfo->aSortOrder!=0 ); + assert( pKeyInfo->aSortFlags!=0 ); p->pKeyInfo = pKeyInfo; p->nField = pKeyInfo->nKeyField + 1; return p; @@ -3912,7 +3914,7 @@ static int vdbeRecordCompareDebug( if( szHdr1>98307 ) return SQLITE_CORRUPT; d1 = szHdr1; assert( pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); - assert( pKeyInfo->aSortOrder!=0 ); + assert( pKeyInfo->aSortFlags!=0 ); assert( pKeyInfo->nKeyField>0 ); assert( idx1<=szHdr1 || CORRUPT_DB ); do{ @@ -3943,7 +3945,12 @@ static int vdbeRecordCompareDebug( pKeyInfo->nAllField>i ? pKeyInfo->aColl[i] : 0); if( rc!=0 ){ assert( mem1.szMalloc==0 ); /* See comment below */ - if( pKeyInfo->aSortOrder[i] ){ + if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) + && ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null)) + ){ + rc = -rc; + } + if( pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_DESC ){ rc = -rc; /* Invert the result for DESC sort order. */ } goto debugCompareEnd; @@ -4319,7 +4326,7 @@ int sqlite3VdbeRecordCompareWithSkip( VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); - assert( pPKey2->pKeyInfo->aSortOrder!=0 ); + assert( pPKey2->pKeyInfo->aSortFlags!=0 ); assert( pPKey2->pKeyInfo->nKeyField>0 ); assert( idx1<=szHdr1 || CORRUPT_DB ); do{ @@ -4442,8 +4449,14 @@ int sqlite3VdbeRecordCompareWithSkip( } if( rc!=0 ){ - if( pPKey2->pKeyInfo->aSortOrder[i] ){ - rc = -rc; + int sortFlags = pPKey2->pKeyInfo->aSortFlags[i]; + if( sortFlags ){ + if( (sortFlags & KEYINFO_ORDER_BIGNULL)==0 + || ((sortFlags & KEYINFO_ORDER_DESC) + !=(serial_type==0 || (pRhs->flags&MEM_Null))) + ){ + rc = -rc; + } } assert( vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, rc) ); assert( mem1.szMalloc==0 ); /* See comment below */ @@ -4660,7 +4673,10 @@ RecordCompare sqlite3VdbeFindCompare(UnpackedRecord *p){ ** header size is (12*5 + 1 + 1) bytes. */ if( p->pKeyInfo->nAllField<=13 ){ int flags = p->aMem[0].flags; - if( p->pKeyInfo->aSortOrder[0] ){ + if( p->pKeyInfo->aSortFlags[0] ){ + if( p->pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL ){ + return sqlite3VdbeRecordCompare; + } p->r1 = 1; p->r2 = -1; }else{ diff --git a/src/vdbesort.c b/src/vdbesort.c index 05590da7ee..7d60ee5116 100644 --- a/src/vdbesort.c +++ b/src/vdbesort.c @@ -829,7 +829,8 @@ static int vdbeSorterCompareText( ); } }else{ - if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ + assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); + if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ res = res * -1; } } @@ -897,7 +898,8 @@ static int vdbeSorterCompareInt( pTask, pbKey2Cached, pKey1, nKey1, pKey2, nKey2 ); } - }else if( pTask->pSorter->pKeyInfo->aSortOrder[0] ){ + }else if( pTask->pSorter->pKeyInfo->aSortFlags[0] ){ + assert( !(pTask->pSorter->pKeyInfo->aSortFlags[0]&KEYINFO_ORDER_BIGNULL) ); res = res * -1; } @@ -1012,6 +1014,7 @@ int sqlite3VdbeSorterInit( if( pKeyInfo->nAllField<13 && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) + && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0 ){ pSorter->typeMask = SORTER_TYPE_INTEGER | SORTER_TYPE_TEXT; } diff --git a/src/where.c b/src/where.c index 65c92863a5..202db50bfc 100644 --- a/src/where.c +++ b/src/where.c @@ -1031,7 +1031,7 @@ static sqlite3_index_info *allocateIndexInfo( for(i=0; ia[i].pExpr; pIdxOrderBy[i].iColumn = pExpr->iColumn; - pIdxOrderBy[i].desc = pOrderBy->a[i].sortOrder; + pIdxOrderBy[i].desc = pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC; } *pmNoOmit = mNoOmit; @@ -3836,6 +3836,7 @@ static i8 wherePathSatisfiesOrderBy( continue; } } + if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) continue; if( iColumn!=XN_ROWID ){ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; @@ -3849,10 +3850,11 @@ static i8 wherePathSatisfiesOrderBy( if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ /* Make sure the sort order is compatible in an ORDER BY clause. ** Sort order is irrelevant for a GROUP BY clause. */ + assert( (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL)==0 ); if( revSet ){ - if( (rev ^ revIdx)!=pOrderBy->a[i].sortOrder ) isMatch = 0; + if( (rev ^ revIdx)!=pOrderBy->a[i].sortFlags ) isMatch = 0; }else{ - rev = revIdx ^ pOrderBy->a[i].sortOrder; + rev = revIdx ^ pOrderBy->a[i].sortFlags; if( rev ) *pRevMask |= MASKBIT(iLoop); revSet = 1; } diff --git a/src/window.c b/src/window.c index ebcb576bb5..287bb114cc 100644 --- a/src/window.c +++ b/src/window.c @@ -888,7 +888,7 @@ static ExprList *exprListAppendList( pDup->flags &= ~(EP_IntValue|EP_IsTrue|EP_IsFalse); } pList = sqlite3ExprListAppend(pParse, pList, pDup); - if( pList ) pList->a[nInit+i].sortOrder = pAppend->a[i].sortOrder; + if( pList ) pList->a[nInit+i].sortFlags = pAppend->a[i].sortFlags; } } return pList; @@ -1296,8 +1296,8 @@ void sqlite3WindowCodeInit(Parse *pParse, Window *pMWin){ pWin->regApp = pParse->nMem+1; pParse->nMem += 3; if( pKeyInfo && pWin->pFunc->zName[1]=='i' ){ - assert( pKeyInfo->aSortOrder[0]==0 ); - pKeyInfo->aSortOrder[0] = 1; + assert( pKeyInfo->aSortFlags[0]==0 ); + pKeyInfo->aSortFlags[0] = KEYINFO_ORDER_DESC; } sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pWin->csrApp, 2); sqlite3VdbeAppendP4(v, pKeyInfo, P4_KEYINFO); @@ -1860,7 +1860,7 @@ static void windowCodeRangeTest( assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 ); - if( p->pMWin->pOrderBy->a[0].sortOrder ){ + if( p->pMWin->pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){ switch( op ){ case OP_Ge: op = OP_Le; break; case OP_Gt: op = OP_Lt; break; diff --git a/test/nulls1.test b/test/nulls1.test new file mode 100644 index 0000000000..7b355e9a85 --- /dev/null +++ b/test/nulls1.test @@ -0,0 +1,53 @@ +# 2019 August 10 +# +# 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. +# + +#################################################### +# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! +#################################################### + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix nulls1 + +do_execsql_test 1.0 { + DROP TABLE IF EXISTS t3; + CREATE TABLE t3(a INTEGER); + INSERT INTO t3 VALUES(NULL), (10), (30), (20), (NULL); +} {} + +for {set a 0} {$a < 2} {incr a} { + foreach {tn limit} { + 1 "" + 2 "LIMIT 10" + } { + do_execsql_test 1.$a.$tn.1 " + SELECT a FROM t3 ORDER BY a nULLS FIRST $limit + " {{} {} 10 20 30} + + do_execsql_test 1.$a.$tn.2 " + SELECT a FROM t3 ORDER BY a nULLS LAST $limit + " {10 20 30 {} {}} + + do_execsql_test 1.$a.$tn.3 " + SELECT a FROM t3 ORDER BY a DESC nULLS FIRST $limit + " {{} {} 30 20 10} + + do_execsql_test 1.$a.$tn.4 " + SELECT a FROM t3 ORDER BY a DESC nULLS LAST $limit + " {30 20 10 {} {}} + } + + catchsql { CREATE INDEX i1 ON t3(a) } +} + +finish_test diff --git a/tool/mkkeywordhash.c b/tool/mkkeywordhash.c index ece8b63e19..77bc4ac5c0 100644 --- a/tool/mkkeywordhash.c +++ b/tool/mkkeywordhash.c @@ -210,6 +210,7 @@ static Keyword aKeywordTable[] = { { "EXPLAIN", "TK_EXPLAIN", EXPLAIN }, { "FAIL", "TK_FAIL", CONFLICT|TRIGGER }, { "FILTER", "TK_FILTER", WINDOWFUNC }, + { "FIRST", "TK_FIRST", ALWAYS }, { "FOLLOWING", "TK_FOLLOWING", WINDOWFUNC }, { "FOR", "TK_FOR", TRIGGER }, { "FOREIGN", "TK_FOREIGN", FKEY }, @@ -235,6 +236,7 @@ static Keyword aKeywordTable[] = { { "ISNULL", "TK_ISNULL", ALWAYS }, { "JOIN", "TK_JOIN", ALWAYS }, { "KEY", "TK_KEY", ALWAYS }, + { "LAST", "TK_LAST", ALWAYS }, { "LEFT", "TK_JOIN_KW", ALWAYS }, { "LIKE", "TK_LIKE_KW", ALWAYS }, { "LIMIT", "TK_LIMIT", ALWAYS }, @@ -245,6 +247,7 @@ static Keyword aKeywordTable[] = { { "NOTHING", "TK_NOTHING", UPSERT }, { "NOTNULL", "TK_NOTNULL", ALWAYS }, { "NULL", "TK_NULL", ALWAYS }, + { "NULLS", "TK_NULLS", ALWAYS }, { "OF", "TK_OF", ALWAYS }, { "OFFSET", "TK_OFFSET", ALWAYS }, { "ON", "TK_ON", ALWAYS }, From 3c1970fceeecef6da620c37cdd0755f31af646a7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Aug 2019 17:27:43 +0000 Subject: [PATCH 002/112] Update some corruption test cases to take [724f4df9c] into account. FossilOrigin-Name: 927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 --- ext/rtree/rtreefuzz001.test | 2 ++ manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts3corrupt4.test | 13 ++++++++++++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/ext/rtree/rtreefuzz001.test b/ext/rtree/rtreefuzz001.test index f4a91264c7..db9df205af 100644 --- a/ext/rtree/rtreefuzz001.test +++ b/ext/rtree/rtreefuzz001.test @@ -465,6 +465,7 @@ do_test rtreefuzz001-100 { | end c1b.db }] catchsql { + PRAGMA writable_schema = 1; SELECT rtreecheck('t1'); } } {1 {SQL logic error}} @@ -1040,6 +1041,7 @@ do_test rtreefuzz001-500 { | 2880: ff ff ff 06 00 00 00 0c 00 00 00 01 00 00 00 0b ................ | 2896: 00 00 00 00 00 00 00 02 40 00 00 00 00 00 00 00 ........@....... | end crash-2e81f5dce5cbd4.db}] + execsql { PRAGMA writable_schema = 1;} catchsql {UPDATE t1 SET ex= ex ISNULL} } {1 {database disk image is malformed}} diff --git a/manifest b/manifest index 349b4244e6..6acb6a9831 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sRBU\sfunction\ssqlite3rbu_bp_progress()\swhen\sused\sduring\san\sRBU\svacuum. -D 2019-08-13T15:11:25.734 +C Update\ssome\scorruption\stest\scases\sto\stake\s[724f4df9c]\sinto\saccount. +D 2019-08-13T17:27:43.409 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -401,7 +401,7 @@ F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b5879 F ext/rtree/rtreecheck.test d67d5b3e9e45bfa8cd90734e8e9302144ac415b8e9176c6f02d4f92892ee8a35 F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d -F ext/rtree/rtreefuzz001.test f9fecd174fc6475174d876f78f77b538122c1db296a96dca4615918953a892be +F ext/rtree/rtreefuzz001.test eef1ed593bb15886cd5d5367a2f2492f81e315848896cdf7afb6e21454978827 F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de F ext/rtree/util/randomshape.tcl 54ee03d0d4a1c621806f7f44d5b78d2db8fac26e0e8687c36c4bd0203b27dbff @@ -935,7 +935,7 @@ F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f F test/fts3corrupt.test 46b9ddda7f6588fd5a5b1f4bb4fc0618dc45010e7dddb8a3a188baf3197177ae F test/fts3corrupt2.test bf55c3fa0b0dc8ea1c0fe5543623bd27714585da6a129038fd6999fe3b0d25f3 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test 9c21ef823a72b0b4a09428d78e63a44c961c19b0821682f4e99cdfe147ac105b +F test/fts3corrupt4.test d5389e14950e57333bfc972f262c90b5ba0e864a958df9e437e3aacd3a5570a7 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3cov.test cb932743da52a1c79a1ab8983e26c8121cf02263d6ff16e1f642e6f9b8348338 F test/fts3d.test 2bd8c97bcb9975f2334147173b4872505b6a41359a4f9068960a36afe07a679f @@ -1836,7 +1836,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 7dae7b969ed314605a3a2da2cfdce4d81152740f5d3bfbc2a6e311b13ee325a7 -R 860238736fdd0447f200637ad8b8114e +P 8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe +R 7c1844eb7914622ca55e2a5e5ecac9a6 U dan -Z 5966eddfdd5804ca0c3aea69442d9a4f +Z 44af29e1f24cdb5aeb5d48277738f602 diff --git a/manifest.uuid b/manifest.uuid index da1d8fd8e3..dcd9c2344a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe \ No newline at end of file +927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 \ No newline at end of file diff --git a/test/fts3corrupt4.test b/test/fts3corrupt4.test index fdcfa969f2..d693702bf5 100644 --- a/test/fts3corrupt4.test +++ b/test/fts3corrupt4.test @@ -2147,6 +2147,7 @@ do_test 14.0 { }]} {} do_execsql_test 14.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; } @@ -3049,6 +3050,7 @@ do_test 19.0 { }]} {} do_catchsql_test 19.1 { + PRAGMA writable_schema = 1; SELECT rowid,a,c,snippet(t1,85101090932165,-1,10) FROM t1 WHERE a MATCH 'rtree'; } {1 {database disk image is malformed}} @@ -3250,6 +3252,7 @@ do_test 20.0 { }]} {} do_execsql_test 20.1 { + PRAGMA writable_schema = 1; BEGIN; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; @@ -3472,8 +3475,8 @@ do_test 21.0 { | end crash-18cc014e42e828.db }]} {} -breakpoint do_catchsql_test 21.1 { + PRAGMA writable_schema = 1; SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'R*'; } {1 {database disk image is malformed}} @@ -3694,6 +3697,7 @@ do_test 22.0 { }]} {} do_catchsql_test 22.1 { + PRAGMA writable_schema = 1; SELECT snippet(t1,'', '', '--',-1,01)==0 FROM t1 WHERE a MATCH 'rtree OR json1rtree OR json1'; } {0 {0 0 0 0 0 0 0}} @@ -3913,6 +3917,7 @@ do_test 23.0 { }]} {} do_catchsql_test 23.1 { + PRAGMA writable_schema = 1; SELECT 'FyzLy'FROM t1 WHERE t1 MATCH 'j'; } {1 {database disk image is malformed}} @@ -4131,6 +4136,7 @@ do_test 24.0 { }]} {} do_catchsql_test 24.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT '4hE'+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} @@ -4374,6 +4380,7 @@ do_test 25.0 { }]} {} do_catchsql_test 25.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x%1 FROM c WHERE x<599237) INSERT INTO t1( a ) SELECT randomblob(3000) FROM t2 ; } {0 {}} @@ -4608,6 +4615,7 @@ do_test 26.0 { }]} {} do_execsql_test 26.1 { + PRAGMA writable_schema = 1; SELECT count(*) FROM ( SELECT t1, (t1) FROM t1 WHERE b MATCH 'x' ) @@ -4826,6 +4834,7 @@ do_test 27.0 { }]} {} do_catchsql_test 27.2 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x GLOB 2.16770 FROM x) INSERT INTO t1(a) SELECT randomblob(3000) FROM t2 ; } {0 {}} @@ -5058,6 +5067,7 @@ do_test 28.0 { }]} {} do_catchsql_test 28.1 { + PRAGMA writable_schema = 1; WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT 3+x FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; } {0 {}} @@ -5312,6 +5322,7 @@ do_test 29.0 { }]} {} do_catchsql_test 29.1 { + PRAGMA writable_schema = 1; INSERT INTO t1(a) SELECT X'819192E578DE3F'; UPDATE t1 SET b=quote(zeroblob(current_date)) WHERE t1 MATCH 't*'; INSERT INTO t1(b) VALUES(x'78'); From 7c2321fdf38986cbf72e656aad204c2b10f5067d Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 13 Aug 2019 17:56:56 +0000 Subject: [PATCH 003/112] Update test cases so that they work with ICU enabled. FossilOrigin-Name: 408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 --- manifest | 14 ++++++------ manifest.uuid | 2 +- test/vtab1.test | 40 +++++++++++++++++---------------- test/vtabH.test | 60 +++++++++++++++++++++++++------------------------ 4 files changed, 60 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index 6acb6a9831..494df1beb8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\ssome\scorruption\stest\scases\sto\stake\s[724f4df9c]\sinto\saccount. -D 2019-08-13T17:27:43.409 +C Update\stest\scases\sso\sthat\sthey\swork\swith\sICU\senabled. +D 2019-08-13T17:56:56.995 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1611,7 +1611,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test c1e64ff5a860fdbb7b52add0996af2ee1af563ddf2e86b964d15d04d81a001be -F test/vtab1.test fa6baded08fdadd6f416a9c54956c049ae327b9bdd05d25bf8163f65e65e849c +F test/vtab1.test efb4c4a45146193d6d55fb85f7162febd6423f29c72ede09bb96383f49e3abc1 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 @@ -1626,7 +1626,7 @@ F test/vtabC.test 4528f459a13136f982e75614d120aef165f17292 F test/vtabD.test 05b3f1d77117271671089e48719524b676842e96 F test/vtabE.test 2a143fe75a11275781d1fd1988d86b66a3f69cb98f4add62e3da8fd0f637b45f F test/vtabF.test 1918844c7c902f6a16c8dacf1ec8f84886d6e78b -F test/vtabH.test e65540eed0f7434cdf0b160374570b51f3e3179548f0fa5e99b1d33f8dcdf9a0 +F test/vtabH.test 2efb5a24b0bb50796b21eca23032cfb77abfa4b0c03938e38ce5897abac404ca F test/vtabI.test 751b07636700dbdea328e4265b6077ccd6811a3f F test/vtabJ.test d7b73675708cf63cfcb9d443bb451fc01a028347275b7311e51f9fdf3ca6757f F test/vtab_alter.test 736e66fb5ec7b4fee58229aa3ada2f27ec58bc58c00edae4836890c3784c6783 @@ -1836,7 +1836,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 8c44b02f1479cec61554800702a3c1d806e4ee64b41ba2af17320f62794a02fe -R 7c1844eb7914622ca55e2a5e5ecac9a6 +P 927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 +R c967e09641613ccf8efee454c9ec6fe8 U dan -Z 44af29e1f24cdb5aeb5d48277738f602 +Z 9b0309a4ce7be165e70467c33152a3d5 diff --git a/manifest.uuid b/manifest.uuid index dcd9c2344a..8829389704 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 \ No newline at end of file +408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 \ No newline at end of file diff --git a/test/vtab1.test b/test/vtab1.test index fd7c1fd41d..0a45c4e2d9 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1311,25 +1311,27 @@ do_execsql_test 18.1.0 { CREATE VIRTUAL TABLE e6 USING echo(t6); } -foreach {tn sql res filter} { - 1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James} - - 1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9} - - 1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8J%} - - 1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8j%} - - 1.5 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4} - {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%} -} { - set echo_module {} - do_execsql_test 18.$tn.1 $sql $res - do_test 18.$tn.2 { lrange $::echo_module 2 end } $filter +ifcapable !icu { + foreach {tn sql res filter} { + 1.1 "SELECT a FROM e6 WHERE b>'8James'" {4 2 6 1 5} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b > ?} 8James} + + 1.2 "SELECT a FROM e6 WHERE b>='8' AND b<'9'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ?} 8 9} + + 1.3 "SELECT a FROM e6 WHERE b LIKE '8J%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8J%} + + 1.4 "SELECT a FROM e6 WHERE b LIKE '8j%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} 8J 8k 8j%} + + 1.5 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4} + {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%} + } { + set echo_module {} + do_execsql_test 18.$tn.1 $sql $res + do_test 18.$tn.2 { lrange $::echo_module 2 end } $filter + } } do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON } diff --git a/test/vtabH.test b/test/vtabH.test index 78b156cb63..f1a0466554 100644 --- a/test/vtabH.test +++ b/test/vtabH.test @@ -30,36 +30,38 @@ do_execsql_test 1.0 { CREATE VIRTUAL TABLE e6 USING echo(t6); } -foreach {tn sql expect} { - 1 "SELECT * FROM e6 WHERE b LIKE '8abc'" { - xBestIndex - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} - xFilter - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} - 8ABC 8abd 8abc +ifcapable !icu { + foreach {tn sql expect} { + 1 "SELECT * FROM e6 WHERE b LIKE '8abc'" { + xBestIndex + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} + xFilter + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b like ?} + 8ABC 8abd 8abc + } + + 2 "SELECT * FROM e6 WHERE b GLOB '8abc'" { + xBestIndex + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} + xFilter + {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} + 8abc 8abd 8abc + } + 3 "SELECT * FROM e6 WHERE b LIKE '8e/'" { + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} + xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/ + } + 4 "SELECT * FROM e6 WHERE b GLOB '8e/'" { + xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} + xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/ + } + } { + do_test 1.$tn { + set echo_module {} + execsql $sql + set ::echo_module + } [list {*}$expect] } - - 2 "SELECT * FROM e6 WHERE b GLOB '8abc'" { - xBestIndex - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} - xFilter - {SELECT rowid, a, b FROM 't6' WHERE b >= ? AND b < ? AND b glob ?} - 8abc 8abd 8abc - } - 3 "SELECT * FROM e6 WHERE b LIKE '8e/'" { - xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b like ?} - xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8e/ - } - 4 "SELECT * FROM e6 WHERE b GLOB '8e/'" { - xBestIndex {SELECT rowid, a, b FROM 't6' WHERE b glob ?} - xFilter {SELECT rowid, a, b FROM 't6' WHERE b glob ?} 8e/ - } -} { - do_test 1.$tn { - set echo_module {} - execsql $sql - set ::echo_module - } [list {*}$expect] } From 87ae34ba1ab96e0e6811c0c49324d562bbb9e6a0 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 13 Aug 2019 20:34:35 +0000 Subject: [PATCH 004/112] Add some static to the 'regexp' extension. FossilOrigin-Name: a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa --- ext/misc/regexp.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ext/misc/regexp.c b/ext/misc/regexp.c index bd82aa5d10..3359109ab3 100644 --- a/ext/misc/regexp.c +++ b/ext/misc/regexp.c @@ -610,7 +610,7 @@ static const char *re_subcompile_string(ReCompiled *p){ ** regular expression. Applications should invoke this routine once ** for every call to re_compile() to avoid memory leaks. */ -void re_free(ReCompiled *pRe){ +static void re_free(ReCompiled *pRe){ if( pRe ){ sqlite3_free(pRe->aOp); sqlite3_free(pRe->aArg); @@ -624,7 +624,7 @@ void re_free(ReCompiled *pRe){ ** compiled regular expression in *ppRe. Return NULL on success or an ** error message if something goes wrong. */ -const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ +static const char *re_compile(ReCompiled **ppRe, const char *zIn, int noCase){ ReCompiled *pRe; const char *zErr; int i, j; diff --git a/manifest b/manifest index 494df1beb8..4183e3a60b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\stest\scases\sso\sthat\sthey\swork\swith\sICU\senabled. -D 2019-08-13T17:56:56.995 +C Add\ssome\sstatic\sto\sthe\s'regexp'\sextension. +D 2019-08-13T20:34:35.045 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -302,7 +302,7 @@ F ext/misc/nextchar.c 279f80fe8ef5ba413242e2704e246503ac601f005eefb180d19e6c9203 F ext/misc/normalize.c b4290464f542bae7a97b43f15bd197949b833ffd668b7c313631bd5d4610212c F ext/misc/percentile.c 148dd07286b16e50f232bb638a47850085ad37d51f270429905bd865e595d1ca F ext/misc/prefixes.c 7be86d17525cfae6ed462fc3c519efc44488ac329890f77491c8f82871f57e17 -F ext/misc/regexp.c 79345bf03496155a640ee0300d3307296761cebb5e115b4e342cc2fb5861ec10 +F ext/misc/regexp.c 653b6ab5e89bcb5d45f9ebe0747d7f8f3f5706cac963fcbc9a3ddbe5fdc1efa2 F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 540a169cb0d74f15522a8930b0cccdcb37a4fd071d219a5a083a319fc6e8db77 F ext/misc/scrub.c db9fff56fed322ca587d73727c6021b11ae79ce3f31b389e1d82891d144f22ad @@ -1836,7 +1836,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 927cd7b4c52fae665e57fb6039c6829e339cff5ad5c405800cac3ee149ef5be1 -R c967e09641613ccf8efee454c9ec6fe8 -U dan -Z 9b0309a4ce7be165e70467c33152a3d5 +P 408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 +R e1eff49797b82e19658f2ee082875e36 +U mistachkin +Z ca11739ed6199651720067a09b5d23b0 diff --git a/manifest.uuid b/manifest.uuid index 8829389704..4123f2650e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 \ No newline at end of file +a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa \ No newline at end of file From 908e7c43a7386594926bdfce4029884cd20ea012 Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 14 Aug 2019 15:17:21 +0000 Subject: [PATCH 005/112] Always check for reads past the end of the file on the in-memory journal driver. This used to be an assert(). FossilOrigin-Name: 4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/memjournal.c | 5 ----- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 4183e3a60b..d3d9df741e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssome\sstatic\sto\sthe\s'regexp'\sextension. -D 2019-08-13T20:34:35.045 +C Always\scheck\sfor\sreads\spast\sthe\send\sof\sthe\sfile\son\sthe\sin-memory\sjournal\ndriver.\s\sThis\sused\sto\sbe\san\sassert(). +D 2019-08-14T15:17:21.194 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -495,7 +495,7 @@ F src/mem2.c f1940d9e91948dd6a908fbb9ce3835c36b5d83c3 F src/mem3.c 8768ac94694f31ffaf8b4d0ea5dc08af7010a35a F src/mem5.c 9bf955937b07f8c32541c8a9991f33ce3173d944 F src/memdb.c 02a5fcec19b9d40dd449ca802dc1b2e8f93f255fbf2a886277a3c3800d8d35db -F src/memjournal.c 6f3d36a0a8f72f48f6c3c722f04301ac64f2515435fa42924293e46fc7994661 +F src/memjournal.c 7561c01c90958f3ba9bc6cb2d857123d932bdfa5539ea34427a0957b2e35154d F src/msvc.h 3a15918220367a8876be3fa4f2abe423a861491e84b864fb2b7426bf022a28f8 F src/mutex.c bae36f8af32c22ad80bbf0ccebec63c252b6a2b86e4d3e42672ff287ebf4a604 F src/mutex.h 779d588e3b7756ec3ecf7d78cde1d84aba414f85 @@ -1836,7 +1836,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 408144a1832569ced8e04840f0dd36a3867405f36b13631b0f13c0f7b8a0fb01 -R e1eff49797b82e19658f2ee082875e36 -U mistachkin -Z ca11739ed6199651720067a09b5d23b0 +P a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa +R ed8fa0e6bed90bb78f3894955acd52ae +U drh +Z 721554492d795644318a412d01d91bde diff --git a/manifest.uuid b/manifest.uuid index 4123f2650e..9d7ba8cea8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa \ No newline at end of file +4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c index 3b0e7a6728..0a14e847a2 100644 --- a/src/memjournal.c +++ b/src/memjournal.c @@ -96,14 +96,9 @@ static int memjrnlRead( int iChunkOffset; FileChunk *pChunk; -#if defined(SQLITE_ENABLE_ATOMIC_WRITE) \ - || defined(SQLITE_ENABLE_BATCH_ATOMIC_WRITE) if( (iAmt+iOfst)>p->endpoint.iOffset ){ return SQLITE_IOERR_SHORT_READ; } -#endif - - assert( (iAmt+iOfst)<=p->endpoint.iOffset ); assert( p->readpoint.iOffset==0 || p->readpoint.pChunk!=0 ); if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ sqlite3_int64 iOff = 0; From b9fc45534dec6b6a5e8047285d8d8527ac963bdb Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 00:04:44 +0000 Subject: [PATCH 006/112] Early detection out-of-bounds page numbers on the direct-overflow-read optimization gives consistent error messages regardless of whether or not the optimization is enabled. FossilOrigin-Name: b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d3d9df741e..5c813276b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Always\scheck\sfor\sreads\spast\sthe\send\sof\sthe\sfile\son\sthe\sin-memory\sjournal\ndriver.\s\sThis\sused\sto\sbe\san\sassert(). -D 2019-08-14T15:17:21.194 +C Early\sdetection\sout-of-bounds\spage\snumbers\son\sthe\sdirect-overflow-read\noptimization\sgives\sconsistent\serror\smessages\sregardless\sof\swhether\sor\snot\nthe\soptimization\sis\senabled. +D 2019-08-15T00:04:44.923 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -464,7 +464,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 6061323b98cc794a1e3ad6907f683f1ad2b8c48d7c7d486072b21f18efe73761 +F src/btree.c a6b6f4730862a4c3b92c903ecebac309626788ac8a977394198d69cd613fbf2b F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556 @@ -1836,7 +1836,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 a21d1dde73f811244b5b43f9fed5877263a9c5061470221f417e501f5530edfa -R ed8fa0e6bed90bb78f3894955acd52ae +P 4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef +R cbbc98ec5ac255f891702508ca882f04 U drh -Z 721554492d795644318a412d01d91bde +Z 5ba220c2acba929340df86e7b8719d9b diff --git a/manifest.uuid b/manifest.uuid index 9d7ba8cea8..a6c01e5fd0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef \ No newline at end of file +b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 932ce04359..dd441aef50 100644 --- a/src/btree.c +++ b/src/btree.c @@ -4879,6 +4879,7 @@ static int accessPayload( assert( aWrite>=pBufStart ); /* due to (6) */ memcpy(aSave, aWrite, 4); rc = sqlite3OsRead(fd, aWrite, a+4, (i64)pBt->pageSize*(nextPage-1)); + if( rc && nextPage>pBt->nPage ) rc = SQLITE_CORRUPT_BKPT; nextPage = get4byte(aWrite); memcpy(aWrite, aSave, 4); }else From 27e80a3b68010d7ece74ed4a6836ab9f0b2fb9ac Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 13:17:49 +0000 Subject: [PATCH 007/112] Ensure that the cell overwrite optimization does not overwrite the header of the b-tree page. FossilOrigin-Name: 4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/btree.c | 6 ++++-- test/fuzzdata8.db | Bin 1288192 -> 1311744 bytes 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 5c813276b7..64901db7c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Early\sdetection\sout-of-bounds\spage\snumbers\son\sthe\sdirect-overflow-read\noptimization\sgives\sconsistent\serror\smessages\sregardless\sof\swhether\sor\snot\nthe\soptimization\sis\senabled. -D 2019-08-15T00:04:44.923 +C Ensure\sthat\sthe\scell\soverwrite\soptimization\sdoes\snot\soverwrite\sthe\sheader\nof\sthe\sb-tree\spage. +D 2019-08-15T13:17:49.826 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -464,7 +464,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c a6b6f4730862a4c3b92c903ecebac309626788ac8a977394198d69cd613fbf2b +F src/btree.c 5cf994516c1b74928b9d15971573a8bc8595e1afec129184099976da603402de F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556 @@ -1011,7 +1011,7 @@ F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e4 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 F test/fuzzdata7.db e7a86fd83dda151d160445d542e32e5c6019c541b3a74c2a525b6ac640639711 -F test/fuzzdata8.db 2f1375f053b772a48e0820fd3684eac0e109bc37d5612b72b0bb4bcebc1f0133 +F test/fuzzdata8.db dc52be9b732f5bc1cdc0db0ff5b8e69b87bc8989b13a94eb8acaef63897a007c F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test 8792cd77fd5bce765b05d0c8e01b9edcf8af8536 @@ -1836,7 +1836,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 4d41ca7d6efbdac70890a8d4159488fc7f59bf78a550b00597b4df990c4fcaef -R cbbc98ec5ac255f891702508ca882f04 +P b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 +R 99504bb8346f69a0c987562da440ce64 U drh -Z 5ba220c2acba929340df86e7b8719d9b +Z c6c5cb19819200b45c3cd69274447def diff --git a/manifest.uuid b/manifest.uuid index a6c01e5fd0..ae239c6fc7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 \ No newline at end of file +4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index dd441aef50..6e6a9b2797 100644 --- a/src/btree.c +++ b/src/btree.c @@ -7675,7 +7675,7 @@ static int balance_nonroot( */ memset(&b.szCell[b.nCell], 0, sizeof(b.szCell[0])*(limit+pOld->nOverflow)); if( pOld->nOverflow>0 ){ - if( limitaiOvfl[0] ){ + if( NEVER(limitaiOvfl[0]) ){ rc = SQLITE_CORRUPT_BKPT; goto balance_cleanup; } @@ -8476,7 +8476,9 @@ static int btreeOverwriteCell(BtCursor *pCur, const BtreePayload *pX){ Pgno ovflPgno; /* Next overflow page to write */ u32 ovflPageSize; /* Size to write on overflow page */ - if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd ){ + if( pCur->info.pPayload + pCur->info.nLocal > pPage->aDataEnd + || pCur->info.pPayload < pPage->aData + pPage->cellOffset + ){ return SQLITE_CORRUPT_BKPT; } /* Overwrite the local portion first */ diff --git a/test/fuzzdata8.db b/test/fuzzdata8.db index 353f39ba70cedd99c078d243654615c4ea9f1d46..5abaf46cb98d6bcbf04076d2ff6971ad0521efa7 100644 GIT binary patch delta 31498 zcmdpf2Y6IP`|r-_d$v=hW<&4U-E1}qHK8Ldp(`z&4haIH2+0a6DoR3>7Yj;MYtf&aVUJ!y^L`f7C5#|17LjwBw{qO(Y=RWtj&t0A~*_|_I=AF09yloBzRbvX) zrWCgF6j&@Ovt0i4DC!Z*3d+*9>1;-^-8hi%m0C$nC6{ECWcCO9mDRHE*q7`C`-r{6 z-eRw@O7=W^j_qJiu}9fvMy!b4$!=l!>;`rnTfk zQ$~jeSS-qra9@=1;XWv1!igw5gcDFkh2t#w7Nuo4h#!r@u_ztk07@h5N6ErIi$(rD z9E0*)xEIQw!aY%b9qxhhc(@zNcf(y!R)ssEJQ&8f@_}%Bl)J;xC`-d$luw4EP?m(- zqTCQ}gYu4WE0i~fTUspn@^#@B_%Scs9OaB~Gn7|{o1h#N_Mq$=cB707yHNHFJ5ja? zJ5V~qHj70%7q+6T4QnVr4y!0%4ofI2@=?673dQ3qQQUtcisI!c?z$eut;S0m%tUb^1I2IYD1J;s z@!bp*Ur$5v#Z(j@U5nzqDJTw4MsaW=idQC}s2q=C?>Nk#m8Ib8_Aw|PAB|%DNEEjW zM{&b26xR<$aorFUd4o~R8;D|75{en1ESuU7#kHU-o6sA@7|@mt2Wi>Bcocm@C_-^4 ze4sGv2m-UVpe(xzgk^Tnl_~k4D3d@?X6bIRSbhUhE$6zT_z{G)obHU`D-hRG-4VsR z9ZHMzOgOiXza} zvJM2b-0rXxzhX<2rq8(9eyg38+a<;8lq`0OWVhIh^IVGM2`V|OMN`)~k|*2ei}m^a z{+#TboXnh@M4#Um#6NsYQ8avFbMVQ^#I49TzrX$tz63Kvc+3~@$ES000PN2C@U0u^GOs1o4E=7YgL$q{k=t{8{Nf zznS6l`QtD`LMS~kfC^uzu9eT15g92bGvJGh4aNmCgK^?c0PX8r;BP2C7#r}%0%E_J zn2;az#|J}!M1LqQ7L_@PacCZlO~{B(Ko9=7U=S6-#9($Xf`o>C#Qc20Y|$4$#|P-i z$*H>?i1+#NSWYP09};Maj}1itLC3z>KwNrGX3&q`&_zx{Tk%NX(u1*=nxQX$Wa>dG zJ;9o`@YUfV5DLa;CIH{QL|mZkUEJPFI>!b806>lLbLu7x4EcPSflCw%08n4Z9}lWx z&awXZ#O&nUR?ppOcUg8_G$fvd37P{P_3;6T{>Lvm;#u0tvA`^Z;T;MvfCBqx;NIb|{#b zo)L#(e2KA`kHBACFg7j_j0-hj+Z5;y#>FQDd>Fiwk8^-p#IPD(ElSy65BsGIPY71jG&4G-KmLJHP@q5^NF|8|$Mmsjc%dE71@7(Wk*O{H*PRaux`VL?i#9D^8rC!O#q_o^N9N3b0-l7zLjoBosmwo8|XqXNT}3 zkdGcBp9mD9v6y#uLPBOjVq$tIGZ8|TksSz%#=gY#thfY!ye~cwpN{r^NSs**ebATf zPsmIRW#vRbiN(bC2f&>zZJp-EMgJsiWvmm{7eAKXL)gcJ;6<;DKO3eNT z*)jhrJRz`QTp$s{fO+Ds6rTSeJNXTg8HyEsT_HV}g$Fzs`P2&!WG5n;mlncH>q=dl zx@E=uFV+>Tc9*d*TC9lmSQS0|8&c!V|2{@3yiRI*B}&apvWX>GKvW0f6*&E0U^_Ed z_Z*n|zh=AqzlcC&Od$e-nX@5HK&#ITKmrmV9kKQFPVgm!E{P%5#<+M0NKR}fwy_-0 zJ`0Ni1hal0i3`Lf_;RuXSZ4pS{|1D>CHnFMV6=w5E=?JK0`+4hW?(-MJ2^gC=pB&N z{Wb#;Qeq{8{5OCm=8Y9QCmjF)9PtR&9qdFH@9!Ug8JC}t5C~*ILh86CfVwPzgPF(W zh)o*L06?)cU>-T~IiYw=EW=;7T;W@+KZG3{%>r0Nu{g$}E9~$-ffH0ilKzel$VYkU!9viD|=?3V~CC^b=no`QOlF8dold5I*AXn0)i-y`rwS@1a=xQUHLlt{pQt!ps57UW0QX38!Ka<%O zuH=e7O6chIQU~5;iS&ug9-*U4rK@Pm3Mq};tEE)_)^aH%vq$M@z7#_>izS`*=L3w4 zo1_w%Jw|I+OUtR?I;k^tUnAW_zUw3>?-`b!Fx1A1=}a#cNwM_OxAIlw{Z*SlGd|Te(61Y$Ww015PprPNiDJ3! z1~lwAHNpu&FiF5?g2Lw1P;h!z>=|_*Yza^ob5O>cxa~Km;@k9Cs8Co9pc44wpzXyb zV3)-1jLj$%Oo)ri31wn238a&2mg*Hs36uv^VbhNX(`4qvCt{C|4<)|-*6W8}f9>_R zWBr#Dl0-3v&!nRx)UK^Fz5TpP{NAp8%n@V84;eSXJ7Ua)v8d_dP4|-LF{6nmbLry6 z*$bDjircS%p0@eRU2EAN(C z5c^naOlL^)kZ+RSUCZc^-ou+g!`Dk4CCqN!dZ{JtST7|j>E1qO`8w%CMQyHFo}Ef3 zvt&Oxi=4~Wir;aMbc4+PC5Gt51Dm8= zyV^prY?xEm%ZHCiYm^;#U3C>t+bTUQvF+tgNKOK=;EQTBonZr&H}o?HWB>P%|MxP}A4lpAK69S_GuyG70OJY@ub< zed7IzSW~I;yw=ziALq|8L)b*HHOIz>=;Sz82g#iJSAxehig31fQu3&YL&kUUF3i5( zOTPWuRjs;Q$I6-|7YaEIot0V#Uwa?Swo*pvDgwHDu5P@81S%=g~C_bLYs2ov$7{VoYSR|MOwncm7+y-frHZ8Q)o);b|QV}7_}Qul$# z6?7!5-OV>tOL;P@FU= zCcH(BbV`<9G3m%TsTpr|R{BO(UiHP9l=mw(w+`o|T$>t=?XQ5+O?RDy)BY0H!fj5? z4rNV`gD1#x0N3ku^lsy3av#;_@)|{MEVDNt(Z*_in<3vMvp4BXm9d=PWS4J~*&#am zgVBNx9Mgx<*!PT{yvQwA=xRH~a{MwbG-~_3UdTJNkUx>sgBalmKRU{`kWv2Yax&l9 zMoy7f73Do=5Ap=B{HDx~Qr;eW49$4d-I0<8$_uD^oJXa3@irI#sDs>1*4_@l#Sx^i zY>(xAyU4G}>>VoWCAZ{ld&ut_Y6rzqeO(>8AC8l|iv{Yv=NL4RQ+gfYP@5*Hhf)7N zrLM7k#6L}tJIU+=N?mKame1%bZ{adcRuCmnj?zwsLk@HlBhTioI5ttkq?ztlv`kL%|DzX zcbC}-I=aQam2Y1skC!QJzFR3zlaDE^BmXo@ZYQgs;K|R39kJ)~`6=?cNY|h9vbE06 zk*?p1bo~W%E9cgRuD$%&TDf(k>6dge-w{P)J8K)n5F_RC$ zaI$O{$fzODWVtaV&3E4VSFk(CRMB2mM4Q@w!_1R1_RlVWy}f|Fl}stQiXtZPJ+8Cd z6LkE_X#aGj33oj!pJnW4DtkwPi0qQzkl8QPHb(i39w<8JU=u5qTMIv!aP@?+PeEG}=3HVhQ#icfm5GbpDH*2-qqbtdd;;q8cW!MsLCutb9}=Hr6JsUzF85q^(AY-~2*ijNgW z8I+b#rXMaKsBsj|v9`}QMGtW~aJ&h}Nvvs3#pX6OkdqlV9r_OD0WBxpmkvh(szJ~uk|;CBeVWH27_if9zA7eh2VLCi$(N`Ni=At z>E_f}=%&*JSTHQ=x3n&ozN9ak)g_~=cjA~4W5?9rTrg*07YctYHJg)uc|#eLJbs8b z!#jESkTKqbV7zyN_!1W%s;hx+P*>wmjIFB)#V6L)02c3%F@w8eN4>O71IE)r{{ETt1gZi9zElusFIcg6DUQfPt!{>Vvry2Q?xe<5e6N)N?y zKb1UX#M1s6xf_Q$&_|LOD?csYrl>u!vt&n}!ObMO8I$1v*97(9o=bpx20jdbNH`E% z(K);ECd2nfJT2+C!x$h1GI^BK=*DP_%V>!^56w0vNPZt3a2bB;ILGMk$u?mg=DjourI-;O!Pkj8@7d^u3|;n+&|VgFz{yF|&G z)y?8eI6^~U05Af~Z$O1#0qXUW-dBb>OACI|TTt8r<63ln@+ZBy1QB{_fw7(?(%onE zUJfu*-J|K?H+uc7o+Ks4lkI1{h=wgPVz6c~gWmjE?=NL$k?j|~4ZX9-XwxDy7T(AD zM-$TH;@|)gT$o8Se$ksL`0l6WzvwBwb21xR`Qa9?dj>ND|EEWOL9}21K!gQ*<41fp z3~v}t0V>Niy0yxTtFKRoEz!^j%ow0yzv_c0g6-=>Lp&>t{!8r>a^RJ}^gWaVXJq~N zY`8UqOrm`#3z7@aBLjyreHnF)psrT`syCCeGU$msqfJN17pyxphfN1L6s_T4^u@wa zENbC{7Y0tRLhB?Nu-Iq^{hpuGC$Iq7f72&7g@@c9%!m_{67Atc4`$@h^5692W}sOR z4*Po0z*9iCmEQbK?@A9}XAG7=z~1Ne81y*zyxyy4I-KN@F<}&5{_X>cF4bdJ=uJ#0 zHiKR{ulHdY#D3SCnPLTl%NVRe(ZB1R>DMJj3wXWZ1Po^R;`}u4cYP#`2>!d?LrTb@ zdzKop?sSY2cL^oJAw)ec=+_H2NLgldk+MQ`S%?`KATDUd}UGh;Hv-DJEbfVI(un~Z2kS=*IH zw3L%Y$t#V+R(Np*meVuos#V4yDc(=h6(bp~9$sa9EoJ7=TGdDd&0kcFe1XDY1;*1Z z>>}{Q3WsmR?@AX6jFzq75x}NZ$8`Y&TznbWX6ool{;)9|HsOt7W0jN@OXtJJTxU*Z zgyw$uw=(^HT5K5p=!BdGf$?YI&L#T$Gh;LBWQ<-mjA8WJ@4ADovKm(d&P=P(V^t{pg!QQ?m-_tYBf4w1B2O?-q0Id?G2m-PhXw%`Xf8a#FW9pP-yTGbh$Bm@uH0R zi!vGvg{<@?*;xFsb&MM#oDyTV>CK&pwZKW95J*6*DmMP!RMv(HTj|5xm-eNe@qxsc zcw`Qu^Q=qWVACExtqaiyIu*r+j;h20A&?e5-o|6qz-n)UNWgy!Qj%;t zK&8d*G5o$ZN^4#9DVEde^|Ld`R%UkMEjub-N-83!@J}TF;AnbTU#n$QF<$OYV^`RR z!fU83!FH85Uv5I@cgbmdc@O1InYE_M6^;RP;T}g9KF_CYl0g*DF?%BK7gWC2RX=Qw z{DuMfoW9CNSw-ZQc_}>FaXnv=q^y-$G_g5yE7}t0m@SmW4F2t4rKQZ;k^g(83vGE$ zj^ZPSE4yXZo;-Q-Kt6PovQM^k5Mev41#!U;75wgK&O4?kw;3#!Z=V7aP4Bd0YCy4^ zpw!-Ggj@z;^sa(V2r0A9lw2xz;@)qR_k~){y6|YtF_RIDgW*&-$9aMm{Gcpj;#OBm z-Ytj7SEKCZXR{QS%(}tD=!g+Id>K{jv9~UtqsThzLFv@EE2Wjny6E>%q~D&D+Fj|- zeJ?2cBfoo5>SVbYmHzDLCVJe@FBB?&3X_4wPcT2e&-KjCl4N&L^q=^a51$5dX8%&!lno_Bmii+*;W z6O%yirAkYch3bf+ioAjTbabH7R-ov3)TNhPP)jmMmNWs&eN>tFs0dK2?P2A{HKU4cDmdCEgg3+JW7pYE)^{Z#~X{#sp zg;QOSctE6@uL!7X8JiCK-vu>3sJ1fH0gC0t?s#y3$gUVbr}ETj9lg%HHM&1P(O2yt zvo!i4N1e)NCaI6fES)@Wy9Q9<4ek(Ml&Tgzq$7CRTI@)B$h+TJ)Ljz zBU9AXx|*a|4#zhD%K>a7iFQm@+tTo5>aRk~GjYu!PiI?Oj;h_PVN4j&b1C&|bqM*! zt5yFn;8T3{Ty>GA4pc0a$@OChcMF@p*+^C_dz;o*4iE!3mDJg|w}4lssbd)*zf>)i z*usY4E=`eRisPBID1%a4=~r|2M6d`Skgu+@s)H5FJt8nNfLyn$ZySr(H6El`HZ_o9 z6t5br4q>$CPIV~DEnla$P}LzY;#2D%X~Sn-ueOLUE^s%U4w2Hf8OJ1 z!}!dn)h$d#Y8G2TJGOcTlD8#%3cgR(6%s%7jM{>+oA~}}b)ZbMm#}5@!cKJWx6=kJVP+@mTI%P0Q@XAACavak+?dC6KXw+P zRi$VZ=KIfzek-1F?iIXoGv9ws{JwZzeTvS!sWxG&>EYMaZoJna^*x!bp}aQIRlIeT z+RUmAheL30zxoL+v-}v&UO&~;jTBR<|nnWaaW>04qke= zH4ZtO@#wQEqIGvuS(a-MdAqwz%AM)dX|v?9Qkxyl&-on()fc4l3#y`+GHYr~T1k%X*+6V%#Vd|~8Sw!gr+*eW6A!etF!=CH-mgSxpi7IZjuA@o1ww-MtPZfjr z%+MyuteB!3YbPjesHRfXaP4a9|DdMRwslq?MZL>{e6vH#k=Q+yw^*G`1@|!V~y6*E<)xo-*ZBN*i3q1H8!yp zw`h&>eMtC$s|v9%SS)pa@f*m18J3xziD);>TjZZzx}crMp(Bw7CPLIfDF2cBct9k% z!03nKgnNmwq!50AI*)K8tkeX*h-D+O0-h@|UN8%8E5xHORf@2=xQV}_2V5faMvM~a z^@O-I)LjZAfioI08S@Yv#5N5HOxK&Qe=8)9l^Kw zi$Z*LGdu!U5RdFaiLPoOUzH)6n`UNn^T384^}R~nhrdOOfy#`e1FM^LAa8_ zUpd;g$?TDF$@k^IWCqpy-|Cx0|9g{kL~{S$EcKt7jUDG*xODz}vmy8+!lap9;k*0i z`hV|swCENVT)m0*pPqy_&hpRq8iHl@6Z(IC&LjStbN;_R---XnY1~6t-Kj3U&Hw#5 zcNLTQXB2k*2mbCWnn%3M5m&)~dhnm?sqlmwPTl+H?(?pA-lw&8P~@vreJ1x{+!w9A zBe4g#(m_M!$%Ewo($<=LyJ(-w^5$%l!c%N5xwi*?Iv((fTa>|v^1s!pbq6jh^?$E{JkAgHaD*%q4fG_>w( z6EvtlB~%oWqv^nB@_QRg8mE$PZKIAnx1UxlA@ilE+zJ=dX_m(CP0|*Mq?Z|Qvq?1d zcI)lb>wR_I#xk`NrM(09Yg)O~j8?tFT2f)TWT*ZI*%->VX|PL%YA-RQ#ZBCzz*zTjWKXhfZVtGmE+)0$ORck?oAE{lbVuF@wed6afqp-oA>PMcf+7wE< z+uD_HpQw$K)J@o7pWK-~=VpoDdabsSVIx(h3G6*xd~{(8-X=}^N=Mej(TxD9W|KCR z60g^6ykNFgp|deOIak{+tJ~1W4st%Ot>F1fv^7YV;C<(4FH1DwE6qbcJgD8s$FI;1 zsjz>%VeKR{p1p70SjDn)s(@x5mF8+|g@W`9uAS6+nWI{X3YTe5@samwyCt@VM?a%wFuH5L2AgGtrtzmYYd2`>IAE`<0BI?0iPl53d#e^J z43g(JXQpz;R_#Yg<@osm75uDqrT%%^K-#iFnoMagYFWI`Vy%*q`@D7?&Df@GW&7yx z^;&>{hY3_VPPbD{0HB;%p?i3X?b<1c?WdzV^%$D@qHgB{O0}1DRzcyP zcWWyRb-ZHv7nJNv5H081D+S3ATxKuvyyM!Pm~D!FAMf(2_6cJzQ}lQp5^+#_z^YDw z0v_M+g$1^_nJ?*5XPE;(Mj=`(QT`Z+g z)OOv$)6Z#-Ag0Zal|fn>UO=#;;#0U1$ zD;YaZ(WkT|`g4hH&|UF*YkH`^K9#@Z(~}~>@b|TYS5Sw8IzKU1P0#uCjyx$v_sX=s zxgOZ~rFKhsUtLz%XNWB8e@a{$q%+1ohtEJ?&wXELPf5J*Fnz7APE{f0(J?;MwnarAPNL@;;{L@aitQ z3P;2ueKq@m^6u2v)0Qept7A+8WA@`S7weCytcF)6A<96xvtbY9k8>>$&ty@n75X=< zmMRD9kMQbsx?AGqtMo!uO;ar8@H0T*1Ro|dLBXFMm_1Xm@H*)b)hib;3Mu)MrI}U_aA|e`)=wDp!A4^xj@aggj}!em{Tc9z9!T=cuH+K9hjoIGVqS z8GOqoJxkY^w80{6c+MlQm9+b(rYp!WgCjJul!wHEw1jScR9~t7f^mN*c0zkV%FZDF zD_So^i^3^-A>7)9cj!H2#KfqiN@`1KgY*H20_LfD%Vr3lg^-U5eIIeKhV(5e@k@={ z#UoIS!wJH?NXUeeo@n~BGZNw=1)}pfyF$^u^&Zq^uQpsloXH=nH$lw8|Ap2O?v<0j zYfyPJscYkYYG~7-ACw~;+u%M z)qO(9Axl8|tx(Yu>ww9jBTwqlux><)x^{Ij9{fy5_lc}CVTeUq2QNJ$GS3jrr_v7q zV$qG*5m&sRCD{-fgMN>Yj4z%}zOMD6=PLEqHXIT`SBVJV`zU1}rsk*G`C5z=%%ZSW zZyw26W5Nd|^`kANnqL;`mcLNeLEZ8O1T$^U1$>^H$>e;|RIQTmT^ zG$k$7()q2A={M^3NW>4zD$c?xi1?k;@5{-C?wBe7m_QlN>ks0fZ1IvTq|Gjf)bUeW z^v9Vdfy|P^(@LSM zEgKm>vQLkdBnjGhA06?l3Vp90i9Ry65ne3rNnq=k{NUsqzGb(bjfPtJLH%7-nFUWO zxwmSgc!$IK#{k1b#}2A&ibI4c&lu-8@&SKDb0^KvZ5gawqp4sN+2eQe{fpwENeJQX_1<8{~Y5ymT}giM61&ZZOiG%Q7C85qm`5n9oq>D3(8` zQc1Rv%I~lnOE5qa4A6#ZU$9=iGws+Gxwzo5MgqNUskXxU;m)d6KDP64xdLsux$zT= z;^9UHw1DFuTP4PCX=$utBGlN-SWg!lneDjyxb;@Hv-IW^R$P(0RP+?u zk&gUggY(vBd@Zw1h=8%?yj9TnMn;&itdB94^8c_`(UJbft-NrCX8@zoQ$0PXNgv}3 z>q73~j$M3rUt^?j-$r>>gq}T4(d&KPLfe!Xmjg~Eg)qIrOd{tPmVAqOKNLC z*n^TkH=ZXro_q7(Mj7y__M`*4HJSRoqrcR^6y15(-{kHhMkMv312%E{1997iguk>Z zL*Y>qjV~lbAP=~3uVTDma9}O*w9oT1N@*k!d&lqeT-<)k^NNRWV z7fXkoMgd@pHP;{VifdSkhP(;EpJ zB?C(JO~zrFC2rJ=5qxxkaoW)4W43n;6D)8YRjl_k;hXG6NJQ2oOhP z1ex{Ym17J$!%1H*oaNz!UK68(;F@l05s=OAd zv;&UA*ooRKCZ0@{GmPfE&BsQV@uZ;jF_e!Q(>1n`KlGFlWcr}J<^siXmi&7pKe;Zx+)kw$(rJ&B89@oj!k)thqHntl zMBj#S*QUrrjp`m6PM-G-Bo4e_AaP&>_k3*JbqN*%EEN>A$wBZ9~eq!_SVVhni-xjR|!eZO}IPULl?aFx1FOByl1Q0^Y96we zqc5X_BV7c6?1U)mYw9&XM>=P(J98PYx?4;R>`_R;_SPdTgGZ+rM;U*wqqUdBGAVk3 z@iu?Ii?yfBvUv0q!<0D2Zow$&xW1Nl#8@Y=Y#u$$$U{v%l_=?)QAW9%ay|V}VZ`u* zvDWt#wuBx^u+B9W9hi2VV!7B)fR+ifLz=Z~?qVb|Uh`L2e-*Zel!j~e<**h8*G7uqwkzq`u)x45wn%d+x!9P`a|c_CWj2p09oC<(Bx~Z;);AcN zPo+PJjy^>$;OlNVlOO(64@fklv23N3hm3Ai@L?p6N+cMq$>c`` z^GvXQuCrXYm#i0cwwP+aw*rM(0)^L6Wpk-3B{c>=V;@+;)8|+pk${?{bJi6+_qcU1 zoLaDHdr5JY!#K{x~A}H_gJ5h5wA?W%>@tN zCM!IA1zdU1iY+V5l`Z1$&D5ir7R@_8W<4$=B3bb-sX6t0SG}74e3c!h3#Dqe|KvsN z#9w>L+E)^h%Y9M|9ZABuz#X}+{#@T~#oBud`G&c%>Xcef8QQYQ4u*JKm z)%w&QE)R{}Yc*)*hi*G>w%7V?BvdP{-RYkVUs9ia)`Jqeo!5S3eTDJYE3LgHb_cKh z)cR6{ei-^r94oRW5h!Q!F$b+kvRX&AUs_*!;$kHk#~0!9+kn&cJCo*C zK;~yz{XFTc^$aT>+Yu+EEK(u4=2{o;{Ip|xsd&-CKj_<`=3G%R!-Ov}F zdfLz!UOH+u+Z5LAjRI!oIiig zIvmFsW!{%DileMgs#Bg3A@(@hELSv5> zh93B%hl-lmr;=P|4prYeus95@yv&?yedWQpum%3^MFQx45%Z=JBfom&$dSWzaygdj z>ON-c2(NEwdVxQG(EKE_8ob79)6B+<-l#D9)5U4#w(`BEEU|+;b(gsVSrnKpRsYNq z1;$?Isk=>uaih}wU1D$WlV#?kjNefOuqoy>^Ii5PkKSh@1qICYs_1dDcx5 z%5}1b8=s0%k5V|n23@?`gf9LzPgCt%FkV~R30nQNS-{@mKCdmvc*3{ln;LtMPOh=7 z;cIKm6*7CDN-Au__{g&+GBQ7)qa3Hgwp6(LKEB8XC8x8dQSK30qo`MHxl|LfP38m7 zoA5G!NYPD|tq8a&R;nIo=X}l|=KT`;=sCqE8O9pSkNw2f2vc|&vsQEot6-gi@q$Ph zu-c{1EB#>wRX1mgsvBv`t8Ob5n6^>sC(kws%e>08VPSn2Est@W9@`>|gKTggTcl4p z4v+~Fd}1P`Ws#2a)O9wE(Vr#m0E{yG$Gjk9LkeJFo-MNIpWvy5wmlNx*U~mrIJ%GC z?arfu1NQEGOKV%E%ue#8O|}Y|a+kS#QQBae2vbO((a9t3D4O}8tqG6sU^}F*zT3tmz4Lq{32aEZd*y4+scW2=IypM5xe9o?jL7^O8*zQRx|cB`6t;* zDCJ)^H&w(tqbY4G1}GfNle}iq5 z#8U>^b~1K~*r)O|4yYg1*=b%@VjGLJpK`0Uc*}gaH^$hYJbcf~w%QCvDO2sGbRgSp zqlZq~bn<>;R&(#mwsDcMexS0aY}@OIT##$Kz}rl+eZ|-r^6W!qZ1r~A4gAlOrUXB} zYOi~uh8I=XQyIC)R!hFt3N)@wwh-gHXWGUn%I6mLxuE?=%-FdytSOeS^97wBr=&OS zh>?Zl0OilJ6{z0<*FSMjH1ci)lTYTAb8Q0|J4~LU?nk+UBWMkWE&p@=XE5Dcd6isTlX1*Ct`5n`Li9NiW(vP)!fH5giy{ zOQx|sI3rMn6|Sly=uo=XZl{7g+Y}zt!G4BOBiUXH zH)6?M?h-JQSgxy7d#uD-QAv>-=8s{A`O}(LwX^x)Sn=5n#``+$CspR4woUAF)wcV` zhwc2XCiXm8lbd1eD5|vDn)0a=?IqHNv5f@Af~|7ecq0z8+%VK(A!mFYuUdcGv?QgxEFb z+h^Nh5-yCf-wVfMx=(J#(?(&d!R?s-sJk64oQdK7DS;{nSS8jm4mev&tUHyB zko~lBmVGrX>~7aMmdGJ8PDPZBmaBMGx@|2mGRA(h#+>}b1iM#O@!~%@h8O*4_K7gY z4gY}9n<5Cu`zab@w_6yrz4A9s*@?3RI33b1&3;nG@u}qf_I}7masL>>9S83EOFB*j zB5Tht;29``D|ZQe2Pyeg0P6iz?kD!}Ah}lA+}v1TZ>Os+_@Ebw-6t0&ztO+|1O|9S zh*B?Hq-xozr+}*gjrDGJaXA2dauVc|b@# zdY3Q!#k~Rc$8YvEqW3{BXShdkVLyo?3~bb}MVdQh@g~%KgP* zf!84z6CB?N5JyH3J3yRBz@dXp_IG5KMBWvSTj)ez$5L{A;HZrNg0vqcp5OeCJT}}{St%&qEkV;-~{3swYK26C-B@%zf`bA^|*9@g8|H_x{cQTl*3L@*%1BQ?RGDpb;$mpIE>-H z*M9K{`6xWtW5|CWRM+R@Ykk96F7} z={)_E`(bPf^W>(2Ll42coG9NUZe<`Dz=@br2geSXW%BeNMLX{%M@!n$39nTc+s(0y z!ISE};JAhH6M1lC@~VA~A*|fzfd4$_AJGGPd_mJ|9PO!ByyHDKiyt`ZK&pq3Sq_=) zjQzIQ0UxSGo=qiqQv%Pu)&cXspfPCa&XWxu)8BzL8gBr)L*B=8H#u%(v^mu|fZsUK zal1IP!AQAC)$3)ic&9`(mBuTrdD;-iLLI@PBcmKXS;bjxc>&MMb*#rS1+tZncZ^2} zB5#QU*6x-WN{a}5{LYDvs#X52yb0VQ{tswnPRN0J0 zQvo$LInL=pA@O!|o)Yjh=C9rD=*!?tJvz$?dsZ-Ab*aNEllx)$Mq0JYAr3{ztHkj= zyd`6|{23+rlVn>A02OS>jN2Xf{Pp zIu^?63UsojIQoIm#`irKA7|JRpdW(#cB}Zd{g_L%(6PR@Xvkhk*sb+~h zPE0D3;mpa=cxMbxTHryD&DUM4;;VjhACB~SJF$t%FfpT4O1l%5S4A^NI>&tO)YVps z<@|M5EEVMa#(q|C&}v*bVKTlOxs&I$J2n`&O1freN=h7z43F+ou_rACD-OUdNDE3;fPxHAQjz* zBcS_+I0s3*rWPxocw{rLUGCT=)otogHb)|z8RfiR+;cvYQtroCk5XE`-0!a&QYx?L3Q*ztEocQH#}UJpmsj~usA8`3c>yMz!M&88bmB(G ztAEo>c&^frPx`{DkLoDB{(+ljkBE#M8a}jU&rTHsAA9wpXA3D;zdL3 zIi9{$MxMj!JZFJ~Y~`b`$gQwhec`l0os`@B71a^u;gmjD>BO<#ZDL}u*8KPl&N+q} ztyq4Ei=aj9$=fMuwex^l2I%%u^i(WjBiA_L=6jyP-zoVVTJ1{V0gzvy@EK(=AHL4{ zyo~JR%F#*?+M}|GR~0&AWuzk)9kli2{(GD)4YfT^X8I#%v2fHZ$6E2++;BV40EF=a&I`^t-(|e%zK@-NP_UGAj6=;T!%{!-kkKh;)ETWrcS5jE~6Zo`W! zdL#7acqMS69C5kn=8`9TsN{8QcMv9{nuB;72I> zE~6=>z3cQ))oW%;K48CEd8sEr{xB;)<~*s26MDPrPGZ(Wx+EfkZvm#adF3z80XQt& z##M&t?N`NtUilqfc^e zkp${GLZt_dPIW+V0C7Ua+q@di>T&d#0B54+f`bw#u47!#t_>HqD!k<@*0rC%Xm=%x z0e+*n(>mBuGY+Y;>nnBSH)75S%15OpyEfk zs=5DV=Mfxr+%MkeW06mi|De-LTELaY*LYn>clnIcN4RiQu!C!oaQ8ZYbiT^p=;2Bf zPTnK`LbB8M->Zr6vG`p`J@|^!%Vb!LcN=ao$(fAb9_PA2SMegDuj)=J3ZfAXVs4;5 z{av?Ozj>rn81a>t>ki7+-z*g1eU9r}@_g=W%45o$MMc_7(x?DJuEEIg?-9 zCm1QhZ52aZgBbgcNsw0NcGj*D6~1 znri3Yk9IYa*!MWlsrzZB=7iU)J6^YTb&6|`j(3Qq{^Hybkv06%XB7^^?G#3`nAE_wORYTr+2#Q|Fa*Z?umOpObH{=>E zaCs#42LSam`R(qd6qC$C91&(D{`|uIZrH(m<5Cw^=3l9@k-I55@AKfr3(H+rL+Pbh z5DhWi!}-zz*B!EY7QLM3${JS_s{(G^CggblZ86;*KL0LPv84Wn27hp+(1norpS<8H z*KtNCM#G_>=5mk5J7Zmb^7e82dFe*ic*ZVL!FCspYRr|aJZqEdAsGTr1!b-P{A-?g zdiVy{82-I+pbPE+|L2 z+%=ys+w1y66))ZRKAWF>*JYFV>K9!rm{URiqH-z2IpC+%)vj%nw83TN6)(F6%Cce$ zQQk&ZGkRv5YjndzZHzzmx@!i8wTpl%QrZr=Dvkfq-j#<{RqavEa4&ZN&))ZhRMdn7HB&<{^*JPznwbU1sZv7`6B^#D z)N;;Vns4o+;tlZq_1@R}Bfjq*KDg)Jz4ktPT)(x~hWW(tGNXZJ*PZxIgAzhmnE1g0|XN(g3RfjTOw8Mt@f^iZu!`y;8Pzzl)PC;cz znLCl0s~3%A3g73?MCKI(`-twMGYPit8+tM3f>Ld;i{&c;I*yId>q_lzRBI{-VU4Ib zgas0cWwa0=$}p|{*l137MzaY7=VLpKU1c;ATcX)C*)i+&L_wbMI97p`)#2CnY!@(-ou1CQMK#m|*ZHyP#x{iI=>8Fi* zC_LARK*~q>qM~4yV8g)|dIQS%+?XZigs^dNM}gLgVR%H9>@OyVGAOwkQAm-2=uQ*X z)M3LSx(Jf=GGie95YAkVW-BsGIA!dUJh7EpD7th#^iACaz+Hjz&X;8R4y*7(@ZP;t z(FH~`XSNzlzHwB_8B1q!$V1z(6B?MroZ~2_^!5yTpQe;kVbrFQrYu9ujAhUIgAc@~ zrAstBsX3ct7p=v@QO*$~R`l%2guenWl&5U9Dds`jvtnKnyThp?I$C&>CVuo<(p6M)7rDMZc6S*xRKOjg3dgfLV@N+4@4k)?8rK}&N z@7D?`p|9H|290FP6>M?HSQg-w(X*x^b~J@i0v0;U(M^i*JRDZyG6jPEZ z>>CA4UcoL6H6`EUPA0g}1xfs^Riz!p)pj4DT1&xMR>CB}JV8Tdu{V_VRB!+b&L2lH z5ABb3BWN}nYy+hq(&T(a??7uGbKg%Xt5~v_HkV;giV@1l04KzUKe%2J>El_3BJ9Mj z>PqZ#!;Nm@ysN(q5!c2yZxZlexk**J+ZSpXZx>@H$o4vRo(hG}(0;@hm1 z-PRu6lvSFP`#D3PdOfpgwvNbDSD}m#=zTqwB*S5U6M>u9B?bJSxy^PTB{Z@dHD!U2 zg-|hQGh41I-No4%%urkv=$Ip_O%lY&oX#x_7xeifxBuTZ(mi^evzWV!oX~edOxX;kzduH zGP(usq?9z!llwY2f`#oWEA&@lMUl=E5CXt0kKw=xIK#EUV4{L(aqxBy=?C)RAY|uW z%47Uh+Y_@Io1H~C=V%*4S2i*`QMreYv^|~^Y9iw1<;8&m;G5;wO~u|(9B}kMKeS4D z`p-kFo<|J#&qJ#sQQ!VA53QmdKk<%^M5%Z8vngm15t&n9@;pIH*G6hXwZU3{?Gde~ z_7JQ^5t7teYE9rvTvw~3G0mmv>Tl|0^_+T2{fAnv9#zZK5_PBgp$gX(wOC!HE>jn) zuc`CY+3E~6OP!>SQ=e2vsHy5ewXd3>#;aY_7`2U+G*Z9$BZAu~6O~N;XEPbC{(^!HhZ)l+#nBwI>`)zdXt! zMNAOi0cR|s-^sBIN)>ut`8!SMA^e(K87AWHh6|zyXu*G0mEmOm7}%J$RzO$1r4@gK z($if{#T^m+l&XxNZ9`rAMOh>d^LLJvDd6mqC~6Sm@>168JXCaP&yySu*gBo;5Vb<3 zxFgWacn*=y zl%aevW>p6fp{g~Ep981f&+@9)$C4SZBea>o5!y@_6?wISF)2#bwup*k-cUs-BqLLs zMfpu?wWiE;{fy7B8W_)C7DWSil1*yKkJP$Dg!kt%n(&k!AeN`{K`@@8g5ikLBK4&j zoU788Xfs9j2tFPHa_V@Ag>sa{3O0t%_Q%|1(Krly6W0thyNZDE{Jd&=3R!xV zl<%dj!VM>)GziG4w6i^o=A0HBVRmPYF@HO4_=_-;m#GM5lUzWe}DzF6QQ|xc^ffg1BYP$Wh%JlxSPrs89n8{2Z>Mq&e!<6;&s2{ zqoS_ihcYU(2vM{Zvk}{LBsiOf)OWU6R~!UWJWGPSahEI2nxVZyL%vc*h_RP>j^>}* zDjGLu(~z!?dXzHBQzZ89;UF#N(S}~0b(%lUu)uwDiC;i0aYPw^U4wg6 zg>Hu-{$ajbQ|5v39=)C;^oQ;5v15YvXV_dD^MYp}_SjUinyq28R0- zoyfn$(-ftk8qPNeIN{CT*aL6=rByI4tA??K2N>V<#kkxTW26Vgw!#-<8_#)%(o4J_ z=jp84mH^tSb!O1CTMu-I^*~oc7VX_GmJIangmpx`=V=A}eB2~Y37oxnHUu#;*)>(r zy)P57K0MAT@xt(TRxgldz0X1;(|iE0`+&}Y!9NRn{QJ| zwp6PmA5^W(TdO>ZZ8blN4}BlSN0pDlA>vnh-qm1A;?us~k`*Q4Mn!oarT58g;O(pi z@6)RAc2$A5yJmQMeBte_gm<&~msEq7cmv+YfLD4Ocn7M%11taguAr<6yn{8vJLC)R z^J?%8`@*xD*&{dL?FYPLw}JOXHF(FX!uzrcyc0FUEBA$0;S0~|1-_~Vug?v5M*;8K z+xG1s)~ojI|E$)xe^+DQ4i5cR-~NLyypz80tZv|xFT9@KGY)%_Z2EE6J5o1}T?EQ+ z@cK!dea8jvbnax&a0MffCDg_ILTSt6WMAJ<6~hO67b>8`EADdz=gn|EOebFPM$5)d zirDnBHv**IZ`dGJoaXJLor`En6$A8OQGd4gn2f#Y=gGX^1sX*6B#F!sUND;%C^5@( zTpXM44YuyM2nD=nj3P!Y@XoQik4u%{?-M=7c{@23%od*aW?1~X{!4B|?Xt=dvk<`n z3`=su4rXY6`oE|_hrpm4U2XYvZzEOtRjl2^H(FS`tI8EB4RhDC#!TA3+2tT?&p=?z zPrph9JNP&P#?2xs$6KO;T5oxnAJAmsTJ+U5(K6DrS`kGHynV2j-j5*czFUr;7EFjI g)Wu%i-`*D`{dy>2$XX=AU+_W+l-ZoWD3iGSZ=Jt}jsO4v delta 23251 zcmeHvcX(Ar5bxdH)9yXDoO?rWNg(u+Tp*!CqV$^3m6p&%YJ#9hOD-KjNeE<60TZN( zKtjpTghY@oBnpa32?&ZvNf0~b&ACWG)c3vj$9v!VzZ8NJo8-KeOBH2lg#H&%R{& z>^S>`?Pt5#HnxeaV;SsSwv;Vm^Vv)`jlISa*eEuP4Pq~_9;^#%$D&v>7S2LhO;*L< zpESxBNxcvBwIbTx*MevpUo)c5`5F<8@I??!tmkV${{;E!6D{KlBkJ&l64iWlhzehA zi$(nDt3~t|UrnM#z8XZY`>GSY;;TmVlCLV!bG{Iwc|Ph}9QFkh{m2(cbeFFp(JWsD zqU(L-h-Uc85PjQMnrKR*uN3|BhOZ>iDZUa!U-5Z}j`F#Q_V*b?d-|M2+xZ+s8~Ajh zb$lApsy>xyC7(jHlustA_#}&k|LWsJFZoCc{A*GGKQNWZrq_vVc$LVSi9{AnATl!{ zk?7QML|z?BWZW1cv7?D}8%3o32qH~hB2s%8kt#!olp9PWAdZL>Yq79Ya*{bM`TnKk(WuCY#8a14QWYaKyxB5G$j(t#~h#t&sSY;?L5bPb4M(~H4 z?3OLQ1rXfa8jLj)_!nGGrM_3d#piiNBpxpdwi2aDW*hH8ej*RS8dLcJzDmI3*5c_L`f+PAQLXtmdx^wjRRL)OuKdJ&(7`r6kMZmmf8Ab~~RXZG5v# zNsQgW-{WjU_D+6FW2NzS4mSk*F#8~{E3-0K?fpR-rMv+<&~U|&K0J^LEmv|98K z5PQUsvL}gi5(~!jQ$=MVpP@I;0juqZ$I&CiLVwfeG3$!6y1(f&{-!TL@Db;l;--V} zT)L>>fAk_;`o<9m-Cj}_n_YAg*~#LHBv+O!=X4|s4-m92S-zp)t}ju8*B~y{UE37MX~BL#W0okS0ge-PQyAC5Jx&Bb&SuCCMDX_w>7k?qtWW4E8ORN}%hQxXajW z$kNRza)PD^D}+ifNtfZh8gk>b`8EkF=Zj066+y~K#|q3iEyif9D!R^#LN4E==I%nm z1HBo<2DnRO?<-=HU_V1lZ_x{1xF$Xj>=%f6QIy28H)z7KU!mnuqY73p6z2r{4OkCp zB3!&_Xz05uu4{5N$@0TQ@`Cko)qOF5v!Aw0gJr3@WO)ZNWNQQ1XP0Wh&6{c&{6?0l zaBle{Ta)HWat-nr!~E~j6Olr(+#|joLR^HaGe(C=+XS;f=7(BG?AlP;AsBq8@hdIZwrftNE4U?5@v}K@W%-ei<5>*3j}jQ?w5{MaIer&14oUJ zmI>wpcVkBrY%yB8smis<2PGDFh%Zl&(u7Q|fO){T!SNbSnIz2b#|YDS z2ICJ?rE-Fm0B=>f2Bd!~0;GQp@!?v@ekAz;TVR-$ph7k?J8%97Ce7woum;q7O|n%+5d|v?QAb2I3<{FJFsCUihrxp# zgBXyrXb;JsI4@#SHThL$-YO4Kc_ISBYRJ3s?sCZ`SOv)chFl}f=`6@8>8OyMAqkaL zg1DaoYLW*Ls@d)df4hMYGel~MVRxl{{=b7DW}GMmnK8~3;6( zgYTNNp4s|I|Dz3_75{z7qe)(plR2BivBfYs%P%W4dW`_uA(b%uDG-o1N@%968)4K) zXP0L>OJWea%;CS^*mRB|W{-IS(jOT9i%lSZhxKZW zg^@Ca6>XjsW*gb5v4-gCB9k9BcMD8UB+KC>woayHpXZSDx`TpA3u~7)LcT0Fk}RuVBe&5K z79EwH(BNhHuG)2GuL#L9*Hm#U|7DyqQl7_HH%PheqIF=jTwar#NS2Rl(~GTO%ORx| zT;CuEtJG@DoZ!ZIae^EoSa-O!QtpR?CdsP>>jCb1Mk`1@V?^M%`Em+}=s9w0*s@Qy z!=i0+0)%GD;er}~j2yKz8gG(JpcTrw5Ib8?jF&72<1aI1hs1hAt1Wc-_!L_0Tq|XA zor&+rb0Bl8yvQ6@pJy9(^)hzh^f%?%ob`pM`Of1=jm=c$rjq4kqv8P|4Zy=;%ObfF zwBIcMYB~UOf7lP)GxbVHmv*w^K54n_4>2?3HW0Qz&ij`RH{i@w@;F6qE?IJ;9`|7e zW^CXJt(j!mUGnk8R%XW~x%?vC8-%&bydc~j*!40aum+p@vg2j#M|+)A=6hDdyUeGmnS*V$8xNy%HcSVMSF3agm9!Ucn16!<~=OCyYtBGMHl_?yr zezU(Ol^ANo8=0y;gu>X*a| zOrAtHXM(pTFA14$B^&>+)23zIqz^80_Q0mq2)P6g^ky& zVGwwl9N&sI%5cu+K*9&|2uOOH>G)cEWuahmVc|7vH~%w0&)6`fvoc;~^Wm-DMk8$2 zUpXS!8<_V%)L|GFr+m)Y0+fa-w6$Ld-YD8_1dUL>72?fdHt=oN%VE%H`qS}NSVY9I zh~W_pBD{@gU7MAahW!u3nY8->F%WjeQx)Tu27X5VtKU`Ye5mJC7N-3mSA*EkDXNS;#7n{S&sjN0KE&(M=?jt9tu=AeQl&eW=aJ@?ZHs$(2FE$?DAO2w8>Qu@^xjF$A6phHrYqm6 zY&qnwC6)@$D*d1dDmo^uS8`O=4x=)aeL{Yh+ISC~-ziftal0~0uyky`K{-e+yPE2T zTj!L?*kg}!LS`K>C|9|}v{i49YA;!~kvqMrjH2LOnP<+RmGpZbD!4om*z}-sRIt@> z>8^V&E;yo05^N1zV4k+vDqqRvkZJRbN^_8cqQ6jT!NyZcU$z#v98v1hR^S)6(|qcn z!q$WLWpzB{eb4Jaa<;MoJAI|>B!~oqZz+Qry!oL*3*8H~?OC*;jit&n8bCc^DKsvFDRRIYQj8S-6PC=4p6*|Alja!_TN;B(PdXv-#- zfh~VirfG6#$@1aEVrC}cCZ>|Mwow1uFrkvVfCieZzKt~$^&7^vLvX4}lR;D8waQ({ zIX5bP^L0oLSA%e1MKyq#Lf%S0gxs@AC=$nw7>+EdUQ*<)l4WzRe|af`%h~kCZb%4F z2|5c>$(ihdtSV|XG)k%S878+-E0ZU@tyBi%RrOEMYODUhWG}eKyQ)Kr+UkL{(#9kl zUQ=Dc3A$k|XgwIzK<$eY>!>v}7L6+#syR&CzftKXS-x=porm=%%Y@6Y95CMJ(GY0W z92nPFT_sp9p0aD3Ic{yK#>k9to9}sT%;~9?B5qz+b5Uul-e-i~q-<2Y7~Wou)#Mn- z@==q&cW}J8-B9R>oKUtvb%xm~K{f0!T=-t81OtNqG9t72=LI_g`Kf9sgl<&wi!HnZ zhAvgRl1=Sbd&9U*N+~EPrQ))X4pZOf>;$-ns6L!MLY-~`K<>6`VA@ZriVy5s8II45 zRdX3T3Bk40NO-Va)!@z7)C#b2y4nv9#H*2lor3&Q>XE0^horur7|Vkl@oH6!Ojd&g zEb61yPphiV&Yr3YiG7B~hw1~4e5T46p+X6x)I}H;qHf^We6BiAm3vB-?fyCKpFsW* zwK2z$ProlPU&H+ zOOKz&+!)o(An2Yt91BLMG6lk0)S2u8Bpg>4LHaeWJTh+}^KOBIwyLXTR)D!lY7~d~ z^@F>bB1msT2BTE7}95vFq>jdr`9NF!$;H z<$^ZzvNi!`e5+2Azat)gggB=Z43RsOIGl4&ovfO2z6rj{S}ep5bsskE(D;i*=$4}P zgdMupg|l0jFkW56aQ|o$D2%P9USCW5xU}`EtXfuB1QB8+MOofwfMnTaLiGOLJ$Nfv zGq{x%zCFA@Ee$cIu*TF?j3sbR~Q&5R+-4|Qf%hc4%4OI zuuC25VQPD;7R+GFC~G_Tp^LQ)bZVp_XTO^m(lSWjp^b!{-K_1gYZGldz4ZrlX=n|? zkmlM2!P%eCrLlE9)aYY9g>9m=E~-38vfK|e#}bKOw%4i)h5bw%JwWd#+8+!bbkQVg zw^#_fFDhf}xGk3O(A1>Wl#L*iABrm2&Th+_9>%tv%$67! zuV_D!mH5VLG;=OQ*f_)4uWHj7L0P`>+9G&3)>avfrnWh3Tjq>tmYNek(QL=IZF8;e zEcL?8eQi+9c>OKf9!6>pv!)D9Vh|X zZAO!RwPQQ(T&8sr1ZTMiD8Ufg!>9`_LbMV%e7TmRDRGZt9TG}kh#o<>&H6Q3A1+hg zkpk4HR@Oa08-u3!`+ChLSSi>)#2N)HLbU_MR#6*kh7&kr4yiQkf62Vvz`R|Bpxf9w zRtW>Mv@4vIf&HWCUd|Rx!?1bQ3k+*#YiAjuT>HnF?=;ie!v3<>A$V)2wpn9?aYe2+ zn9G!8;}ziKNG%Cx9n=y9tBBGOQ!JIBS9dKCtDMj%mlX)TdTT%7uX&nXupmeZlE}_Z zYZnCzP8+Csp-C0#Fy1?>5vo)yPVT*Xvz>8`y1^{gLnm!6i*3UHbRRqu@O$0 zKVB8m)2thD%Qda1VAU}91I^CRxT*cb37X2?to;gwhSiR0k#>)>8koCPBOrw)Ln9ni z(wgQMNKMGirW8r5rrO&W_`4~FT9CV2D~%N+tUg97hjlg4huQ#z4a1ePwINgM?6wV+ z2w3(W$i-BmQNb4F5 zEny8~Fr}GfAi1Y3wQj|evDR=wz|>>oe+zpJvu@^uP8HiblD%(dKyI-HW{))4Y6~qI znUmo!hqwR|TS#~C+*oUM#@anGdLW~3h?nB66Et}QrJsVIhyy7nMwnycDb~aCb0m(A z$f~;H8RlKrXmDf)$-aWNiqo&OCbi$d@T;@xtGE{nZSeIpzF$%%e?i*z>fXr$K~sG$LH}84%}Y zAi}#t=JVEQ)2^P@XR%+QmEXd9K-6t*G{&b}Qw8e@xi4FPep;@A-)(bMbnGH43 zD#FnkVhEmWqSfaxu(q&5^dDL+NNQ+3Y_`@La}%sB*i$;!He3H>1bsz4G>s?I`mM@d zKxwD-p-KQ&Q3o4|Fvk>Of5G7R{Pw#Qk6zamMbP48<|>2nGQk_wN(73 z7L5MJnyL_@#Rq%AK2Q4)v(8z&3pOOx8x;$A?~@a~*i?ywygSSW(Vxqi5M7E%X(I^$ z$ZVmkrG3sR77ej`jPg+Mxg1n{7w9f!qb(E~=3KINH&F)4Bj(J}g27dZSAm<~TT77x z>epH+WO(-ntBbSYu>Vu?xts1=&rukC%lbZ}8Jls!)ff90TGtW01u@^cXk&fXN*n8! zQTokFK6xbNq0N6sL7lEj@Q$js3xbV?oV~O#)U^|g@!$}}+4ru=wf<}GUJVb+w&tAh zu7po{D4dF<%7!f`TrE+x+Q`X{g|PPx@-KGVbxj%LU$_We@j=r2Oo7wUH1Ds!V7Q@M zDVqj^8oKRRs+8>qCdbjp6SjFr&q?GuJaE83cxU{_HS+X27+sOt$( z)PkZs(wq&uhS&(2nFvKuwgc-9*Ra{-v81;a+p>m-`K>&j8lJQ*a%2w8`2$ujMn>Ci zv(#=?DT{C6uY>E5b^NyTRjcsSabxep536i6e=K}5xQHiux5o9Pr_r@J)F>u3vQ z@@w?^bjTlOtC(6i$&Ph9+rAJiaa+{20W39a`biA!Zad9bQfg3j#63N2?FI9t2Gu@| zXZzYH!#pE3D6{}hZLle+Tl#;F9}TeWRAic_Ukw4@J=-AsYN)LWmu6)RjZb^Y_E4Ed zoy{HsML87E^?S#*hCx^+l_AU?X``5E4irS#%0l8+RsoxgwjC47+@TTPupuycm2Dt| zA#I%2zi(@fuO!%#IiJ@cHLFf#DBMlBNZD$(An3Es_9nhE(Uz>RH(*>zc6Dn>3hN5a zdP=jjYWkn1m=-|FFeoB*th3akkv&bFOF&um)}XK#XUx{Xluc{W1P z--4o!1Ry27Y=05AFSJqF%LK`CX^J_vMTA@Mw9N9aK-Vz;WUSwzp&kc&Uh$=NRwNhcTG7&6dcP!Jv}tXLEo+100F*<@99okY$->4)bjY z{)L^xf}OT11TsNzTPNkI_mV)_yBM|J6G+?lXwP+Yd~EwgW-B1!K)@m>OmTk=gX6^^31=#9vO>9ABM%dP+0iGd{yvL^DxVtuo#$Lr~_iQtSyp~?w2q|Utb{P4) ztrJ;sBAM0SWEKza)g?Zs2z?&GS>77@czjjTlT|H)>fKmJO9pMxQq^6`>jYf5Atm14 z512!5t7Y#WKZ%yhmrXnJFPEE_hrdQ}(>Rmy7JkM*px(D&ms_?i3<|Gly&!LwwIc2b z(ZBKgf=n#hYYSj-tb*PW9`3Yl%r2$V#wiP941Ehh+cZ`v_?b~Y$-=i{ObK0Ls8!Ve zP_&EhPqX-UEoXBe}d=*!i`!Jv)A3=TcT5W zSaY4q!}efooIRcTo2*}ina}Gy$vxf&2iyj08w3@2HLGlk_2i9mB}G zdX9kj&y0Eyo35LXAU_V5YP$nr&~JJPY?P#*Pzkrn|ISVIc7L(i0mshMmkL@>6RwJn z$rIYA!HNjc1P5K!XZiOYr_j4ur?~xZe9bgbEALi41EMv%0XeD8V2EYzdXRjQ^whGI zXoooy^)LMPmk+E+gu}yF`$gP5Nx$ZA^)pO7qj%;Qy;9$10$c2N(I1KH_f>WVv+nEN zC=uhaSyR(TO9Ud35fYk}#q1h`XtZa-{#-+cl`ZTl1U1qNDCKSM?(geM$dc`w9%(q~ zgnkbzZq>hI>@2v;IzyqrYJVLcw9q-BVR3)G@fD_2aKtch{iGK`SWk(9t-E>z!<~Ed zu99?xfFaWR*G%0uZJK2HKG9V2T8OOf*b7NrMSVy-peM@pBy|Aa9RdH;d28 zLS~je27(S5Eg-(1n1#_H_5=O_Uc{`{c1=KFP5WI_!3CJro@#1frm&-dUPp6$j z2c&@p6R!6et)yY=^@(OQPNiG?+u~^4ikW%#bPD_F5u`^d`4xKwgBR)-1r*E|6-@@O zVsNtFgFTso#(4cjNH6K2MCSiw++OqD?=X0Yt_Zl$pNfF?<>|N0i{C^1F=JD)<%bCK z;gMn4QP@Eb{s_6{?X6&CQ~QNtJI~O`f(GgS0OJ=dI-`G0b91HM8ynWMtExoO{uMGBs*#u% zZ$IV_bAQ|A@-c{MWZ$IlLK@WXsh3_Z4e=g#AtZlpE02lYMJU5wP3@bA$v>bl&3*#& zn%nEs82^Nr2UJDyQKY>M{dEswxSRG_t?ifTultY@D`GKvr#^zb=@_Ln1Rk>cZSMhO z3>64DKN?oZTxX9?`$%7gA9k_#QG_L82ztBf?@}SmXgvV8_p*1RBL)!FPKv2xce=82bu82$nyr_e-HKKVy6!2S4Aq` zUTQDF30@3tFO|ilBYG=tihUiU2rllSQ5nYWq3-@?LSEn>T>xwzWbY0I{YjYQCKfUz zJ}Ypls>_O_vhQgJ>@#8PT)TqgASv%(60(MgJk0xuq8jY~fqjNT?_JEa2MO6l<1T|K zUG-*u!+8B)1Ul6(@Ujp*j#j#{$@(YHSjslaAqT%gB`cNp+Aj&Sq^_K!1*LzDJAUaQ zNv|bWD|o}|hlP1fj-C@_m)lK=SA?j_j+qejyJ%sq;0?j`wQitx)LvPY6~dgynX6Ac zZS}Qc696)SRpgrmohJ}MkP#&BhQKV*58mr#FA0H*9XD`GWtrBu*d>moW*@-HU0{(aSN*Y&`_x#z}p!-xd2QN(PR*X?m*j@YQg4KkeFCDYt;xflXa5Zoi`5B=MyW9w8 z{9*Sovusbc(|ld-*hmF#{q3b8y^k{nk|v7ACSOzhP1c5tGR`|DOE!@$IX;nOa#=T` ziuwB5jG+Y`>JarHrW3*MTOJ6im!rCdYWTLpG13G@if zqdT|7*i8-!tdm}HCPAw?PC^4LWOlw|q8wx{cJzB_zV9$3_{DuY5PO1V5 zI_k9g#oG#EzjBPianX(?CKj5q(m~5qPY0DMJcr&79LLEgC5oze`=rCo(mt|Pgs_*K zd2n%qWX7lBdC0fQQ5c!;m`;(dF2`fiJm<&E)hNuIAN9i;ghkL(ts&nbuY+V@Ius5g z81~RmM+>u_&pnH(^D2)p_0pD9VHPfocIX;asad}7uY836acJxtU z-&H>TSa4&&yE<^*8LtW2Q#S- zo2>H$?I*{GsphRt5O>H)$)h9(C678|TvzkCpu3K8kUpFW;k(UoY-a?W2K9B$W_a;a zXMMt4%R1Yz?1c`3#=HHict{^tU_fVQ6{wf$I712h{dJvD+&^ED=4*9YX>U6SUa*K5 z$e`MGjL&w^em`j(>C%`lGz@*mLEgDLTv{bQ!uY$6$qZI(a<;~0W;n*G%!#MgJHmuaN3cY1OgQ0KMDB^ymbt~zgL1nGd5%sbhBT?H zpFdoX<(OpF^~L;b?*kv+bZB_wrh~xw+ru0LD{n$aZ}tMj{BECTvXsx@wnv_c1-l(p z7<&<7?%S6X^EHPoWvrBpH}^S8G1dRarDVP=pZ1;kSvAn;#pOJwqIhv zuEtcyVYxH0`0{*nK2zzS82I-oq`%d2hPx=sM}R%h({uZ{qpOE=lmm z;ruZX2FWAEXK?X2`AdIcxNETE7gOG`z>c~rVf=h&GR>VnauO`M=6nT?<%zy(SQs57 z6LIkA5$EeT?W|*tp!Ackq%)CYPPPkM|XG_b> z2405Tu@X(frp_et`*)mGVRH|~hLyNuA?2k0bo68+A%B^+018$+UWFAEopW%(eTS?v zH>OC=u|gh7jf_bRem5emsiy?QCJG1KxF`$^{me<)59{Q79UcbDhBnnonenBj9d}Ke8cn~681;dp9K%XAomV*(EMBt8UJSZpFCblg?kJ$$DWU1fKTG{g zX}$)R95NL9t@d~;%vn;fNf10ss!Cuwg>tbOf}*~*;m(gZl`=AP@51Q5&d+G8*iu*E z_9(>-#57e6SV+yq3IS5cS=3uNK{d~}{i+wU3(PuocW+;SWck@!e6hM2ev1k8n+6#d z#QV6ey|cey(;@ea{RJdHvz8EE$oFfY!4+^crViuHHiP}wXjI^n3t%$`pAW3<_jk|i4A zM;XrNITm&yXK21N2a8TSw)018eBeutCUASb^BwcfT*&|3P8fZ>lX8Ib!1pF0a^%9M z(bP?KhCNa0E|ZDgRGXO394q~ub1*8=eldHHvm?Z2J1atRx-4Z+b*@w7l9UmBplMDe;pLuq{%;`XkaLg8Cn3VarMhtO3&){n zA{C4u;b`X{3#rZzSTeGaN?V2SG%3#g-1EbQPk$S~5R7jVofXBt%{nu1)+Fl~)<3};Ir__&)6ur+Y>z^Ut< zbLluI#@ux@Wk_oKgyJ}i`OQIjv&TwXiPg6{&oQvX= zm+xXivf~}{Q+j#=R-1 z#$o2C&Lqy>!~FB2JS||6E*+A9jtBlN9`Kt_I>b$t=$OhJ=Q3t?Rsk=ZalWj{WhBcl z;eN50>+~jwyy)C7zeC);PZfCN#yS-^3GG`=ptGEa6y;7c0RgcFeATJYxBWHe9>LZ^ z?rf)___I z!{C%J0kt2JD2stnB%a7OsRUvFRb+c*`c|DctG z*f5tH@~TkLZ>wMA+$W9QVcCscmt>jt%Y1Uzz?Y1Lmaj=Wv%7bQ86m<`E(Sr4f`QASKc!VoT5N_^Gb=81+ zb(JX)Sj*K5?~Qg%QsrRDa^lgcgvXMh(!B|MgK+i@7a%mH^dbL%3H2joHf;zXr672TjQdF@FZ7n6Z~~{bsfTE^IT0#$oJHT zbV~VVRiz1`E^oT12H_OM9TlY@=elN?;~T_qev0dLRjxw2nMVcaCT~E6@{6I_JFYp_ z{8iO_l_kr;M+X@m-%K{yJ3+tCz}<=ttb{sT`5eYAaHRl=cDAY2&mp6MYY;yC*|em` z7MJR`q|=bm$h`HtT#m$_V-jrorHzWrNgrwKXmO<*;$O~?xO4nS=J@EI@INZEe%{TK)rW`?da;p zzQUN^F3JvCce$wO>uZP^>7paYdtKy2zk!scu0jYpOc~O9Ij&Bcc_{SjVxyx%qoXc2 zm%k*gE`WE0F%d$eSOikKxu;+k(L35OJ#@Z{Jaj>7aHSI9xbN05=(NkKNmV5aiF~-x z9w(l2y&>fD)X29e6}U=RrD{~EX-?}_w2v^{IQj=yDwi+Q1K*)^!$sNg?=eX>E>IQp z1|tw+M;Top>6FV0L11_>^Ny&~{FjjLe=qzk`qZ{@xj4kwNA>^E+;^m-n21QBn0mf*2wUlvR zHjkX%9EO*|44vc5O2!oC6hBh`KT#Y_|JCgITW#?!M{STnIiD??Sxqov2IntY%0LkGW7 z`}ZNMvZpDwY;PQ-79RksbGOL0D~?a*2KE;4;mJ!g(^4mi0Fb8>@{2ha2h4F6cO}B%5*xZv+`rjVh2i)o=jG zWi;Y6gGvj-DjRj6%u?f3pszd7UPm!%;l8EDEOSmt3TE7K(R?ZRj&d}ctwzm9M)Bt| z;~06?pItJL&>F*@Sw@8UxQa!yjA*(OLv^)o0A*1StmT z1|@xF88tPT-0zk~Kr-zQ*B2T#Enr=Oubw$O2txMHfU4x&CFdH+M}F>@!+dg{*}rD0 zK(f-0K9SIxpuNHhhGE|L+N^8LzvT|XkR`@NK_FvF6OvW@GJ`6BJdo1DCtB2!iI-5UE^vrf?mR8zY%945S5^R1L&>*ydz1w;6J_t9qm=s> zM$n+|cey%54^dqIHUyv{RK)>h-D^3OP8MA@T+FnNs>R$tBViMslNvzLcSbxkKWrQ< z9?3#8N~7Sm=(<73XL(1^-$#@F#7rvq#~hADx6ID`W1~}72JP)?xv!`)P5f1_kZpuP z-}>&iv?hxZeBqMiJ#zxqhoA=TaBHJoim#zro?u##DTmQA9Xpm9qtwt%g>FsZQjCXu zTXQ$<|C*zBz0{IW*?+^LX)onAxo%y8$7IzKG6 zZWPhLTfcE*h+M@9cNyw#rpe7HKpsHjsRn7I-Am=p3qpKNF>H*RCP%0BReVjLV61zj z+%~1EuQ7BR=g!ohr-s^jyxjzxCJxWvEv?zB#Darh|BTBQ}4|M|m zqRMgF;oDQ(zj8WL=IiJTq2f6z58L;SyF0|6pmLbfOWij(A%VF$wmdw&%pIy)W6T~J zd&9yZc&aS`k{-INV(WBwPfa5L>Bkn~>o`P(+xwWfI#r|9`@lVzS$iy+ng58YJ1)C+>YBsf0yhjTM-YY({x5U2+k2Pl<5y}xgkLdK(b1K&E~o+zjQvQ>9?=%WN$-kTyH zjePe)l?rWFoF(xO+SK3I6765Pf8z2BG$aDyf)zSuSKsprrk`^U5iAb!XDXqvD3-n^ zaZy(Su}^{fLqGhs#t0!t(!o$M^s4(bXG0+WI3fCB8)%KB!+O2&t!wUyDnW0@XHq?K zlR`IDMGc4eQRMIKWtFKAcucu~6MuHUWggB=iE>bk@SFRZ;3I-k+f}NI_3yd!h5mA* zhD{na3?D+MHKZI3s0ACAuu*B3t;?|$^Bm-6L8IguV^!!7@9%Np;ASQ09NSgJfBvH+ zY{^ybrMWy0P4G+_15rUnXmRxQA(nD`Zki>F1$~SlGhjH5w@Y|R2sRF)%6s-xIAF;)xbAAzIQa z5I5OccUxu&I$7^8j?1p55AnN-2@rRg&L5BK=}8gl;D{#l@I;7vpQ>YHzwm6qyf6># zq+d*()7*1h5Xu#F(cKcF zh0TH8B0by9Q@b&j$&W{WZd;80S~+UaXg zbhED=(RY1qiKh5k6P@cb7tJX?I(8r>_$bBpzx3_J|N8V|;{T;@FaFo37Zd+4eS47# zWd8Nji;YIno&W7`FG`82z7hj*aI`1G{4{~Df=-y;N_S<`yDy;-oqZ zP|iq=s#2}kt!E4R)Id>|Z3-0D^t6ZNHv-bB zA2V3i0&`b*nsKYS;7zCBd`PG(g*~+fVS0DZ5Jq*|&oa7z&OO=a`)NrY`hMENXPJES zA56|SnSASMCKo-;WU{&bBtOmM63YmIwXc%Jv4)R$7X`AW=svNXo|m&PSj`W$c& z-`g2*gwA8H^}NCeevkUXa}sD(e2c1I%x=@3We@(ro?nK`o@Vdur`hu_kMBIq-d+y{ zD{ZmmLC+*+TYjRV&-})~-{eWay|eR(Ao2^(DRYeF!l!&LftoPA?7;oFXEIkAh?ky z7;60(@CAg$dH~X=+lJwZe&;>TRKy$b0aJfndEfu6AFOB>Z;x1mrV`Nmr z#s~kdjEzq#cr@JFco-yOn7&+@nL-}&4BG=Dk&;4k-S z{`_;T!(aT-CkLd1|H0oU|KRV?v-}-?mcJwa&fn3e`8)PBe|}#;nUp87sGq-%fAM#K z_&fQZu`|I|2AAo{Q1-Toqn1>zcV=VG=J*@3N@vZ=>Vc0IaGaU zqlU!hr}R6EMNXZd(d4t9ml%cgZ}|PzSHM=fqfDn?nd3{l1C}!ayD!bO1*ToLb%l#R z1T-=gj*du Date: Thu, 15 Aug 2019 13:46:39 +0000 Subject: [PATCH 008/112] Avoid downgrading SQLITE_CORRUPT errors detected by the schema parser into SQLITE_NOMEM or SQLITE_ERROR errors. FossilOrigin-Name: b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/prepare.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 64901db7c3..394b53716c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\scell\soverwrite\soptimization\sdoes\snot\soverwrite\sthe\sheader\nof\sthe\sb-tree\spage. -D 2019-08-15T13:17:49.826 +C Avoid\sdowngrading\sSQLITE_CORRUPT\serrors\sdetected\sby\sthe\sschema\sparser\sinto\nSQLITE_NOMEM\sor\sSQLITE_ERROR\serrors. +D 2019-08-15T13:46:39.741 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -518,7 +518,7 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848 F src/pragma.c a42d4c6040893a59b69a0c987e5ed0402730c444ee451fde9bbe6203e7f73b1d F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13 -F src/prepare.c 1dcd92a57f63f7ba02ece7997c0cd36647f6ea05c05726f02d7709b18bd368ac +F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c d49679d55d3cf529bbdff8734c4ac02cedfb2fc785545b89815ddb79680b9198 @@ -1836,7 +1836,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 b517a52fa36df0a0854a75858b5e81861771d2e9032a5a0ad79aa76ae64130a2 -R 99504bb8346f69a0c987562da440ce64 +P 4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 +R 8d34b75339aca80871316bc3b34ad384 U drh -Z c6c5cb19819200b45c3cd69274447def +Z 6594db806a9430ef05667df996896231 diff --git a/manifest.uuid b/manifest.uuid index ae239c6fc7..191b74e093 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 \ No newline at end of file +b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a \ No newline at end of file diff --git a/src/prepare.c b/src/prepare.c index c6d7fba703..70c162658a 100644 --- a/src/prepare.c +++ b/src/prepare.c @@ -115,7 +115,7 @@ int sqlite3InitCallback(void *pInit, int argc, char **argv, char **NotUsed){ if( db->init.orphanTrigger ){ assert( iDb==1 ); }else{ - pData->rc = rc; + if( rc > pData->rc ) pData->rc = rc; if( rc==SQLITE_NOMEM ){ sqlite3OomFault(db); }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){ From a3fcc000cb7bd5b12816512834e6484c68658576 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 15 Aug 2019 13:53:22 +0000 Subject: [PATCH 009/112] Ensure that SQLite does not attempt to process incompatible window functions in a single scan. Fix for [256741a1]. FossilOrigin-Name: 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/expr.c | 7 +------ src/resolve.c | 11 +---------- src/sqliteInt.h | 1 + src/window.c | 21 +++++++++++++++++++++ test/window9.test | 23 +++++++++++++++++++++++ 7 files changed, 59 insertions(+), 28 deletions(-) diff --git a/manifest b/manifest index 394b53716c..ade3aa6fda 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sdowngrading\sSQLITE_CORRUPT\serrors\sdetected\sby\sthe\sschema\sparser\sinto\nSQLITE_NOMEM\sor\sSQLITE_ERROR\serrors. -D 2019-08-15T13:46:39.741 +C Ensure\sthat\sSQLite\sdoes\snot\sattempt\sto\sprocess\sincompatible\swindow\sfunctions\sin\sa\ssingle\sscan.\sFix\sfor\s[256741a1]. +D 2019-08-15T13:53:22.869 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 85239130e25f54279b1dfb3641984a335ce5a38709af29f9b62b555ed1459d07 +F src/expr.c 1b4f5a53a5f48ba3f718413586e0f9715cf90c684fba9038186a62728e2ebe72 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -521,14 +521,14 @@ F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13 F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c d49679d55d3cf529bbdff8734c4ac02cedfb2fc785545b89815ddb79680b9198 +F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117 F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 0598c87a995d63b09bcc408552bf38205cd902b577e74b7c3237bde71093c28b +F src/sqliteInt.h 4875fb443102c9d92ed1cb23b7fb6e2d97714591f02725d595576ef316596b94 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -613,7 +613,7 @@ F src/where.c 90cb93dc8eb9383e72f661b2074551d47ff21e5379f7167f7e078bed436989e9 F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc -F src/window.c 98b2571c66246bddadf42e76da45ed970fe7518a4c9c1ccc8cdace0711bfabba +F src/window.c 07e1c15081a735750218185c6b17053c87ecb764d06ab2c0a1ce568a2b4688e5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1712,7 +1712,7 @@ F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d761 F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f F test/window8.tcl 9e9a82ae9eea90a4a83481d641a812b974980c38f9247f3b89a6e3c8bed45518 F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91d43f -F test/window9.test 1fd3ff49119c28006e8f55e48e8425bf4d5bf560195c4df470ef147641004f56 +F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test 403693d7d951c5473f052f7ecddb61ed15ac9d212f238b8904ea270ba90f83e5 @@ -1836,7 +1836,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 4cc5694cbd69749c146679c367860952fdf3f5356426ddfd1dce470569702bc1 -R 8d34b75339aca80871316bc3b34ad384 -U drh -Z 6594db806a9430ef05667df996896231 +P b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a +R b2cc9a11d7f17926cd103784a544e4bc +U dan +Z a8ef7cc1d7134e3e2d9b097acd8c412a diff --git a/manifest.uuid b/manifest.uuid index 191b74e093..2c85f9837b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a \ No newline at end of file +4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e00b319ed2..8f02ae569a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1325,12 +1325,7 @@ static int gatherSelectWindowsCallback(Walker *pWalker, Expr *pExpr){ assert( pWin ); assert( IsWindowFunc(pExpr) ); assert( pWin->ppThis==0 ); - if( pSelect->pWin ){ - pSelect->pWin->ppThis = &pWin->pNextWin; - } - pWin->pNextWin = pSelect->pWin; - pWin->ppThis = &pSelect->pWin; - pSelect->pWin = pWin; + sqlite3WindowLink(pSelect, pWin); } return WRC_Continue; } diff --git a/src/resolve.c b/src/resolve.c index d88abc4a4b..31600382fb 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -908,16 +908,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ sqlite3WalkExprList(pWalker, pWin->pPartition); sqlite3WalkExprList(pWalker, pWin->pOrderBy); sqlite3WalkExpr(pWalker, pWin->pFilter); - if( 0==pSel->pWin - || 0==sqlite3WindowCompare(pParse, pSel->pWin, pWin, 0) - ){ - pWin->pNextWin = pSel->pWin; - if( pSel->pWin ){ - pSel->pWin->ppThis = &pWin->pNextWin; - } - pSel->pWin = pWin; - pWin->ppThis = &pSel->pWin; - } + sqlite3WindowLink(pSel, pWin); pNC->ncFlags |= NC_HasWin; }else #endif /* SQLITE_OMIT_WINDOWFUNC */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 1104b771f3..d6746aadca 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3609,6 +3609,7 @@ void sqlite3WindowUnlinkFromSelect(Window*); void sqlite3WindowListDelete(sqlite3 *db, Window *p); Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8); void sqlite3WindowAttach(Parse*, Expr*, Window*); +void sqlite3WindowLink(Select *pSel, Window *pWin); int sqlite3WindowCompare(Parse*, Window*, Window*, int); void sqlite3WindowCodeInit(Parse*, Window*); void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int); diff --git a/src/window.c b/src/window.c index ebcb576bb5..e2f0b62276 100644 --- a/src/window.c +++ b/src/window.c @@ -1229,6 +1229,25 @@ void sqlite3WindowAttach(Parse *pParse, Expr *p, Window *pWin){ } } +/* +** Possibly link window pWin into the list at pSel->pWin (window functions +** to be processed as part of SELECT statement pSel). The window is linked +** in if either (a) there are no other windows already linked to this +** SELECT, or (b) the windows already linked use a compatible window frame. +*/ +void sqlite3WindowLink(Select *pSel, Window *pWin){ + if( 0==pSel->pWin + || 0==sqlite3WindowCompare(0, pSel->pWin, pWin, 0) + ){ + pWin->pNextWin = pSel->pWin; + if( pSel->pWin ){ + pSel->pWin->ppThis = &pWin->pNextWin; + } + pSel->pWin = pWin; + pWin->ppThis = &pSel->pWin; + } +} + /* ** Return 0 if the two window objects are identical, or non-zero otherwise. ** Identical window objects can be processed in a single scan. @@ -1416,6 +1435,8 @@ static void windowAggStep( int nArg = windowArgCount(pWin); int i; + assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); + for(i=0; izName!=nth_valueName ){ sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+i, reg+i); diff --git a/test/window9.test b/test/window9.test index cf4d83ae8e..d79e5f3d00 100644 --- a/test/window9.test +++ b/test/window9.test @@ -171,6 +171,29 @@ foreach {tn sql} { } {~/ORDER/} } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t0(c0); + INSERT INTO t0(c0) VALUES (0); +} + +do_execsql_test 6.1 { + SELECT * FROM t0 WHERE + EXISTS ( + SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 + ) >=1 AND + EXISTS ( + SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 + ) <=1; +} {0} + +do_execsql_test 6.2 { + SELECT * FROM t0 WHERE EXISTS ( + SELECT MIN(c0) OVER (), CUME_DIST() OVER () FROM t0 + ) + BETWEEN 1 AND 1; +} {0} finish_test From 725dd72400872da94dcfb6af48128905b93d57fe Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 14:35:45 +0000 Subject: [PATCH 010/112] Ensure that the optional "sz=N" parameter that can be manually added to the end of an sqlite_stat1 entry does not have an N value that is too small. Ticket [e4598ecbdd18bd82] FossilOrigin-Name: 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/analyze.c | 4 +++- src/where.c | 1 + test/analyzeC.test | 14 ++++++++++++++ 5 files changed, 28 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index ade3aa6fda..7d4def8408 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sSQLite\sdoes\snot\sattempt\sto\sprocess\sincompatible\swindow\sfunctions\sin\sa\ssingle\sscan.\sFix\sfor\s[256741a1]. -D 2019-08-15T13:53:22.869 +C Ensure\sthat\sthe\soptional\s"sz=N"\sparameter\sthat\scan\sbe\smanually\sadded\sto\sthe\nend\sof\san\ssqlite_stat1\sentry\sdoes\snot\shave\san\sN\svalue\sthat\sis\stoo\ssmall.\nTicket\s[e4598ecbdd18bd82] +D 2019-08-15T14:35:45.987 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -458,7 +458,7 @@ F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190 -F src/analyze.c 0278dbf6dbc0be90dc5391cb020772b461d789af17c390f857a34308c7ac9858 +F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2 F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 90cb93dc8eb9383e72f661b2074551d47ff21e5379f7167f7e078bed436989e9 +F src/where.c 2fac51d2420f05ab6f644f1813d4f73f6214304836fd9b22345738d943faad9b F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc @@ -643,7 +643,7 @@ F test/analyze6.test 6c3f7df2996cb6872f355a6ac1eb6d5de00a5a9288214bad7ef25c97d9c F test/analyze7.test 6ef0b12369f61ddeadc7d8a705c40e6b52cb29f63de3a4c56581b510b46b5783 F test/analyze8.test 36ce54947710bd44e4f9484e1ad07e725ef01a9d7078b417c1bc884356febe4d F test/analyze9.test 9fbf0e0101eef4f5dc149769aa14e10b76ee06e7c28598264b32173cd1999a54 -F test/analyzeC.test 555a6cc388b9818b6eda6df816f01ce0a75d3a93 +F test/analyzeC.test 489fe2ea3be3f17548e8dd895f1b41c9669b52de1b0861f5bffe6eec46eac710 F test/analyzeD.test e50cd0b3e6063216cc0c88a1776e8645dc0bd65a6bb275769cbee33b7fd8d90c F test/analyzeE.test 8684e8ac5722fb97c251887ad97e5d496a98af1d F test/analyzeF.test 9e1a0537949eb5483642b1140a5c39e5b4025939024b935398471fa552f4dabb @@ -1836,7 +1836,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 b2e79f8ff0836fcc98a2df9377aad9137307c34058030ecd1b5d4ec3277ed36a -R b2cc9a11d7f17926cd103784a544e4bc -U dan -Z a8ef7cc1d7134e3e2d9b097acd8c412a +P 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a +R e211e009e748f2e64e3d39bc31b03be2 +U drh +Z bec392cb43d1df3c3b62ac4b05f24424 diff --git a/manifest.uuid b/manifest.uuid index 2c85f9837b..7672348cd3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a \ No newline at end of file +98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 \ No newline at end of file diff --git a/src/analyze.c b/src/analyze.c index 31fb6f5b51..1904b9be02 100644 --- a/src/analyze.c +++ b/src/analyze.c @@ -1450,7 +1450,9 @@ static void decodeIntArray( if( sqlite3_strglob("unordered*", z)==0 ){ pIndex->bUnordered = 1; }else if( sqlite3_strglob("sz=[0-9]*", z)==0 ){ - pIndex->szIdxRow = sqlite3LogEst(sqlite3Atoi(z+3)); + int sz = sqlite3Atoi(z+3); + if( sz<2 ) sz = 2; + pIndex->szIdxRow = sqlite3LogEst(sz); }else if( sqlite3_strglob("noskipscan*", z)==0 ){ pIndex->noSkipScan = 1; } diff --git a/src/where.c b/src/where.c index 65c92863a5..a37a810a2b 100644 --- a/src/where.c +++ b/src/where.c @@ -2670,6 +2670,7 @@ static int whereLoopAddBtreeIndex( ** it to pNew->rRun, which is currently set to the cost of the index ** seek only. Then, if this is a non-covering index, add the cost of ** visiting the rows in the main table. */ + assert( pSrc->pTab->szTabRow>0 ); rCostIdx = pNew->nOut + 1 + (15*pProbe->szIdxRow)/pSrc->pTab->szTabRow; pNew->rRun = sqlite3LogEstAdd(rLogSize, rCostIdx); if( (pNew->wsFlags & (WHERE_IDX_ONLY|WHERE_IPK))==0 ){ diff --git a/test/analyzeC.test b/test/analyzeC.test index 02faa9c7e9..2a0a897810 100644 --- a/test/analyzeC.test +++ b/test/analyzeC.test @@ -132,6 +132,20 @@ do_execsql_test 4.3 { SELECT count(a) FROM t1; } {/.*INDEX t1ca.*/} +# 2019-08-15. +# Ticket https://www.sqlite.org/src/tktview/e4598ecbdd18bd82945f602901 +# The sz=N parameter in the sqlite_stat1 table needs to have a value of +# 2 or more to avoid a division by zero in the query planner. +# +do_execsql_test 4.4 { + DROP TABLE IF EXISTS t44; + CREATE TABLE t44(a PRIMARY KEY); + INSERT INTO sqlite_stat1 VALUES('t44',null,'sz=0'); + ANALYZE sqlite_master; + SELECT 0 FROM t44 WHERE a IN(1,2,3); +} {} + + # The sz=NNN parameter works even if there is other extraneous text # in the sqlite_stat1.stat column. From 42d2fce7f5b5e5776f3e881b4685deae2e0266ff Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 20:04:09 +0000 Subject: [PATCH 011/112] Provide the SQLITE_DIRECTONLY flag for app-defined functions that prohibits the use of those functions within triggers or views. FossilOrigin-Name: fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1 --- manifest | 31 ++++++++++++---------- manifest.uuid | 2 +- src/attach.c | 1 + src/main.c | 4 ++- src/resolve.c | 9 +++++++ src/sqlite.h.in | 13 +++++++++- src/sqliteInt.h | 63 ++++++++++++++++++++++++--------------------- src/tclsqlite.c | 14 ++++++++-- src/treeview.c | 6 ++--- test/func.test | 40 +++++++++++++++++++++++++++- test/tclsqlite.test | 2 +- 11 files changed, 131 insertions(+), 54 deletions(-) diff --git a/manifest b/manifest index 7d4def8408..9b54e4ca09 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\soptional\s"sz=N"\sparameter\sthat\scan\sbe\smanually\sadded\sto\sthe\nend\sof\san\ssqlite_stat1\sentry\sdoes\snot\shave\san\sN\svalue\sthat\sis\stoo\ssmall.\nTicket\s[e4598ecbdd18bd82] -D 2019-08-15T14:35:45.987 +C Provide\sthe\sSQLITE_DIRECTONLY\sflag\sfor\sapp-defined\sfunctions\sthat\sprohibits\nthe\suse\sof\sthose\sfunctions\swithin\striggers\sor\sviews. +D 2019-08-15T20:04:09.316 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -459,7 +459,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190 F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2 -F src/attach.c 78e986baee90cb7b83fb9eafa79c22581a8ada14030fd633b0683c95cf11213c +F src/attach.c a6f108eb7922fad920e8aba0cda56fb56d89d136d519be5177cd3bd3559f2566 F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -487,7 +487,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c -F src/main.c 3add6433e077635dac5579edaf7b3942e3ff3dda5588c49c0edd7abea2096482 +F src/main.c ff418603f9435914e8bd2febd1d5dbfcbf2ece3a4e853481a81a50fc27b321ab F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -521,18 +521,18 @@ F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13 F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa +F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117 F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e -F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906 +F src/sqlite.h.in dfbb64c0b8e4b3de2958d8372208437509acdc523aed8ae90a164f3a5d9a5739 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 4875fb443102c9d92ed1cb23b7fb6e2d97714591f02725d595576ef316596b94 +F src/sqliteInt.h 12e8af40a561a3006b6996938c88cce1e24efe690955e193824571d20c3ef352 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424 +F src/tclsqlite.c a65eb317f8b83f7ae546f88db56600f9a39550688d70501b8eb0cc3a4b4960c9 F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -588,7 +588,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e -F src/treeview.c 06e65db6ffa14dd583f90403192190dfe3855c0e3acfcbac0e82109a46e2b16c +F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e F src/trigger.c 2305271878e95addc1c01361e5e8e342e87cba5efefdd7d3032687e5d67e05d1 F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 @@ -990,7 +990,7 @@ F test/fts4rename.test 15fd9985c2bce6dea20da2245b22029ec89bd4710ed317c4c53abbe3c F test/fts4umlaut.test fcaca4471de7e78c9d1f7e8976e3e8704d7d8ad979d57a739d00f3f757380429 F test/fts4unicode.test ceca76422abc251818cb25dabe33d3c3970da5f7c90e1540f190824e6b3a7c95 F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test e4313baba80bf933e58eb89a7c617bec0f0c348c862b096ec4387f36e05ad0a6 +F test/func.test 0889128141b99b38aa9ce78445acfc4c1f9fbe9aa4f51d4c6aff88ae43cf125b F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 2bb0f31ab7baaed690b962a88544d7be6b34fa389364bc36a44e441ed3e3f1e6 F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f @@ -1388,7 +1388,7 @@ F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test 5a06962d8f18edf4703931f6b7dacd83678d02fa5c8ced9a7958c007ad58626a +F test/tclsqlite.test 6c7368554f15ea6df3852173c0f1d6353f824afb1896f6fc17fb21b057c0685a F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1836,7 +1836,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 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a -R e211e009e748f2e64e3d39bc31b03be2 +P 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 +R ad310bbebd66791c892628fc8eec172c +T *branch * directonly +T *sym-directonly * +T -sym-trunk * U drh -Z bec392cb43d1df3c3b62ac4b05f24424 +Z 950f463a47bf34120eda446765855ee2 diff --git a/manifest.uuid b/manifest.uuid index 7672348cd3..bd2dbbdbb6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 \ No newline at end of file +fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1 \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 55e0eb5363..61f169ed76 100644 --- a/src/attach.c +++ b/src/attach.c @@ -560,6 +560,7 @@ int sqlite3FixExpr( Expr *pExpr /* The expression to be fixed to one database */ ){ while( pExpr ){ + ExprSetProperty(pExpr, EP_Indirect); if( pExpr->op==TK_VARIABLE ){ if( pFix->pParse->db->init.busy ){ pExpr->op = TK_NULL; diff --git a/src/main.c b/src/main.c index 06a55eca02..969bd570c4 100644 --- a/src/main.c +++ b/src/main.c @@ -1720,7 +1720,8 @@ int sqlite3CreateFunc( } assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); - extraFlags = enc & SQLITE_DETERMINISTIC; + assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); + extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); #ifndef SQLITE_OMIT_UTF16 @@ -1783,6 +1784,7 @@ int sqlite3CreateFunc( p->u.pDestructor = pDestructor; p->funcFlags = (p->funcFlags & SQLITE_FUNC_ENCMASK) | extraFlags; testcase( p->funcFlags & SQLITE_DETERMINISTIC ); + testcase( p->funcFlags & SQLITE_DIRECTONLY ); p->xSFunc = xSFunc ? xSFunc : xStep; p->xFinalize = xFinal; p->xValue = xValue; diff --git a/src/resolve.c b/src/resolve.c index 31600382fb..ab22664095 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -823,6 +823,15 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ ** SQL is being compiled using sqlite3NestedParse() */ no_such_func = 1; pDef = 0; + }else + if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0 + && ExprHasProperty(pExpr, EP_Indirect) + && !IN_RENAME_OBJECT + ){ + /* Functions tagged with SQLITE_DIRECTONLY may not be used + ** inside of triggers and views */ + sqlite3ErrorMsg(pParse, "%s() prohibited in triggers and views", + pDef->zName); } } diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d68cef2490..d50f44e6cc 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4848,6 +4848,9 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** function that is not deterministic. The SQLite query planner is able to ** perform additional optimizations on deterministic functions, so use ** of the [SQLITE_DETERMINISTIC] flag is recommended where possible. +** ^The fourth parameter may also optionally include the [SQLITE_DIRECTONLY] +** flag, which if present prevents the function from being invoked from +** within VIEWs or TRIGGERs. ** ** ^(The fifth parameter is an arbitrary pointer. The implementation of the ** function can gain access to this pointer using [sqlite3_user_data()].)^ @@ -4965,8 +4968,16 @@ int sqlite3_create_window_function( ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. +** +** The SQLITE_DETERMINISTIC flag means that the new function will always +** maps the same inputs into the same output. The abs() function is +** deterministic, for example, but randomblob() is not. +** +** The SQLITE_DIRECTONLY flag means that the function may only be invoked +** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. */ -#define SQLITE_DETERMINISTIC 0x800 +#define SQLITE_DETERMINISTIC 0x000000800 +#define SQLITE_DIRECTONLY 0x000080000 /* ** CAPI3REF: Deprecated Functions diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d6746aadca..47b4e749da 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1663,6 +1663,7 @@ struct FuncDestructor { ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API +** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API ** SQLITE_FUNC_ENCMASK depends on SQLITE_UTF* macros in the API */ #define SQLITE_FUNC_ENCMASK 0x0003 /* SQLITE_UTF8, SQLITE_UTF16BE or UTF16LE */ @@ -1683,6 +1684,7 @@ struct FuncDestructor { #define SQLITE_FUNC_OFFSET 0x8000 /* Built-in sqlite_offset() function */ #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ +#define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -2494,36 +2496,37 @@ struct Expr { ** EP_Agg == NC_HasAgg == SF_HasAgg ** EP_Win == NC_HasWin */ -#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ -#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */ -#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ -#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ -#define EP_Agg 0x000010 /* Contains one or more aggregate functions */ -#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ -#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ -#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ -#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ -#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ -#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ -#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ -#define EP_Skip 0x001000 /* Operator does not contribute to affinity */ -#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ -#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ -#define EP_Win 0x008000 /* Contains window functions */ -#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ -#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ -#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ -#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ -#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ -#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ -#define EP_Alias 0x400000 /* Is an alias for a result set column */ -#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ -#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ -#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ -#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ -#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ -#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ -#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ +#define EP_FromJoin 0x000001 /* Originates in ON/USING clause of outer join */ +#define EP_Distinct 0x000002 /* Aggregate function with DISTINCT keyword */ +#define EP_HasFunc 0x000004 /* Contains one or more functions of any kind */ +#define EP_FixedCol 0x000008 /* TK_Column with a known fixed value */ +#define EP_Agg 0x000010 /* Contains one or more aggregate functions */ +#define EP_VarSelect 0x000020 /* pSelect is correlated, not constant */ +#define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ +#define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ +#define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ +#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ +#define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ +#define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ +#define EP_Skip 0x001000 /* Operator does not contribute to affinity */ +#define EP_Reduced 0x002000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ +#define EP_TokenOnly 0x004000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ +#define EP_Win 0x008000 /* Contains window functions */ +#define EP_MemToken 0x010000 /* Need to sqlite3DbFree() Expr.zToken */ +#define EP_NoReduce 0x020000 /* Cannot EXPRDUP_REDUCE this Expr */ +#define EP_Unlikely 0x040000 /* unlikely() or likelihood() function */ +#define EP_ConstFunc 0x080000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ +#define EP_CanBeNull 0x100000 /* Can be null despite NOT NULL constraint */ +#define EP_Subquery 0x200000 /* Tree contains a TK_SELECT operator */ +#define EP_Alias 0x400000 /* Is an alias for a result set column */ +#define EP_Leaf 0x800000 /* Expr.pLeft, .pRight, .u.pSelect all NULL */ +#define EP_WinFunc 0x1000000 /* TK_FUNCTION with Expr.y.pWin set */ +#define EP_Subrtn 0x2000000 /* Uses Expr.y.sub. TK_IN, _SELECT, or _EXISTS */ +#define EP_Quoted 0x4000000 /* TK_ID was originally quoted */ +#define EP_Static 0x8000000 /* Held in memory not obtained from malloc() */ +#define EP_IsTrue 0x10000000 /* Always has boolean value of TRUE */ +#define EP_IsFalse 0x20000000 /* Always has boolean value of FALSE */ +#define EP_Indirect 0x40000000 /* Contained within a TRIGGER or a VIEW */ /* ** The EP_Propagate mask is a set of properties that automatically propagate diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a78d5676c7..511a9c8a66 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2741,10 +2741,16 @@ deserialize_error: } /* - ** $db function NAME [-argcount N] [-deterministic] SCRIPT + ** $db function NAME [OPTIONS] SCRIPT ** ** Create a new SQL function called NAME. Whenever that function is ** called, invoke SCRIPT to evaluate the function. + ** + ** Options: + ** --argcount N Function has exactly N arguments + ** --deterministic The function is pure + ** --directonly Prohibit use inside triggers and views + ** --returntype TYPE Specify the return type of the function */ case DB_FUNCTION: { int flags = SQLITE_UTF8; @@ -2777,6 +2783,9 @@ deserialize_error: if( n>1 && strncmp(z, "-deterministic",n)==0 ){ flags |= SQLITE_DETERMINISTIC; }else + if( n>1 && strncmp(z, "-directonly",n)==0 ){ + flags |= SQLITE_DIRECTONLY; + }else if( n>1 && strncmp(z, "-returntype", n)==0 ){ const char *azType[] = {"integer", "real", "text", "blob", "any", 0}; assert( SQLITE_INTEGER==1 && SQLITE_FLOAT==2 && SQLITE_TEXT==3 ); @@ -2792,7 +2801,8 @@ deserialize_error: eType++; }else{ Tcl_AppendResult(interp, "bad option \"", z, - "\": must be -argcount, -deterministic or -returntype", (char*)0 + "\": must be -argcount, -deterministic, -directonly," + " or -returntype", (char*)0 ); return TCL_ERROR; } diff --git a/src/treeview.c b/src/treeview.c index 753f214899..6dfdccd7ee 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -557,10 +557,10 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ #endif } if( pExpr->op==TK_AGG_FUNCTION ){ - sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q", - pExpr->op2, pExpr->u.zToken); + sqlite3TreeViewLine(pView, "AGG_FUNCTION%d %Q%s", + pExpr->op2, pExpr->u.zToken, zFlgs); }else{ - sqlite3TreeViewLine(pView, "FUNCTION %Q", pExpr->u.zToken); + sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); diff --git a/test/func.test b/test/func.test index 579bad8e44..7315af322a 100644 --- a/test/func.test +++ b/test/func.test @@ -1419,7 +1419,45 @@ do_execsql_test func-32.150 { SELECT test_frombind(x.a,y.b,x.c,:123,y.e,x.f,$xyz+y.f) FROM t1 x, t1 y; } {8} - +# 2019-08-15 +# Direct-only functions. +# +proc testdirectonly {x} {return [expr {$x*2}]} +do_test func-33.1 { + db func testdirectonly -directonly testdirectonly + db eval {SELECT testdirectonly(15)} +} {30} +do_catchsql_test func-33.2 { + CREATE VIEW v33(y) AS SELECT testdirectonly(15); + SELECT * FROM v33; +} {1 {testdirectonly() prohibited in triggers and views}} +do_execsql_test func-33.3 { + SELECT * FROM (SELECT testdirectonly(15)) AS v33; +} {30} +do_execsql_test func-33.4 { + WITH c(x) AS (SELECT testdirectonly(15)) + SELECT * FROM c; +} {30} +do_catchsql_test func-33.5 { + WITH c(x) AS (SELECT * FROM v33) + SELECT * FROM c; +} {1 {testdirectonly() prohibited in triggers and views}} +do_execsql_test func-33.10 { + CREATE TABLE t33a(a,b); + CREATE TABLE t33b(x,y); + CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN + INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b); + END; +} {} +do_catchsql_test func-33.11 { + INSERT INTO t33a VALUES(1,2); +} {1 {testdirectonly() prohibited in triggers and views}} +do_execsql_test func-33.20 { + ALTER TABLE t33a RENAME COLUMN a TO aaa; + SELECT sql FROM sqlite_master WHERE name='r1'; +} {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN + INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b); + END}} finish_test diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 319737426f..ec0312254c 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -789,7 +789,7 @@ do_test 17.6.2 { do_test 17.6.3 { list [catch { db function xyz -n object ret } msg] $msg -} {1 {bad option "-n": must be -argcount, -deterministic or -returntype}} +} {1 {bad option "-n": must be -argcount, -deterministic, -directonly, or -returntype}} # 2019-02-28: The "bind_fallback" command. # From 11d88e68abdf23f131dca81ad8d3517a5cf8449b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 21:27:20 +0000 Subject: [PATCH 012/112] Add the SQLITE_DBCONFIG_ENABLE_VIEW option, together with a "db config" command in the TCL interface that can access that option as well as all the other sqlite3_db_config() boolean options. FossilOrigin-Name: 61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 --- manifest | 26 +++++----- manifest.uuid | 2 +- src/main.c | 2 + src/select.c | 4 ++ src/shell.c.in | 1 + src/sqlite.h.in | 14 +++++- src/sqliteInt.h | 13 ++--- src/tclsqlite.c | 114 +++++++++++++++++++++++++++++++++++--------- test/tclsqlite.test | 2 +- test/view.test | 12 +++++ 10 files changed, 146 insertions(+), 44 deletions(-) diff --git a/manifest b/manifest index 7d4def8408..de79942910 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\soptional\s"sz=N"\sparameter\sthat\scan\sbe\smanually\sadded\sto\sthe\nend\sof\san\ssqlite_stat1\sentry\sdoes\snot\shave\san\sN\svalue\sthat\sis\stoo\ssmall.\nTicket\s[e4598ecbdd18bd82] -D 2019-08-15T14:35:45.987 +C Add\sthe\sSQLITE_DBCONFIG_ENABLE_VIEW\soption,\stogether\swith\sa\s"db\sconfig"\ncommand\sin\sthe\sTCL\sinterface\sthat\scan\saccess\sthat\soption\sas\swell\sas\sall\sthe\nother\ssqlite3_db_config()\sboolean\soptions. +D 2019-08-15T21:27:20.669 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c -F src/main.c 3add6433e077635dac5579edaf7b3942e3ff3dda5588c49c0edd7abea2096482 +F src/main.c 9465ba2bfc021f5c2ec1f58fc97c55b123d277ad0993c49a2f333df9da483f8f F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -523,16 +523,16 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 11087458ec2af5c4b377559ea0462c2ab842e02badd35b21a8d67257c4e0b117 -F src/shell.c.in 66cd8289adbcd159ca67872c242990ca6bed29fe80be7ebf9c6a1c068249a41e -F src/sqlite.h.in 1fe019ae55182040e6ea10c89ddbb8d24c1b1015c423da53e55205398a65a906 +F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 +F src/shell.c.in b748cfb4277fe1952609d688b181b152dd5920425a83dab1baddbfdcb722346c +F src/sqlite.h.in fe09e2452f68148dcd2724fa1aefe0939802b4fab89355fb194aa40126ac4b51 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h 4875fb443102c9d92ed1cb23b7fb6e2d97714591f02725d595576ef316596b94 +F src/sqliteInt.h d8e878fa1cb949ee8943f51965cbb917acdb4cc1238af8481eb839d11bf34d0a F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c cfe7f93daf9d8787f65e099efb67d7cdfc2c35236dec5d3f6758520bd3519424 +F src/tclsqlite.c 172792eb66e9a8985e8a246e689318cadbda50e10c13f0e51eea32215c6c9161 F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -1388,7 +1388,7 @@ F test/tabfunc01.test 20e98ffe55f35d8d33fd834ca8bf9d4b637e560af8fcd00464b4154d90 F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 -F test/tclsqlite.test 5a06962d8f18edf4703931f6b7dacd83678d02fa5c8ced9a7958c007ad58626a +F test/tclsqlite.test f7bacdbe12bc208e0fe81b5cf5d712331d52f724917a6b4810c4cd686202843e F test/tempdb.test 4cdaa23ddd8acb4d79cbb1b68ccdfd09b0537aaba909ca69a876157c2a2cbd08 F test/tempdb2.test 353864e96fd3ae2f70773d0ffbf8b1fe48589b02c2ec05013b540879410c3440 F test/tempfault.test 0c0d349c9a99bf5f374655742577f8712c647900 @@ -1610,7 +1610,7 @@ F test/vacuum5.test 263b144d537e92ad8e9ca8a73cc6e1583f41cfd0dda9432b87f7806174a2 F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 -F test/view.test c1e64ff5a860fdbb7b52add0996af2ee1af563ddf2e86b964d15d04d81a001be +F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5 F test/vtab1.test efb4c4a45146193d6d55fb85f7162febd6423f29c72ede09bb96383f49e3abc1 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e @@ -1836,7 +1836,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 4f5b2d938194fab7627486e2ced633def2c90d9d3328e3700612feb9dbfa3d9a -R e211e009e748f2e64e3d39bc31b03be2 +P 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 +R 039c157cf6533868154794e96c549de4 U drh -Z bec392cb43d1df3c3b62ac4b05f24424 +Z 9ba4f898522b0ea8e4f41f060393ee57 diff --git a/manifest.uuid b/manifest.uuid index 7672348cd3..6e0115e877 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 \ No newline at end of file +61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 \ No newline at end of file diff --git a/src/main.c b/src/main.c index 06a55eca02..ecc7e5c518 100644 --- a/src/main.c +++ b/src/main.c @@ -836,6 +836,7 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ } aFlagOp[] = { { SQLITE_DBCONFIG_ENABLE_FKEY, SQLITE_ForeignKeys }, { SQLITE_DBCONFIG_ENABLE_TRIGGER, SQLITE_EnableTrigger }, + { SQLITE_DBCONFIG_ENABLE_VIEW, SQLITE_EnableView }, { SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER, SQLITE_Fts3Tokenizer }, { SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION, SQLITE_LoadExtension }, { SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE, SQLITE_NoCkptOnClose }, @@ -3075,6 +3076,7 @@ static int openDatabase( db->nMaxSorterMmap = 0x7FFFFFFF; db->flags |= SQLITE_ShortColNames | SQLITE_EnableTrigger + | SQLITE_EnableView | SQLITE_CacheSpill /* The SQLITE_DQS compile-time option determines the default settings diff --git a/src/select.c b/src/select.c index ca1256d160..bd8fee87ed 100644 --- a/src/select.c +++ b/src/select.c @@ -4906,6 +4906,10 @@ static int selectExpander(Walker *pWalker, Select *p){ u8 eCodeOrig = pWalker->eCode; if( sqlite3ViewGetColumnNames(pParse, pTab) ) return WRC_Abort; assert( pFrom->pSelect==0 ); + if( pTab->pSelect && (db->flags & SQLITE_EnableView)==0 ){ + sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited", + pTab->zName); + } pFrom->pSelect = sqlite3SelectDup(db, pTab->pSelect, 0); nCol = pTab->nCol; pTab->nCol = -1; diff --git a/src/shell.c.in b/src/shell.c.in index 19280e318d..0ffd9aece7 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -7135,6 +7135,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } aDbConfig[] = { { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, + { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, diff --git a/src/sqlite.h.in b/src/sqlite.h.in index d68cef2490..4b1d4723bb 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -2093,6 +2093,17 @@ struct sqlite3_mem_methods { ** following this call. The second parameter may be a NULL pointer, in ** which case the trigger setting is not reported back. ** +** [[SQLITE_DBCONFIG_ENABLE_VIEW]] +**
SQLITE_DBCONFIG_ENABLE_VIEW
+**
^This option is used to enable or disable [CREATE VIEW | views]. +** There should be two additional arguments. +** The first argument is an integer which is 0 to disable views, +** positive to enable views or negative to leave the setting unchanged. +** The second parameter is a pointer to an integer into which +** is written 0 or 1 to indicate whether views are disabled or enabled +** following this call. The second parameter may be a NULL pointer, in +** which case the view setting is not reported back.
+** ** [[SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER]] **
SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER
**
^This option is used to enable or disable the @@ -2265,7 +2276,8 @@ struct sqlite3_mem_methods { #define SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012 /* int int* */ #define SQLITE_DBCONFIG_DQS_DML 1013 /* int int* */ #define SQLITE_DBCONFIG_DQS_DDL 1014 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1014 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ +#define SQLITE_DBCONFIG_MAX 1015 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d6746aadca..52c982159b 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1537,16 +1537,17 @@ struct sqlite3 { #define SQLITE_Defensive 0x10000000 /* Input SQL is likely hostile */ #define SQLITE_DqsDDL 0x20000000 /* dbl-quoted strings allowed in DDL*/ #define SQLITE_DqsDML 0x40000000 /* dbl-quoted strings allowed in DML*/ +#define SQLITE_EnableView 0x80000000 /* Enable the use of views */ /* Flags used only if debugging */ #define HI(X) ((u64)(X)<<32) #ifdef SQLITE_DEBUG -#define SQLITE_SqlTrace HI(0x0001) /* Debug print SQL as it executes */ -#define SQLITE_VdbeListing HI(0x0002) /* Debug listings of VDBE progs */ -#define SQLITE_VdbeTrace HI(0x0004) /* True to trace VDBE execution */ -#define SQLITE_VdbeAddopTrace HI(0x0008) /* Trace sqlite3VdbeAddOp() calls */ -#define SQLITE_VdbeEQP HI(0x0010) /* Debug EXPLAIN QUERY PLAN */ -#define SQLITE_ParserTrace HI(0x0020) /* PRAGMA parser_trace=ON */ +#define SQLITE_SqlTrace HI(0x0100000) /* Debug print SQL as it executes */ +#define SQLITE_VdbeListing HI(0x0200000) /* Debug listings of VDBE progs */ +#define SQLITE_VdbeTrace HI(0x0400000) /* True to trace VDBE execution */ +#define SQLITE_VdbeAddopTrace HI(0x0800000) /* Trace sqlite3VdbeAddOp() calls */ +#define SQLITE_VdbeEQP HI(0x1000000) /* Debug EXPLAIN QUERY PLAN */ +#define SQLITE_ParserTrace HI(0x2000000) /* PRAGMA parser_trace=ON */ #endif /* diff --git a/src/tclsqlite.c b/src/tclsqlite.c index a78d5676c7..d296af8f9f 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -1917,33 +1917,33 @@ static int SQLITE_TCLAPI DbObjCmd( "authorizer", "backup", "bind_fallback", "busy", "cache", "changes", "close", "collate", "collation_needed", - "commit_hook", "complete", "copy", - "deserialize", "enable_load_extension", "errorcode", - "eval", "exists", "function", - "incrblob", "interrupt", "last_insert_rowid", - "nullvalue", "onecolumn", "preupdate", - "profile", "progress", "rekey", - "restore", "rollback_hook", "serialize", - "status", "timeout", "total_changes", - "trace", "trace_v2", "transaction", - "unlock_notify", "update_hook", "version", - "wal_hook", 0 + "commit_hook", "complete", "config", + "copy", "deserialize", "enable_load_extension", + "errorcode", "eval", "exists", + "function", "incrblob", "interrupt", + "last_insert_rowid", "nullvalue", "onecolumn", + "preupdate", "profile", "progress", + "rekey", "restore", "rollback_hook", + "serialize", "status", "timeout", + "total_changes", "trace", "trace_v2", + "transaction", "unlock_notify", "update_hook", + "version", "wal_hook", 0 }; enum DB_enum { DB_AUTHORIZER, DB_BACKUP, DB_BIND_FALLBACK, DB_BUSY, DB_CACHE, DB_CHANGES, DB_CLOSE, DB_COLLATE, DB_COLLATION_NEEDED, - DB_COMMIT_HOOK, DB_COMPLETE, DB_COPY, - DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION,DB_ERRORCODE, - DB_EVAL, DB_EXISTS, DB_FUNCTION, - DB_INCRBLOB, DB_INTERRUPT, DB_LAST_INSERT_ROWID, - DB_NULLVALUE, DB_ONECOLUMN, DB_PREUPDATE, - DB_PROFILE, DB_PROGRESS, DB_REKEY, - DB_RESTORE, DB_ROLLBACK_HOOK, DB_SERIALIZE, - DB_STATUS, DB_TIMEOUT, DB_TOTAL_CHANGES, - DB_TRACE, DB_TRACE_V2, DB_TRANSACTION, - DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, DB_VERSION, - DB_WAL_HOOK + DB_COMMIT_HOOK, DB_COMPLETE, DB_CONFIG, + DB_COPY, DB_DESERIALIZE, DB_ENABLE_LOAD_EXTENSION, + DB_ERRORCODE, DB_EVAL, DB_EXISTS, + DB_FUNCTION, DB_INCRBLOB, DB_INTERRUPT, + DB_LAST_INSERT_ROWID, DB_NULLVALUE, DB_ONECOLUMN, + DB_PREUPDATE, DB_PROFILE, DB_PROGRESS, + DB_REKEY, DB_RESTORE, DB_ROLLBACK_HOOK, + DB_SERIALIZE, DB_STATUS, DB_TIMEOUT, + DB_TOTAL_CHANGES, DB_TRACE, DB_TRACE_V2, + DB_TRANSACTION, DB_UNLOCK_NOTIFY, DB_UPDATE_HOOK, + DB_VERSION, DB_WAL_HOOK }; /* don't leave trailing commas on DB_enum, it confuses the AIX xlc compiler */ @@ -2331,6 +2331,76 @@ static int SQLITE_TCLAPI DbObjCmd( break; } + /* $db config ?OPTION? ?BOOLEAN? + ** + ** Configure the database connection using the sqlite3_db_config() + ** interface. + */ + case DB_CONFIG: { + static const struct DbConfigChoices { + const char *zName; + int op; + } aDbConfig[] = { + { "enable_fkey", SQLITE_DBCONFIG_ENABLE_FKEY }, + { "enable_trigger", SQLITE_DBCONFIG_ENABLE_TRIGGER }, + { "enable_view", SQLITE_DBCONFIG_ENABLE_VIEW }, + { "fts3_tokenizer", SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER }, + { "load_extension", SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION }, + { "no_ckpt_on_close", SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE }, + { "enable_qpsg", SQLITE_DBCONFIG_ENABLE_QPSG }, + { "trigger_eqp", SQLITE_DBCONFIG_TRIGGER_EQP }, + { "reset_database", SQLITE_DBCONFIG_RESET_DATABASE }, + { "defensive", SQLITE_DBCONFIG_DEFENSIVE }, + { "writable_schema", SQLITE_DBCONFIG_WRITABLE_SCHEMA }, + { "legacy_alter_table", SQLITE_DBCONFIG_LEGACY_ALTER_TABLE }, + { "dqs_dml", SQLITE_DBCONFIG_DQS_DML }, + { "dqs_ddl", SQLITE_DBCONFIG_DQS_DDL }, + }; + Tcl_Obj *pResult; + int ii; + if( objc>4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "?OPTION? ?BOOLEAN?"); + return TCL_ERROR; + } + if( objc==2 ){ + /* With no arguments, list all configuration options and with the + ** current value */ + pResult = Tcl_NewListObj(0,0); + for(ii=0; iidb, aDbConfig[ii].op, -1, &v); + if( rc!=SQLITE_OK ) continue; + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewStringObj(aDbConfig[ii].zName,-1)); + Tcl_ListObjAppendElement(interp, pResult, + Tcl_NewIntObj(v)); + } + }else{ + const char *zOpt = Tcl_GetString(objv[2]); + int rc; + int onoff = -1; + int v = 0; + if( zOpt[0]=='-' ) zOpt++; + for(ii=0; ii=sizeof(aDbConfig)/sizeof(aDbConfig[0]) ){ + Tcl_AppendResult(interp, "unknown config option: \"", zOpt, + "\"", (void*)0); + return TCL_ERROR; + } + if( objc==4 ){ + if( Tcl_GetBooleanFromObj(interp, objv[3], &onoff) ){ + return TCL_ERROR; + } + } + rc = sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); + pResult = Tcl_NewIntObj(v); + } + Tcl_SetObjResult(interp, pResult); + break; + } + /* $db copy conflict-algorithm table filename ?SEPARATOR? ?NULLINDICATOR? ** ** Copy data into table from filename, optionally using SEPARATOR diff --git a/test/tclsqlite.test b/test/tclsqlite.test index 319737426f..02f8dd9db8 100644 --- a/test/tclsqlite.test +++ b/test/tclsqlite.test @@ -42,7 +42,7 @@ do_test tcl-1.1.1 { do_test tcl-1.2 { set v [catch {db bogus} msg] lappend v $msg -} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} +} {1 {bad option "bogus": must be authorizer, backup, bind_fallback, busy, cache, changes, close, collate, collation_needed, commit_hook, complete, config, copy, deserialize, enable_load_extension, errorcode, eval, exists, function, incrblob, interrupt, last_insert_rowid, nullvalue, onecolumn, preupdate, profile, progress, rekey, restore, rollback_hook, serialize, status, timeout, total_changes, trace, trace_v2, transaction, unlock_notify, update_hook, version, or wal_hook}} do_test tcl-1.2.1 { set v [catch {db cache bogus} msg] lappend v $msg diff --git a/test/view.test b/test/view.test index 490dc65a68..b3f50dc008 100644 --- a/test/view.test +++ b/test/view.test @@ -38,6 +38,18 @@ do_test view-1.1 { SELECT * FROM v1 ORDER BY a; } } {1 2 4 5 7 8} +do_test view-1.1.100 { + db config enable_view off + catchsql { + SELECT * FROM v1 ORDER BY a; + } +} {1 {access to view "v1" prohibited}} +do_test view-1.1.110 { + db config enable_view on + catchsql { + SELECT * FROM v1 ORDER BY a; + } +} {0 {1 2 4 5 7 8}} do_test view-1.2 { catchsql { ROLLBACK; From 4043cfef7590c5a8b90cfbee44b45f6ca8bbf176 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 15 Aug 2019 23:11:42 +0000 Subject: [PATCH 013/112] Fix harmless compiler warnings in the TCL interface. FossilOrigin-Name: f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/tclsqlite.c | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index de79942910..d1c778bab0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_DBCONFIG_ENABLE_VIEW\soption,\stogether\swith\sa\s"db\sconfig"\ncommand\sin\sthe\sTCL\sinterface\sthat\scan\saccess\sthat\soption\sas\swell\sas\sall\sthe\nother\ssqlite3_db_config()\sboolean\soptions. -D 2019-08-15T21:27:20.669 +C Fix\sharmless\scompiler\swarnings\sin\sthe\sTCL\sinterface. +D 2019-08-15T23:11:42.012 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -532,7 +532,7 @@ F src/sqliteInt.h d8e878fa1cb949ee8943f51965cbb917acdb4cc1238af8481eb839d11bf34d F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 -F src/tclsqlite.c 172792eb66e9a8985e8a246e689318cadbda50e10c13f0e51eea32215c6c9161 +F src/tclsqlite.c 2170b327318f888aa3ed861a6ef3e88c6906839f584ab2b01552c8b19db6f9e5 F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 @@ -1836,7 +1836,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 98357d8c1263920b33a3648ef9214a63c99728bafa7a8d3dd6a1241b2303fd42 -R 039c157cf6533868154794e96c549de4 +P 61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 +R ad07753edbdb65bae98d204ed9a7c2cb U drh -Z 9ba4f898522b0ea8e4f41f060393ee57 +Z f83b80ce99769ab61a563e51215a8c91 diff --git a/manifest.uuid b/manifest.uuid index 6e0115e877..5e9e71cf03 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 \ No newline at end of file +f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f \ No newline at end of file diff --git a/src/tclsqlite.c b/src/tclsqlite.c index d296af8f9f..8b32bf82de 100644 --- a/src/tclsqlite.c +++ b/src/tclsqlite.c @@ -2368,8 +2368,7 @@ static int SQLITE_TCLAPI DbObjCmd( pResult = Tcl_NewListObj(0,0); for(ii=0; iidb, aDbConfig[ii].op, -1, &v); - if( rc!=SQLITE_OK ) continue; + sqlite3_db_config(pDb->db, aDbConfig[ii].op, -1, &v); Tcl_ListObjAppendElement(interp, pResult, Tcl_NewStringObj(aDbConfig[ii].zName,-1)); Tcl_ListObjAppendElement(interp, pResult, @@ -2377,7 +2376,6 @@ static int SQLITE_TCLAPI DbObjCmd( } }else{ const char *zOpt = Tcl_GetString(objv[2]); - int rc; int onoff = -1; int v = 0; if( zOpt[0]=='-' ) zOpt++; @@ -2394,7 +2392,7 @@ static int SQLITE_TCLAPI DbObjCmd( return TCL_ERROR; } } - rc = sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); + sqlite3_db_config(pDb->db, aDbConfig[ii].op, onoff, &v); pResult = Tcl_NewIntObj(v); } Tcl_SetObjResult(interp, pResult); From 15750a26fa7127af7b1aa3e3a2046f5379eaca43 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 16 Aug 2019 21:07:19 +0000 Subject: [PATCH 014/112] Add support for using indexes for some ORDER BY clauses that use non-default NULL handling. Still some problems on this branch. FossilOrigin-Name: 81069d7196857e909c94195d67388f71bc9f832eafd9156d8c5cdddb63513b4a --- manifest | 22 +++++------- manifest.uuid | 2 +- src/where.c | 32 ++++++++++++----- src/whereInt.h | 6 ++-- src/wherecode.c | 94 ++++++++++++++++++++++++++++-------------------- test/nulls1.test | 46 ++++++++++++++++++++---- 6 files changed, 133 insertions(+), 69 deletions(-) diff --git a/manifest b/manifest index 168990dfe6..32086b8fc1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Experimental\simplementation\sof\sNULLS\sFIRST/LAST.\sThis\sbranch\sstill\shas\sproblems\s-\sthe\smost\ssignificant\sof\swhich\sis\sthat\sORDER\sBY\sclauses\swith\sa\snon-default\sNULLS\sFIRST/LAST\squalifier\scan\snever\suse\san\sindex. -D 2019-08-12T16:36:38.041 +C Add\ssupport\sfor\susing\sindexes\sfor\ssome\sORDER\sBY\sclauses\sthat\suse\snon-default\sNULL\shandling.\sStill\ssome\sproblems\son\sthis\sbranch. +D 2019-08-16T21:07:19.697 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,9 +609,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 83fc2acadfbb1c86501fc0847fd068040ecd9a250a2fc0b81bab5698aa4bc72d -F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb -F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0 +F src/where.c c4ec116264555c512edf49ef7244113cad5028bd1ea70f3500982b7c10f9a121 +F src/whereInt.h 807766a6a92893dbba8a887e5b13466d2257ce07a84cf1be0aae2c41aee3bf4f +F src/wherecode.c 58889def15cb57375a5f4f83db6d2b28b372d87cf1b4f23e47928a4847a94ae4 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc F src/window.c 4d56fc1e3dbd3a4fa0653b3f48a3ad7066d0da91d0273cff8bab13c3412ddaf5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1182,7 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test eac9f46d9bf7a3883700bbc063e8a64fa2f4677ea64f12e173d3052d635f6b23 +F test/nulls1.test 522f0da68881b6ac616b1361fbd5a9897bd366597809495143968af743e3318c F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1837,11 +1837,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 636ca4472c9f41eb3989f28854d4968867837399a2092f389d1b814d98cccbae -R 6d8a33d8edc53ea630705f876c1c3795 -T *branch * nulls-last -T *sym-nulls-last * -T +closed 8174b2ca587e87083950ab21a47b4b4fe4bf309a8e16a82d4dc26d2c471e28cc -T -sym-trunk * +P 07babb0f897fc8c9cb5b30481899c32fdd743f3f3ca508d8d957826252107dd5 +R 39b3bc3a5371ac212f22834b463e006c U dan -Z 02a41ef53191d3d08ca3291791a40934 +Z d691c31e642275ddd26770c7946ed411 diff --git a/manifest.uuid b/manifest.uuid index 3ff2df6757..ef8a25f596 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -07babb0f897fc8c9cb5b30481899c32fdd743f3f3ca508d8d957826252107dd5 \ No newline at end of file +81069d7196857e909c94195d67388f71bc9f832eafd9156d8c5cdddb63513b4a \ No newline at end of file diff --git a/src/where.c b/src/where.c index 202db50bfc..663dcdc4e0 100644 --- a/src/where.c +++ b/src/where.c @@ -3798,7 +3798,7 @@ static i8 wherePathSatisfiesOrderBy( */ if( pIndex ){ iColumn = pIndex->aiColumn[j]; - revIdx = pIndex->aSortOrder[j]; + revIdx = pIndex->aSortOrder[j] & KEYINFO_ORDER_DESC; if( iColumn==pIndex->pTable->iPKey ) iColumn = XN_ROWID; }else{ iColumn = XN_ROWID; @@ -3836,7 +3836,6 @@ static i8 wherePathSatisfiesOrderBy( continue; } } - if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) continue; if( iColumn!=XN_ROWID ){ pColl = sqlite3ExprNNCollSeq(pWInfo->pParse, pOrderBy->a[i].pExpr); if( sqlite3StrICmp(pColl->zName, pIndex->azColl[j])!=0 ) continue; @@ -3850,24 +3849,29 @@ static i8 wherePathSatisfiesOrderBy( if( isMatch && (wctrlFlags & WHERE_GROUPBY)==0 ){ /* Make sure the sort order is compatible in an ORDER BY clause. ** Sort order is irrelevant for a GROUP BY clause. */ - assert( (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL)==0 ); if( revSet ){ - if( (rev ^ revIdx)!=pOrderBy->a[i].sortFlags ) isMatch = 0; + if( (rev ^ revIdx)!=(pOrderBy->a[i].sortFlags&KEYINFO_ORDER_DESC) ){ + isMatch = 0; + } }else{ - rev = revIdx ^ pOrderBy->a[i].sortFlags; + rev = revIdx ^ (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_DESC); if( rev ) *pRevMask |= MASKBIT(iLoop); revSet = 1; } } + if( isMatch && (pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL) ){ + if( j==pLoop->u.btree.nEq ){ + pLoop->wsFlags |= WHERE_BIGNULL_SORT; + }else{ + isMatch = 0; + } + } if( isMatch ){ if( iColumn==XN_ROWID ){ testcase( distinctColumns==0 ); distinctColumns = 1; } obSat |= MASKBIT(i); - if( (wctrlFlags & WHERE_ORDERBY_MIN) && j==pLoop->u.btree.nEq ){ - pLoop->wsFlags |= WHERE_MIN_ORDERED; - } }else{ /* No match found */ if( j==0 || jwsFlags & WHERE_CONSTRAINT)!=0 && (pLoop->wsFlags & (WHERE_COLUMN_RANGE|WHERE_SKIPSCAN))==0 + && (pLoop->wsFlags & WHERE_BIGNULL_SORT)==0 && (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 && pWInfo->eDistinct!=WHERE_DISTINCT_ORDERED ){ @@ -5202,6 +5207,17 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeCoverageIf(v, pLevel->op==OP_Next); VdbeCoverageIf(v, pLevel->op==OP_Prev); VdbeCoverageIf(v, pLevel->op==OP_VNext); + if( pLevel->regBignull ){ + sqlite3VdbeResolveLabel(v, pLevel->addrBignull); + addr = sqlite3VdbeAddOp1(v, OP_If, pLevel->regBignull); + sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->regBignull); + sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->p2-1); + sqlite3VdbeChangeP5(v, pLevel->p5); + VdbeCoverage(v); + VdbeCoverageIf(v, pLevel->op==OP_Next); + VdbeCoverageIf(v, pLevel->op==OP_Prev); + sqlite3VdbeJumpHere(v, addr); + } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); #endif diff --git a/src/whereInt.h b/src/whereInt.h index 09e45024c1..f402a18f8c 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -71,13 +71,15 @@ struct WhereLevel { int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ + int regBignull; /* big-null flag register */ + int addrBignull; /* Jump here for next part of big-null scan */ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ int addrLikeRep; /* LIKE range processing address */ #endif u8 iFrom; /* Which entry in the FROM clause */ u8 op, p3, p5; /* Opcode, P3 & P5 of the opcode that ends the loop */ - int p1, p2; /* Operands of the opcode used to ends the loop */ + int p1, p2; /* Operands of the opcode used to end the loop */ union { /* Information that depends on pWLoop->wsFlags */ struct { int nIn; /* Number of entries in aInLoop[] */ @@ -586,6 +588,6 @@ void sqlite3WhereTabFuncArgs(Parse*, struct SrcList_item*, WhereClause*); #define WHERE_UNQ_WANTED 0x00010000 /* WHERE_ONEROW would have been helpful*/ #define WHERE_PARTIALIDX 0x00020000 /* The automatic index is partial */ #define WHERE_IN_EARLYOUT 0x00040000 /* Perhaps quit IN loops early */ -#define WHERE_MIN_ORDERED 0x00080000 /* Column nEq of index is min() expr */ +#define WHERE_BIGNULL_SORT 0x00080000 /* Column nEq of index is BIGNULL */ #endif /* !defined(SQLITE_WHEREINT_H) */ diff --git a/src/wherecode.c b/src/wherecode.c index c781b06c15..d4f26a3af0 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1549,31 +1549,12 @@ Bitmask sqlite3WhereCodeOneLoopStart( u8 bSeekPastNull = 0; /* True to seek past initial nulls */ u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ int omitTable; /* True if we use the index only */ - + int regBignull = 0; pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; assert( nEq>=pLoop->nSkip ); - /* If this loop satisfies a sort order (pOrderBy) request that - ** was passed to this function to implement a "SELECT min(x) ..." - ** query, then the caller will only allow the loop to run for - ** a single iteration. This means that the first row returned - ** should not have a NULL value stored in 'x'. If column 'x' is - ** the first one after the nEq equality constraints in the index, - ** this requires some special handling. - */ - assert( (pWInfo->pOrderBy!=0 && pWInfo->pOrderBy->nExpr==1) - || (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)==0 ); - if( pLoop->wsFlags & WHERE_MIN_ORDERED ){ - assert( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN) ); - assert( pWInfo->nOBSat ); - assert( pIdx->nColumn>nEq ); - assert( pLoop->nSkip==0 ); - bSeekPastNull = 1; - nExtraReg = 1; - } - /* Find any inequality constraint terms for the start and end ** of the range. */ @@ -1614,6 +1595,26 @@ Bitmask sqlite3WhereCodeOneLoopStart( } assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); + /* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses + ** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS + ** FIRST). In both cases separate ordered scans are made of those + ** index entries for which the column is null and for those for which + ** it is not. For an ASC sort, the non-NULL entries are scanned first. + ** For DESC, NULL entries are scanned first. + */ + addrNxt = pLevel->addrNxt; + if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0 + && (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0 + ){ + assert( bSeekPastNull==0 && nExtraReg==0 && nBtm==0 && nTop==0 ); + assert( pRangeEnd==0 && pRangeStart==0 ); + assert( pLoop->nSkip==0 ); + nExtraReg = 1; + bSeekPastNull = 1; + pLevel->regBignull = regBignull = ++pParse->nMem; + addrNxt = pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); + } + /* If we are doing a reverse order scan on an ascending index, or ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). @@ -1636,7 +1637,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( zStartAff && nTop ){ zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); } - addrNxt = pLevel->addrNxt; testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); @@ -1674,6 +1674,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( nConstraint++; startEq = 0; start_constraints = 1; + }else if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + start_constraints = 1; + nConstraint++; } codeApplyAffinity(pParse, regBase, nConstraint - bSeekPastNull, zStartAff); if( pLoop->nSkip>0 && nConstraint==pLoop->nSkip ){ @@ -1684,6 +1688,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); } + if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull); + } + op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); @@ -1695,23 +1703,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); - if( bSeekPastNull && (pLoop->wsFlags & WHERE_TOP_LIMIT)==0 ){ - /* If bSeekPastNull is set only to skip past the NULL values for - ** a query like "SELECT min(a), b FROM t1", then add code so that - ** if there are no rows with (a IS NOT NULL), then do the seek - ** without jumping past NULLs instead. This allows the code in - ** select.c to pick a value for "b" in the above query. */ - assert( startEq==0 && (op==OP_SeekGT || op==OP_SeekLT) ); - assert( (pWInfo->wctrlFlags&WHERE_ORDERBY_MIN)!=0 && pWInfo->nOBSat>0 ); - sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1); + if( regBignull ){ sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); - - op = aStartOp[(start_constraints<<2) + (1<<1) + bRev]; - assert( op==OP_SeekGE || op==OP_SeekLE ); - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); - VdbeCoverage(v); - VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); - VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + if( bStopAtNull ){ + start_constraints = (nConstraint>1); + op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint-1); + }else{ + op = aStartOp[(start_constraints<<2) + ((!startEq)<<1) + bRev]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + } } } @@ -1744,8 +1745,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( endEq = 1; } }else if( bStopAtNull ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); - endEq = 0; + if( regBignull==0 ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); + endEq = 0; + } nConstraint++; } sqlite3DbFree(db, zStartAff); @@ -1756,6 +1759,9 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ + if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+3); + } op = aEndOp[bRev*2 + endEq]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); @@ -1763,6 +1769,16 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } + if( regBignull ){ + sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+2); + if( bStopAtNull ){ + op = aEndOp[bRev*2 + 0]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + }else{ + op = aEndOp[bRev*2 + endEq]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint+1); + } + } if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ sqlite3VdbeAddOp2(v, OP_SeekHit, iIdxCur, 1); diff --git a/test/nulls1.test b/test/nulls1.test index 7b355e9a85..866ed2b296 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -11,21 +11,19 @@ # This file implements regression tests for SQLite library. # -#################################################### -# DO NOT EDIT! THIS FILE IS AUTOMATICALLY GENERATED! -#################################################### - set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix nulls1 +if 1 { + do_execsql_test 1.0 { DROP TABLE IF EXISTS t3; CREATE TABLE t3(a INTEGER); INSERT INTO t3 VALUES(NULL), (10), (30), (20), (NULL); } {} -for {set a 0} {$a < 2} {incr a} { +for {set a 0} {$a < 3} {incr a} { foreach {tn limit} { 1 "" 2 "LIMIT 10" @@ -47,7 +45,43 @@ for {set a 0} {$a < 2} {incr a} { " {30 20 10 {} {}} } - catchsql { CREATE INDEX i1 ON t3(a) } + switch $a { + 0 { + execsql { CREATE INDEX i1 ON t3(a) } + } + 1 { + execsql { DROP INDEX i1 ; CREATE INDEX i1 ON t3(a DESC) } + } + } } +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t2(a, b, c); + CREATE INDEX i2 ON t2(a, b); + INSERT INTO t2 VALUES(1, 1, 1); + INSERT INTO t2 VALUES(1, NULL, 2); + INSERT INTO t2 VALUES(1, NULL, 3); + INSERT INTO t2 VALUES(1, 4, 4); +} + +do_execsql_test 2.1 { + SELECT * FROM t2 WHERE a=1 ORDER BY b NULLS LAST +} { + 1 1 1 1 4 4 1 {} 2 1 {} 3 +} + +do_execsql_test 2.2 { + SELECT * FROM t2 WHERE a=1 ORDER BY b DESC NULLS FIRST +} { + 1 {} 3 + 1 {} 2 + 1 4 4 + 1 1 1 +} + + finish_test From cc5979dbd384049c1efef847e5cc22082191024b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 16 Aug 2019 22:58:29 +0000 Subject: [PATCH 015/112] Add the ability to unregister a virtual table module by invoking sqlite3_create_module() with a NULL sqlite3_module pointer. FossilOrigin-Name: 31e34fa3390196cdc3178bf120224b08df5ec58fa2c77079ede6e9461a430dad --- manifest | 24 ++++++++++---------- manifest.uuid | 2 +- src/main.c | 5 +---- src/shell.c.in | 18 +++++++++++++++ src/sqlite.h.in | 4 ++++ src/sqliteInt.h | 3 +++ src/vtab.c | 55 ++++++++++++++++++++++++++++++++++------------ test/intarray.test | 8 +++---- test/vtab1.test | 4 ++-- 9 files changed, 86 insertions(+), 37 deletions(-) diff --git a/manifest b/manifest index d1c778bab0..5feb38ed1a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings\sin\sthe\sTCL\sinterface. -D 2019-08-15T23:11:42.012 +C Add\sthe\sability\sto\sunregister\sa\svirtual\stable\smodule\sby\sinvoking\nsqlite3_create_module()\swith\sa\sNULL\ssqlite3_module\spointer. +D 2019-08-16T22:58:29.636 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -487,7 +487,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c -F src/main.c 9465ba2bfc021f5c2ec1f58fc97c55b123d277ad0993c49a2f333df9da483f8f +F src/main.c 1ffcd1890908444567471e72246f22595a8f63cfa84fa8f5ee7fc80c0d2a1863 F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -524,11 +524,11 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 14ae3326af3d8b94bd64a29e0369986f3125cf4c0dcb8f8dc1b8be2cd1bcdbaa F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 -F src/shell.c.in b748cfb4277fe1952609d688b181b152dd5920425a83dab1baddbfdcb722346c -F src/sqlite.h.in fe09e2452f68148dcd2724fa1aefe0939802b4fab89355fb194aa40126ac4b51 +F src/shell.c.in d2465e7747a014bd48a75c1bcf648e8e6cb46832dcc6e1293c5f285bc5542e8b +F src/sqlite.h.in fe836f566b3517201077f4ff69ec7379b626b311ccc6e24ad5ca11c262775ca7 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h d8e878fa1cb949ee8943f51965cbb917acdb4cc1238af8481eb839d11bf34d0a +F src/sqliteInt.h a89fe72e4a00652fdad88911e73ad376a351a477ec86a822f602863f01a495d3 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -604,7 +604,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75 F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c 1fa256c6ddad7a81e2a4dc080d015d4b0a7135767717d311298e47f6fca64bb3 +F src/vtab.c 4d833811e3784409627919899e1fd75ee08f0e5db6d9924eac9a0bfe0cb762dc F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1064,7 +1064,7 @@ F test/insert5.test 394f96728d1258f406fe5f5aeb0aaf29487c39a6 F test/insertfault.test ac63d14ea3b49c573673a572f4014b9117383a03e497c58f308b5c776e4a7f74 F test/instr.test 9a8802f28437d8ade53fedfc47b2ca599b4e48ba F test/instrfault.test 0f870b218ea17cd477bb19ed330eecdb460dd53a -F test/intarray.test 8319986182af37c8eb4879c6bfe9cf0074e9d43b193a4c728a0efa3417c53fb7 +F test/intarray.test bb976b0b3df0ebb6a2eddfb61768280440e672beba5460ed49679ea984ccf440 F test/interrupt.test 16ea879ec728cb76414c148c5f24afd5d1f91054 F test/interrupt2.test e4408ca770a6feafbadb0801e54a0dcd1a8d108d F test/intpkey.test ac71107a49a06492b69b82aafaf225400598d3c8 @@ -1611,7 +1611,7 @@ F test/vacuummem.test 7b42abb3208bd82dd23a7536588396f295a314f2 F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test 10ea54300a097d7c0337fd104abffe4a4786d1598b94017a37efe0e0d3e04dd5 -F test/vtab1.test efb4c4a45146193d6d55fb85f7162febd6423f29c72ede09bb96383f49e3abc1 +F test/vtab1.test c5d9e90ed02bcacd776dcbb7360199d290f7f53c26b484ddece543060c54319f F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 @@ -1836,7 +1836,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 61b4bccd2984f4c2cf50f58ef08677588e57aa7e079af07473b2e188d9ce4f52 -R ad07753edbdb65bae98d204ed9a7c2cb +P f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f +R cde2fc12434d097e80f94e2e70c1f8fb U drh -Z f83b80ce99769ab61a563e51215a8c91 +Z bcecf677f5410a7291761a23528080f1 diff --git a/manifest.uuid b/manifest.uuid index 5e9e71cf03..b8c13348fd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f17e72291f197a92b3e15e054271b997d45211a5a31ca4ea6c7fbb33026d5f1f \ No newline at end of file +31e34fa3390196cdc3178bf120224b08df5ec58fa2c77079ede6e9461a430dad \ No newline at end of file diff --git a/src/main.c b/src/main.c index ecc7e5c518..79a17e5a5c 100644 --- a/src/main.c +++ b/src/main.c @@ -1236,11 +1236,8 @@ void sqlite3LeaveMutexAndCloseZombie(sqlite3 *db){ #ifndef SQLITE_OMIT_VIRTUALTABLE for(i=sqliteHashFirst(&db->aModule); i; i=sqliteHashNext(i)){ Module *pMod = (Module *)sqliteHashData(i); - if( pMod->xDestroy ){ - pMod->xDestroy(pMod->pAux); - } sqlite3VtabEponymousTableClear(db, pMod); - sqlite3DbFree(db, pMod); + sqlite3VtabModuleUnref(db, pMod); } sqlite3HashClear(&db->aModule); #endif diff --git a/src/shell.c.in b/src/shell.c.in index 0ffd9aece7..494a3d7e21 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3649,6 +3649,9 @@ static const char *(azHelp[]) = { " --row Trace each row (SQLITE_TRACE_ROW)", " --close Trace connection close (SQLITE_TRACE_CLOSE)", #endif /* SQLITE_OMIT_TRACE */ +#ifdef SQLITE_DEBUG + ".unmodule NAME ... Unregister virtual table modules", +#endif ".vfsinfo ?AUX? Information about the top-level VFS", ".vfslist List all available VFSes", ".vfsname ?AUX? Print the name of the VFS stack", @@ -9401,6 +9404,21 @@ static int do_meta_command(char *zLine, ShellState *p){ }else #endif /* !defined(SQLITE_OMIT_TRACE) */ +#ifdef SQLITE_DEBUG + if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){ + int ii; + if( nArg<2 ){ + raw_printf(stderr, "Usage: .unmodule NAME ...\n"); + rc = 1; + goto meta_command_exit; + } + open_db(p, 0); + for(ii=1; iidb, azArg[ii], 0, 0); + } + }else +#endif + #if SQLITE_USER_AUTHENTICATION if( c=='u' && strncmp(azArg[0], "user", n)==0 ){ if( nArg<2 ){ diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 4b1d4723bb..e0d02b2722 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6624,6 +6624,10 @@ struct sqlite3_index_info { ** ^The sqlite3_create_module() ** interface is equivalent to sqlite3_create_module_v2() with a NULL ** destructor. +** +** ^If the third parameter (the pointer to the sqlite3_module object) is +** NULL then no new module is create and any existing modules with the +** same name are dropped. */ int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 52c982159b..07e241a1c4 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1797,6 +1797,7 @@ struct Savepoint { struct Module { const sqlite3_module *pModule; /* Callback pointers */ const char *zName; /* Name passed to create_module() */ + int nRefModule; /* Number of pointers to this object */ void *pAux; /* pAux passed to create_module() */ void (*xDestroy)(void *); /* Module destructor function */ Table *pEpoTab; /* Eponymous table for this module */ @@ -4438,6 +4439,7 @@ void sqlite3AutoLoadExtensions(sqlite3*); # define sqlite3VtabInSync(db) 0 # define sqlite3VtabLock(X) # define sqlite3VtabUnlock(X) +# define sqlite3VtabModuleUnref(D,X) # define sqlite3VtabUnlockList(X) # define sqlite3VtabSavepoint(X, Y, Z) SQLITE_OK # define sqlite3GetVTable(X,Y) ((VTable*)0) @@ -4449,6 +4451,7 @@ void sqlite3AutoLoadExtensions(sqlite3*); int sqlite3VtabCommit(sqlite3 *db); void sqlite3VtabLock(VTable *); void sqlite3VtabUnlock(VTable *); + void sqlite3VtabModuleUnref(sqlite3*,Module*); void sqlite3VtabUnlockList(sqlite3*); int sqlite3VtabSavepoint(sqlite3 *, int, int); void sqlite3VtabImportErrmsg(Vdbe*, sqlite3_vtab*); diff --git a/src/vtab.c b/src/vtab.c index 41e26ef62f..a711a7be5f 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -32,6 +32,9 @@ struct VtabCtx { ** Construct and install a Module object for a virtual table. When this ** routine is called, it is guaranteed that all appropriate locks are held ** and the module is not already part of the connection. +** +** If there already exists a module with zName, replace it with the new one. +** If pModule==0, then delete the module zName if it exists. */ Module *sqlite3VtabCreateModule( sqlite3 *db, /* Database in which module is registered */ @@ -41,25 +44,35 @@ Module *sqlite3VtabCreateModule( void (*xDestroy)(void *) /* Module destructor function */ ){ Module *pMod; - int nName = sqlite3Strlen30(zName); - pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); - if( pMod==0 ){ - sqlite3OomFault(db); + Module *pDel; + char *zCopy; + if( pModule==0 ){ + zCopy = (char*)zName; + pMod = 0; }else{ - Module *pDel; - char *zCopy = (char *)(&pMod[1]); + int nName = sqlite3Strlen30(zName); + pMod = (Module *)sqlite3Malloc(sizeof(Module) + nName + 1); + if( pMod==0 ){ + sqlite3OomFault(db); + return 0; + } + zCopy = (char *)(&pMod[1]); memcpy(zCopy, zName, nName+1); pMod->zName = zCopy; pMod->pModule = pModule; pMod->pAux = pAux; pMod->xDestroy = xDestroy; pMod->pEpoTab = 0; - pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); - assert( pDel==0 || pDel==pMod ); - if( pDel ){ + pMod->nRefModule = 1; + } + pDel = (Module *)sqlite3HashInsert(&db->aModule,zCopy,(void*)pMod); + if( pDel ){ + if( pDel==pMod ){ sqlite3OomFault(db); sqlite3DbFree(db, pDel); pMod = 0; + }else{ + sqlite3VtabModuleUnref(db, pDel); } } return pMod; @@ -80,11 +93,7 @@ static int createModule( int rc = SQLITE_OK; sqlite3_mutex_enter(db->mutex); - if( sqlite3HashFind(&db->aModule, zName) ){ - rc = SQLITE_MISUSE_BKPT; - }else{ - (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); - } + (void)sqlite3VtabCreateModule(db, zName, pModule, pAux, xDestroy); rc = sqlite3ApiExit(db, rc); if( rc!=SQLITE_OK && xDestroy ) xDestroy(pAux); sqlite3_mutex_leave(db->mutex); @@ -123,6 +132,22 @@ int sqlite3_create_module_v2( return createModule(db, zName, pModule, pAux, xDestroy); } +/* +** Decrement the reference count on a Module object. Destroy the +** module when the reference count reaches zero. +*/ +void sqlite3VtabModuleUnref(sqlite3 *db, Module *pMod){ + assert( pMod->nRefModule>0 ); + pMod->nRefModule--; + if( pMod->nRefModule==0 ){ + if( pMod->xDestroy ){ + pMod->xDestroy(pMod->pAux); + } + assert( pMod->pEpoTab==0 ); + sqlite3DbFree(db, pMod); + } +} + /* ** Lock the virtual table so that it cannot be disconnected. ** Locks nest. Every lock should have a corresponding unlock. @@ -162,6 +187,7 @@ void sqlite3VtabUnlock(VTable *pVTab){ pVTab->nRef--; if( pVTab->nRef==0 ){ sqlite3_vtab *p = pVTab->pVtab; + sqlite3VtabModuleUnref(pVTab->db, pVTab->pMod); if( p ){ p->pModule->xDisconnect(p); } @@ -566,6 +592,7 @@ static int vtabCallConstructor( ** the sqlite3_vtab object if successful. */ memset(pVTable->pVtab, 0, sizeof(pVTable->pVtab[0])); pVTable->pVtab->pModule = pMod->pModule; + pMod->nRefModule++; pVTable->nRef = 1; if( sCtx.bDeclared==0 ){ const char *zFormat = "vtable constructor did not declare schema: %s"; diff --git a/test/intarray.test b/test/intarray.test index 049f117cc2..2250027c5d 100644 --- a/test/intarray.test +++ b/test/intarray.test @@ -47,12 +47,12 @@ do_test intarray-1.1 { } } {table ia1 table ia2 table ia3 table ia4} -# Verify the inability to DROP and recreate an intarray virtual table. +# Verify the ability to DROP and recreate an intarray virtual table. do_test intarray-1.1b { db eval {DROP TABLE ia1} - set rc [catch {sqlite3_intarray_create db ia1} msg] - lappend rc $msg -} {1 SQLITE_MISUSE} + set rc [catch {sqlite3_intarray_create db ia1} ia1] + lappend rc $ia1 +} {/0 [0-9A-Z]+/} do_test intarray-1.2 { db eval { diff --git a/test/vtab1.test b/test/vtab1.test index 0a45c4e2d9..e8891a632c 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1352,7 +1352,7 @@ foreach {tn sql res filter} { do_execsql_test 18.2.x { PRAGMA case_sensitive_like = OFF } #------------------------------------------------------------------------- -# Test that an existing module may not be overridden. +# Test that it is ok to override and existing module. # do_test 19.1 { sqlite3 db2 test.db @@ -1360,7 +1360,7 @@ do_test 19.1 { } SQLITE_OK do_test 19.2 { register_echo_module [sqlite3_connection_pointer db2] -} SQLITE_MISUSE +} SQLITE_OK do_test 19.3 { db2 close } {} From cc3f3d1f055e5bce28d7c7fa122ac5f922a7706b Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Aug 2019 15:27:58 +0000 Subject: [PATCH 016/112] Activate introspection pragmas by default. The new option SQLITE_OMIT_INTROSPECTION_PRAGMAS must be provided to keep them out. FossilOrigin-Name: 9c4bca64fb5f635296a8d7d7c1bf2808e02ca734a9983e5cee9132f5352a9a6d --- Makefile.in | 1 - Makefile.msc | 1 - main.mk | 1 - manifest | 27 +++++++++++++-------------- manifest.uuid | 2 +- src/pragma.c | 2 +- src/pragma.h | 8 ++++---- src/shell.c.in | 2 +- test/pragma5.test | 4 ++-- tool/mkpragmatab.tcl | 6 +++--- 10 files changed, 25 insertions(+), 29 deletions(-) diff --git a/Makefile.in b/Makefile.in index 8df09826fc..cadc2eda99 100644 --- a/Makefile.in +++ b/Makefile.in @@ -609,7 +609,6 @@ SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC SHELL_OPT += -DSQLITE_ENABLE_DESERIALIZE -SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 diff --git a/Makefile.msc b/Makefile.msc index e9997bd9c5..01d20d2d65 100644 --- a/Makefile.msc +++ b/Makefile.msc @@ -351,7 +351,6 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1 -OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1 !ENDIF OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1 diff --git a/main.mk b/main.mk index 508554d733..5462292023 100644 --- a/main.mk +++ b/main.mk @@ -527,7 +527,6 @@ SHELL_OPT += -DSQLITE_ENABLE_STMTVTAB SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC -SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1 FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000 diff --git a/manifest b/manifest index 428b9dbdb0..e9dfb2d42c 100644 --- a/manifest +++ b/manifest @@ -1,11 +1,11 @@ -C The\sSQLITE_DIRECTONLY\sflag,\swhen\sadded\sto\ssqlite3_create_function()\sprevents\nthe\sfunction\sfrom\sbeing\sused\sinside\sa\strigger\sor\sview. -D 2019-08-17T00:53:29.797 +C Activate\sintrospection\spragmas\sby\sdefault.\s\sThe\snew\soption\nSQLITE_OMIT_INTROSPECTION_PRAGMAS\smust\sbe\sprovided\sto\skeep\sthem\sout. +D 2019-08-17T15:27:58.078 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 4640daf826b80947a924ac44275c451ffc13007c7c866a5730c8ce5cf9e1dc74 +F Makefile.in 578f123620087ea459aa08fa872810a25ca7c0aaf16331de985bfcddb5f1e747 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 -F Makefile.msc 1ce5a2f754201baf709132fe5b45027c73343fba2607107821f759d78cf136c0 +F Makefile.msc a463dca3c50d8a36094fe5c8c39077907f530b54edfc5388c66c85e2cfc8dc04 F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a F VERSION 4c516d84c2a5f26c477ed34c09ac4136630f71c68139631f2eb591b22eea7cf1 F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 @@ -445,7 +445,7 @@ F ext/userauth/userauth.c f81aa5a3ecacf406f170c62a144405858f6f6de51dbdc0920134e6 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 8273bf49ba3b0c8559cb2774495390c31fd61c60 -F main.mk 125adda36bb32c99dc3a11340bd029ef373b9523eac2b2af76087bfe82d4fdf8 +F main.mk 09716d345766a55b25ed157b14786526cf67c761c61d99c53e117196fb3b391a F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 @@ -516,15 +516,15 @@ F src/parse.y 6d03a24bc0dcd15b93c480ea8a87f7ccd25313fe826485726d9ef13b82f2378d F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848 -F src/pragma.c a42d4c6040893a59b69a0c987e5ed0402730c444ee451fde9bbe6203e7f73b1d -F src/pragma.h 4a9fabff14db4487a734dfeeb4be984ce662bfdccfae16145b9c732327735e13 +F src/pragma.c b47bc7db02ab13d04c680aee424466b4e34f4ef5aa7b2e464876ec005806f98f +F src/pragma.h 40962d65b645bb3f08c1f4c456effd01c6e7f073f68ea25177e0c95e181cff75 F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 -F src/shell.c.in d2465e7747a014bd48a75c1bcf648e8e6cb46832dcc6e1293c5f285bc5542e8b +F src/shell.c.in 48f7a9ee4bfc95aaea09f45c37f0cc305f56d4840c988565cdb92df2db689c32 F src/sqlite.h.in 5445ee2844c15bf277ebb64e910b56b0e6fb9377f184a81cd9bd78f0946be8c8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 @@ -1221,7 +1221,7 @@ F test/pragma.test cf066fe0f7f5d49f4758de4986407b8676c61aaa7871599340d64f42a8edc F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9 F test/pragma4.test 1cb4b32f1a304ed9e291d7c4d49c91c2c8dc1b9450e6d2c1198b2cc895d40d77 -F test/pragma5.test 824ce6ced5d6b7ec71abe37fc6005ff836fe39d638273dc5192b39864b9ee983 +F test/pragma5.test 2be6a44c91e8585ccb4c71c5f221ccebe0692a49557215a912916ed391188959 F test/pragmafault.test 275edaf3161771d37de60e5c2b412627ac94cef11739236bec12ed1258b240f8 F test/prefixes.test b524a1c44bffec225b9aec98bd728480352aa8532ac4c15771fb85e8beef65d9 F test/printf.test 0300699733e53101b2ce48800518427249edd4053bb50fa0621c6607482f0fdb @@ -1769,7 +1769,7 @@ F tool/mkmsvcmin.tcl cad0c7b54d7dd92bc87d59f36d4cc4f070eb2e625f14159dc2f5c4204e6 F tool/mkopcodec.tcl d1b6362bd3aa80d5520d4d6f3765badf01f6c43c F tool/mkopcodeh.tcl 352a4319c0ad869eb26442bf7c3b015aa15594c21f1cce5a6420dbe999367c21 F tool/mkopts.tcl 680f785fdb09729fd9ac50632413da4eadbdf9071535e3f26d03795828ab07fa -F tool/mkpragmatab.tcl 8250ef3df54aee09f6c6ed36cad390bb6dd20bbe71927d8bff069ed9fe0bbf98 +F tool/mkpragmatab.tcl f115d63ada8171f9da28dc8e34e043a1a159692d46b89f66b6e681140bc4683d F tool/mkshellc.tcl 70a9978e363b0f3280ca9ce1c46d72563ff479c1930a12a7375e3881b7325712 F tool/mksourceid.c d458f9004c837bee87a6382228ac20d3eae3c49ea3b0a5aace936f8b60748d3b F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 @@ -1836,8 +1836,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 31e34fa3390196cdc3178bf120224b08df5ec58fa2c77079ede6e9461a430dad fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1 -R 3eb19b0b7177f98eb83ded0471cbec7c -T +closed fc745845d8d76adc165575e2192f4176e3c28e614c72571d56f4011560499fe1 +P de767376987f7668b0770c4920f1532e341b5a27f797d69c0f5e92b87d036170 +R ba0ddacef7e202b222af2845e11208f7 U drh -Z 353e54297be426c470f9f50229f09a1d +Z 608f836d0fe4bfadfea3872ae408e744 diff --git a/manifest.uuid b/manifest.uuid index d5baa3c05c..29f3d49d56 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -de767376987f7668b0770c4920f1532e341b5a27f797d69c0f5e92b87d036170 \ No newline at end of file +9c4bca64fb5f635296a8d7d7c1bf2808e02ca734a9983e5cee9132f5352a9a6d \ No newline at end of file diff --git a/src/pragma.c b/src/pragma.c index 6899bad6be..858e314a1e 100644 --- a/src/pragma.c +++ b/src/pragma.c @@ -1245,7 +1245,7 @@ void sqlite3Pragma( } break; -#ifdef SQLITE_INTROSPECTION_PRAGMAS +#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS case PragTyp_FUNCTION_LIST: { int i; HashElem *j; diff --git a/src/pragma.h b/src/pragma.h index 11e55ee9c7..b7f3282ded 100644 --- a/src/pragma.h +++ b/src/pragma.h @@ -311,7 +311,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_FullFSync }, #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) -#if defined(SQLITE_INTROSPECTION_PRAGMAS) +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "function_list", /* ePragTyp: */ PragTyp_FUNCTION_LIST, /* ePragFlg: */ PragFlg_Result0, @@ -435,7 +435,7 @@ static const PragmaName aPragmaName[] = { #endif #if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) #if !defined(SQLITE_OMIT_VIRTUALTABLE) -#if defined(SQLITE_INTROSPECTION_PRAGMAS) +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "module_list", /* ePragTyp: */ PragTyp_MODULE_LIST, /* ePragFlg: */ PragFlg_Result0, @@ -470,7 +470,7 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_ParserTrace }, #endif #endif -#if defined(SQLITE_INTROSPECTION_PRAGMAS) +#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) {/* zName: */ "pragma_list", /* ePragTyp: */ PragTyp_PRAGMA_LIST, /* ePragFlg: */ PragFlg_Result0, @@ -668,4 +668,4 @@ static const PragmaName aPragmaName[] = { /* iArg: */ SQLITE_WriteSchema|SQLITE_NoSchemaError }, #endif }; -/* Number of pragmas: 62 on by default, 81 total. */ +/* Number of pragmas: 65 on by default, 81 total. */ diff --git a/src/shell.c.in b/src/shell.c.in index 494a3d7e21..e2c49dd3ed 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -8461,7 +8461,7 @@ static int do_meta_command(char *zLine, ShellState *p){ appendText(&sSelect, ".sqlite_master", 0); } sqlite3_finalize(pStmt); -#ifdef SQLITE_INTROSPECTION_PRAGMAS +#ifndef SQLITE_OMIT_INTROSPECTION_PRAGMAS if( zName ){ appendText(&sSelect, " UNION ALL SELECT shell_module_schema(name)," diff --git a/test/pragma5.test b/test/pragma5.test index d2c58000cf..f16e4627ba 100644 --- a/test/pragma5.test +++ b/test/pragma5.test @@ -11,9 +11,9 @@ # This file implements regression tests for SQLite library. # # This file implements tests for the PRAGMA command. Specifically, -# those pragmas enabled at build time by setting: +# those pragmas that are not disabled at build time by setting: # -# -DSQLITE_INTROSPECTION_PRAGMAS +# -DSQLITE_OMIT_INTROSPECTION_PRAGMAS # set testdir [file dirname $argv0] diff --git a/tool/mkpragmatab.tcl b/tool/mkpragmatab.tcl index 85c8cc74f8..832153916e 100644 --- a/tool/mkpragmatab.tcl +++ b/tool/mkpragmatab.tcl @@ -264,19 +264,19 @@ set pragma_def { FLAG: Result0 COLS: name builtin IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) - IF: defined(SQLITE_INTROSPECTION_PRAGMAS) + IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) NAME: module_list FLAG: Result0 COLS: name IF: !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) IF: !defined(SQLITE_OMIT_VIRTUALTABLE) - IF: defined(SQLITE_INTROSPECTION_PRAGMAS) + IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) NAME: pragma_list FLAG: Result0 COLS: name - IF: defined(SQLITE_INTROSPECTION_PRAGMAS) + IF: !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) NAME: collation_list FLAG: Result0 From 9e9a67adb059733e05e0791f2ec519985eaa333c Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Aug 2019 17:07:15 +0000 Subject: [PATCH 017/112] Ensure the functions that appear to be constant are not factored out of expression that originate on the right-hand side of a LEFT JOIN. Ticket [6710d2f7a13a2997] FossilOrigin-Name: 500c9152daaf11cf69d778aa8592175f6088337c6667c59af6df3a24cd81eb0e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 13 +++++++++++++ test/join.test | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index e9dfb2d42c..1e155600d1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Activate\sintrospection\spragmas\sby\sdefault.\s\sThe\snew\soption\nSQLITE_OMIT_INTROSPECTION_PRAGMAS\smust\sbe\sprovided\sto\skeep\sthem\sout. -D 2019-08-17T15:27:58.078 +C Ensure\sthe\sfunctions\sthat\sappear\sto\sbe\sconstant\sare\snot\sfactored\sout\sof\nexpression\sthat\soriginate\son\sthe\sright-hand\sside\sof\sa\sLEFT\sJOIN.\nTicket\s[6710d2f7a13a2997] +D 2019-08-17T17:07:15.587 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 1b4f5a53a5f48ba3f718413586e0f9715cf90c684fba9038186a62728e2ebe72 +F src/expr.c abb98379d53defc742ffbfb3f6260036fdeac775643b9d0c52490d717949327e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1077,7 +1077,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a -F test/join.test d53a3662762eff50b65da8775201e609878a27dd0885a1ae7bcde9bb46cecbc5 +F test/join.test f505c78a793b0c807d534c1cacf71c7bf96aa734f78d091721f2a6859077b7e8 F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -1836,7 +1836,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 de767376987f7668b0770c4920f1532e341b5a27f797d69c0f5e92b87d036170 -R ba0ddacef7e202b222af2845e11208f7 +P 9c4bca64fb5f635296a8d7d7c1bf2808e02ca734a9983e5cee9132f5352a9a6d +R 522398ea68495c38ea0fcdb681aed94e U drh -Z 608f836d0fe4bfadfea3872ae408e744 +Z 11aed5fc406f7abcc5b902e904ad4203 diff --git a/manifest.uuid b/manifest.uuid index 29f3d49d56..74872cc0c3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9c4bca64fb5f635296a8d7d7c1bf2808e02ca734a9983e5cee9132f5352a9a6d \ No newline at end of file +500c9152daaf11cf69d778aa8592175f6088337c6667c59af6df3a24cd81eb0e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 8f02ae569a..ef4221ff8d 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3994,10 +3994,23 @@ expr_code_doover: break; } + /* TK_IF_NULL_ROW Expr nodes are inserted ahead of expressions + ** that derive from the right-hand table of a LEFT JOIN. The + ** Expr.iTable value is the table number for the right-hand table. + ** The expression is only evaluated if that table is not currently + ** on a LEFT JOIN NULL row. + */ case TK_IF_NULL_ROW: { int addrINR; + u8 okConstFactor = pParse->okConstFactor; addrINR = sqlite3VdbeAddOp1(v, OP_IfNullRow, pExpr->iTable); + /* Temporarily disable factoring of constant expressions, since + ** even though expressions may appear to be constant, they are not + ** really constant because they originate from the right-hand side + ** of a LEFT JOIN. */ + pParse->okConstFactor = 0; inReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft, target); + pParse->okConstFactor = okConstFactor; sqlite3VdbeJumpHere(v, addrINR); sqlite3VdbeChangeP3(v, addrINR, inReg); break; diff --git a/test/join.test b/test/join.test index f613df85b0..25c31705c8 100644 --- a/test/join.test +++ b/test/join.test @@ -864,4 +864,19 @@ do_execsql_test join-16.100 { WHERE (b IS NOT NULL)=0; } {1 {}} +# 2019-08-17 ticket https://sqlite.org/src/tktview/6710d2f7a13a299728ab +# Ensure that constants that derive from the right-hand table of a LEFT JOIN +# are never factored out, since they are not really constant. +# +do_execsql_test join-17.100 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x); + INSERT INTO t1(x) VALUES(0),(1); + SELECT * FROM t1 LEFT JOIN (SELECT abs(1) AS y FROM t1) ON x WHERE NOT(y='a'); +} {1 1 1 1} +do_execsql_test join-17.110 { + SELECT * FROM t1 LEFT JOIN (SELECT abs(1)+2 AS y FROM t1) ON x + WHERE NOT(y='a'); +} {1 3 1 3} + finish_test From cc491f4b1bd7a07d931cd36bf5b763f9007e9916 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Aug 2019 17:55:54 +0000 Subject: [PATCH 018/112] Fix problem with DESC indexes on this branch. FossilOrigin-Name: b49df1fe9b7174ebc60023179e8da628c926e59df3dc01b15d4a28e17807bb97 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 55a84428cc..d9a93aa0b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\strunk\schanges\sinto\sthis\sbranch. -D 2019-08-17T15:47:32.932 +C Fix\sproblem\swith\sDESC\sindexes\son\sthis\sbranch. +D 2019-08-17T17:55:54.575 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -611,7 +611,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c 52c433208eafdc7e1750ea4622cfffb5d14d906a0a9258e07bae4b6fee182fef F src/whereInt.h 807766a6a92893dbba8a887e5b13466d2257ce07a84cf1be0aae2c41aee3bf4f -F src/wherecode.c 58889def15cb57375a5f4f83db6d2b28b372d87cf1b4f23e47928a4847a94ae4 +F src/wherecode.c 81c5d1eb909f8e1284df58367d25f748d126c475725665e7bb9b10a9bf702242 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc F src/window.c 331cdac4992c7402da01c981861f3cc989bf7b4a97dd03eb122993e670f7a588 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1837,7 +1837,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 81069d7196857e909c94195d67388f71bc9f832eafd9156d8c5cdddb63513b4a de767376987f7668b0770c4920f1532e341b5a27f797d69c0f5e92b87d036170 -R f0ae3249555e7bff0d2d8fdff62897ad +P db1e60800bc260cdcd604739daaba72c6b486158123fc62a3898aca4ead33cd3 +R a80a5d388fedda22f42c8717a7ac1c28 U dan -Z 9638aef683da83fd6b6a17e587485fa1 +Z 58eff66993c9d8fc329438790f4752fe diff --git a/manifest.uuid b/manifest.uuid index 7034da3e9f..4935f00760 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -db1e60800bc260cdcd604739daaba72c6b486158123fc62a3898aca4ead33cd3 \ No newline at end of file +b49df1fe9b7174ebc60023179e8da628c926e59df3dc01b15d4a28e17807bb97 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index d4f26a3af0..610c45001c 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1602,7 +1602,6 @@ Bitmask sqlite3WhereCodeOneLoopStart( ** it is not. For an ASC sort, the non-NULL entries are scanned first. ** For DESC, NULL entries are scanned first. */ - addrNxt = pLevel->addrNxt; if( (pLoop->wsFlags & (WHERE_TOP_LIMIT|WHERE_BTM_LIMIT))==0 && (pLoop->wsFlags & WHERE_BIGNULL_SORT)!=0 ){ @@ -1612,7 +1611,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( nExtraReg = 1; bSeekPastNull = 1; pLevel->regBignull = regBignull = ++pParse->nMem; - addrNxt = pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); + pLevel->addrBignull = sqlite3VdbeMakeLabel(pParse); } /* If we are doing a reverse order scan on an ascending index, or @@ -1637,6 +1636,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( zStartAff && nTop ){ zEndAff = sqlite3DbStrDup(db, &zStartAff[nEq]); } + addrNxt = (regBignull ? pLevel->addrBignull : pLevel->addrNxt); testcase( pRangeStart && (pRangeStart->eOperator & WO_LE)!=0 ); testcase( pRangeStart && (pRangeStart->eOperator & WO_GE)!=0 ); From 8328369740b33c1de8ed362fc70e76d07f1e1159 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Aug 2019 18:16:59 +0000 Subject: [PATCH 019/112] Add tests to ensure that this branch really does fix ticket [f8a7060ece]. FossilOrigin-Name: f892066425671a8a0ac923e3ad4744677f6434a66f97b91afa8141f11f179975 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/minmax4.test | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index d9a93aa0b4..2584ef1bad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblem\swith\sDESC\sindexes\son\sthis\sbranch. -D 2019-08-17T17:55:54.575 +C Add\stests\sto\sensure\sthat\sthis\sbranch\sreally\sdoes\sfix\sticket\s[f8a7060ece]. +D 2019-08-17T18:16:59.747 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1150,7 +1150,7 @@ F test/memsubsys2.test 3e4a8d0c05fd3e5fa92017c64666730a520c7e08 F test/minmax.test 6751e87b409fe11b02e70a306d846fa544e25a41 F test/minmax2.test dae92964ac87c1d2ef978c582e81a95e11c00f1cbef68980bfb2abaf10315063 F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354 -F test/minmax4.test 838fe32b812dc50778be3799767cefb5ff59bb04cff81d4f12c0708642f65151 +F test/minmax4.test 272ca395257f05937dc96441c9dde4bc9fbf116a8d4fa02baeb0d13d50e36c87 F test/misc1.test 7ce84b25df9872e7d7878613a96815d2ba5bc974ac4e15a50118dde8f3917599 F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d @@ -1837,7 +1837,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 db1e60800bc260cdcd604739daaba72c6b486158123fc62a3898aca4ead33cd3 -R a80a5d388fedda22f42c8717a7ac1c28 +P b49df1fe9b7174ebc60023179e8da628c926e59df3dc01b15d4a28e17807bb97 +R 45771ddb0f2c68cf3dbfa90b9e4149c6 U dan -Z 58eff66993c9d8fc329438790f4752fe +Z 6452b2b9b9aca3f08bbef29f8e41e25a diff --git a/manifest.uuid b/manifest.uuid index 4935f00760..b6a8464c5f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b49df1fe9b7174ebc60023179e8da628c926e59df3dc01b15d4a28e17807bb97 \ No newline at end of file +f892066425671a8a0ac923e3ad4744677f6434a66f97b91afa8141f11f179975 \ No newline at end of file diff --git a/test/minmax4.test b/test/minmax4.test index eeb8bff0bb..775fee86be 100644 --- a/test/minmax4.test +++ b/test/minmax4.test @@ -200,4 +200,37 @@ do_execsql_test 5.1 { SELECT MIN(a) FROM t1 WHERE a=123; } {123} +#------------------------------------------------------------------------- +# Tests for ticket f8a7060ece. +# +reset_db +do_execsql_test 6.1.0 { + CREATE TABLE t1(a, b, c); + INSERT INTO t1 VALUES(NULL, 1, 'x'); + CREATE INDEX i1 ON t1(a); +} +do_execsql_test 6.1.1 { + SELECT min(a), b, c FROM t1 WHERE c='x'; +} {{} 1 x} +do_execsql_test 6.1.2 { + INSERT INTO t1 VALUES(1, 2, 'y'); +} {} +do_execsql_test 6.1.3 { + SELECT min(a), b, c FROM t1 WHERE c='x'; +} {{} 1 x} + +do_execsql_test 6.2.0 { + CREATE TABLE t0(c0 UNIQUE, c1); + INSERT INTO t0(c1) VALUES (0); + INSERT INTO t0(c0) VALUES (0); + CREATE VIEW v0(c0, c1) AS + SELECT t0.c1, t0.c0 FROM t0 WHERE CAST(t0.rowid AS INT) = 1; +} +do_execsql_test 6.2.1 { + SELECT c0, c1 FROM v0; +} {0 {}} +do_execsql_test 6.2.2 { + SELECT v0.c0, MIN(v0.c1) FROM v0; +} {0 {}} + finish_test From c324d44690c7b6dc640c46670e358d7f939e24f5 Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Aug 2019 19:13:49 +0000 Subject: [PATCH 020/112] When populating an ephemeral b-tree for the RHS of an IN(...) clause, avoid applying an affinity to a value that may be used later on for some other purpose. Fix for [c7a117190]. FossilOrigin-Name: 43e8b14314d876178d487c3b519296ac1de065fdcaa70768e40d684015bceb9d --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 8 ++++---- test/in5.test | 17 +++++++++++++++++ 4 files changed, 30 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 1e155600d1..df03417876 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthe\sfunctions\sthat\sappear\sto\sbe\sconstant\sare\snot\sfactored\sout\sof\nexpression\sthat\soriginate\son\sthe\sright-hand\sside\sof\sa\sLEFT\sJOIN.\nTicket\s[6710d2f7a13a2997] -D 2019-08-17T17:07:15.587 +C When\spopulating\san\sephemeral\sb-tree\sfor\sthe\sRHS\sof\san\sIN(...)\sclause,\savoid\sapplying\san\saffinity\sto\sa\svalue\sthat\smay\sbe\sused\slater\son\sfor\ssome\sother\spurpose.\sFix\sfor\s[c7a117190]. +D 2019-08-17T19:13:49.573 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c abb98379d53defc742ffbfb3f6260036fdeac775643b9d0c52490d717949327e +F src/expr.c 66a844757e865624c51e3c23dedf7f650adf75f799947f202aacbb1c394c3cda F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1029,7 +1029,7 @@ F test/in.test 63e642e97bc22c8fd970752fb4f0b3992a957003ea87524fe69e5a700500c500 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 -F test/in5.test 7ae37fcd4a5e198291c6ab5f31a5bb3d15397efe8b75a6736d7a95a7b8dd9e08 +F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 F test/incrblob2.test a494c9e848560039a23974b9119cfc2cf3ad3bd15cc2694ee6367ae537ef8f1f @@ -1836,7 +1836,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 9c4bca64fb5f635296a8d7d7c1bf2808e02ca734a9983e5cee9132f5352a9a6d -R 522398ea68495c38ea0fcdb681aed94e -U drh -Z 11aed5fc406f7abcc5b902e904ad4203 +P 500c9152daaf11cf69d778aa8592175f6088337c6667c59af6df3a24cd81eb0e +R bed36c864428d4b8c6d5512dcb77ee7b +U dan +Z a90573f564583a398fa8c41c8ec06335 diff --git a/manifest.uuid b/manifest.uuid index 74872cc0c3..d076e59ff2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -500c9152daaf11cf69d778aa8592175f6088337c6667c59af6df3a24cd81eb0e \ No newline at end of file +43e8b14314d876178d487c3b519296ac1de065fdcaa70768e40d684015bceb9d \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ef4221ff8d..41cc2724f6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2787,7 +2787,7 @@ void sqlite3CodeRhsOfIN( int i; ExprList *pList = pExpr->x.pList; struct ExprList_item *pItem; - int r1, r2, r3; + int r1, r2; affinity = sqlite3ExprAffinity(pLeft); if( affinity<=SQLITE_AFF_NONE ){ affinity = SQLITE_AFF_BLOB; @@ -2815,9 +2815,9 @@ void sqlite3CodeRhsOfIN( } /* Evaluate the expression and insert it into the temp table */ - r3 = sqlite3ExprCodeTarget(pParse, pE2, r1); - sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1); - sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r3, 1); + sqlite3ExprCode(pParse, pE2, r1); + sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1); } sqlite3ReleaseTempReg(pParse, r1); sqlite3ReleaseTempReg(pParse, r2); diff --git a/test/in5.test b/test/in5.test index a5ea7c1784..6680641ff3 100644 --- a/test/in5.test +++ b/test/in5.test @@ -248,5 +248,22 @@ do_execsql_test 9.1 { SELECT * FROM t9 WHERE a IN (44, 45, 44, 45) } {44 45} +#------------------------------------------------------------------------- +# Test that ticket c7a117190 is fixed. +# +reset_db +do_execsql_test 9.0 { + CREATE TABLE t0(c0); + CREATE VIEW v0(c0) AS SELECT LOWER(CAST('1e500' AS TEXT)) FROM t0; + INSERT INTO t0(c0) VALUES (NULL); +} + +do_execsql_test 9.1 { + SELECT lower('1e500') FROM t0 WHERE rowid NOT IN (0, 0, lower('1e500')); +} {1e500} + +do_execsql_test 9.2 { + SELECT lower('1e500') FROM t0 WHERE rowid != lower('1e500'); +} {1e500} finish_test From 87ca8067af3a0d3550eb339b06cac8bd47f010fa Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Aug 2019 19:31:09 +0000 Subject: [PATCH 021/112] Fix the new ability to unregister virtual table modules so that it works for the automatic PRAGMA virtual tables. FossilOrigin-Name: 5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vtab.c | 1 + 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index df03417876..32bd5fa7b7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\spopulating\san\sephemeral\sb-tree\sfor\sthe\sRHS\sof\san\sIN(...)\sclause,\savoid\sapplying\san\saffinity\sto\sa\svalue\sthat\smay\sbe\sused\slater\son\sfor\ssome\sother\spurpose.\sFix\sfor\s[c7a117190]. -D 2019-08-17T19:13:49.573 +C Fix\sthe\snew\sability\sto\sunregister\svirtual\stable\smodules\sso\sthat\sit\sworks\nfor\sthe\sautomatic\sPRAGMA\svirtual\stables. +D 2019-08-17T19:31:09.807 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -604,7 +604,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75 F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c 4d833811e3784409627919899e1fd75ee08f0e5db6d9924eac9a0bfe0cb762dc +F src/vtab.c 994a4686197c00cee75f4ade8645e7336d8bb612c80ed61f4b8b7ceecf0a32ea F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1836,7 +1836,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 500c9152daaf11cf69d778aa8592175f6088337c6667c59af6df3a24cd81eb0e -R bed36c864428d4b8c6d5512dcb77ee7b -U dan -Z a90573f564583a398fa8c41c8ec06335 +P 43e8b14314d876178d487c3b519296ac1de065fdcaa70768e40d684015bceb9d +R f1b8fe83962102831e60e3831104d937 +U drh +Z 2bda6aa8d3d9e8159fe6c0f170b565ec diff --git a/manifest.uuid b/manifest.uuid index d076e59ff2..3e15bb7e94 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -43e8b14314d876178d487c3b519296ac1de065fdcaa70768e40d684015bceb9d \ No newline at end of file +5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 \ No newline at end of file diff --git a/src/vtab.c b/src/vtab.c index a711a7be5f..8f6db9f47b 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -72,6 +72,7 @@ Module *sqlite3VtabCreateModule( sqlite3DbFree(db, pDel); pMod = 0; }else{ + sqlite3VtabEponymousTableClear(db, pDel); sqlite3VtabModuleUnref(db, pDel); } } From 5df84280692df828b2c76d5a3a7ebf4c877f3900 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Aug 2019 19:45:25 +0000 Subject: [PATCH 022/112] The experimental sqlite3_drop_modules_except() interface. FossilOrigin-Name: 0851db4d337a87f8b2d3ce2ae9f9c928b9483591ca41a9e39cc01548059b1888 --- manifest | 21 ++++++++++++--------- manifest.uuid | 2 +- src/shell.c.in | 20 +++++++++++++++----- src/sqlite.h.in | 15 +++++++++++++++ src/test1.c | 27 +++++++++++++++++++++++++++ src/vtab.c | 22 ++++++++++++++++++++++ 6 files changed, 92 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 32bd5fa7b7..97b204c96f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\snew\sability\sto\sunregister\svirtual\stable\smodules\sso\sthat\sit\sworks\nfor\sthe\sautomatic\sPRAGMA\svirtual\stables. -D 2019-08-17T19:31:09.807 +C The\sexperimental\ssqlite3_drop_modules_except()\sinterface. +D 2019-08-17T19:45:25.613 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,8 +524,8 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 -F src/shell.c.in 48f7a9ee4bfc95aaea09f45c37f0cc305f56d4840c988565cdb92df2db689c32 -F src/sqlite.h.in 5445ee2844c15bf277ebb64e910b56b0e6fb9377f184a81cd9bd78f0946be8c8 +F src/shell.c.in e0754f1d73c8e7d09548a29537e9e7d65fa0f4869c41722b7b89a64d9cdeff91 +F src/sqlite.h.in cbc4729565b6787c462fffac540b912acc24b32d22428f07d2cf3a937ba7a72e F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 F src/sqliteInt.h b7d612d9c63abc8a8a7dcf7fbec5326b1770f40c81502c56f508e272154e7615 @@ -533,7 +533,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290 -F src/test1.c 87059457fb90b73a74044b379fe2cb0aefbb53c010c646ecaff23179a423638c +F src/test1.c 17f5334199c02e69292d826ba660f0fcb75f50f7686a76553afb55a2c74e87f7 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -604,7 +604,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75 F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c 994a4686197c00cee75f4ade8645e7336d8bb612c80ed61f4b8b7ceecf0a32ea +F src/vtab.c 8849cbd67596bebe58e2095fb95309aa3c5bf330d5501ec2b2511109de5a8f13 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1836,7 +1836,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 43e8b14314d876178d487c3b519296ac1de065fdcaa70768e40d684015bceb9d -R f1b8fe83962102831e60e3831104d937 +P 5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 +R 1452e34f48dd7f53a8de382ba3305e88 +T *branch * sqlite3_drop_modules_except +T *sym-sqlite3_drop_modules_except * +T -sym-trunk * U drh -Z 2bda6aa8d3d9e8159fe6c0f170b565ec +Z 3751a55606ec64d5cdbb771325aed7c0 diff --git a/manifest.uuid b/manifest.uuid index 3e15bb7e94..9cc49bf88f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 \ No newline at end of file +0851db4d337a87f8b2d3ce2ae9f9c928b9483591ca41a9e39cc01548059b1888 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index e2c49dd3ed..9bfca22e53 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3651,6 +3651,7 @@ static const char *(azHelp[]) = { #endif /* SQLITE_OMIT_TRACE */ #ifdef SQLITE_DEBUG ".unmodule NAME ... Unregister virtual table modules", + " --allexcept Unregister everything except those named", #endif ".vfsinfo ?AUX? Information about the top-level VFS", ".vfslist List all available VFSes", @@ -6892,7 +6893,7 @@ static int do_meta_command(char *zLine, ShellState *p){ int nArg = 0; int n, c; int rc = 0; - char *azArg[50]; + char *azArg[52]; #ifndef SQLITE_OMIT_VIRTUALTABLE if( p->expert.pExpert ){ @@ -6902,7 +6903,7 @@ static int do_meta_command(char *zLine, ShellState *p){ /* Parse the input line into tokens. */ - while( zLine[h] && nArgdb, azArg[ii], 0, 0); + zOpt = azArg[1]; + if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++; + if( strcmp(zOpt, "-allexcept")==0 ){ + assert( azArg[nArg]==0 ); + sqlite3_drop_modules_except(p->db, nArg>2 ? (const char**)(azArg+2) : 0); + }else{ + for(ii=1; iidb, azArg[ii], 0, 0); + } } }else #endif diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ed5e2922c6..ace4da70b1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6654,6 +6654,21 @@ int sqlite3_create_module_v2( void(*xDestroy)(void*) /* Module destructor function */ ); +/* +** CAPI3REF: Remove Unnecessary Virtual Table Implementations +** METHOD: sqlite3 +** +** ^The sqlite3_drop_modules_except(D,L) interface removes all virtual +** table modules from database connection D except those named on list L. +** The L parameter must be either NULL or a pointer to an array of pointers +** to strings where the array is terminated by a single NULL pointer. +** ^If the L parameter is NULL, then all virtual table modules are removed. +*/ +int sqlite3_drop_modules_except( + sqlite3 *db, /* Remove modules from this connection */ + const char **azKeep /* Except, do not remove the ones named here */ +); + /* ** CAPI3REF: Virtual Table Instance Object ** KEYWORDS: sqlite3_vtab diff --git a/src/test1.c b/src/test1.c index 6bc64e7626..7243339056 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1110,6 +1110,32 @@ static int SQLITE_TCLAPI test_create_function( return TCL_OK; } +/* +** Usage: sqlite3_drop_modules_except DB ?NAME ...? +** +** Invoke the sqlite3_drop_modules_except(D,L) interface on database +** connection DB, in order to drop all modules except those named in +** the argument. +*/ +static int SQLITE_TCLAPI test_drop_except( + void *NotUsed, + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int argc, /* Number of arguments */ + char **argv /* Text of each argument */ +){ + int rc; + sqlite3 *db; + + if( argc!=2 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], + " DB\"", 0); + return TCL_ERROR; + } + if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; + sqlite3_drop_modules_except(db, argc>2 ? (const char**)(argv+2) : 0); + return TCL_OK; +} + /* ** Routines to implement the x_count() aggregate function. ** @@ -7860,6 +7886,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, + { "sqlite3_drop_modules_except", (Tcl_CmdProc*)test_drop_except }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, diff --git a/src/vtab.c b/src/vtab.c index 8f6db9f47b..760993120c 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -133,6 +133,28 @@ int sqlite3_create_module_v2( return createModule(db, zName, pModule, pAux, xDestroy); } +/* +** External API to drop all virtual-table modules, except those named +** on the azNames list. +*/ +int sqlite3_drop_modules_except(sqlite3 *db, const char** azNames){ + HashElem *pThis, *pNext; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; +#endif + for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ + Module *pMod = (Module*)sqliteHashData(pThis); + pNext = sqliteHashNext(pThis); + if( azNames ){ + int ii; + for(ii=0; azNames[ii]!=0 && strcmp(azNames[ii],pMod->zName)!=0; ii++){} + if( azNames[ii]!=0 ) continue; + } + createModule(db, pMod->zName, 0, 0, 0); + } + return SQLITE_OK; +} + /* ** Decrement the reference count on a Module object. Destroy the ** module when the reference count reaches zero. From 5976b2c80533728e974c2dfb2a6abc8f1acaf3b6 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 17 Aug 2019 19:55:26 +0000 Subject: [PATCH 023/112] Fix to the query planner for the LSM1 extension. FossilOrigin-Name: 7496e872a1a50ac65ad04709365a43038fb015ac9c690196de3cb02ce54c2e57 --- ext/lsm1/lsm_vtab.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/lsm1/lsm_vtab.c b/ext/lsm1/lsm_vtab.c index fe7c160b62..f96a6bbd71 100644 --- a/ext/lsm1/lsm_vtab.c +++ b/ext/lsm1/lsm_vtab.c @@ -842,7 +842,7 @@ static int lsm1BestIndex( const struct sqlite3_index_constraint *pConstraint; pConstraint = pIdxInfo->aConstraint; - for(i=0; inConstraint && idxNum<16; i++, pConstraint++){ + for(i=0; inConstraint; i++, pConstraint++){ if( pConstraint->usable==0 ) continue; if( pConstraint->iColumn!=0 ) continue; switch( pConstraint->op ){ diff --git a/manifest b/manifest index 32bd5fa7b7..1305dd6a16 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\snew\sability\sto\sunregister\svirtual\stable\smodules\sso\sthat\sit\sworks\nfor\sthe\sautomatic\sPRAGMA\svirtual\stables. -D 2019-08-17T19:31:09.807 +C Fix\sto\sthe\squery\splanner\sfor\sthe\sLSM1\sextension. +D 2019-08-17T19:55:26.642 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -269,7 +269,7 @@ F ext/lsm1/lsm_str.c 65e361b488c87b10bf3e5c0070b14ffc602cf84f094880bece77bbf6678 F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb F ext/lsm1/lsm_unix.c 57361bcf5b1a1a028f5d66571ee490e9064d2cfb145a2cc9e5ddade467bb551b F ext/lsm1/lsm_varint.c 43f954af668a66c7928b81597c14d6ad4be9fedbc276bbd80f52fa28a02fdb62 -F ext/lsm1/lsm_vtab.c 529255dc704289001b225d97e57e0cfa14b29c3f281c7349cfa8fdb655de79ae +F ext/lsm1/lsm_vtab.c 169bfe7ef8e6c9de9c77e17c4c50c9ae55fb0167d80be3d1be82c991184b6f35 F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82 F ext/lsm1/test/lsm1_simple.test ca949efefa102f4644231dcd9291d8cda7699a4ce1006b26e0e3fcb72233f422 @@ -1836,7 +1836,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 43e8b14314d876178d487c3b519296ac1de065fdcaa70768e40d684015bceb9d -R f1b8fe83962102831e60e3831104d937 +P 5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 +R bd11da9af99d4a05979e56c686a272e3 U drh -Z 2bda6aa8d3d9e8159fe6c0f170b565ec +Z e640ff9ea98c214eb3589753b7432e52 diff --git a/manifest.uuid b/manifest.uuid index 3e15bb7e94..0c50b90553 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 \ No newline at end of file +7496e872a1a50ac65ad04709365a43038fb015ac9c690196de3cb02ce54c2e57 \ No newline at end of file From dac7e69dc2bbfa895cb31c2f9305c11ff4fba51c Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 17 Aug 2019 19:58:26 +0000 Subject: [PATCH 024/112] Add some extra tests for the lsm virtual table module. FossilOrigin-Name: 4cb009b0f724f72eaea90e45488122f7c2a7d0caf31a8422da4060469507e921 --- ext/lsm1/Makefile | 4 +-- ext/lsm1/test/lsm1_simple.test | 59 ++++++++++++++++++++++++++++++++++ manifest | 16 ++++----- manifest.uuid | 2 +- 4 files changed, 70 insertions(+), 11 deletions(-) diff --git a/ext/lsm1/Makefile b/ext/lsm1/Makefile index 7022b5682c..7056432d2d 100644 --- a/ext/lsm1/Makefile +++ b/ext/lsm1/Makefile @@ -43,10 +43,10 @@ LSMTESTSRC = $(LSMDIR)/lsm-test/lsmtest1.c $(LSMDIR)/lsm-test/lsmtest2.c \ # all: lsm.so -LSMOPTS += -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB +LSMOPTS += -fPIC -DLSM_MUTEX_PTHREADS=1 -I$(LSMDIR) -DHAVE_ZLIB lsm.so: $(LSMOBJ) - $(TCCX) -shared -o lsm.so $(LSMOBJ) + $(TCCX) -shared -fPIC -o lsm.so $(LSMOBJ) %.o: $(LSMDIR)/%.c $(LSMHDR) sqlite3.h $(TCCX) $(LSMOPTS) -c $< diff --git a/ext/lsm1/test/lsm1_simple.test b/ext/lsm1/test/lsm1_simple.test index bc0cb4c660..2eab50a83a 100644 --- a/ext/lsm1/test/lsm1_simple.test +++ b/ext/lsm1/test/lsm1_simple.test @@ -88,6 +88,65 @@ do_execsql_test 210 { do_execsql_test 211 { SELECT quote(a), quote(lsm1_key), quote(lsm1_value), '|' FROM x1; } {'12' X'3132' X'05320000000000000A401FFB42ABE9DB' | '15' X'3135' X'4284C6' | '8' X'38' X'2162616E6A6F1633323105' |} +do_execsql_test 212 { + SELECT quote(a), quote(lsm1_key), quote(lsm1_value) FROM x1 WHERE a='12'; +} {'12' X'3132' X'05320000000000000A401FFB42ABE9DB'} +#------------------------------------------------------------------------- +reset_db +forcedelete testlsm.db +load_lsm1_vtab db +do_execsql_test 300 { + CREATE VIRTUAL TABLE x1 USING lsm1(testlsm.db,a,TEXT,b,c,d); +} +do_eqp_test 310 { + SELECT * FROM x1 WHERE a=? +} {SCAN TABLE x1 VIRTUAL TABLE INDEX 0:} + +do_eqp_test 320 { + SELECT * FROM x1 WHERE a>? +} {SCAN TABLE x1 VIRTUAL TABLE INDEX 2:} + +do_eqp_test 330 { + SELECT * FROM x1 WHERE a 'five'; +} {4 1 3 2} +do_execsql_test 421 { + SELECT b FROM x1 WHERE a <= 'three'; +} {3 1 4 5} finish_test diff --git a/manifest b/manifest index 1305dd6a16..fe2eb7bdc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sto\sthe\squery\splanner\sfor\sthe\sLSM1\sextension. -D 2019-08-17T19:55:26.642 +C Add\ssome\sextra\stests\sfor\sthe\slsm\svirtual\stable\smodule. +D 2019-08-17T19:58:26.438 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -229,7 +229,7 @@ F ext/fts5/tool/showfts5.tcl d54da0e067306663e2d5d523965ca487698e722c F ext/icu/README.txt a295e91db742b153e8dce8f7efd31d28ad1eea4df31ef4daa3eedc85be2f5138 F ext/icu/icu.c c2c7592574c08cd1270d909b8fb8797f6ea1f49e931e71dbcc25506b9b224580 F ext/icu/sqliteicu.h 728867a802baa5a96de7495e9689a8e01715ef37 -F ext/lsm1/Makefile 98b0a24b45e248283d6bea4b6cb3e58d7b394edd8e96a0ac28c5fa5104813bad +F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9 F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 F ext/lsm1/lsm-test/lsmtest.h cf58528ffe0cfe535e91b44584e2ec5fb1caacdabecef0d8dcf83bf83168bf28 @@ -272,7 +272,7 @@ F ext/lsm1/lsm_varint.c 43f954af668a66c7928b81597c14d6ad4be9fedbc276bbd80f52fa28 F ext/lsm1/lsm_vtab.c 169bfe7ef8e6c9de9c77e17c4c50c9ae55fb0167d80be3d1be82c991184b6f35 F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82 -F ext/lsm1/test/lsm1_simple.test ca949efefa102f4644231dcd9291d8cda7699a4ce1006b26e0e3fcb72233f422 +F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5 F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0 F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240 F ext/misc/amatch.c 50a9ef2d38dabfa371f8c1904097d493271e63d58ccb0e9b79a4fa4a94e66660 @@ -1836,7 +1836,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 5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 -R bd11da9af99d4a05979e56c686a272e3 -U drh -Z e640ff9ea98c214eb3589753b7432e52 +P 7496e872a1a50ac65ad04709365a43038fb015ac9c690196de3cb02ce54c2e57 +R 7c52be13cef9eee33da71a3e3a70b980 +U dan +Z 775a473efffe71d8a3fe393281372f17 diff --git a/manifest.uuid b/manifest.uuid index 0c50b90553..bfffac683c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7496e872a1a50ac65ad04709365a43038fb015ac9c690196de3cb02ce54c2e57 \ No newline at end of file +4cb009b0f724f72eaea90e45488122f7c2a7d0caf31a8422da4060469507e921 \ No newline at end of file From 9105fd51893062a8503c8850e5d88ad49de28495 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Aug 2019 17:26:32 +0000 Subject: [PATCH 025/112] Prevent NULLS FIRST/LAST from being used in CREATE INDEX and other statements. FossilOrigin-Name: bb9767a287097a615aeb4abdba689b10e1a1c36c016c8e55905b508075e62c86 --- manifest | 22 +++++++++++----------- manifest.uuid | 2 +- src/build.c | 24 ++++++++++++++++++++++++ src/expr.c | 17 +++++++++++++---- src/insert.c | 3 +++ src/sqliteInt.h | 4 +++- src/trigger.c | 3 +++ test/nulls1.test | 38 ++++++++++++++++++++++++++++++++++++++ 8 files changed, 96 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 2584ef1bad..b8cb71e76a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sto\sensure\sthat\sthis\sbranch\sreally\sdoes\sfix\sticket\s[f8a7060ece]. -D 2019-08-17T18:16:59.747 +C Prevent\sNULLS\sFIRST/LAST\sfrom\sbeing\sused\sin\sCREATE\sINDEX\sand\sother\sstatements. +D 2019-08-19T17:26:32.202 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -467,7 +467,7 @@ F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 F src/btree.c 5cf994516c1b74928b9d15971573a8bc8595e1afec129184099976da603402de F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f -F src/build.c 39f448776a17f202e0d205bda9e2b0bb80853503268ceb36a48ff6d0d963fd7b +F src/build.c da5d5d82eb53cb004e9120277cfe93a9c3dd294871eae3d728ebd0faee84d969 F src/callback.c 25dda5e1c2334a367b94a64077b1d06b2553369f616261ca6783c48bcb6bda73 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e F src/ctime.c 1b0724e66f95f33b160b1af85caaf9cceb325d22abf39bd24df4f54a73982251 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c bef29885d12c1b7ec4353fc07f61f18d044430fc4f9c1476fd5098a5834d17bd +F src/expr.c 0a3442b0df31f1eca86b2aa3634f61bca5f1a6781f543ca9a0d87e29961f7f4f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -484,7 +484,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b +F src/insert.c 81eec6acf4fbf0942bbab6804fe50df3e109acba40b8bbfb00fec9a14d0715a6 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c F src/main.c 51c55eb579eac4180bfcc6242741084710911350d2cd0c3fdd0f9fde55442128 @@ -528,7 +528,7 @@ F src/shell.c.in d2465e7747a014bd48a75c1bcf648e8e6cb46832dcc6e1293c5f285bc5542e8 F src/sqlite.h.in 5445ee2844c15bf277ebb64e910b56b0e6fb9377f184a81cd9bd78f0946be8c8 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 -F src/sqliteInt.h ed60d41dbb600515abdd5bbfd7f826f0238153d7d70fc3383f5e1179e131b3b8 +F src/sqliteInt.h 84d3b381b515acfd098152bb2c9a91fb3ea72b55e15dfc2b86c031da222a910c F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -589,7 +589,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e -F src/trigger.c 2305271878e95addc1c01361e5e8e342e87cba5efefdd7d3032687e5d67e05d1 +F src/trigger.c d115eb6c1e2a22e116e0c6e34c35e5b2029238238e05b9708fe1567434da3230 F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 @@ -1182,7 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test 522f0da68881b6ac616b1361fbd5a9897bd366597809495143968af743e3318c +F test/nulls1.test 6d226787ee0d479bc009e00b7fa812fb261fbb3eab764de18ecb988f4ec69f4a F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1837,7 +1837,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 b49df1fe9b7174ebc60023179e8da628c926e59df3dc01b15d4a28e17807bb97 -R 45771ddb0f2c68cf3dbfa90b9e4149c6 +P f892066425671a8a0ac923e3ad4744677f6434a66f97b91afa8141f11f179975 +R 453ca41ba88968d27d033b2c6ac5c131 U dan -Z 6452b2b9b9aca3f08bbef29f8e41e25a +Z d9760a7ecfe79d11a5b817a651ccacbf diff --git a/manifest.uuid b/manifest.uuid index b6a8464c5f..05637d33b1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f892066425671a8a0ac923e3ad4744677f6434a66f97b91afa8141f11f179975 \ No newline at end of file +bb9767a287097a615aeb4abdba689b10e1a1c36c016c8e55905b508075e62c86 \ No newline at end of file diff --git a/src/build.c b/src/build.c index 3f9ab0b975..106b995d31 100644 --- a/src/build.c +++ b/src/build.c @@ -3153,6 +3153,27 @@ Index *sqlite3AllocateIndexObject( return p; } +/* +** If expression list pList contains an expression that was parsed with +** an explicit "NULLS FIRST" or "NULLS LAST" clause, leave an error in +** pParse and return non-zero. Otherwise, return zero. +*/ +int sqlite3HasExplicitNulls(Parse *pParse, ExprList *pList){ + if( pList ){ + int i; + for(i=0; inExpr; i++){ + if( pList->a[i].bNulls ){ + u8 sf = pList->a[i].sortFlags; + sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", + (sf==0 || sf==3) ? "FIRST" : "LAST" + ); + return 1; + } + } + } + return 0; +} + /* ** Create a new index for an SQL table. pName1.pName2 is the name of the index ** and pTblList is the name of the table that is to be indexed. Both will @@ -3204,6 +3225,9 @@ void sqlite3CreateIndex( if( SQLITE_OK!=sqlite3ReadSchema(pParse) ){ goto exit_create_index; } + if( sqlite3HasExplicitNulls(pParse, pList) ){ + goto exit_create_index; + } /* ** Find the table that is to be indexed. Return early if not found. diff --git a/src/expr.c b/src/expr.c index c5072aa615..6948c5a0fe 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1653,6 +1653,7 @@ vector_append_error: ** Set the sort order for the last element on the given ExprList. */ void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ + struct ExprList_item *pItem; if( p==0 ) return; assert( p->nExpr>0 ); @@ -1666,10 +1667,18 @@ void sqlite3ExprListSetSortOrder(ExprList *p, int iSortOrder, int eNulls){ || eNulls==SQLITE_SO_DESC ); - if( iSortOrder==SQLITE_SO_UNDEFINED ) iSortOrder = SQLITE_SO_ASC; - p->a[p->nExpr-1].sortFlags = (u8)iSortOrder; - if( eNulls!=SQLITE_SO_UNDEFINED && iSortOrder!=eNulls ){ - p->a[p->nExpr-1].sortFlags |= KEYINFO_ORDER_BIGNULL; + pItem = &p->a[p->nExpr-1]; + assert( pItem->bNulls==0 ); + if( iSortOrder==SQLITE_SO_UNDEFINED ){ + iSortOrder = SQLITE_SO_ASC; + } + pItem->sortFlags = (u8)iSortOrder; + + if( eNulls!=SQLITE_SO_UNDEFINED ){ + pItem->bNulls = 1; + if( iSortOrder!=eNulls ){ + pItem->sortFlags |= KEYINFO_ORDER_BIGNULL; + } } } diff --git a/src/insert.c b/src/insert.c index 53d7e89b2a..04d3d580f5 100644 --- a/src/insert.c +++ b/src/insert.c @@ -833,6 +833,9 @@ void sqlite3Insert( pTab->zName); goto insert_cleanup; } + if( sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget) ){ + goto insert_cleanup; + } pTabList->a[0].iCursor = iDataCur; pUpsert->pUpsertSrc = pTabList; pUpsert->regData = regData; diff --git a/src/sqliteInt.h b/src/sqliteInt.h index c47cc6ffc7..b777409179 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2605,11 +2605,12 @@ struct ExprList { Expr *pExpr; /* The parse tree for this expression */ char *zName; /* Token associated with this expression */ char *zSpan; /* Original text of the expression */ - u8 sortFlags; /* 1 for DESC or 0 for ASC */ + u8 sortFlags; /* Mask of KEYINFO_ORDER_* flags */ unsigned done :1; /* A flag to indicate when processing is finished */ unsigned bSpanIsTab :1; /* zSpan holds DB.TABLE.COLUMN */ unsigned reusable :1; /* Constant expression is reusable */ unsigned bSorterRef :1; /* Defer evaluation until after sorting */ + unsigned bNulls: 1; /* True if explicit "NULLS FIRST/LAST" */ union { struct { u16 iOrderByCol; /* For ORDER BY, column number in result set */ @@ -4366,6 +4367,7 @@ void sqlite3KeyInfoUnref(KeyInfo*); KeyInfo *sqlite3KeyInfoRef(KeyInfo*); KeyInfo *sqlite3KeyInfoOfIndex(Parse*, Index*); KeyInfo *sqlite3KeyInfoFromExprList(Parse*, ExprList*, int, int); +int sqlite3HasExplicitNulls(Parse*, ExprList*); #ifdef SQLITE_DEBUG int sqlite3KeyInfoIsWriteable(KeyInfo*); diff --git a/src/trigger.c b/src/trigger.c index 989df9678a..84f80c23ee 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -463,6 +463,9 @@ TriggerStep *sqlite3TriggerInsertStep( pTriggerStep->pIdList = pColumn; pTriggerStep->pUpsert = pUpsert; pTriggerStep->orconf = orconf; + if( pUpsert ){ + sqlite3HasExplicitNulls(pParse, pUpsert->pUpsertTarget); + } }else{ testcase( pColumn ); sqlite3IdListDelete(db, pColumn); diff --git a/test/nulls1.test b/test/nulls1.test index 866ed2b296..dc7fb6e86b 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -83,5 +83,43 @@ do_execsql_test 2.2 { 1 1 1 } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(a, b, c, d, UNIQUE (b)); +} +foreach {tn sql err} { + 1 { CREATE INDEX i1 ON t1(a ASC NULLS LAST) } LAST + 2 { CREATE INDEX i1 ON t1(a ASC NULLS FIRST) } FIRST + 3 { CREATE INDEX i1 ON t1(a, b ASC NULLS LAST) } LAST + 4 { CREATE INDEX i1 ON t1(a, b ASC NULLS FIRST) } FIRST + 5 { CREATE INDEX i1 ON t1(a DESC NULLS LAST) } LAST + 6 { CREATE INDEX i1 ON t1(a DESC NULLS FIRST) } FIRST + 7 { CREATE INDEX i1 ON t1(a, b DESC NULLS LAST) } LAST + 8 { CREATE INDEX i1 ON t1(a, b DESC NULLS FIRST) } FIRST + 9 { CREATE TABLE t2(a, b, PRIMARY KEY(a DESC, b NULLS FIRST)) } FIRST + 10 { CREATE TABLE t2(a, b, UNIQUE(a DESC NULLS FIRST, b)) } FIRST + 11 { INSERT INTO t1 VALUES(1, 2, 3, 4) + ON CONFLICT (b DESC NULLS LAST) DO UPDATE SET a = a+1 } LAST + 12 { + CREATE TRIGGER tr1 AFTER INSERT ON t1 BEGIN + INSERT INTO t1 VALUES(1, 2, 3, 4) + ON CONFLICT (b DESC NULLS FIRST) DO UPDATE SET a = a+1; + END + } FIRST +} { + do_catchsql_test 3.1.$tn $sql "1 {unsupported use of NULLS $err}" +} + +do_execsql_test 3.2 { + CREATE TABLE first(nulls, last); + INSERT INTO first(last, nulls) VALUES(100,200), (300,400), (200,300); + SELECT * FROM first ORDER BY nulls; +} { + 200 100 + 300 200 + 400 300 +} + finish_test From ae8e45cb0c26457c9c020055cc3f8421954670d3 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 19 Aug 2019 19:59:50 +0000 Subject: [PATCH 026/112] Fix problems with window frames that use ORDER BY ... NULLS LAST etc. FossilOrigin-Name: 75d665a494dd7d6e77d5a80af386ee5accc0a53416d5493424dc0fef6c7b01a0 --- manifest | 24 +- manifest.uuid | 2 +- src/expr.c | 1 + src/window.c | 21 +- test/nulls1.test | 6 +- test/pg_common.tcl | 4 +- test/window7.test | 110 +++- test/window8.tcl | 41 +- test/window8.test | 1530 +++++++++++++++++++++++++++++++++++++++++--- 9 files changed, 1600 insertions(+), 139 deletions(-) diff --git a/manifest b/manifest index b8cb71e76a..2dac1918cc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Prevent\sNULLS\sFIRST/LAST\sfrom\sbeing\sused\sin\sCREATE\sINDEX\sand\sother\sstatements. -D 2019-08-19T17:26:32.202 +C Fix\sproblems\swith\swindow\sframes\sthat\suse\sORDER\sBY\s...\sNULLS\sLAST\setc. +D 2019-08-19T19:59:50.467 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 0a3442b0df31f1eca86b2aa3634f61bca5f1a6781f543ca9a0d87e29961f7f4f +F src/expr.c 223bd0d5132e217fc0967be55a0a31f5e06d4b61805176d487ffe4ce6b4c6a6e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -613,7 +613,7 @@ F src/where.c 52c433208eafdc7e1750ea4622cfffb5d14d906a0a9258e07bae4b6fee182fef F src/whereInt.h 807766a6a92893dbba8a887e5b13466d2257ce07a84cf1be0aae2c41aee3bf4f F src/wherecode.c 81c5d1eb909f8e1284df58367d25f748d126c475725665e7bb9b10a9bf702242 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc -F src/window.c 331cdac4992c7402da01c981861f3cc989bf7b4a97dd03eb122993e670f7a588 +F src/window.c 94dccce0568dbcc65658d762e5b11c390fd5509d40e73205cb7f0c22f0051532 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1182,7 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test 6d226787ee0d479bc009e00b7fa812fb261fbb3eab764de18ecb988f4ec69f4a +F test/nulls1.test d2f1da489fd24d7af54aed9d7e117e4c7d6bb3e67f3a87ef54377cc088563073 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1217,7 +1217,7 @@ F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff F test/permutations.test 4282fb00e5ac0f8c2cd1be62652f6da4ac03ce3c58b7d785fa17f4684492a0e0 -F test/pg_common.tcl 4740dc35190d6acdab14c097783331361301ab504a94d948f6afbb56ce0a51e8 +F test/pg_common.tcl 222a1bad1c41c308fa366313cd7b51b3be7e9b21c8736a421b974ac941693b54 F test/pragma.test cf066fe0f7f5d49f4758de4986407b8676c61aaa7871599340d64f42a8edc352 F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f F test/pragma3.test 8300aa9c63cff1027006ca34bf413a148abbd6dcd471fa9a1ded322fe18c0df9 @@ -1710,9 +1710,9 @@ F test/window4.test 807f3e6b15f9338e5b9742b87c5c7ca825b42b9657fde6096e8901193708 F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32 F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f -F test/window7.test ce7f865241fdd1c5c4db869cd7bb2986c3be836bc2e73649a6846dd920f63e0f -F test/window8.tcl 9e9a82ae9eea90a4a83481d641a812b974980c38f9247f3b89a6e3c8bed45518 -F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91d43f +F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd +F test/window8.tcl 5884cc884f9605bf88c0d18a534894bf9342f72687bf1bc43ed0cab4c8af7973 +F test/window8.test 48590f3737d17eec503d77769c13ead15d12e8819820b1dc68afe8a3c5bc3250 F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b @@ -1837,7 +1837,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 f892066425671a8a0ac923e3ad4744677f6434a66f97b91afa8141f11f179975 -R 453ca41ba88968d27d033b2c6ac5c131 +P bb9767a287097a615aeb4abdba689b10e1a1c36c016c8e55905b508075e62c86 +R 0d189432ffc682f45a241a646815eff1 U dan -Z d9760a7ecfe79d11a5b817a651ccacbf +Z 3a5c6bb3c2c9a1118645ddff85026963 diff --git a/manifest.uuid b/manifest.uuid index 05637d33b1..7a21ed26bb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bb9767a287097a615aeb4abdba689b10e1a1c36c016c8e55905b508075e62c86 \ No newline at end of file +75d665a494dd7d6e77d5a80af386ee5accc0a53416d5493424dc0fef6c7b01a0 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6948c5a0fe..e0b55903d6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1401,6 +1401,7 @@ ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){ pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortFlags = pOldItem->sortFlags; pItem->done = 0; + pItem->bNulls = pOldItem->bNulls; pItem->bSpanIsTab = pOldItem->bSpanIsTab; pItem->bSorterRef = pOldItem->bSorterRef; pItem->u = pOldItem->u; diff --git a/src/window.c b/src/window.c index b3a7cee1bc..80dfd612c4 100644 --- a/src/window.c +++ b/src/window.c @@ -1876,12 +1876,13 @@ static void windowCodeRangeTest( int reg2 = sqlite3GetTempReg(pParse); int arith = OP_Add; int addrGe; + ExprList *pOrderBy = p->pMWin->pOrderBy; int regString = ++pParse->nMem; assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); - assert( p->pMWin->pOrderBy && p->pMWin->pOrderBy->nExpr==1 ); - if( p->pMWin->pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){ + assert( pOrderBy && pOrderBy->nExpr==1 ); + if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_DESC ){ switch( op ){ case OP_Ge: op = OP_Le; break; case OP_Gt: op = OP_Lt; break; @@ -1901,6 +1902,22 @@ static void windowCodeRangeTest( VdbeCoverage(v); sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); sqlite3VdbeJumpHere(v, addrGe); + if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){ + int addr; + addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); + switch( op ){ + case OP_Ge: sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; + case OP_Gt: sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); break; + case OP_Le: sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); break; + default: assert( op==OP_Lt ); /* no-op */ + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); + if( op==OP_Gt || op==OP_Ge ){ + sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1); + } + } sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); diff --git a/test/nulls1.test b/test/nulls1.test index dc7fb6e86b..e54d60856d 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -15,8 +15,6 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix nulls1 -if 1 { - do_execsql_test 1.0 { DROP TABLE IF EXISTS t3; CREATE TABLE t3(a INTEGER); @@ -55,8 +53,6 @@ for {set a 0} {$a < 3} {incr a} { } } -} - #------------------------------------------------------------------------- reset_db do_execsql_test 2.0 { @@ -84,6 +80,7 @@ do_execsql_test 2.2 { } #------------------------------------------------------------------------- +# reset_db do_execsql_test 3.0 { CREATE TABLE t1(a, b, c, d, UNIQUE (b)); @@ -121,5 +118,4 @@ do_execsql_test 3.2 { 400 300 } - finish_test diff --git a/test/pg_common.tcl b/test/pg_common.tcl index bbc52ebede..b3f35cd0ed 100644 --- a/test/pg_common.tcl +++ b/test/pg_common.tcl @@ -70,8 +70,8 @@ proc execsql {sql} { proc execsql_test {tn sql} { set res [execsql $sql] set sql [string map {string_agg group_concat} $sql] - set sql [string map [list {NULLS FIRST} {}] $sql] - set sql [string map [list {NULLS LAST} {}] $sql] + # set sql [string map [list {NULLS FIRST} {}] $sql] + # set sql [string map [list {NULLS LAST} {}] $sql] puts $::fd "do_execsql_test $tn {" puts $::fd " [string trim $sql]" puts $::fd "} {$res}" diff --git a/test/window7.test b/test/window7.test index fd04e23c43..441e2b126a 100644 --- a/test/window7.test +++ b/test/window7.test @@ -41,54 +41,146 @@ do_execsql_test 1.0 { do_execsql_test 1.1 { SELECT a, sum(b) FROM t3 GROUP BY a ORDER BY 1; -} {0 550 1 460 2 470 3 480 4 490 5 500 6 510 7 520 8 530 9 540} +} {0 550 1 460 2 470 3 480 4 490 5 500 6 510 7 520 8 530 + 9 540} do_execsql_test 1.2 { SELECT a, sum(b) OVER ( ORDER BY a GROUPS BETWEEN CURRENT ROW AND CURRENT ROW ) FROM t3 ORDER BY 1; -} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} +} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 + 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 + 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 + 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 + 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 + 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 + 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 + 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 + 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 + 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 + 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 + 9 540} do_execsql_test 1.3 { SELECT a, sum(b) OVER ( ORDER BY a GROUPS BETWEEN 0 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1; -} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} +} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 + 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 + 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 + 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 + 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 + 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 + 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 + 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 + 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 + 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 + 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 + 9 540} do_execsql_test 1.4 { SELECT a, sum(b) OVER ( ORDER BY a GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING ) FROM t3 ORDER BY 1; -} {0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590} +} {0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 + 0 1480 0 1480 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 + 1 1960 1 1960 1 1960 1 1960 2 2450 2 2450 2 2450 2 2450 + 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 3 2400 3 2400 + 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 + 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 + 4 2450 4 2450 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 + 5 2500 5 2500 5 2500 5 2500 6 2550 6 2550 6 2550 6 2550 + 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 7 2600 7 2600 + 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 + 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 + 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 + 9 1590 9 1590 9 1590 9 1590} do_execsql_test 1.5 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING ) FROM t3 ORDER BY 1; -} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} +} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 + 0 550 1 460 1 460 1 460 1 460 1 460 1 460 1 460 1 460 + 1 460 1 460 2 470 2 470 2 470 2 470 2 470 2 470 2 470 + 2 470 2 470 2 470 3 480 3 480 3 480 3 480 3 480 3 480 + 3 480 3 480 3 480 3 480 4 490 4 490 4 490 4 490 4 490 + 4 490 4 490 4 490 4 490 4 490 5 500 5 500 5 500 5 500 + 5 500 5 500 5 500 5 500 5 500 5 500 6 510 6 510 6 510 + 6 510 6 510 6 510 6 510 6 510 6 510 6 510 7 520 7 520 + 7 520 7 520 7 520 7 520 7 520 7 520 7 520 7 520 8 530 + 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 8 530 + 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 + 9 540} do_execsql_test 1.6 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 2 PRECEDING AND 2 FOLLOWING ) FROM t3 ORDER BY 1; -} {0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590} +} {0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 0 1480 + 0 1480 0 1480 1 1960 1 1960 1 1960 1 1960 1 1960 1 1960 + 1 1960 1 1960 1 1960 1 1960 2 2450 2 2450 2 2450 2 2450 + 2 2450 2 2450 2 2450 2 2450 2 2450 2 2450 3 2400 3 2400 + 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 3 2400 + 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 4 2450 + 4 2450 4 2450 5 2500 5 2500 5 2500 5 2500 5 2500 5 2500 + 5 2500 5 2500 5 2500 5 2500 6 2550 6 2550 6 2550 6 2550 + 6 2550 6 2550 6 2550 6 2550 6 2550 6 2550 7 2600 7 2600 + 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 7 2600 + 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 + 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 + 9 1590 9 1590 9 1590 9 1590} do_execsql_test 1.7 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 2 PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1; -} {0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590} +} {0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 + 0 1010 0 1010 1 1480 1 1480 1 1480 1 1480 1 1480 1 1480 + 1 1480 1 1480 1 1480 1 1480 2 1960 2 1960 2 1960 2 1960 + 2 1960 2 1960 2 1960 2 1960 2 1960 2 1960 3 1900 3 1900 + 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 3 1900 + 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 4 1940 + 4 1940 4 1940 5 1980 5 1980 5 1980 5 1980 5 1980 5 1980 + 5 1980 5 1980 5 1980 5 1980 6 2020 6 2020 6 2020 6 2020 + 6 2020 6 2020 6 2020 6 2020 6 2020 6 2020 7 2060 7 2060 + 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 7 2060 + 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 8 2100 + 8 2100 8 2100 9 1590 9 1590 9 1590 9 1590 9 1590 9 1590 + 9 1590 9 1590 9 1590 9 1590} do_execsql_test 1.8.1 { SELECT a, sum(b) OVER ( ORDER BY a RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1; -} {0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 1 930 1 930 1 930 1 930 1 930 1 930 1 930 1 930 1 930 1 930 2 950 2 950 2 950 2 950 2 950 2 950 2 950 2 950 2 950 2 950 3 970 3 970 3 970 3 970 3 970 3 970 3 970 3 970 3 970 3 970 4 990 4 990 4 990 4 990 4 990 4 990 4 990 4 990 4 990 4 990 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 8 1070 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540 9 540} +} {0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 0 1010 + 0 1010 0 1010 1 930 1 930 1 930 1 930 1 930 1 930 1 930 + 1 930 1 930 1 930 2 950 2 950 2 950 2 950 2 950 2 950 + 2 950 2 950 2 950 2 950 3 970 3 970 3 970 3 970 3 970 + 3 970 3 970 3 970 3 970 3 970 4 990 4 990 4 990 4 990 + 4 990 4 990 4 990 4 990 4 990 4 990 5 1010 5 1010 5 1010 + 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 5 1010 6 1030 + 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 6 1030 + 6 1030 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 7 1050 + 7 1050 7 1050 7 1050 8 1070 8 1070 8 1070 8 1070 8 1070 + 8 1070 8 1070 8 1070 8 1070 8 1070 9 540 9 540 9 540 9 540 + 9 540 9 540 9 540 9 540 9 540 9 540} do_execsql_test 1.8.2 { SELECT a, sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 0 PRECEDING AND 1 FOLLOWING ) FROM t3 ORDER BY 1; -} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 2 930 2 930 2 930 2 930 2 930 2 930 2 930 2 930 2 930 2 930 3 950 3 950 3 950 3 950 3 950 3 950 3 950 3 950 3 950 3 950 4 970 4 970 4 970 4 970 4 970 4 970 4 970 4 970 4 970 4 970 5 990 5 990 5 990 5 990 5 990 5 990 5 990 5 990 5 990 5 990 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070} +} {0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 0 550 + 0 550 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 1 1010 + 1 1010 1 1010 1 1010 2 930 2 930 2 930 2 930 2 930 2 930 + 2 930 2 930 2 930 2 930 3 950 3 950 3 950 3 950 3 950 + 3 950 3 950 3 950 3 950 3 950 4 970 4 970 4 970 4 970 + 4 970 4 970 4 970 4 970 4 970 4 970 5 990 5 990 5 990 + 5 990 5 990 5 990 5 990 5 990 5 990 5 990 6 1010 6 1010 + 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 6 1010 + 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 7 1030 + 7 1030 7 1030 8 1050 8 1050 8 1050 8 1050 8 1050 8 1050 + 8 1050 8 1050 8 1050 8 1050 9 1070 9 1070 9 1070 9 1070 + 9 1070 9 1070 9 1070 9 1070 9 1070 9 1070} finish_test diff --git a/test/window8.tcl b/test/window8.tcl index df1fd78ab7..64fd98aea9 100644 --- a/test/window8.tcl +++ b/test/window8.tcl @@ -197,30 +197,55 @@ execsql_test 4.2.1 { ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } - execsql_test 4.2.2 { + SELECT sum(b) OVER ( + ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} + +execsql_test 4.2.3 { SELECT sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } +execsql_test 4.2.4 { + SELECT sum(b) OVER ( + ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} execsql_test 4.3.1 { SELECT sum(b) OVER ( ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } +execsql_test 4.3.2 { + SELECT sum(b) OVER ( + ORDER BY a NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} execsql_test 4.4.1 { SELECT sum(b) OVER ( ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } - execsql_test 4.4.2 { + SELECT sum(b) OVER ( + ORDER BY a NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} + +execsql_test 4.4.3 { SELECT sum(b) OVER ( ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING ) FROM t1 ORDER BY 1 NULLS FIRST; } +execsql_test 4.4.4 { + SELECT sum(b) OVER ( + ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} ========== @@ -248,6 +273,17 @@ foreach {tn ex} { 6 { ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING } 7 { ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING } + + 8 { RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } + 9 { ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } + 10 { PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING } + 11 { ORDER BY a NULLS LAST GROUPS 6 PRECEDING } + 12 { ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING } + 13 { ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING } + 14 { ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING } } { execsql_test 5.$tn.$tn2.1 " SELECT max(c) OVER win, @@ -294,6 +330,7 @@ execsql_test 6.2 { } + finish_test diff --git a/test/window8.test b/test/window8.test index 829bd0b252..e149979cd4 100644 --- a/test/window8.test +++ b/test/window8.test @@ -3522,31 +3522,61 @@ do_execsql_test 4.1.2 { do_execsql_test 4.2.1 { SELECT sum(b) OVER ( ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING - ) FROM t1 ORDER BY 1 ; + ) FROM t1 ORDER BY 1 NULLS FIRST; } {{} {} 6 6 6} do_execsql_test 4.2.2 { + SELECT sum(b) OVER ( + ORDER BY a RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} {6 6 6 {} {}} + +do_execsql_test 4.2.3 { SELECT sum(b) OVER ( ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING - ) FROM t1 ORDER BY 1 ; + ) FROM t1 ORDER BY 1 NULLS FIRST; } {{} {} 6 6 6} +do_execsql_test 4.2.4 { + SELECT sum(b) OVER ( + ORDER BY a DESC RANGE BETWEEN 5 FOLLOWING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} {6 6 6 {} {}} + do_execsql_test 4.3.1 { SELECT sum(b) OVER ( - ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING - ) FROM t1 ORDER BY 1 ; + ORDER BY a NULLS FIRST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS FIRST; } {6 6 6 15 15} +do_execsql_test 4.3.2 { + SELECT sum(b) OVER ( + ORDER BY a NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} {9 9 15 15 15} + do_execsql_test 4.4.1 { SELECT sum(b) OVER ( - ORDER BY a ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING - ) FROM t1 ORDER BY 1 ; + ORDER BY a NULLS FIRST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS FIRST; } {3 6 9 9 12} do_execsql_test 4.4.2 { SELECT sum(b) OVER ( - ORDER BY a DESC ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING - ) FROM t1 ORDER BY 1 ; + ORDER BY a NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} {5 6 8 9 10} + +do_execsql_test 4.4.3 { + SELECT sum(b) OVER ( + ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS FIRST; +} {5 6 8 9 10} + +do_execsql_test 4.4.4 { + SELECT sum(b) OVER ( + ORDER BY a DESC NULLS LAST ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; } {5 6 8 9 10} #========================================================================== @@ -3564,7 +3594,7 @@ do_execsql_test 5.1.1.1 { count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 @@ -3587,7 +3617,7 @@ do_execsql_test 5.1.1.2 { dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 @@ -3609,9 +3639,9 @@ do_execsql_test 5.1.2.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 979 102 44 979 102 44 @@ -3633,9 +3663,9 @@ do_execsql_test 5.1.2.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 5287 74 10 5287 74 10 5287 74 10 5287 74 10 5287 74 10 5287 74 10 5287 74 10 8400 65 9 8400 65 9 @@ -3659,7 +3689,7 @@ do_execsql_test 5.1.3.1 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {777 113 5 777 113 5 777 113 5 777 113 5 777 113 5 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 @@ -3683,7 +3713,7 @@ do_execsql_test 5.1.3.2 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 @@ -3703,8 +3733,8 @@ do_execsql_test 5.1.4.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 934 158 21 934 158 21 934 158 21 934 158 21 @@ -3726,8 +3756,8 @@ do_execsql_test 5.1.4.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 4359 7 2 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 7840 15 3 @@ -3750,8 +3780,8 @@ do_execsql_test 5.1.5.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 160 158 2 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 @@ -3773,8 +3803,8 @@ do_execsql_test 5.1.5.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 @@ -3795,8 +3825,8 @@ do_execsql_test 5.1.6.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 158 158 1 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 @@ -3818,8 +3848,8 @@ do_execsql_test 5.1.6.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 @@ -3840,9 +3870,9 @@ do_execsql_test 5.1.7.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 @@ -3864,9 +3894,335 @@ do_execsql_test 5.1.7.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 + 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 + 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 + 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66 + 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62 + 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56 + 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52 + 17126 49 49 17126 50 50 17126 51 51 17733 44 44 17733 45 45 + 17733 46 46 17733 47 47 17733 48 48 18176 42 42 18176 43 43 + 18597 40 40 18597 41 41 18996 39 39 19395 37 37 19395 38 38 + 19788 36 36 20181 35 35 20536 34 34 20891 30 30 20891 31 31 + 20891 32 32 20891 33 33 21226 28 28 21226 29 29 21535 27 27 + 21830 26 26 22087 22 22 22087 23 23 22087 24 24 22087 25 25 + 22334 21 21 22573 17 17 22573 18 18 22573 19 19 22573 20 20 + 22796 11 11 22796 12 12 22796 13 13 22796 14 14 22796 15 15 + 22796 16 16 22929 10 10 23042 9 9 23155 1 1 23155 2 2 23155 3 3 + 23155 4 4 23155 5 5 23155 6 6 23155 7 7 23155 8 8} + +do_execsql_test 5.1.8.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83} + +do_execsql_test 5.1.8.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} + +do_execsql_test 5.1.9.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 + 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 + 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 + 899 113 16 899 113 16 899 113 16 899 113 16 979 102 44 979 102 44 + 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 + 979 102 44 979 102 44 979 102 44 979 102 49 979 102 49 979 102 49 + 979 102 49 979 102 49 979 102 56 979 102 56 979 102 56 979 102 56 + 979 102 56 979 102 56 979 102 56 979 102 62 979 102 62 979 102 62 + 979 102 62 979 102 62 979 102 62 979 102 75 979 102 75 979 102 75 + 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 + 979 102 75 979 102 75 979 102 75 979 102 75 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 + 979 113 25 979 113 25 979 113 25 979 113 33 979 113 33 979 113 33 + 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33} + +do_execsql_test 5.1.9.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {2050 84 11 2050 84 11 2050 84 11 2050 84 11 2050 84 11 2050 84 11 + 4997 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 4997 75 10 + 4997 75 10 4997 75 10 4997 75 10 7337 68 9 7337 68 9 7337 68 9 + 7337 68 9 7337 68 9 7337 68 9 7337 68 9 10450 59 8 10450 59 8 + 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 10450 59 8 + 10450 59 8 11714 51 7 11714 51 7 11714 51 7 11714 51 7 11714 51 7 + 11714 51 7 11714 51 7 11714 51 7 12676 40 6 12676 40 6 12676 40 6 + 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 + 12676 40 6 12676 40 6 14195 35 5 14195 35 5 14195 35 5 14195 35 5 + 14195 35 5 15999 28 4 15999 28 4 15999 28 4 15999 28 4 15999 28 4 + 15999 28 4 15999 28 4 17365 22 3 17365 22 3 17365 22 3 17365 22 3 + 17365 22 3 17365 22 3 20846 9 2 20846 9 2 20846 9 2 20846 9 2 + 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 20846 9 2 + 20846 9 2 20846 9 2 20846 9 2 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} + +do_execsql_test 5.1.10.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {777 113 5 777 113 5 777 113 5 777 113 5 777 113 5 805 250 7 + 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 805 250 7 + 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 822 158 6 + 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 + 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 840 247 13 + 840 247 13 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 + 870 158 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 + 899 113 9 899 113 9 899 113 9 899 113 9 934 223 8 934 223 8 + 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 + 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 + 938 102 11 938 102 11 938 102 11 938 102 11 938 102 11 938 148 8 + 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8 938 148 8 + 938 148 8 959 224 7 959 224 7 959 224 7 959 224 7 959 224 7 + 959 224 7 959 224 7 979 133 9 979 133 9 979 133 9 979 133 9 + 979 133 9 979 133 9 979 133 9 979 133 9 979 133 9} + +do_execsql_test 5.1.10.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 + 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 1264 1 1 + 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 + 1366 1 1 1366 1 1 1366 1 1 1366 1 1 1519 1 1 1519 1 1 1519 1 1 + 1519 1 1 1519 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 1804 1 1 + 1804 1 1 1804 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 2050 1 1 + 2050 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 + 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 2340 1 1 + 2340 1 1 2340 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2947 1 1 + 2947 1 1 2947 1 1 2947 1 1 2947 1 1 3113 1 1 3113 1 1 3113 1 1 + 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3481 1 1 + 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1 + 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1} + +do_execsql_test 5.1.11.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 + 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 + 934 223 8 934 223 8 934 223 21 934 223 21 934 223 21 934 223 21 + 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 934 223 21 + 934 223 21 934 223 21 934 223 21 959 102 50 959 102 50 959 102 50 + 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 + 959 102 50 959 102 50 959 102 58 959 102 58 959 102 58 959 102 58 + 959 102 58 959 102 58 959 102 58 959 102 58 959 113 39 959 113 39 + 959 113 39 959 113 39 959 113 39 959 158 34 959 158 34 959 158 34 + 959 158 34 959 158 34 959 158 34 959 158 34 979 102 49 979 102 49 + 979 102 49 979 102 49 979 102 49 979 102 49 979 102 53 979 102 53 + 979 102 53 979 102 53 979 102 53 979 102 53 979 102 53 979 102 56 + 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 + 979 102 56 979 102 56 979 102 59 979 102 59 979 102 59 979 102 59 + 979 102 59 979 102 59 979 102 59 979 102 59 979 102 59} + +do_execsql_test 5.1.11.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 2309 1 1 + 2309 1 1 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 + 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 + 7156 22 3 7156 22 3 7156 22 3 7156 22 3 7156 22 3 7156 22 3 + 8960 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 + 8960 28 4 10479 35 5 10479 35 5 10479 35 5 10479 35 5 10479 35 5 + 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 + 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 12368 68 9 + 12368 68 9 12368 68 9 12368 68 9 12368 68 9 12368 68 9 12368 68 9 + 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12705 51 7 + 12705 51 7 12705 51 7 13509 59 8 13509 59 8 13509 59 8 13509 59 8 + 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13509 59 8 + 13949 75 10 13949 75 10 13949 75 10 13949 75 10 13949 75 10 + 13949 75 10 13949 75 10 13949 75 10 13949 75 10 14195 84 11 + 14195 84 11 14195 84 11 14195 84 11 14195 84 11 14195 84 11} + +do_execsql_test 5.1.12.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 160 158 2 + 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 + 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 + 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3 + 346 346 1 355 354 2 355 354 2 355 354 2 399 393 4 399 393 4 + 399 393 4 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1 + 443 443 1 480 480 2 480 480 2 574 572 2 574 572 2 607 607 1 + 618 618 2 618 618 2 634 627 4 634 627 4 634 627 4 634 627 4 + 634 629 3 652 652 1 667 660 2 671 667 3 671 667 3 671 667 3 + 671 667 3 683 683 1 711 705 2 716 705 3 716 711 2 730 726 2 + 730 726 2 762 759 2 768 759 4 768 762 3 768 762 3 777 777 1 + 792 786 3 794 786 4 794 786 4 794 790 3 805 805 1 822 822 1 + 845 839 5 845 839 5 845 839 5 845 839 5 845 839 5 870 870 2 + 870 870 2 870 870 2 899 899 1 911 911 1 934 929 2 938 929 4 + 938 934 3 938 934 3 963 959 2 963 959 2 979 979 1} + +do_execsql_test 5.1.12.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 + {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 + {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 + {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72 + {} 85 72 133 4 3 223 10 8 223 11 9 226 2 2 226 2 2 239 12 10 + 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18 + 309 21 19 335 22 20 335 23 21 335 24 22 421 35 30 443 37 32 + 504 16 14 504 17 15 607 42 36 683 56 47 710 26 24 710 27 25 + 710 27 25 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61 + 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1334 51 43 + 1416 57 48 1416 58 49 1584 29 26 1584 29 26 1584 31 27 1584 32 28 + 1584 32 28 1891 49 41 1922 87 73 1922 88 74 2005 52 44 2005 52 44 + 2005 54 45 2005 55 46 2518 45 38 2518 46 39 2518 46 39 2518 48 40 + 2523 73 63 2523 73 63 2523 75 64 2523 76 65 2523 77 66} + +do_execsql_test 5.1.13.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {102 102 1 113 113 2 113 113 2 133 133 1 148 148 1 158 158 1 + 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 + 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 + 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 + 346 346 1 354 354 1 355 355 1 355 355 1 393 393 2 393 393 2 + 398 398 1 399 399 1 399 399 1 412 412 1 421 421 1 430 430 1 + 443 443 1 480 480 2 480 480 2 572 572 1 574 574 1 607 607 1 + 618 618 2 618 618 2 627 627 1 629 629 1 629 629 1 633 633 1 + 634 634 1 652 652 1 660 660 1 667 667 1 667 667 1 670 670 1 + 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 + 730 730 1 759 759 1 762 762 1 768 768 2 768 768 2 777 777 1 + 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 + 839 839 2 839 839 2 840 840 1 844 844 1 845 845 1 870 870 2 + 870 870 2 870 870 2 899 899 1 911 911 1 929 929 1 934 934 1 + 938 938 2 938 938 2 959 959 1 963 963 1 979 979 1} + +do_execsql_test 5.1.13.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 + {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 + {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 + {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45 + {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57 + {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67 + {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 133 4 3 223 10 8 + 226 2 2 226 2 2 239 14 12 247 15 13 257 19 17 295 20 18 + 309 21 19 335 23 21 421 35 30 443 37 32 607 42 36 627 45 38 + 633 48 40 671 55 46 683 56 47 705 57 48 710 27 25 710 27 25 + 711 58 49 759 62 53 777 66 56 786 29 26 786 29 26 798 32 28 + 798 32 28 805 71 61 845 77 66 899 81 68 911 82 69 929 83 70 + 959 87 73 963 88 74 979 89 75 1258 46 39 1258 46 39 1334 52 44 + 1334 52 44 1678 73 63 1678 73 63} + +do_execsql_test 5.1.14.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 + 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 + 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67 + 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61 + 979 346 60 979 354 59 979 355 57 979 355 58 979 393 56 979 393 57 + 979 398 55 979 399 53 979 399 54 979 412 53 979 421 52 979 430 51 + 979 443 50 979 480 48 979 480 49 979 572 47 979 574 46 979 607 45 + 979 618 43 979 618 44 979 627 42 979 629 40 979 629 41 979 633 40 + 979 634 39 979 652 38 979 660 37 979 667 35 979 667 36 979 670 35 + 979 671 34 979 683 33 979 705 32 979 711 31 979 716 30 979 726 29 + 979 730 28 979 759 27 979 762 26 979 768 24 979 768 25 979 777 23 + 979 786 22 979 790 21 979 792 20 979 794 19 979 805 18 979 822 17 + 979 839 15 979 839 16 979 840 14 979 844 13 979 845 12 979 870 9 + 979 870 10 979 870 11 979 899 9 979 911 8 979 929 7} + +do_execsql_test 5.1.14.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE NO OTHERS ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 @@ -3891,7 +4247,7 @@ do_execsql_test 5.2.1.1 { count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 @@ -3914,7 +4270,7 @@ do_execsql_test 5.2.1.2 { dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {22176 1 1 22192 1 1 22196 1 1 22226 1 1 22244 1 1 22256 1 1 22310 1 1 22316 1 1 22316 1 1 22350 1 1 22378 1 1 22396 1 1 22444 1 1 22450 1 1 22472 1 1 22484 1 1 22488 1 1 22488 1 1 @@ -3936,9 +4292,9 @@ do_execsql_test 5.2.2.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {839 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 113 15 899 234 8 963 113 24 979 102 43 @@ -3960,9 +4316,9 @@ do_execsql_test 5.2.2.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2048 81 11 2108 81 11 2108 81 11 2690 81 11 2834 81 11 2947 81 11 2947 81 11 2947 81 11 2947 81 11 4482 74 10 4616 74 10 4844 74 10 4866 74 10 5287 74 10 5287 74 10 5287 74 10 7421 65 9 7437 65 9 @@ -3986,7 +4342,7 @@ do_execsql_test 5.2.3.1 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {667 158 0 671 250 6 759 158 5 768 113 4 777 113 4 777 113 4 777 113 4 777 252 4 792 247 12 805 250 6 805 250 6 805 250 6 805 250 6 805 250 6 805 398 6 822 158 5 822 158 5 822 158 5 @@ -4010,7 +4366,7 @@ do_execsql_test 5.2.3.2 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {295 1 1 335 1 1 607 1 1 667 1 1 742 1 1 759 1 1 845 1 1 890 1 1 929 1 1 959 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 @@ -4030,8 +4386,8 @@ do_execsql_test 5.2.4.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {667 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 355 0 911 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 7 934 158 20 934 158 20 934 158 20 934 158 20 @@ -4053,8 +4409,8 @@ do_execsql_test 5.2.4.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {1383 1 1 1421 1 1 1651 1 1 1695 1 1 2050 1 1 2050 1 1 3448 7 2 3732 7 2 4050 7 2 4120 7 2 4136 7 2 4359 7 2 4359 7 2 4359 7 2 7129 15 3 7135 15 3 7207 15 3 7441 15 3 7447 15 3 7447 15 3 @@ -4077,8 +4433,8 @@ do_execsql_test 5.2.5.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1 @@ -4100,8 +4456,8 @@ do_execsql_test 5.2.5.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23 {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 @@ -4122,8 +4478,8 @@ do_execsql_test 5.2.6.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 @@ -4144,8 +4500,8 @@ do_execsql_test 5.2.6.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 {} 23 21 {} 24 22 @@ -4165,9 +4521,9 @@ do_execsql_test 5.2.7.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 @@ -4189,9 +4545,334 @@ do_execsql_test 5.2.7.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 + 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 + 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 + 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65 + 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63 + 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56 + 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52 + 17100 48 48 17104 46 46 17104 47 47 17106 45 45 17126 49 49 + 17126 50 50 17126 51 51 17569 42 42 17733 44 44 18176 43 43 + 18597 40 40 18597 41 41 18952 37 37 18996 39 39 19395 38 38 + 19760 35 35 19788 36 36 20492 32 32 20492 33 33 20498 30 30 + 20536 34 34 20833 29 29 20871 28 28 20891 31 31 21180 27 27 + 21752 23 23 21830 26 26 22025 21 21 22087 22 22 22087 24 24 + 22087 25 25 22278 20 20 22316 19 19 22549 15 15 22557 14 14 + 22573 17 17 22573 18 18 22706 10 10 22796 11 11 22796 12 12 + 22796 13 13 22796 16 16 23022 4 4 23042 2 2 23042 3 3 23042 9 9 + 23155 1 1 23155 5 5 23155 6 6 23155 7 7 23155 8 8} + +do_execsql_test 5.2.8.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {963 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 102 83 + 979 102 83 979 102 83 979 102 83 979 102 83 979 113 82} + +do_execsql_test 5.2.8.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {22176 1 1 22192 1 1 22196 1 1 22226 1 1 22244 1 1 22256 1 1 + 22310 1 1 22316 1 1 22316 1 1 22350 1 1 22378 1 1 22396 1 1 + 22444 1 1 22450 1 1 22472 1 1 22484 1 1 22488 1 1 22488 1 1 + 22522 1 1 22526 1 1 22526 1 1 22528 1 1 22548 1 1 22712 1 1 + 22734 1 1 22756 1 1 22756 1 1 22762 1 1 22762 1 1 22800 1 1 + 22800 1 1 22820 1 1 22846 1 1 22860 1 1 22898 1 1 22908 1 1 + 22916 1 1 22932 1 1 23022 1 1 23042 1 1 23042 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1 + 23155 1 1 23155 1 1 23155 1 1 23155 1 1 23155 1 1} + +do_execsql_test 5.2.9.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {667 158 0 870 113 8 870 158 0 870 158 0 870 158 0 870 158 0 + 870 355 0 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 + 899 113 8 899 113 8 899 113 15 899 113 15 899 113 15 899 113 15 + 899 113 15 899 113 15 899 113 15 899 158 8 963 113 24 979 102 43 + 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 979 102 43 + 979 102 43 979 102 43 979 102 43 979 102 48 979 102 48 979 102 48 + 979 102 48 979 102 48 979 102 55 979 102 55 979 102 55 979 102 55 + 979 102 55 979 102 55 979 102 55 979 102 61 979 102 61 979 102 61 + 979 102 61 979 102 61 979 102 61 979 102 74 979 102 74 979 102 74 + 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 979 102 74 + 979 102 74 979 102 74 979 102 74 979 102 74 979 102 82 979 102 82 + 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24 979 113 24 + 979 113 24 979 113 24 979 113 32 979 113 32 979 113 32 979 113 32 + 979 113 32 979 113 32 979 113 32 979 113 32 979 113 43} + +do_execsql_test 5.2.9.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {1383 84 11 1421 84 11 1651 84 11 1695 84 11 2050 84 11 2050 84 11 + 4098 75 10 4158 75 10 4158 75 10 4740 75 10 4884 75 10 4997 75 10 + 4997 75 10 4997 75 10 4997 75 10 6532 68 9 6666 68 9 6894 68 9 + 6916 68 9 7337 68 9 7337 68 9 7337 68 9 9471 59 8 9487 59 8 + 9767 59 8 10095 59 8 10317 59 8 10450 59 8 10450 59 8 10450 59 8 + 10450 59 8 10785 51 7 11379 51 7 11714 51 7 11714 51 7 11714 51 7 + 11714 51 7 11714 51 7 11714 51 7 12009 40 6 12381 40 6 12676 40 6 + 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 12676 40 6 + 12676 40 6 12676 40 6 13418 35 5 13566 35 5 14082 35 5 14195 35 5 + 14195 35 5 15040 28 4 15154 28 4 15999 28 4 15999 28 4 15999 28 4 + 15999 28 4 15999 28 4 16606 22 3 16758 22 3 17365 22 3 17365 22 3 + 17365 22 3 17365 22 3 20135 9 2 20141 9 2 20213 9 2 20447 9 2 + 20453 9 2 20453 9 2 20599 9 2 20846 9 2 20846 9 2 20846 9 2 + 20846 9 2 20846 9 2 20846 9 2 22244 1 1 22528 1 1 22846 1 1 + 22916 1 1 22932 1 1 23155 1 1 23155 1 1 23155 1 1} + +do_execsql_test 5.2.10.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {667 158 0 671 250 6 759 158 5 768 113 4 777 113 4 777 113 4 + 777 113 4 777 252 4 792 247 12 805 250 6 805 250 6 805 250 6 + 805 250 6 805 250 6 805 398 6 822 158 5 822 158 5 822 158 5 + 822 158 5 822 346 5 839 113 8 840 247 12 840 247 12 840 247 12 + 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 840 247 12 + 840 247 12 840 247 12 840 393 12 845 224 6 870 102 10 870 158 0 + 870 158 0 870 158 0 870 158 0 870 355 0 899 113 8 899 113 8 + 899 113 8 899 113 8 899 113 8 899 113 8 899 113 8 899 234 8 + 911 223 7 929 148 7 934 223 7 934 223 7 934 223 7 934 223 7 + 934 223 7 934 223 7 934 239 7 938 102 10 938 102 10 938 102 10 + 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 938 102 10 + 938 148 7 938 148 7 938 148 7 938 148 7 938 148 7 938 148 7 + 938 160 7 938 208 10 959 224 6 959 224 6 959 224 6 959 224 6 + 959 224 6 959 238 6 963 133 8 979 133 8 979 133 8 979 133 8 + 979 133 8 979 133 8 979 133 8 979 133 8 979 330 8} + +do_execsql_test 5.2.10.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {295 1 1 335 1 1 607 1 1 667 1 1 742 1 1 759 1 1 845 1 1 + 890 1 1 929 1 1 959 1 1 962 1 1 962 1 1 962 1 1 962 1 1 + 962 1 1 962 1 1 962 1 1 962 1 1 962 1 1 1264 1 1 1264 1 1 + 1264 1 1 1264 1 1 1264 1 1 1264 1 1 1366 1 1 1366 1 1 1366 1 1 + 1366 1 1 1383 1 1 1398 1 1 1406 1 1 1421 1 1 1519 1 1 1519 1 1 + 1535 1 1 1651 1 1 1669 1 1 1682 1 1 1695 1 1 1804 1 1 1804 1 1 + 1804 1 1 1804 1 1 1804 1 1 1897 1 1 1919 1 1 2000 1 1 2048 1 1 + 2050 1 1 2050 1 1 2070 1 1 2086 1 1 2108 1 1 2108 1 1 2134 1 1 + 2150 1 1 2309 1 1 2309 1 1 2309 1 1 2340 1 1 2340 1 1 2340 1 1 + 2430 1 1 2690 1 1 2758 1 1 2770 1 1 2776 1 1 2834 1 1 2848 1 1 + 2947 1 1 2947 1 1 2947 1 1 2947 1 1 2980 1 1 3082 1 1 3088 1 1 + 3088 1 1 3113 1 1 3113 1 1 3113 1 1 3113 1 1 3234 1 1 3481 1 1 + 3481 1 1 3481 1 1 3481 1 1 3481 1 1 3481 1 1} + +do_execsql_test 5.2.11.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {911 223 7 934 158 26 934 158 26 934 158 26 934 158 26 934 158 26 + 934 158 33 934 223 7 934 223 7 934 223 7 934 223 7 934 223 7 + 934 223 7 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 + 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 934 223 20 + 934 223 20 934 223 20 934 223 26 934 239 7 959 102 49 959 102 49 + 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 959 102 49 + 959 102 49 959 102 49 959 102 57 959 102 57 959 102 57 959 102 57 + 959 102 57 959 102 57 959 102 57 959 102 57 959 113 38 959 113 38 + 959 113 38 959 113 38 959 113 49 959 158 33 959 158 33 959 158 33 + 959 158 33 959 158 33 959 158 33 959 158 38 963 102 58 979 102 49 + 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 52 + 979 102 52 979 102 52 979 102 52 979 102 52 979 102 52 979 102 52 + 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 979 102 55 + 979 102 55 979 102 55 979 102 55 979 102 58 979 102 58 979 102 58 + 979 102 58 979 102 58 979 102 58 979 102 58 979 102 58} + +do_execsql_test 5.2.11.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {1398 1 1 1682 1 1 2000 1 1 2070 1 1 2086 1 1 2309 1 1 2309 1 1 + 2309 1 1 5079 9 2 5085 9 2 5157 9 2 5391 9 2 5397 9 2 5397 9 2 + 5543 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 5790 9 2 + 6397 22 3 6549 22 3 7156 22 3 7156 22 3 7156 22 3 7156 22 3 + 8001 28 4 8115 28 4 8960 28 4 8960 28 4 8960 28 4 8960 28 4 + 8960 28 4 9702 35 5 9850 35 5 10366 35 5 10479 35 5 10479 35 5 + 10774 40 6 11146 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 + 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11441 40 6 11563 68 9 + 11697 68 9 11776 51 7 11925 68 9 11947 68 9 12368 68 9 12368 68 9 + 12368 68 9 12370 51 7 12530 59 8 12546 59 8 12705 51 7 12705 51 7 + 12705 51 7 12705 51 7 12705 51 7 12705 51 7 12826 59 8 + 13050 75 10 13110 75 10 13110 75 10 13154 59 8 13376 59 8 + 13509 59 8 13509 59 8 13509 59 8 13509 59 8 13528 84 11 + 13566 84 11 13692 75 10 13796 84 11 13836 75 10 13840 84 11 + 13949 75 10 13949 75 10 13949 75 10 13949 75 10 14195 84 11 + 14195 84 11} + +do_execsql_test 5.2.12.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1 + 113 113 1 158 158 1 160 158 1 160 158 2 223 223 1 224 224 1 + 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4 + 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 355 354 1 + 355 354 2 355 355 1 399 393 3 399 393 3 399 393 3 399 393 3 + 399 393 4 480 480 1 480 480 1 572 572 1 574 574 1 618 618 1 + 618 618 1 633 629 2 634 627 3 634 627 3 634 627 4 634 629 3 + 667 667 1 670 667 2 671 667 2 671 667 2 671 667 3 711 711 1 + 711 711 1 716 705 2 726 726 1 730 730 1 762 762 1 768 759 3 + 768 762 2 768 762 2 792 790 2 792 790 2 794 786 3 794 786 3 + 844 839 4 845 839 4 845 839 4 845 839 4 845 839 4 870 870 1 + 870 870 1 870 870 2 934 934 1 938 929 3 938 934 2 938 934 2 + 959 959 1 963 963 1} + +do_execsql_test 5.2.12.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 + {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23 + {} 34 29 {} 35 30 {} 36 31 {} 37 32 {} 38 33 {} 38 33 {} 40 34 + {} 41 35 {} 42 36 {} 43 37 {} 43 37 {} 50 42 {} 56 47 {} 60 51 + {} 61 52 {} 62 53 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 + {} 69 59 {} 70 60 {} 71 61 {} 72 62 {} 78 67 {} 78 67 {} 78 67 + {} 81 68 {} 82 69 {} 83 70 {} 85 72 {} 85 72 {} 89 75 113 2 2 + 113 2 2 223 11 9 239 12 10 239 13 11 257 18 16 335 22 20 + 335 24 22 355 27 25 355 27 25 504 16 14 504 17 15 705 58 49 + 710 26 24 711 57 48 711 59 50 759 63 54 929 84 71 959 88 74 + 963 87 73 1185 32 28 1185 32 28 1191 29 26 1191 29 26 1334 51 43 + 1334 55 46 1338 52 44 1338 52 44 1584 31 27 1678 77 66 1684 73 63 + 1684 73 63 1885 48 40 1889 46 39 1889 46 39 1891 45 38 1891 49 41 + 2005 54 45 2523 75 64 2523 76 65} + +do_execsql_test 5.2.13.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 113 113 1 + 113 113 1 158 158 0 158 158 1 355 355 0 355 355 1 393 393 1 + 393 393 1 399 399 0 399 399 1 480 480 1 480 480 1 618 618 1 + 618 618 1 629 629 0 629 629 1 667 667 0 667 667 1 768 768 1 + 768 768 1 839 839 1 839 839 1 870 870 1 870 870 1 870 870 2 + 938 938 1 938 938 1} + +do_execsql_test 5.2.13.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 + {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15 + {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 {} 23 21 {} 24 22 + {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 35 30 {} 36 31 {} 37 32 + {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 {} 43 37 + {} 45 38 {} 48 40 {} 49 41 {} 50 42 {} 51 43 {} 54 45 {} 55 46 + {} 56 47 {} 57 48 {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53 + {} 63 54 {} 64 55 {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 + {} 70 60 {} 71 61 {} 72 62 {} 75 64 {} 76 65 {} 77 66 {} 78 67 + {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72 + {} 85 72 {} 87 73 {} 88 74 {} 89 75 113 2 2 113 2 2 355 27 25 + 355 27 25 393 29 26 393 29 26 399 32 28 399 32 28 629 46 39 + 629 46 39 667 52 44 667 52 44 839 73 63 839 73 63} + +do_execsql_test 5.2.14.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 + 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 + 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67 + 979 256 66 979 257 65 979 295 64 979 309 63 979 330 63 979 335 61 + 979 336 60 979 346 59 979 354 58 979 355 56 979 355 58 979 393 55 + 979 393 56 979 398 54 979 399 52 979 399 53 979 412 52 979 421 51 + 979 430 50 979 443 49 979 480 47 979 480 48 979 572 46 979 574 46 + 979 607 44 979 618 42 979 618 43 979 627 41 979 629 40 979 629 40 + 979 633 39 979 634 38 979 652 37 979 660 36 979 667 34 979 667 35 + 979 670 34 979 671 33 979 683 32 979 705 31 979 711 30 979 716 29 + 979 726 28 979 730 27 979 759 26 979 762 25 979 768 23 979 768 24 + 979 777 22 979 786 21 979 790 20 979 792 19 979 794 18 979 805 17 + 979 822 16 979 839 15 979 839 15 979 840 13 979 844 12 979 845 11 + 979 870 8 979 870 9 979 870 10 979 899 8 979 911 7} + +do_execsql_test 5.2.14.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE CURRENT ROW ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 @@ -4216,7 +4897,7 @@ do_execsql_test 5.3.1.1 { count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 @@ -4237,7 +4918,7 @@ do_execsql_test 5.3.1.2 { dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 @@ -4256,9 +4937,9 @@ do_execsql_test 5.3.2.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 @@ -4280,9 +4961,9 @@ do_execsql_test 5.3.2.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 {} 81 11 2947 74 10 2947 74 10 2947 74 10 2947 74 10 2947 74 10 2947 74 10 2947 74 10 5287 65 9 5287 65 9 5287 65 9 @@ -4306,7 +4987,7 @@ do_execsql_test 5.3.3.1 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 @@ -4328,7 +5009,7 @@ do_execsql_test 5.3.3.2 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 @@ -4347,8 +5028,8 @@ do_execsql_test 5.3.4.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 934 158 8 934 158 8 934 158 8 934 158 8 934 158 8 @@ -4370,8 +5051,8 @@ do_execsql_test 5.3.4.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 2050 7 2 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 @@ -4393,8 +5074,8 @@ do_execsql_test 5.3.5.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 @@ -4416,8 +5097,8 @@ do_execsql_test 5.3.5.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 {} 23 21 {} 25 23 {} 27 25 {} 27 25 {} 34 29 {} 35 30 {} 36 31 @@ -4438,8 +5119,8 @@ do_execsql_test 5.3.6.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 @@ -4459,8 +5140,8 @@ do_execsql_test 5.3.6.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 @@ -4480,9 +5161,9 @@ do_execsql_test 5.3.7.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 @@ -4504,9 +5185,324 @@ do_execsql_test 5.3.7.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 + 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 + 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 + 9727 66 66 9745 69 69 9745 70 70 9745 72 72 10504 65 65 + 10504 67 67 10504 68 68 11215 64 64 11844 62 62 11920 63 63 + 13274 60 60 13274 61 61 13897 58 58 13903 57 57 13925 56 56 + 13937 55 55 13941 59 59 15203 53 53 15241 54 54 15832 52 52 + 17100 48 48 17104 46 46 17104 47 47 17106 45 45 17126 49 49 + 17126 50 50 17126 51 51 17569 42 42 17733 44 44 18176 43 43 + 18597 40 40 18597 41 41 18952 37 37 18996 39 39 19395 38 38 + 19760 35 35 19788 36 36 20492 32 32 20492 33 33 20498 30 30 + 20536 34 34 20833 29 29 20871 28 28 20891 31 31 21180 27 27 + 21752 23 23 21830 26 26 22025 21 21 22087 22 22 22087 24 24 + 22087 25 25 22278 20 20 22316 19 19 22549 15 15 22557 14 14 + 22573 17 17 22573 18 18 22706 10 10 22796 11 11 22796 12 12 + 22796 13 13 22796 16 16 23022 4 4 23042 2 2 23042 3 3 23042 9 9 + 23155 1 1 23155 5 5 23155 6 6 23155 7 7 23155 8 8} + +do_execsql_test 5.3.8.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} + +do_execsql_test 5.3.8.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1} + +do_execsql_test 5.3.9.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 870 158 0 + 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 870 158 0 + 870 158 0 870 158 0 899 113 9 899 113 9 899 113 9 899 113 9 + 899 113 9 899 113 9 899 113 9 899 113 16 899 113 16 899 113 16 + 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 899 113 16 + 979 102 44 979 102 44 979 102 44 979 102 44 979 102 44 979 102 49 + 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 979 102 49 + 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 979 102 56 + 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 + 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 979 102 62 + 979 102 62 979 102 75 979 102 75 979 102 75 979 102 75 979 102 75 + 979 102 75 979 102 75 979 102 75 979 113 25 979 113 25 979 113 25 + 979 113 25 979 113 25 979 113 25 979 113 25 979 113 25 979 113 33 + 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 979 113 33 + 979 113 33 979 113 33 979 113 33 979 113 33} + +do_execsql_test 5.3.9.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 84 11 {} 84 11 {} 84 11 {} 84 11 {} 84 11 {} 84 11 + 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2050 75 10 + 2050 75 10 2050 75 10 2050 75 10 4997 68 9 4997 68 9 4997 68 9 + 4997 68 9 4997 68 9 4997 68 9 4997 68 9 7337 59 8 7337 59 8 + 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7337 59 8 7337 59 8 + 7337 59 8 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 + 10450 51 7 10450 51 7 10450 51 7 11714 40 6 11714 40 6 11714 40 6 + 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 + 11714 40 6 11714 40 6 12676 35 5 12676 35 5 12676 35 5 12676 35 5 + 12676 35 5 14195 28 4 14195 28 4 14195 28 4 14195 28 4 14195 28 4 + 14195 28 4 14195 28 4 15999 22 3 15999 22 3 15999 22 3 15999 22 3 + 15999 22 3 15999 22 3 17365 9 2 17365 9 2 17365 9 2 17365 9 2 + 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 17365 9 2 + 17365 9 2 17365 9 2 17365 9 2 20846 1 1 20846 1 1 20846 1 1 + 20846 1 1 20846 1 1 20846 1 1 20846 1 1 20846 1 1} + +do_execsql_test 5.3.10.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} + +do_execsql_test 5.3.10.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1} + +do_execsql_test 5.3.11.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 934 158 27 934 158 27 934 158 27 934 158 27 934 158 27 + 934 158 27 934 158 27 934 223 8 934 223 8 934 223 8 934 223 8 + 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 934 223 8 + 934 223 8 934 223 8 934 223 8 934 223 21 934 223 21 934 223 21 + 934 223 21 934 223 21 934 223 21 959 102 50 959 102 50 959 102 50 + 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 + 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 959 102 50 + 959 102 50 959 102 50 959 113 39 959 113 39 959 113 39 959 113 39 + 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 959 113 39 + 959 113 39 959 158 34 959 158 34 959 158 34 959 158 34 959 158 34 + 979 102 46 979 102 46 979 102 46 979 102 46 979 102 46 979 102 46 + 979 102 46 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 + 979 102 47 979 102 47 979 102 47 979 102 47 979 102 49 979 102 49 + 979 102 49 979 102 49 979 102 49 979 102 49} + +do_execsql_test 5.3.11.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 + 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 5790 22 3 + 5790 22 3 5790 22 3 5790 22 3 5790 22 3 5790 22 3 7156 28 4 + 7156 28 4 7156 28 4 7156 28 4 7156 28 4 7156 28 4 7156 28 4 + 8960 35 5 8960 35 5 8960 35 5 8960 35 5 8960 35 5 10028 68 9 + 10028 68 9 10028 68 9 10028 68 9 10028 68 9 10028 68 9 10028 68 9 + 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10396 59 8 10396 59 8 + 10396 59 8 10396 59 8 10396 59 8 10479 40 6 10479 40 6 10479 40 6 + 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 + 10479 40 6 10479 40 6 11002 75 10 11002 75 10 11002 75 10 + 11002 75 10 11002 75 10 11002 75 10 11002 75 10 11002 75 10 + 11002 75 10 11441 51 7 11441 51 7 11441 51 7 11441 51 7 + 11441 51 7 11441 51 7 11441 51 7 11441 51 7 12145 84 11 + 12145 84 11 12145 84 11 12145 84 11 12145 84 11 12145 84 11} + +do_execsql_test 5.3.12.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 158 158 1 160 160 1 160 160 1 223 223 1 224 224 1 + 238 234 2 239 234 2 239 238 2 252 250 2 256 252 2 257 247 4 + 257 247 4 257 250 3 335 330 2 336 330 2 336 335 2 354 354 1 + 354 354 1 355 355 1 398 393 3 398 393 3 399 393 3 399 398 2 + 399 398 2 572 572 1 574 574 1 633 629 2 634 627 3 634 627 3 + 634 627 3 634 629 3 667 667 1 670 667 2 671 667 2 671 670 2 + 671 670 2 711 711 1 711 711 1 716 705 2 726 726 1 730 730 1 + 762 762 1 762 762 1 762 762 1 768 759 3 792 790 2 792 790 2 + 794 786 3 794 786 3 844 839 4 845 839 4 845 839 4 845 840 3 + 845 840 3 934 934 1 934 934 1 934 934 1 938 929 3 959 959 1 + 963 963 1} + +do_execsql_test 5.3.12.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 + {} 9 7 {} 10 8 {} 14 12 {} 15 13 {} 19 17 {} 20 18 {} 21 19 + {} 23 21 {} 25 23 {} 27 25 {} 27 25 {} 34 29 {} 35 30 {} 36 31 + {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 + {} 43 37 {} 50 42 {} 56 47 {} 60 51 {} 61 52 {} 62 53 {} 64 55 + {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 + {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 + {} 85 72 {} 85 72 {} 89 75 223 11 9 239 12 10 239 13 11 + 257 18 16 335 22 20 335 24 22 504 16 14 504 17 15 671 52 44 + 671 52 44 705 58 49 710 26 24 711 57 48 711 59 50 759 63 54 + 786 32 28 786 32 28 798 29 26 798 29 26 845 73 63 845 73 63 + 929 84 71 959 88 74 963 87 73 1260 46 39 1260 46 39 1334 51 43 + 1334 55 46 1584 31 27 1678 77 66 1885 48 40 1891 45 38 1891 49 41 + 2005 54 45 2523 75 64 2523 76 65} + +do_execsql_test 5.3.13.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0 + {} {} 0 {} {} 0 {} {} 0 {} {} 0 {} {} 0} + +do_execsql_test 5.3.13.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 2 2 {} 2 2 {} 4 3 {} 5 4 {} 6 5 {} 6 5 {} 8 6 + {} 9 7 {} 10 8 {} 11 9 {} 12 10 {} 13 11 {} 14 12 {} 15 13 + {} 16 14 {} 17 15 {} 18 16 {} 19 17 {} 20 18 {} 21 19 {} 22 20 + {} 23 21 {} 24 22 {} 25 23 {} 26 24 {} 27 25 {} 27 25 {} 29 26 + {} 29 26 {} 31 27 {} 32 28 {} 32 28 {} 34 29 {} 35 30 {} 36 31 + {} 37 32 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 42 36 {} 43 37 + {} 43 37 {} 45 38 {} 46 39 {} 46 39 {} 48 40 {} 49 41 {} 50 42 + {} 51 43 {} 52 44 {} 52 44 {} 54 45 {} 55 46 {} 56 47 {} 57 48 + {} 58 49 {} 59 50 {} 60 51 {} 61 52 {} 62 53 {} 63 54 {} 64 55 + {} 64 55 {} 66 56 {} 67 57 {} 68 58 {} 69 59 {} 70 60 {} 71 61 + {} 72 62 {} 73 63 {} 73 63 {} 75 64 {} 76 65 {} 77 66 {} 78 67 + {} 78 67 {} 78 67 {} 81 68 {} 82 69 {} 83 70 {} 84 71 {} 85 72 + {} 85 72 {} 87 73 {} 88 74 {} 89 75} + +do_execsql_test 5.3.14.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {963 929 6 979 102 82 979 102 82 979 102 82 979 102 82 979 102 82 + 979 102 83 979 113 80 979 113 81 979 113 82 979 133 79 979 148 78 + 979 158 76 979 158 77 979 160 76 979 208 75 979 223 74 979 224 73 + 979 234 72 979 238 71 979 239 70 979 247 69 979 250 68 979 252 67 + 979 256 66 979 257 65 979 295 64 979 309 63 979 330 63 979 335 61 + 979 336 60 979 346 59 979 354 58 979 355 56 979 355 58 979 393 55 + 979 393 56 979 398 54 979 399 52 979 399 53 979 412 52 979 421 51 + 979 430 50 979 443 49 979 480 47 979 480 48 979 572 46 979 574 46 + 979 607 44 979 618 42 979 618 43 979 627 41 979 629 40 979 629 40 + 979 633 39 979 634 38 979 652 37 979 660 36 979 667 34 979 667 35 + 979 670 34 979 671 33 979 683 32 979 705 31 979 711 30 979 716 29 + 979 726 28 979 730 27 979 759 26 979 762 25 979 768 23 979 768 24 + 979 777 22 979 786 21 979 790 20 979 792 19 979 794 18 979 805 17 + 979 822 16 979 839 15 979 839 15 979 840 13 979 844 12 979 845 11 + 979 870 8 979 870 9 979 870 10 979 899 8 979 911 7} + +do_execsql_test 5.3.14.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE GROUP ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {2851 89 89 3778 88 88 4681 87 87 5556 83 83 5574 82 82 5586 81 81 5640 84 84 5640 85 85 5640 86 86 7324 80 80 8123 77 77 8129 73 73 8129 74 74 8163 78 78 8163 79 79 8940 71 71 8968 75 75 8968 76 76 @@ -4531,7 +5527,7 @@ do_execsql_test 5.4.1.1 { count(a) OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 @@ -4554,7 +5550,7 @@ do_execsql_test 5.4.1.2 { dense_rank() OVER win FROM t3 WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 @@ -4573,9 +5569,9 @@ do_execsql_test 5.4.2.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {113 113 1 234 234 1 257 257 1 336 336 1 354 354 1 768 768 1 839 839 1 839 839 1 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 10 899 113 17 899 113 17 899 113 17 @@ -4597,9 +5593,9 @@ do_execsql_test 5.4.2.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a + WINDOW win AS ( ORDER BY a NULLS FIRST RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 81 11 {} 81 11 {} 81 11 {} 81 11 113 81 11 257 81 11 839 81 11 839 81 11 899 81 11 2947 74 10 2947 74 10 2947 74 10 3368 74 10 3390 74 10 3618 74 10 3752 74 10 5287 65 9 5287 65 9 @@ -4623,7 +5619,7 @@ do_execsql_test 5.4.3.1 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 @@ -4647,7 +5643,7 @@ do_execsql_test 5.4.3.2 { FROM t3 WINDOW win AS ( PARTITION BY coalesce(a, '') RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 @@ -4666,8 +5662,8 @@ do_execsql_test 5.4.4.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {158 158 0 355 355 0 399 399 0 629 629 0 667 667 0 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 870 0 911 158 1 934 158 1 934 158 9 934 158 9 934 158 9 934 158 9 @@ -4689,8 +5685,8 @@ do_execsql_test 5.4.4.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY a GROUPS 6 PRECEDING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY a NULLS FIRST GROUPS 6 PRECEDING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 1 1 355 1 1 399 1 1 629 1 1 667 1 1 2050 7 2 2050 7 2 2050 7 2 2273 7 2 2289 7 2 2359 7 2 2677 7 2 2961 7 2 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 4359 15 3 @@ -4713,8 +5709,8 @@ do_execsql_test 5.4.5.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 160 158 1 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 @@ -4736,8 +5732,8 @@ do_execsql_test 5.4.5.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 @@ -4758,8 +5754,8 @@ do_execsql_test 5.4.6.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 @@ -4781,8 +5777,8 @@ do_execsql_test 5.4.6.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + WINDOW win AS ( ORDER BY c NULLS FIRST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 @@ -4803,9 +5799,9 @@ do_execsql_test 5.4.7.1 { min(c) OVER win, count(a) OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 @@ -4827,9 +5823,331 @@ do_execsql_test 5.4.7.2 { rank() OVER win, dense_rank() OVER win FROM t3 - WINDOW win AS ( ORDER BY c , b , a + WINDOW win AS ( ORDER BY c NULLS FIRST, b NULLS FIRST, a NULLS FIRST ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) - ORDER BY 1 , 2 , 3 + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 + 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 + 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 + 9745 70 70 9745 71 71 9745 72 72 10504 65 65 10504 66 66 + 10504 67 67 10504 68 68 11215 64 64 11920 63 63 12603 62 62 + 13274 60 60 13274 61 61 13941 59 59 14608 55 55 14608 56 56 + 14608 57 57 14608 58 58 15241 54 54 15870 53 53 16499 52 52 + 17126 49 49 17126 50 50 17126 51 51 17733 44 44 17733 45 45 + 17733 46 46 17733 47 47 17733 48 48 18176 42 42 18176 43 43 + 18597 40 40 18597 41 41 18996 39 39 19395 37 37 19395 38 38 + 19788 36 36 20181 35 35 20536 34 34 20891 30 30 20891 31 31 + 20891 32 32 20891 33 33 21226 28 28 21226 29 29 21535 27 27 + 21830 26 26 22087 22 22 22087 23 23 22087 24 24 22087 25 25 + 22334 21 21 22573 17 17 22573 18 18 22573 19 19 22573 20 20 + 22796 11 11 22796 12 12 22796 13 13 22796 14 14 22796 15 15 + 22796 16 16 22929 10 10 23042 9 9 23155 1 1 23155 2 2 23155 3 3 + 23155 4 4 23155 5 5 23155 6 6 23155 7 7 23155 8 8} + +do_execsql_test 5.4.8.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 + 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 + 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 + 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 + 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 + 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 + 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 + 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1 + 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1 + 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 + 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1 + 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 + 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0 + 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1 + 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} + +do_execsql_test 5.4.8.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1 + 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1 + 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1 + 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1 + 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1 + 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1} + +do_execsql_test 5.4.9.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {158 158 0 355 355 0 399 399 0 629 629 0 667 667 0 870 113 1 + 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 870 158 1 + 870 158 1 870 870 0 899 113 10 899 113 10 899 113 10 899 113 10 + 899 113 10 899 113 10 899 113 10 899 113 17 899 113 17 899 113 17 + 899 113 17 899 113 17 899 113 17 899 113 17 899 158 1 963 113 17 + 979 102 34 979 102 45 979 102 45 979 102 45 979 102 45 979 102 45 + 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 979 102 50 + 979 102 50 979 102 57 979 102 57 979 102 57 979 102 57 979 102 57 + 979 102 57 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 + 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 979 102 63 + 979 102 63 979 102 63 979 102 76 979 102 76 979 102 76 979 102 76 + 979 102 76 979 102 76 979 102 76 979 102 76 979 113 17 979 113 26 + 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26 979 113 26 + 979 113 26 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34 + 979 113 34 979 113 34 979 113 34 979 113 34 979 113 34} + +do_execsql_test 5.4.9.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 84 11 {} 84 11 355 84 11 399 84 11 629 84 11 667 84 11 + 2050 75 10 2050 75 10 2050 75 10 2050 75 10 2163 75 10 2307 75 10 + 2889 75 10 2889 75 10 2949 75 10 4997 68 9 4997 68 9 4997 68 9 + 5418 68 9 5440 68 9 5668 68 9 5802 68 9 7337 59 8 7337 59 8 + 7337 59 8 7337 59 8 7470 59 8 7692 59 8 8020 59 8 8300 59 8 + 8316 59 8 10450 51 7 10450 51 7 10450 51 7 10450 51 7 10450 51 7 + 10450 51 7 10785 51 7 11379 51 7 11714 40 6 11714 40 6 11714 40 6 + 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 11714 40 6 + 12009 40 6 12381 40 6 12676 35 5 12676 35 5 12789 35 5 13305 35 5 + 13453 35 5 14195 28 4 14195 28 4 14195 28 4 14195 28 4 14195 28 4 + 15040 28 4 15154 28 4 15999 22 3 15999 22 3 15999 22 3 15999 22 3 + 16606 22 3 16758 22 3 17365 9 2 17365 9 2 17365 9 2 17365 9 2 + 17365 9 2 17365 9 2 17612 9 2 17758 9 2 17758 9 2 17764 9 2 + 17998 9 2 18070 9 2 18076 9 2 20846 1 1 20846 1 1 20846 1 1 + 21069 1 1 21085 1 1 21155 1 1 21473 1 1 21757 1 1} + +do_execsql_test 5.4.10.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 + 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 + 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 + 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 + 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 + 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 + 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 + 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1 + 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1 + 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 + 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1 + 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 + 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0 + 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1 + 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} + +do_execsql_test 5.4.10.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( PARTITION BY coalesce(a, '') + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 {} 1 1 + 113 1 1 113 1 1 133 1 1 223 1 1 239 1 1 247 1 1 257 1 1 + 295 1 1 309 1 1 335 1 1 355 1 1 355 1 1 393 1 1 393 1 1 + 399 1 1 399 1 1 421 1 1 443 1 1 607 1 1 627 1 1 629 1 1 + 629 1 1 633 1 1 667 1 1 667 1 1 671 1 1 683 1 1 705 1 1 + 711 1 1 759 1 1 777 1 1 805 1 1 839 1 1 839 1 1 845 1 1 + 899 1 1 911 1 1 929 1 1 959 1 1 963 1 1 979 1 1} + +do_execsql_test 5.4.11.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {223 223 1 239 239 1 309 309 1 572 572 1 627 627 1 870 870 1 + 911 911 1 934 158 22 934 158 28 934 158 28 934 158 28 934 158 28 + 934 158 28 934 158 28 934 223 9 934 223 9 934 223 9 934 223 9 + 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 934 223 9 + 934 223 9 934 223 9 934 223 9 934 223 22 934 223 22 934 223 22 + 934 223 22 934 223 22 934 934 1 959 102 40 959 102 51 959 102 51 + 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 + 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 959 102 51 + 959 102 51 959 113 35 959 113 40 959 113 40 959 113 40 959 113 40 + 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 959 113 40 + 959 158 28 959 158 35 959 158 35 959 158 35 959 158 35 963 102 51 + 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 979 102 47 + 979 102 47 979 102 48 979 102 48 979 102 48 979 102 48 979 102 48 + 979 102 48 979 102 48 979 102 48 979 102 48 979 102 49 979 102 49 + 979 102 49 979 102 49 979 102 49 979 102 49 979 102 51} + +do_execsql_test 5.4.11.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY a NULLS LAST GROUPS 6 PRECEDING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 1 1 {} 1 1 223 1 1 239 1 1 309 1 1 627 1 1 911 1 1 + 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2309 9 2 2556 9 2 + 2702 9 2 2702 9 2 2708 9 2 2942 9 2 3014 9 2 3020 9 2 5790 22 3 + 5790 22 3 5790 22 3 5790 22 3 6397 22 3 6549 22 3 7156 28 4 + 7156 28 4 7156 28 4 7156 28 4 7156 28 4 8001 28 4 8115 28 4 + 8960 35 5 8960 35 5 9073 35 5 9589 35 5 9737 35 5 10028 68 9 + 10028 68 9 10028 68 9 10396 59 8 10396 59 8 10396 59 8 10396 59 8 + 10449 68 9 10471 68 9 10479 40 6 10479 40 6 10479 40 6 10479 40 6 + 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10479 40 6 10529 59 8 + 10699 68 9 10751 59 8 10774 40 6 10833 68 9 11002 75 10 + 11002 75 10 11002 75 10 11002 75 10 11079 59 8 11115 75 10 + 11146 40 6 11259 75 10 11359 59 8 11375 59 8 11441 51 7 + 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11441 51 7 11776 51 7 + 11841 75 10 11841 75 10 11901 75 10 12145 84 11 12145 84 11 + 12370 51 7 12500 84 11 12544 84 11 12774 84 11 12812 84 11} + +do_execsql_test 5.4.12.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 160 158 1 + 160 158 2 160 158 2 208 208 1 224 223 2 224 223 2 239 234 3 + 239 234 3 239 234 3 252 247 3 257 247 5 257 247 5 257 250 4 + 257 252 3 295 295 1 309 309 1 336 330 3 336 330 3 336 330 3 + 346 346 1 355 354 1 355 354 2 355 354 2 399 393 3 399 393 3 + 399 393 3 399 393 4 399 393 4 412 412 1 421 421 1 430 430 1 + 443 443 1 480 480 1 480 480 1 574 572 2 574 572 2 607 607 1 + 618 618 1 618 618 1 634 627 3 634 627 4 634 627 4 634 627 4 + 634 629 3 652 652 1 667 660 2 671 667 2 671 667 3 671 667 3 + 671 667 3 683 683 1 711 705 2 716 705 3 716 711 2 730 726 2 + 730 726 2 762 759 2 768 759 4 768 762 2 768 762 2 777 777 1 + 792 786 3 794 786 4 794 786 4 794 790 3 805 805 1 822 822 1 + 845 839 4 845 839 4 845 839 5 845 839 5 845 839 5 870 870 0 + 870 870 1 870 870 1 899 899 1 911 911 1 934 929 2 938 929 4 + 938 934 2 938 934 2 963 959 2 963 959 2 979 979 1} + +do_execsql_test 5.4.12.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 6 PRECEDING AND 7 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 25 23 {} 34 29 + {} 36 31 {} 38 33 {} 38 33 {} 40 34 {} 41 35 {} 43 37 {} 43 37 + {} 50 42 {} 60 51 {} 61 52 {} 64 55 {} 64 55 {} 67 57 {} 68 58 + {} 69 59 {} 70 60 {} 72 62 {} 78 67 {} 78 67 {} 78 67 {} 85 72 + {} 85 72 113 2 2 113 2 2 133 4 3 223 10 8 223 11 9 239 12 10 + 239 13 11 239 14 12 247 15 13 257 18 16 257 19 17 295 20 18 + 309 21 19 335 22 20 335 23 21 335 24 22 355 27 25 355 27 25 + 421 35 30 443 37 32 504 16 14 504 17 15 607 42 36 683 56 47 + 710 26 24 711 59 50 759 62 53 759 63 54 777 66 56 805 71 61 + 899 81 68 911 82 69 929 83 70 929 84 71 979 89 75 1185 32 28 + 1185 32 28 1191 29 26 1191 29 26 1334 51 43 1338 52 44 1338 52 44 + 1416 57 48 1416 58 49 1584 31 27 1684 73 63 1684 73 63 1889 46 39 + 1889 46 39 1891 49 41 1922 87 73 1922 88 74 2005 54 45 2005 55 46 + 2518 45 38 2518 48 40 2523 75 64 2523 76 65 2523 77 66} + +do_execsql_test 5.4.13.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {102 102 1 113 113 1 113 113 1 133 133 1 148 148 1 158 158 0 + 158 158 1 160 160 1 208 208 1 223 223 1 224 224 1 234 234 1 + 238 238 1 239 239 1 247 247 1 250 250 1 252 252 1 256 256 1 + 257 257 1 295 295 1 309 309 1 330 330 1 335 335 1 336 336 1 + 346 346 1 354 354 1 355 355 0 355 355 1 393 393 1 393 393 1 + 398 398 1 399 399 0 399 399 1 412 412 1 421 421 1 430 430 1 + 443 443 1 480 480 1 480 480 1 572 572 1 574 574 1 607 607 1 + 618 618 1 618 618 1 627 627 1 629 629 0 629 629 1 633 633 1 + 634 634 1 652 652 1 660 660 1 667 667 0 667 667 1 670 670 1 + 671 671 1 683 683 1 705 705 1 711 711 1 716 716 1 726 726 1 + 730 730 1 759 759 1 762 762 1 768 768 1 768 768 1 777 777 1 + 786 786 1 790 790 1 792 792 1 794 794 1 805 805 1 822 822 1 + 839 839 1 839 839 1 840 840 1 844 844 1 845 845 1 870 870 0 + 870 870 1 870 870 1 899 899 1 911 911 1 929 929 1 934 934 1 + 938 938 1 938 938 1 959 959 1 963 963 1 979 979 1} + +do_execsql_test 5.4.13.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST RANGE BETWEEN 0 PRECEDING AND 0 FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {{} 1 1 {} 5 4 {} 6 5 {} 6 5 {} 8 6 {} 9 7 {} 11 9 {} 12 10 + {} 13 11 {} 16 14 {} 17 15 {} 18 16 {} 22 20 {} 24 22 {} 25 23 + {} 26 24 {} 31 27 {} 34 29 {} 36 31 {} 38 33 {} 38 33 {} 40 34 + {} 41 35 {} 43 37 {} 43 37 {} 49 41 {} 50 42 {} 51 43 {} 54 45 + {} 59 50 {} 60 51 {} 61 52 {} 63 54 {} 64 55 {} 64 55 {} 67 57 + {} 68 58 {} 69 59 {} 70 60 {} 72 62 {} 75 64 {} 76 65 {} 78 67 + {} 78 67 {} 78 67 {} 84 71 {} 85 72 {} 85 72 113 2 2 113 2 2 + 133 4 3 223 10 8 239 14 12 247 15 13 257 19 17 295 20 18 + 309 21 19 335 23 21 355 27 25 355 27 25 393 29 26 393 29 26 + 399 32 28 399 32 28 421 35 30 443 37 32 607 42 36 627 45 38 + 629 46 39 629 46 39 633 48 40 667 52 44 667 52 44 671 55 46 + 683 56 47 705 57 48 711 58 49 759 62 53 777 66 56 805 71 61 + 839 73 63 839 73 63 845 77 66 899 81 68 911 82 69 929 83 70 + 959 87 73 963 88 74 979 89 75} + +do_execsql_test 5.4.14.1 { + SELECT max(c) OVER win, + min(c) OVER win, + count(a) OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST +} {979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 979 102 83 + 979 102 83 979 113 81 979 113 82 979 133 80 979 148 79 979 158 77 + 979 158 78 979 160 77 979 208 76 979 223 75 979 224 74 979 234 73 + 979 238 72 979 239 71 979 247 70 979 250 69 979 252 68 979 256 67 + 979 257 66 979 295 65 979 309 64 979 330 63 979 335 62 979 336 61 + 979 346 60 979 354 59 979 355 57 979 355 58 979 393 56 979 393 57 + 979 398 55 979 399 53 979 399 54 979 412 53 979 421 52 979 430 51 + 979 443 50 979 480 48 979 480 49 979 572 47 979 574 46 979 607 45 + 979 618 43 979 618 44 979 627 42 979 629 40 979 629 41 979 633 40 + 979 634 39 979 652 38 979 660 37 979 667 35 979 667 36 979 670 35 + 979 671 34 979 683 33 979 705 32 979 711 31 979 716 30 979 726 29 + 979 730 28 979 759 27 979 762 26 979 768 24 979 768 25 979 777 23 + 979 786 22 979 790 21 979 792 20 979 794 19 979 805 18 979 822 17 + 979 839 15 979 839 16 979 840 14 979 844 13 979 845 12 979 870 9 + 979 870 10 979 870 11 979 899 9 979 911 8 979 929 7} + +do_execsql_test 5.4.14.2 { + SELECT sum(c) FILTER (WHERE (c%2)!=0) OVER win, + rank() OVER win, + dense_rank() OVER win + FROM t3 + WINDOW win AS ( ORDER BY c NULLS LAST, b NULLS LAST, a NULLS LAST + ROWS BETWEEN 6 PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE TIES ) + ORDER BY 1 NULLS FIRST, 2 NULLS FIRST, 3 NULLS FIRST } {3830 89 89 4741 88 88 5640 84 84 5640 85 85 5640 86 86 5640 87 87 6485 81 81 6485 82 82 6485 83 83 7324 80 80 8163 78 78 8163 79 79 8968 73 73 8968 74 74 8968 75 75 8968 76 76 8968 77 77 9745 69 69 @@ -4860,14 +6178,14 @@ do_execsql_test 6.0 { do_execsql_test 6.1 { SELECT group_concat(a, '.') OVER ( - ORDER BY b RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING + ORDER BY b NULLS FIRST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING ) FROM t2 } {A.B A.B {}} do_execsql_test 6.2 { SELECT group_concat(a, '.') OVER ( - ORDER BY b DESC RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING + ORDER BY b DESC NULLS LAST RANGE BETWEEN 7 PRECEDING AND 2 PRECEDING ) FROM t2 } {{} A.B A.B} From 8c754a3613e22b0f19c8e0847615cca9f98a4ac4 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 19 Aug 2019 20:35:30 +0000 Subject: [PATCH 027/112] Omit the "_except" term from the name of the new interface. FossilOrigin-Name: e5ba47c2d8eb9f48a0e0d325e57d0092d536f85983819634c871ebd51829f1d1 --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/shell.c.in | 6 ++++-- src/sqlite.h.in | 8 ++++++-- src/test1.c | 10 +++++----- src/vtab.c | 2 +- 6 files changed, 26 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 97b204c96f..bc476dd61d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sexperimental\ssqlite3_drop_modules_except()\sinterface. -D 2019-08-17T19:45:25.613 +C Omit\sthe\s"_except"\sterm\sfrom\sthe\sname\sof\sthe\snew\sinterface. +D 2019-08-19T20:35:30.961 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,8 +524,8 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 -F src/shell.c.in e0754f1d73c8e7d09548a29537e9e7d65fa0f4869c41722b7b89a64d9cdeff91 -F src/sqlite.h.in cbc4729565b6787c462fffac540b912acc24b32d22428f07d2cf3a937ba7a72e +F src/shell.c.in e0f0758b6ab506d8ab12502fd2b8c55546bb9e4bb772374344a5a1b73f5bc2b9 +F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 F src/sqliteInt.h b7d612d9c63abc8a8a7dcf7fbec5326b1770f40c81502c56f508e272154e7615 @@ -533,7 +533,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290 -F src/test1.c 17f5334199c02e69292d826ba660f0fcb75f50f7686a76553afb55a2c74e87f7 +F src/test1.c af2f21f9aee617582129bdef3934734d88c0d53de0c71019453bb72185430389 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -604,7 +604,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75 F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c 8849cbd67596bebe58e2095fb95309aa3c5bf330d5501ec2b2511109de5a8f13 +F src/vtab.c 6b36944fdf05a33150787236e3506e878dca027a239e39eaf408f09c4821170c F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1836,10 +1836,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 5d6f4dfeea75c7dcd8c511545accb9eb4b405a02db034332249ba54794e313d2 -R 1452e34f48dd7f53a8de382ba3305e88 -T *branch * sqlite3_drop_modules_except -T *sym-sqlite3_drop_modules_except * -T -sym-trunk * +P 0851db4d337a87f8b2d3ce2ae9f9c928b9483591ca41a9e39cc01548059b1888 +R 0f164de667dc5b660a325950332b0cdd U drh -Z 3751a55606ec64d5cdbb771325aed7c0 +Z 965480cc8555a710613c03b1277cb66b diff --git a/manifest.uuid b/manifest.uuid index 9cc49bf88f..8140e9400c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0851db4d337a87f8b2d3ce2ae9f9c928b9483591ca41a9e39cc01548059b1888 \ No newline at end of file +e5ba47c2d8eb9f48a0e0d325e57d0092d536f85983819634c871ebd51829f1d1 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 9bfca22e53..0ee136389d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -9409,6 +9409,7 @@ static int do_meta_command(char *zLine, ShellState *p){ #ifdef SQLITE_DEBUG if( c=='u' && strncmp(azArg[0], "unmodule", n)==0 ){ int ii; + int lenOpt; char *zOpt; if( nArg<2 ){ raw_printf(stderr, "Usage: .unmodule [--allexcept] NAME ...\n"); @@ -9418,9 +9419,10 @@ static int do_meta_command(char *zLine, ShellState *p){ open_db(p, 0); zOpt = azArg[1]; if( zOpt[0]=='-' && zOpt[1]=='-' && zOpt[2]!=0 ) zOpt++; - if( strcmp(zOpt, "-allexcept")==0 ){ + lenOpt = (int)strlen(zOpt); + if( lenOpt>=3 && strncmp(zOpt, "-allexcept",lenOpt)==0 ){ assert( azArg[nArg]==0 ); - sqlite3_drop_modules_except(p->db, nArg>2 ? (const char**)(azArg+2) : 0); + sqlite3_drop_modules(p->db, nArg>2 ? (const char**)(azArg+2) : 0); }else{ for(ii=1; iidb, azArg[ii], 0, 0); diff --git a/src/sqlite.h.in b/src/sqlite.h.in index ace4da70b1..521ddffdb4 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -6639,6 +6639,8 @@ struct sqlite3_index_info { ** ^If the third parameter (the pointer to the sqlite3_module object) is ** NULL then no new module is create and any existing modules with the ** same name are dropped. +** +** See also: [sqlite3_drop_modules()] */ int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ @@ -6658,13 +6660,15 @@ int sqlite3_create_module_v2( ** CAPI3REF: Remove Unnecessary Virtual Table Implementations ** METHOD: sqlite3 ** -** ^The sqlite3_drop_modules_except(D,L) interface removes all virtual +** ^The sqlite3_drop_modules(D,L) interface removes all virtual ** table modules from database connection D except those named on list L. ** The L parameter must be either NULL or a pointer to an array of pointers ** to strings where the array is terminated by a single NULL pointer. ** ^If the L parameter is NULL, then all virtual table modules are removed. +** +** See also: [sqlite3_create_module()] */ -int sqlite3_drop_modules_except( +int sqlite3_drop_modules( sqlite3 *db, /* Remove modules from this connection */ const char **azKeep /* Except, do not remove the ones named here */ ); diff --git a/src/test1.c b/src/test1.c index 7243339056..e238d31e84 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1111,13 +1111,13 @@ static int SQLITE_TCLAPI test_create_function( } /* -** Usage: sqlite3_drop_modules_except DB ?NAME ...? +** Usage: sqlite3_drop_modules DB ?NAME ...? ** -** Invoke the sqlite3_drop_modules_except(D,L) interface on database +** Invoke the sqlite3_drop_modules(D,L) interface on database ** connection DB, in order to drop all modules except those named in ** the argument. */ -static int SQLITE_TCLAPI test_drop_except( +static int SQLITE_TCLAPI test_drop_modules( void *NotUsed, Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ int argc, /* Number of arguments */ @@ -1132,7 +1132,7 @@ static int SQLITE_TCLAPI test_drop_except( return TCL_ERROR; } if( getDbPointer(interp, argv[1], &db) ) return TCL_ERROR; - sqlite3_drop_modules_except(db, argc>2 ? (const char**)(argv+2) : 0); + sqlite3_drop_modules(db, argc>2 ? (const char**)(argv+2) : 0); return TCL_OK; } @@ -7886,7 +7886,7 @@ int Sqlitetest1_Init(Tcl_Interp *interp){ { "sqlite3_close_v2", (Tcl_CmdProc*)sqlite_test_close_v2 }, { "sqlite3_create_function", (Tcl_CmdProc*)test_create_function }, { "sqlite3_create_aggregate", (Tcl_CmdProc*)test_create_aggregate }, - { "sqlite3_drop_modules_except", (Tcl_CmdProc*)test_drop_except }, + { "sqlite3_drop_modules", (Tcl_CmdProc*)test_drop_modules }, { "sqlite_register_test_function", (Tcl_CmdProc*)test_register_func }, { "sqlite_abort", (Tcl_CmdProc*)sqlite_abort }, { "sqlite_bind", (Tcl_CmdProc*)test_bind }, diff --git a/src/vtab.c b/src/vtab.c index 760993120c..dd8a755be2 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -137,7 +137,7 @@ int sqlite3_create_module_v2( ** External API to drop all virtual-table modules, except those named ** on the azNames list. */ -int sqlite3_drop_modules_except(sqlite3 *db, const char** azNames){ +int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ HashElem *pThis, *pNext; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; From 3722b3abf1da4e9bde859df68e679e00c6829f41 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Tue, 20 Aug 2019 02:19:26 +0000 Subject: [PATCH 028/112] Fix a typo and a harmless compiler warning. FossilOrigin-Name: ec4c63e00c957f98d61ddc1b9d20406c7e1072d6ab0c12ac6939db6c63d90cb8 --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/test1.c | 1 - src/vtab.c | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index d592f7b0c3..1b402b9276 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\ssqlite3_drop_modules()\sinterface. -D 2019-08-19T20:44:07.937 +C Fix\sa\stypo\sand\sa\sharmless\scompiler\swarning. +D 2019-08-20T02:19:26.962 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -533,7 +533,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290 -F src/test1.c af2f21f9aee617582129bdef3934734d88c0d53de0c71019453bb72185430389 +F src/test1.c 8ce455da8dcec886a0e1e608da0fee7de67c8195b14517a8824a2a40c2d11fbf F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -604,7 +604,7 @@ F src/vdbeblob.c 253ed82894924c362a7fa3079551d3554cd1cdace39aa833da77d3bc67e7c1b F src/vdbemem.c 920285c3b7f5c64369e02da437dab71e9e91862df9c486541c14633739f91d75 F src/vdbesort.c 3531ae3a431ad6b98b67bd891fb42ec9d66867157188a2b1a9e58c55da6151b2 F src/vdbetrace.c fa3bf238002f0bbbdfb66cc8afb0cea284ff9f148d6439bc1f6f2b4c3b7143f0 -F src/vtab.c 6b36944fdf05a33150787236e3506e878dca027a239e39eaf408f09c4821170c +F src/vtab.c 5a0b7193d586991b3db30e343d6b59959906bfe8658a6a0a85709b20ca50bb49 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a @@ -1836,8 +1836,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 4cb009b0f724f72eaea90e45488122f7c2a7d0caf31a8422da4060469507e921 e5ba47c2d8eb9f48a0e0d325e57d0092d536f85983819634c871ebd51829f1d1 -R 9f3cd232033726d002a567b7aed22f3d -T +closed e5ba47c2d8eb9f48a0e0d325e57d0092d536f85983819634c871ebd51829f1d1 -U drh -Z ea1a16d1273af50410789215c7a1a587 +P e2c6fed8f84929ed51a4e876bb09c85ac4b86a2e4cf0832a7da724bb9f4df5bf +R 8b1ae3c95bd6ffc47e9182b0d67348c9 +U mistachkin +Z 2a3c93f956b1ecd418b937639070a999 diff --git a/manifest.uuid b/manifest.uuid index 2aebc48857..1d741309c7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2c6fed8f84929ed51a4e876bb09c85ac4b86a2e4cf0832a7da724bb9f4df5bf \ No newline at end of file +ec4c63e00c957f98d61ddc1b9d20406c7e1072d6ab0c12ac6939db6c63d90cb8 \ No newline at end of file diff --git a/src/test1.c b/src/test1.c index e238d31e84..c6c9e17afe 100644 --- a/src/test1.c +++ b/src/test1.c @@ -1123,7 +1123,6 @@ static int SQLITE_TCLAPI test_drop_modules( int argc, /* Number of arguments */ char **argv /* Text of each argument */ ){ - int rc; sqlite3 *db; if( argc!=2 ){ diff --git a/src/vtab.c b/src/vtab.c index dd8a755be2..085290914b 100644 --- a/src/vtab.c +++ b/src/vtab.c @@ -140,7 +140,7 @@ int sqlite3_create_module_v2( int sqlite3_drop_modules(sqlite3 *db, const char** azNames){ HashElem *pThis, *pNext; #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zName==0 ) return SQLITE_MISUSE_BKPT; + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; #endif for(pThis=sqliteHashFirst(&db->aModule); pThis; pThis=pNext){ Module *pMod = (Module*)sqliteHashData(pThis); From b6ce71bd265314f65ad95ecdb2735af54121a4dd Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Aug 2019 11:43:44 +0000 Subject: [PATCH 029/112] Retain the affinity of an expression in a WHERE clause when it is transformed to a reference to an index column on the same expression. Fix for [f043b113]. FossilOrigin-Name: 511da0815673ca4a176aa61dc23a8231b2ab77e8363fc184a78b6e17dba64d49 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/wherecode.c | 1 + test/affinity2.test | 27 +++++++++++++++++++++++++++ 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1b402b9276..87f8421097 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\stypo\sand\sa\sharmless\scompiler\swarning. -D 2019-08-20T02:19:26.962 +C Retain\sthe\saffinity\sof\san\sexpression\sin\sa\sWHERE\sclause\swhen\sit\sis\stransformed\sto\sa\sreference\sto\san\sindex\scolumn\son\sthe\ssame\sexpression.\sFix\sfor\s[f043b113]. +D 2019-08-20T11:43:44.838 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -611,11 +611,11 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c 2fac51d2420f05ab6f644f1813d4f73f6214304836fd9b22345738d943faad9b F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb -F src/wherecode.c cf885ea2d439af9827c5cbab7d4c12be5c079439b7bd12e97151ccfe088c13c0 +F src/wherecode.c e1131fe94c8728cbecc707f6455afbda9418896497bdca2d49a04ce6c57999f6 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc F src/window.c 07e1c15081a735750218185c6b17053c87ecb764d06ab2c0a1ce568a2b4688e5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 -F test/affinity2.test a6d901b436328bd67a79b41bb0ac2663918fe3bd +F test/affinity2.test 34f2cf88e2a08d7a54a1fa2c9773ba81bf8b8216c0895e476118a1285540ee71 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1 @@ -1836,7 +1836,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 e2c6fed8f84929ed51a4e876bb09c85ac4b86a2e4cf0832a7da724bb9f4df5bf -R 8b1ae3c95bd6ffc47e9182b0d67348c9 -U mistachkin -Z 2a3c93f956b1ecd418b937639070a999 +P ec4c63e00c957f98d61ddc1b9d20406c7e1072d6ab0c12ac6939db6c63d90cb8 +R 95e8d7b4c9783731533e987936fe1358 +U dan +Z 9e91c8360eb84da6700bb773b0dba23e diff --git a/manifest.uuid b/manifest.uuid index 1d741309c7..9ea5046c2d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ec4c63e00c957f98d61ddc1b9d20406c7e1072d6ab0c12ac6939db6c63d90cb8 \ No newline at end of file +511da0815673ca4a176aa61dc23a8231b2ab77e8363fc184a78b6e17dba64d49 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index c781b06c15..934e3e2e8f 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1117,6 +1117,7 @@ typedef struct IdxExprTrans { static int whereIndexExprTransNode(Walker *p, Expr *pExpr){ IdxExprTrans *pX = p->u.pIdxTrans; if( sqlite3ExprCompare(0, pExpr, pX->pIdxExpr, pX->iTabCur)==0 ){ + pExpr->affExpr = sqlite3ExprAffinity(pExpr); pExpr->op = TK_COLUMN; pExpr->iTable = pX->iIdxCur; pExpr->iColumn = pX->iIdxCol; diff --git a/test/affinity2.test b/test/affinity2.test index 9838bd660a..033c90f448 100644 --- a/test/affinity2.test +++ b/test/affinity2.test @@ -14,6 +14,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix affinity2 do_execsql_test affinity2-100 { CREATE TABLE t1( @@ -58,4 +59,30 @@ do_execsql_test affinity2-300 { SELECT rowid, xt==+xi, xt==xi, xt==xb FROM t1 ORDER BY rowid; } {1 1 1 0 2 1 1 1 3 0 1 1} +#------------------------------------------------------------------------- +do_execsql_test 400 { + CREATE TABLE ttt(c0, c1); + CREATE INDEX ii ON ttt(CAST(c0 AS NUMERIC)); + INSERT INTO ttt VALUES('abc', '-1'); +} +do_execsql_test 410 { + SELECT * FROM ttt WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid; +} {abc -1} +do_execsql_test 420 { + SELECT * FROM ttt INDEXED BY ii WHERE CAST(c0 AS NUMERIC) > c1 GROUP BY rowid; +} {abc -1} + +do_execsql_test 430 { + CREATE TABLE t3(a, b, c INTEGER); + CREATE INDEX t3ac ON t3(a, c-1); + INSERT INTO t3 VALUES(1, 1, 1); + INSERT INTO t3 VALUES(2, 1, 0); + INSERT INTO t3 VALUES(3, 1, 1); + INSERT INTO t3 VALUES(4, 1, 0); + INSERT INTO t3 VALUES(5, 1, 1); +} +do_execsql_test 440 { + SELECT * FROM t3 WHERE c='0' ORDER BY a; +} {2 1 0 4 1 0} + finish_test From 95da9d5d46a1df00053191dfce9758dbda434e07 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 20 Aug 2019 13:49:12 +0000 Subject: [PATCH 030/112] Add the new sqlite3_drop_modules() interface to the loadable extension mechanism. FossilOrigin-Name: 658bd51623787be4ca87b066a051d119f39056286e223afef3691629cf1ab0e1 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/loadext.c | 4 +++- src/sqlite3ext.h | 4 ++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 87f8421097..6cb80d1226 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Retain\sthe\saffinity\sof\san\sexpression\sin\sa\sWHERE\sclause\swhen\sit\sis\stransformed\sto\sa\sreference\sto\san\sindex\scolumn\son\sthe\ssame\sexpression.\sFix\sfor\s[f043b113]. -D 2019-08-20T11:43:44.838 +C Add\sthe\snew\ssqlite3_drop_modules()\sinterface\sto\sthe\sloadable\sextension\nmechanism. +D 2019-08-20T13:49:12.572 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -486,7 +486,7 @@ F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c c2194dd2886337b870226fcb31c13e7df8c4b5e0ea85140e510a6f1daf1ad65b F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa -F src/loadext.c 22afc33c3a61b4fd80a60a54f1882688371e6bc64685df2696b008fce65a999c +F src/loadext.c a045bb3425a9a633cc0f78e93d9beda6866f4c0f15bfdee735aba7c6b39f5cc4 F src/main.c 51c55eb579eac4180bfcc6242741084710911350d2cd0c3fdd0f9fde55442128 F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 @@ -527,7 +527,7 @@ F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 F src/shell.c.in e0f0758b6ab506d8ab12502fd2b8c55546bb9e4bb772374344a5a1b73f5bc2b9 F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h 9ecc93b8493bd20c0c07d52e2ac0ed8bab9b549c7f7955b59869597b650dd8b5 +F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 F src/sqliteInt.h b7d612d9c63abc8a8a7dcf7fbec5326b1770f40c81502c56f508e272154e7615 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e @@ -1836,7 +1836,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 ec4c63e00c957f98d61ddc1b9d20406c7e1072d6ab0c12ac6939db6c63d90cb8 -R 95e8d7b4c9783731533e987936fe1358 -U dan -Z 9e91c8360eb84da6700bb773b0dba23e +P 511da0815673ca4a176aa61dc23a8231b2ab77e8363fc184a78b6e17dba64d49 +R b9c7a359cc9df9e55c5869fd605fd14d +U drh +Z 1abdc81b7e3d81dfcfc6c75af513ad72 diff --git a/manifest.uuid b/manifest.uuid index 9ea5046c2d..7456e32878 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -511da0815673ca4a176aa61dc23a8231b2ab77e8363fc184a78b6e17dba64d49 \ No newline at end of file +658bd51623787be4ca87b066a051d119f39056286e223afef3691629cf1ab0e1 \ No newline at end of file diff --git a/src/loadext.c b/src/loadext.c index 9ca139c8dc..03997c0275 100644 --- a/src/loadext.c +++ b/src/loadext.c @@ -461,7 +461,9 @@ static const sqlite3_api_routines sqlite3Apis = { #endif /* Version 3.28.0 and later */ sqlite3_stmt_isexplain, - sqlite3_value_frombind + sqlite3_value_frombind, + /* Version 3.30.0 and later */ + sqlite3_drop_modules, }; /* diff --git a/src/sqlite3ext.h b/src/sqlite3ext.h index 088148b936..416ac94231 100644 --- a/src/sqlite3ext.h +++ b/src/sqlite3ext.h @@ -322,6 +322,8 @@ struct sqlite3_api_routines { /* Version 3.28.0 and later */ int (*stmt_isexplain)(sqlite3_stmt*); int (*value_frombind)(sqlite3_value*); + /* Version 3.30.0 and later */ + int (*drop_modules)(sqlite3*,const char**); }; /* @@ -614,6 +616,8 @@ typedef int (*sqlite3_loadext_entry)( /* Version 3.28.0 and later */ #define sqlite3_stmt_isexplain sqlite3_api->isexplain #define sqlite3_value_frombind sqlite3_api->frombind +/* Version 3.30.0 and later */ +#define sqlite3_drop_modules sqlite3_api->drop_modules #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) From 4780b9ad46ebf5b9a2628cd80ef2ec95a6566f56 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Aug 2019 14:43:01 +0000 Subject: [PATCH 031/112] Fix a segfault that could occur following an OOM while processing a SELECT statement for which one or more of the expressions in the window frame declaration are themselves sub-selects that use window functions. FossilOrigin-Name: 75aec4fc886c04fe098828cc03bc72c197cbf40f0a1890fe5bbb98d4fd5c3c7e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 2 +- test/windowfault.test | 22 ++++++++++++++++++++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6cb80d1226..f7957a23fb 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\snew\ssqlite3_drop_modules()\sinterface\sto\sthe\sloadable\sextension\nmechanism. -D 2019-08-20T13:49:12.572 +C Fix\sa\ssegfault\sthat\scould\soccur\sfollowing\san\sOOM\swhile\sprocessing\sa\sSELECT\sstatement\sfor\swhich\sone\sor\smore\sof\sthe\sexpressions\sin\sthe\swindow\sframe\sdeclaration\sare\sthemselves\ssub-selects\sthat\suse\swindow\sfunctions. +D 2019-08-20T14:43:01.572 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 66a844757e865624c51e3c23dedf7f650adf75f799947f202aacbb1c394c3cda +F src/expr.c abef10556e47c3fca04de6a80d802d428e008ed61b4c76dd8439c189f4cd778f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1715,7 +1715,7 @@ F test/window8.test df187dc19921f7be0ab709d531d681bd80ccaac96a913a89ecee8b272b91 F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b -F test/windowfault.test 403693d7d951c5473f052f7ecddb61ed15ac9d212f238b8904ea270ba90f83e5 +F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 F test/with1.test d32792084dcb5f6c047d77bb8a032822ef9fe050ade07d0aeffa37753a05e3c9 F test/with2.test e0030e2f0267a910d6c0e4f46f2dfe941c1cc0d4f659ba69b3597728e7e8f1ab F test/with3.test b5f1372097690c6ef84db2f13fc7e64a88c7263c3f88493605f90597e8a68d45 @@ -1836,7 +1836,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 511da0815673ca4a176aa61dc23a8231b2ab77e8363fc184a78b6e17dba64d49 -R b9c7a359cc9df9e55c5869fd605fd14d -U drh -Z 1abdc81b7e3d81dfcfc6c75af513ad72 +P 658bd51623787be4ca87b066a051d119f39056286e223afef3691629cf1ab0e1 +R de5c373fa0aa9adc1be1e5804cb9b91d +U dan +Z d06c51f62e0fa708481e21348393bcb2 diff --git a/manifest.uuid b/manifest.uuid index 7456e32878..e37939af6d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -658bd51623787be4ca87b066a051d119f39056286e223afef3691629cf1ab0e1 \ No newline at end of file +75aec4fc886c04fe098828cc03bc72c197cbf40f0a1890fe5bbb98d4fd5c3c7e \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 41cc2724f6..c9deef0b6a 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1511,7 +1511,7 @@ Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){ #ifndef SQLITE_OMIT_WINDOWFUNC pNew->pWin = 0; pNew->pWinDefn = sqlite3WindowListDup(db, p->pWinDefn); - if( p->pWin ) gatherSelectWindows(pNew); + if( p->pWin && db->mallocFailed==0 ) gatherSelectWindows(pNew); #endif pNew->selId = p->selId; *pp = pNew; diff --git a/test/windowfault.test b/test/windowfault.test index 41c4bb6ad0..e037c467b0 100644 --- a/test/windowfault.test +++ b/test/windowfault.test @@ -224,4 +224,26 @@ do_faultsim_test 9 -end 25 -faults tmpread -body { catch {db close} tvfs delete +reset_db +do_execsql_test 10.0 { + CREATE TABLE t1(a, b, c, d); + CREATE TABLE t2(a, b, c, d); +} + +do_faultsim_test 1 -faults oom* -prep { +} -body { + execsql { + SELECT row_number() OVER win + FROM t1 + WINDOW win AS ( + ORDER BY ( + SELECT percent_rank() OVER win2 FROM t2 + WINDOW win2 AS (ORDER BY a) + ) + ) + } +} -test { + faultsim_test_result {0 {}} +} + finish_test From 4fcb9caa60c3939cd562574f744a8514737ae7fb Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Aug 2019 15:47:28 +0000 Subject: [PATCH 032/112] Do not pass ORDER BY clauses with non-standard NULL handling to virtual table implementations. FossilOrigin-Name: a9a82ee88d2d12209a674bd19167277aa91a6912e7a8bbf3714f90d559307fee --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 1 + test/nulls1.test | 29 +++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2dac1918cc..0c034215e3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sproblems\swith\swindow\sframes\sthat\suse\sORDER\sBY\s...\sNULLS\sLAST\setc. -D 2019-08-19T19:59:50.467 +C Do\snot\spass\sORDER\sBY\sclauses\swith\snon-standard\sNULL\shandling\sto\svirtual\stable\simplementations. +D 2019-08-20T15:47:28.909 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 52c433208eafdc7e1750ea4622cfffb5d14d906a0a9258e07bae4b6fee182fef +F src/where.c 391e856e4e73e3b68731ed6ee4fa0cb0e43a17c8565ddaad2b554e06db9ad239 F src/whereInt.h 807766a6a92893dbba8a887e5b13466d2257ce07a84cf1be0aae2c41aee3bf4f F src/wherecode.c 81c5d1eb909f8e1284df58367d25f748d126c475725665e7bb9b10a9bf702242 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc @@ -1182,7 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test d2f1da489fd24d7af54aed9d7e117e4c7d6bb3e67f3a87ef54377cc088563073 +F test/nulls1.test 085aae8cd3442159d993e6b5317b7503a71d82107ab1a87390a370d5891945f9 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1837,7 +1837,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 bb9767a287097a615aeb4abdba689b10e1a1c36c016c8e55905b508075e62c86 -R 0d189432ffc682f45a241a646815eff1 +P 75d665a494dd7d6e77d5a80af386ee5accc0a53416d5493424dc0fef6c7b01a0 +R c52f59575d6f8f4774d29df09eb77ad3 U dan -Z 3a5c6bb3c2c9a1118645ddff85026963 +Z b71d521722a995099edda82dc88d1b7f diff --git a/manifest.uuid b/manifest.uuid index 7a21ed26bb..3553c8723d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75d665a494dd7d6e77d5a80af386ee5accc0a53416d5493424dc0fef6c7b01a0 \ No newline at end of file +a9a82ee88d2d12209a674bd19167277aa91a6912e7a8bbf3714f90d559307fee \ No newline at end of file diff --git a/src/where.c b/src/where.c index 37eca3b7ea..a6349987a4 100644 --- a/src/where.c +++ b/src/where.c @@ -933,6 +933,7 @@ static sqlite3_index_info *allocateIndexInfo( for(i=0; ia[i].pExpr; if( pExpr->op!=TK_COLUMN || pExpr->iTable!=pSrc->iCursor ) break; + if( pOrderBy->a[i].sortFlags & KEYINFO_ORDER_BIGNULL ) break; } if( i==n){ nOrderBy = n; diff --git a/test/nulls1.test b/test/nulls1.test index e54d60856d..9faf82110b 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -118,4 +118,33 @@ do_execsql_test 3.2 { 400 300 } +#------------------------------------------------------------------------- +ifcapable vtab { + register_echo_module db + do_execsql_test 4.0 { + CREATE TABLE tx(a INTEGER PRIMARY KEY, b, c); + CREATE INDEX i1 ON tx(b); + INSERT INTO tx VALUES(1, 1, 1); + INSERT INTO tx VALUES(2, NULL, 2); + INSERT INTO tx VALUES(3, 3, 3); + INSERT INTO tx VALUES(4, NULL, 4); + INSERT INTO tx VALUES(5, 5, 5); + CREATE VIRTUAL TABLE te USING echo(tx); + } + + do_execsql_test 4.1 { + SELECT * FROM tx ORDER BY b NULLS FIRST; + } {2 {} 2 4 {} 4 1 1 1 3 3 3 5 5 5} + do_execsql_test 4.2 { + SELECT * FROM te ORDER BY b NULLS FIRST; + } {2 {} 2 4 {} 4 1 1 1 3 3 3 5 5 5} + + do_execsql_test 4.3 { + SELECT * FROM tx ORDER BY b NULLS LAST; + } {1 1 1 3 3 3 5 5 5 2 {} 2 4 {} 4} + do_execsql_test 4.4 { + SELECT * FROM te ORDER BY b NULLS LAST; + } {1 1 1 3 3 3 5 5 5 2 {} 2 4 {} 4} +} + finish_test From 2a0c16f27653982880ab76714b5aaae65db43315 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Aug 2019 17:51:13 +0000 Subject: [PATCH 033/112] Add tests for sort-by-index cases that use IN() and non-default NULL handling. FossilOrigin-Name: 09d660ecde723fb30f3bb3684bbb7f95825d78da6a6f33ddf57846054cd563e0 --- manifest | 12 +++++------ manifest.uuid | 2 +- test/nulls1.test | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 0c034215e3..5e0da8bb80 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Do\snot\spass\sORDER\sBY\sclauses\swith\snon-standard\sNULL\shandling\sto\svirtual\stable\simplementations. -D 2019-08-20T15:47:28.909 +C Add\stests\sfor\ssort-by-index\scases\sthat\suse\sIN()\sand\snon-default\sNULL\shandling. +D 2019-08-20T17:51:13.442 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1182,7 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test 085aae8cd3442159d993e6b5317b7503a71d82107ab1a87390a370d5891945f9 +F test/nulls1.test abf8ab564357136d0a1c9909ab068d4fcb0a5e94e168bed6b6c6f548a6f56d07 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1837,7 +1837,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 75d665a494dd7d6e77d5a80af386ee5accc0a53416d5493424dc0fef6c7b01a0 -R c52f59575d6f8f4774d29df09eb77ad3 +P a9a82ee88d2d12209a674bd19167277aa91a6912e7a8bbf3714f90d559307fee +R 72239629606cb191b8fd5443e5ad57ff U dan -Z b71d521722a995099edda82dc88d1b7f +Z 5d1aadbb6bb817df7ca002049c5a7d6e diff --git a/manifest.uuid b/manifest.uuid index 3553c8723d..e1b28f0039 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a9a82ee88d2d12209a674bd19167277aa91a6912e7a8bbf3714f90d559307fee \ No newline at end of file +09d660ecde723fb30f3bb3684bbb7f95825d78da6a6f33ddf57846054cd563e0 \ No newline at end of file diff --git a/test/nulls1.test b/test/nulls1.test index 9faf82110b..38fba79be0 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -119,6 +119,7 @@ do_execsql_test 3.2 { } #------------------------------------------------------------------------- +# ifcapable vtab { register_echo_module db do_execsql_test 4.0 { @@ -147,4 +148,59 @@ ifcapable vtab { } {1 1 1 3 3 3 5 5 5 2 {} 2 4 {} 4} } +#------------------------------------------------------------------------- +# +do_execsql_test 5.0 { + CREATE TABLE t4(a, b, c); + INSERT INTO t4 VALUES(1, 1, 11); + INSERT INTO t4 VALUES(1, 2, 12); + INSERT INTO t4 VALUES(1, NULL, 1); + + INSERT INTO t4 VALUES(2, NULL, 1); + INSERT INTO t4 VALUES(2, 2, 12); + INSERT INTO t4 VALUES(2, 1, 11); + + INSERT INTO t4 VALUES(3, NULL, 1); + INSERT INTO t4 VALUES(3, 2, 12); + INSERT INTO t4 VALUES(3, NULL, 3); +} + +do_execsql_test 5.1 { + SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST +} { + 1 1 11 1 2 12 1 {} 1 + 2 1 11 2 2 12 2 {} 1 + 3 2 12 3 {} 1 3 {} 3 +} +do_execsql_test 5.2 { + CREATE INDEX t4ab ON t4(a, b); + SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST +} { + 1 1 11 1 2 12 1 {} 1 + 2 1 11 2 2 12 2 {} 1 + 3 2 12 3 {} 1 3 {} 3 +} +do_eqp_test 5.3 { + SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a, b NULLS LAST +} { + QUERY PLAN + `--SEARCH TABLE t4 USING INDEX t4ab (a=?) +} + +do_execsql_test 5.4 { + SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST +} { + 3 {} 3 3 {} 1 3 2 12 + 2 {} 1 2 2 12 2 1 11 + 1 {} 1 1 2 12 1 1 11 +} +do_eqp_test 5.5 { + SELECT * FROM t4 WHERE a IN (1, 2, 3) ORDER BY a DESC, b DESC NULLS FIRST +} { + QUERY PLAN + `--SEARCH TABLE t4 USING INDEX t4ab (a=?) +} + finish_test + + From 35fb866ea334beedadb258eaacb68b627a6b2554 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Aug 2019 19:11:29 +0000 Subject: [PATCH 034/112] Fix a problem with fts5 "ORDER BY rank" queries when the fts5 table name requires quoting. FossilOrigin-Name: 00e9a8f2730eb7239bf7fd107c97c409e4f9fbd968510766373440a9079898eb --- ext/fts5/fts5_main.c | 2 +- ext/fts5/test/fts5corrupt3.test | 69 ++++++++++++++++----------------- ext/fts5/test/fts5rank.test | 18 +++++++++ manifest | 16 ++++---- manifest.uuid | 2 +- 5 files changed, 62 insertions(+), 45 deletions(-) diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index d44e95942c..4bb3a9965f 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -932,7 +932,7 @@ static int fts5CursorFirstSorted( ** ** If SQLite a built-in statement cache, this wouldn't be a problem. */ rc = fts5PrepareStatement(&pSorter->pStmt, pConfig, - "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(%s%s%s) %s", + "SELECT rowid, rank FROM %Q.%Q ORDER BY %s(\"%w\"%s%s) %s", pConfig->zDb, pConfig->zName, zRank, pConfig->zName, (zRankArgs ? ", " : ""), (zRankArgs ? zRankArgs : ""), diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 0497c95bcf..2391d97eea 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -767,7 +767,7 @@ SELECT * FROM t1 WHERE t1 MATCH 'abandon'; do_catchsql_test 13.1 { SELECT * FROM t1 WHERE t1 MATCH 'abandon'; -} {1 {vtable constructor failed: t1}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -958,7 +958,7 @@ do_test 15.0 { do_catchsql_test 15.1 { INSERT INTO t1(t1) VALUES('integrity-check'); -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #--------------------------------------------------------------------------- # @@ -3903,19 +3903,19 @@ do_test 33.0 { | end crash-fed6e90021ba5d.db }]} {} -do_execsql_test 33.1 { +do_catchsql_test 33.1 { CREATE VIRTUAL TABLE t2 USING fts5vocab('t1','row'); CREATE VIRTUAL TABLE t3 USING fts5vocab('t1','col'); CREATE VIRTUAL TABLE t4 USING fts5vocab('t1','instance'); -} +} {/*malformed database schema*/} do_catchsql_test 33.2 { SELECT * FROM t2; -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} do_catchsql_test 33.3 { SELECT * FROM t2, t3, t4 WHERE t2.term=t3.term AND t3.term=t4.term; -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -4637,17 +4637,17 @@ do_test 37.0 { do_catchsql_test 37.1 { SELECT * FROM t3; -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db -do_execsql_test 37.0 { +do_execsql_test 37a.0 { CREATE VIRTUAL TABLE t1 USING fts5(b, c); INSERT INTO t1 VALUES('a', 'b'); SELECT quote(block) FROM t1_data WHERE rowid=10; } {X'000000000101010001010101'} -do_execsql_test 37.1 { +do_execsql_test 37a.1 { UPDATE t1_data SET block = X'FFFFFFFF0101010001010101' WHERE rowid = 10; SELECT rowid FROM t1('a'); } {1} @@ -4894,7 +4894,7 @@ do_test 38.0 { do_catchsql_test 38.1 { UPDATE t1 SET b=quote(zeroblob(200)) WHERE t1 MATCH 'thread*'; -} {0 {}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -5326,16 +5326,16 @@ do_test 40.0 { | end crash2.txt.db }]} {} -do_execsql_test 40.1 { +do_catchsql_test 40.1 { BEGIN; INSERT INTO t1(b) VALUES(X'819192e578de3fa24af3733ca8769291a0fee3669f9fddefc5cba913e4225d4b6ce2b04f26b87fad3ee6f9b7d90a1ea62a169bf41e5d32707a6ca5c3d05e4bde05c9d89eaaa8c50e74333d2e9fcd7dfe95528a3a016aac1102d825c5cd70cf99d8a88e0ea7f798d4334386518b7ad359beb168b93aba059a2a3bd93112d65b44c12b9904ea786b204d80531cdf0504bf9b203dbe927061974caf7b9f30cbc3397b61f802e732012a6663d41c3607d6f1c0dbcfd489adac05ca500c0b04439d894cd93a840159225ef73b627e178b9f84b3ffe66cf22a963a8368813ff7961fc47f573211ccec95e0220dcbb3bf429f4a50ba54d7a53784ac51bf'); INSERT INTO t1(b) VALUES(X'c8ae0d0e7c3175946e62ba2b449511d4eb504079984a20f77969f62206c9f3d7ea25358ab705e6978627290b6d48db9032f815a06a79a4f4b809841a0942eed12954ed166f666111812a508abc3bec87958846edaec0a6fe14564bc0a4b78f1c35ebcacca6bae29cc37ae9b59d8a2d7593af1e47dda0ece2268a98d20febafad037964f139851f9a57f48b3706b01721769071991412044cd6006f1d72eb6eb4aa5ad77e378176db8c15575fbeee47165e38a7c6c5a557ac2dfe11813976eaf6741cf593a9e457053a3c34cddfbe605a6e25419f993de8374fafcd3636509d8416a51dc7bcc14cfca322ae343078f47e23522431c17d0da0c033'); INSERT INTO t1(b) VALUES(X'dc29a94e873a45a4243fce9b912aaefbadf1d0423e0345793874b356eeb500b92fb05284c1601fe9bad3143f72162f10242cec27c44ebf764c8fc9fb0824e32c4161472a4f914f579e0e8274f08ca1a02e59b9d8eec1f31061f9ccb9ed97a6f06534e991f7992c761489e6a7724f6e9c2b581e77487ded3a986d53c4419bbd3e9747cee300e670dd7294874c77e2ed48da68eaa6c3ec954a09ac410493d98e34d6686e54fbbe80696705f10e040c66093efb40746b33600685c94c664c7942835a9e954866121d5dcfb2cb12e92521ea3df175ee17072502dad9b9c1565f801b2179799011eb7418bfa00323e3157589e648ff7378be233c79b7'); -} +} {/*malformed database schema*/} do_catchsql_test 40.2 { INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3, true ),(4,44); -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -5789,7 +5789,7 @@ do_test 43.0 { do_catchsql_test 43.1 { INSERT INTO t1(t1) VALUES('optimize'); -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -6047,7 +6047,7 @@ do_catchsql_test 45.2 { INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); INSERT INTO t1(t1, rank) VALUES('merge', 5); -} {0 {}} +} {/*malformed database schema*/} #-------------------------------------------------------------------------- reset_db @@ -6265,7 +6265,7 @@ do_test 46.0 { do_catchsql_test 46.1 { SELECT snippet(t1,'[','', '--',-1,10) FROM t1('*'); -} {0 {{}}} +} {/*malformed database schema*/} #-------------------------------------------------------------------------- reset_db @@ -6418,7 +6418,7 @@ do_test 47.0 { do_catchsql_test 47.1 { INSERT INTO t1(t1) VALUES('integrity-check'); -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} do_catchsql_test 47.2 { SELECT count(*) FROM ( @@ -6426,7 +6426,7 @@ do_catchsql_test 47.2 { highlight(t1, 2, '[', ']') FROM t1('g h') WHERE rank MATCH 'bm25(1.0, 1.0)' ORDER BY rank ) -} {0 3} +} {/*malformed database schema*/} #-------------------------------------------------------------------------- reset_db @@ -7130,7 +7130,7 @@ do_test 52.0 { do_catchsql_test 52.1 { SELECT fts5_decode(id, block) FROM t1_data; -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -7346,7 +7346,7 @@ do_test 53.0 { do_catchsql_test 53.1 { WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x<>1 FROM c WHERE x<10) INSERT INTO t1(a) SELECT randomblob(3000) FROM c; -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -7562,7 +7562,7 @@ do_test 54.0 { do_catchsql_test 54.1 { SELECT rowid==-1 FROM t1('t*'); -} {0 {0 0 0}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -7777,10 +7777,10 @@ do_test 55.0 { | end crash-b366b5ac0d3887.db }]} {} -do_execsql_test 55.1 { +do_catchsql_test 55.1 { SAVEPOINT one; DELETE FROM t1 WHERE a MATCH 'ts'; -} +} {/*malformed database schema*/} do_execsql_test 55.2 { ROLLBACK TO one; @@ -8013,7 +8013,7 @@ do_test 56.1 { set res "1 {database disk image is malformed}" } set res -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -8131,7 +8131,7 @@ do_test 57.0 { do_catchsql_test 57.1 { INSERT INTO t1(t1) VALUES('optimize') -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- reset_db @@ -8339,9 +8339,9 @@ do_test 58.0 { | end crash-5a5acd0ab42d31.db }]} {} -do_execsql_test 58.1 { +do_catchsql_test 58.1 { SELECT * FROM t1('t*'); -} {{} {} {} {} {} {}} +} {/*malformed database schema*/} #------------------------------------------------------------------------- do_test 59.0 { @@ -8948,13 +8948,13 @@ do_test 61.0 { | end crash-e5fa281edabddf.db }]} {} -do_execsql_test 61.1 { +do_catchsql_test 61.1 { CREATE VIRTUAL TABLE t3 USING fts5vocab('t1'(),'col' ); -} +} {/*malformed database schema*/} do_catchsql_test 61.2 { SELECT * FROM t3 ORDER BY rowid; -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} breakpoint #------------------------------------------------------------------------- @@ -9159,7 +9159,7 @@ do_test 62.0 { do_catchsql_test 62.1 { WITH c(x) AS (VALUES(false) UNION ALL SELECT x+1 FROM c WHERE x<72) INSERT INTO t1(a) SELECT randomblob(2829) FROM c; -} {0 {}} +} {/*malformed database schema*/} #--------------------------------------------------------------------------- do_test 63.0 { @@ -9357,16 +9357,15 @@ do_test 63.0 { do_catchsql_test 63.1 { SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*'; -} {1 {database disk image is malformed}} +} {/*malformed database schema*/} do_catchsql_test 63.2 { INSERT INTO t1(t1) VALUES('optimize'); -} {0 {}} +} {/*malformed database schema*/} -breakpoint do_catchsql_test 63.3 { SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*'; -} {0 {}} +} {/*malformed database schema*/} sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/ext/fts5/test/fts5rank.test b/ext/fts5/test/fts5rank.test index e8f5473c4b..22534e8e03 100644 --- a/ext/fts5/test/fts5rank.test +++ b/ext/fts5/test/fts5rank.test @@ -162,4 +162,22 @@ do_execsql_test 5.1 { SELECT rowid FROM ttt('word') WHERE rowid BETWEEN 30 AND 40 ORDER BY rank; } {30 31 32 33 34 35 36 37 38 39 40} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE "My.Table" USING fts5(Text); + + INSERT INTO "My.Table" VALUES ('hello this is a test'); + INSERT INTO "My.Table" VALUES ('of trying to order by'); + INSERT INTO "My.Table" VALUES ('rank on an fts5 table'); + INSERT INTO "My.Table" VALUES ('that have periods in'); + INSERT INTO "My.Table" VALUES ('the table names.'); + INSERT INTO "My.Table" VALUES ('table table table'); +} +do_execsql_test 6.1 { + SELECT * FROM "My.Table" WHERE Text MATCH 'table' ORDER BY rank; +} { + {table table table} {the table names.} {rank on an fts5 table} +} + finish_test diff --git a/manifest b/manifest index f7957a23fb..cfd08c86b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\ssegfault\sthat\scould\soccur\sfollowing\san\sOOM\swhile\sprocessing\sa\sSELECT\sstatement\sfor\swhich\sone\sor\smore\sof\sthe\sexpressions\sin\sthe\swindow\sframe\sdeclaration\sare\sthemselves\ssub-selects\sthat\suse\swindow\sfunctions. -D 2019-08-20T14:43:01.572 +C Fix\sa\sproblem\swith\sfts5\s"ORDER\sBY\srank"\squeries\swhen\sthe\sfts5\stable\sname\srequires\squoting. +D 2019-08-20T19:11:29.544 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,7 +117,7 @@ F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1 F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 F ext/fts5/fts5_index.c cd363c2fa3e626c04a9b7c705ff50222b4cab052704938f6a24881602ed3ed0d -F ext/fts5/fts5_main.c 346a1ec08caa66f1187f1e0bf12e39e4d24682323b839e8a76ef653b8db8a91d +F ext/fts5/fts5_main.c b2c42f1cef9673ecdd498b22c38483a4380bcf1701d1e61b021a2945f18e42e1 F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 9517cc527a8e8a33949652d5c7b5e251f8c3d5ae3f23f01d4320e30f29a0336b F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test 1f36c04fdd717f7d44a0addcdad0f5e54a5a403eab8a25426b069757830682ee +F ext/fts5/test/fts5corrupt3.test 99318789d84c678ed6388e61109b9f7b92c64419e87e4881093c01e219c5d397 F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -199,7 +199,7 @@ F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a9863 F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457 F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056 F ext/fts5/test/fts5query.test ac363b17a442620bb0780e93c24f16a5f963dfe2f23dc85647b869efcfada728 -F ext/fts5/test/fts5rank.test ca5000241924ecc2882db33c60f4f3a62b1ee6b16b5a9c8c6ddd9b6b2138489c +F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee7e017ce46f2416 F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7 F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415 F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6 @@ -1836,7 +1836,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 658bd51623787be4ca87b066a051d119f39056286e223afef3691629cf1ab0e1 -R de5c373fa0aa9adc1be1e5804cb9b91d +P 75aec4fc886c04fe098828cc03bc72c197cbf40f0a1890fe5bbb98d4fd5c3c7e +R 1c1c766fc2c729d2e5f3a524114c00f7 U dan -Z d06c51f62e0fa708481e21348393bcb2 +Z 8a025a4c149038423df368f1009cf0d8 diff --git a/manifest.uuid b/manifest.uuid index e37939af6d..508e9fd646 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -75aec4fc886c04fe098828cc03bc72c197cbf40f0a1890fe5bbb98d4fd5c3c7e \ No newline at end of file +00e9a8f2730eb7239bf7fd107c97c409e4f9fbd968510766373440a9079898eb \ No newline at end of file From 546738f855d8c7e01c1d04b287040938ffeed81c Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 20 Aug 2019 20:09:51 +0000 Subject: [PATCH 035/112] Further tests for the special null-handling on this branch. FossilOrigin-Name: 0dbbb51f4d39cafb01d625d65c12dcb232a9c1da7ed5a9397bf55cfea1b980d2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- test/nulls1.test | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5e0da8bb80..42a0a50ee3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stests\sfor\ssort-by-index\scases\sthat\suse\sIN()\sand\snon-default\sNULL\shandling. -D 2019-08-20T17:51:13.442 +C Further\stests\sfor\sthe\sspecial\snull-handling\son\sthis\sbranch. +D 2019-08-20T20:09:51.176 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1182,7 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test abf8ab564357136d0a1c9909ab068d4fcb0a5e94e168bed6b6c6f548a6f56d07 +F test/nulls1.test 5b978fbae9c73b497608c16f2636a2f71de6e2c914e4c78955cf022e39b7a0d5 F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1837,7 +1837,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 a9a82ee88d2d12209a674bd19167277aa91a6912e7a8bbf3714f90d559307fee -R 72239629606cb191b8fd5443e5ad57ff +P 09d660ecde723fb30f3bb3684bbb7f95825d78da6a6f33ddf57846054cd563e0 +R fb0a3ff22d0818546ad42a3f60c048f9 U dan -Z 5d1aadbb6bb817df7ca002049c5a7d6e +Z 9ee5e455d6aba2bd43615893c1e9314b diff --git a/manifest.uuid b/manifest.uuid index e1b28f0039..ecfaa97382 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -09d660ecde723fb30f3bb3684bbb7f95825d78da6a6f33ddf57846054cd563e0 \ No newline at end of file +0dbbb51f4d39cafb01d625d65c12dcb232a9c1da7ed5a9397bf55cfea1b980d2 \ No newline at end of file diff --git a/test/nulls1.test b/test/nulls1.test index 38fba79be0..75d398782d 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -201,6 +201,42 @@ do_eqp_test 5.5 { `--SEARCH TABLE t4 USING INDEX t4ab (a=?) } +#------------------------------------------------------------------------- +# +do_execsql_test 6.0 { + CREATE TABLE t5(a, b, c); + WITH s(i) AS ( + VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<200 + ) + INSERT INTO t5 SELECT i%2, CASE WHEN (i%10)==0 THEN NULL ELSE i END, i FROM s; +} + +set res1 [db eval { SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c }] +set res2 [db eval { + SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC +}] + +do_execsql_test 6.1.1 { + CREATE INDEX t5ab ON t5(a, b, c); + SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c; +} $res1 +do_eqp_test 6.1.2 { + SELECT a,b FROM t5 WHERE a=1 ORDER BY b NULLS LAST, c; +} { + QUERY PLAN + `--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?) +} +do_execsql_test 6.2.1 { + SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC +} $res2 +do_eqp_test 6.2.2 { + SELECT a,b FROM t5 WHERE a=1 ORDER BY b DESC NULLS FIRST, c DESC +} { + QUERY PLAN + `--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?) +} + + finish_test From 6fcb9f3ad96ea42eb46ff33b5fbd182f51d968b2 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Aug 2019 11:31:48 +0000 Subject: [PATCH 036/112] Fix a broken assert() in the fts3 snippet code that was failing for queries containging more than 64 phrases. FossilOrigin-Name: 4c01e0170e113ad052b6c3980beb4be9f1dc03fb3cf34132b90e8b82b23f654e --- ext/fts3/fts3_snippet.c | 4 ++-- manifest | 14 +++++++------- manifest.uuid | 2 +- test/fts3snippet.test | 24 ++++++++++++++++++++++++ 4 files changed, 34 insertions(+), 10 deletions(-) diff --git a/ext/fts3/fts3_snippet.c b/ext/fts3/fts3_snippet.c index d5ebda6a05..6db3fd7d96 100644 --- a/ext/fts3/fts3_snippet.c +++ b/ext/fts3/fts3_snippet.c @@ -433,10 +433,10 @@ static void fts3SnippetDetails( while( iCsr<(iStart+pIter->nSnippet) && iCsr>=iStart ){ int j; - u64 mPhrase = (u64)1 << i; + u64 mPhrase = (u64)1 << (i%64); u64 mPos = (u64)1 << (iCsr - iStart); assert( iCsr>=iStart && (iCsr - iStart)<=64 ); - assert( i>=0 && i<=64 ); + assert( i>=0 ); if( (mCover|mCovered)&mPhrase ){ iScore++; }else{ diff --git a/manifest b/manifest index cfd08c86b4..a7c9848843 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\sfts5\s"ORDER\sBY\srank"\squeries\swhen\sthe\sfts5\stable\sname\srequires\squoting. -D 2019-08-20T19:11:29.544 +C Fix\sa\sbroken\sassert()\sin\sthe\sfts3\ssnippet\scode\sthat\swas\sfailing\sfor\squeries\scontainging\smore\sthan\s64\sphrases. +D 2019-08-21T11:31:48.364 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -90,7 +90,7 @@ F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_porter.c 3565faf04b626cddf85f03825e86056a4562c009 -F ext/fts3/fts3_snippet.c 2f3a78b990f1c8658225618c8a0fa06ab60046688d6fb627a548e8ada9011150 +F ext/fts3/fts3_snippet.c 7963dd25ec81013c31f3c61697d0a1f3d06be21af3565774645c08d3dedf1fa7 F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1 F ext/fts3/fts3_test.c 73b16e229e517c1b1f0fb8e1046182a4e5dbc8dbe6eea8a5d4353fcce7dbbf39 F ext/fts3/fts3_tokenize_vtab.c 1de9a61acfa2a0445ed989310c31839c57f6b6086dd9d5c97177ae734a17fd8b @@ -965,7 +965,7 @@ F test/fts3query.test ca033ff2ebcc22c69d89032fb0bc1850997d31e7e60ecd26440796ba16 F test/fts3rank.test cd99bc83a3c923c8d52afd90d86979cf05fc41849f892faeac3988055ef37b99 F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0 F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e -F test/fts3snippet.test dace744104d1a44dc12dc9dd10b8d7542342df503d96942b7c4a55034e761789 +F test/fts3snippet.test 430bb5ace2b31ccd99de4d71775d956da832c114c4b3e39589748f114458647c F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca F test/fts3tok1.test a663f4cac22a9505400bc22aacb818d7055240409c28729669ea7d4cc2120d15 F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d @@ -1836,7 +1836,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 75aec4fc886c04fe098828cc03bc72c197cbf40f0a1890fe5bbb98d4fd5c3c7e -R 1c1c766fc2c729d2e5f3a524114c00f7 +P 00e9a8f2730eb7239bf7fd107c97c409e4f9fbd968510766373440a9079898eb +R 255eac821d14dded7de17c80283ba7c2 U dan -Z 8a025a4c149038423df368f1009cf0d8 +Z f165fea3d8f5943a2e39a213216b0a66 diff --git a/manifest.uuid b/manifest.uuid index 508e9fd646..bc8cee914d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00e9a8f2730eb7239bf7fd107c97c409e4f9fbd968510766373440a9079898eb \ No newline at end of file +4c01e0170e113ad052b6c3980beb4be9f1dc03fb3cf34132b90e8b82b23f654e \ No newline at end of file diff --git a/test/fts3snippet.test b/test/fts3snippet.test index ebcdb8cffd..976c8c8492 100644 --- a/test/fts3snippet.test +++ b/test/fts3snippet.test @@ -561,7 +561,31 @@ do_test 4.3 { }] } {64} +#------------------------------------------------------------------------- +# Request a snippet from a query with more than 64 phrases. +# +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE t5 USING fts3(x); + INSERT INTO t5 VALUES('a1 a2 a3'); + INSERT INTO t5 VALUES('a4 a5 a6'); + INSERT INTO t5 VALUES('a70 a71 a72'); +} +do_execsql_test 5.1 { + SELECT snippet(t5, '[', ']') FROM t5 WHERE t5 MATCH + 'a1 OR a2 OR a3 OR a4 OR a5 OR a6 OR a7 OR a8 OR a9 OR a10 OR ' || + 'a11 OR a12 OR a13 OR a14 OR a15 OR a16 OR a17 OR a18 OR a19 OR a10 OR ' || + 'a21 OR a22 OR a23 OR a24 OR a25 OR a26 OR a27 OR a28 OR a29 OR a20 OR ' || + 'a31 OR a32 OR a33 OR a34 OR a35 OR a36 OR a37 OR a38 OR a39 OR a30 OR ' || + 'a41 OR a42 OR a43 OR a44 OR a45 OR a46 OR a47 OR a48 OR a49 OR a40 OR ' || + 'a51 OR a52 OR a53 OR a54 OR a55 OR a56 OR a57 OR a58 OR a59 OR a50 OR ' || + 'a61 OR a62 OR a63 OR a64 OR a65 OR a66 OR a67 OR a68 OR a69 OR a60 OR ' || + 'a71 OR a72 OR a73 OR a74 OR a75 OR a76 OR a77 OR a78 OR a79 OR a70' +} { + {[a1] [a2] [a3]} + {[a4] [a5] [a6]} + {[a70] [a71] [a72]} +} set sqlite_fts3_enable_parentheses 0 finish_test From f7c92e82d27b88b1fa56ff72796ed42e89f614c9 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Aug 2019 14:54:50 +0000 Subject: [PATCH 037/112] Avoid assuming that "column IS ?", where column is declared UNIQUE, matches only a single row (as "?" might be NULL). Fix for [b8689402]. FossilOrigin-Name: d02490a2f0cae047087130b4ad8f55f265845c2ffb3bde3b7d507edb54acea6d --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 12 +++++++++--- test/distinct2.test | 26 ++++++++++++++++++++++++++ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index a7c9848843..b14d09aa2a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbroken\sassert()\sin\sthe\sfts3\ssnippet\scode\sthat\swas\sfailing\sfor\squeries\scontainging\smore\sthan\s64\sphrases. -D 2019-08-21T11:31:48.364 +C Avoid\sassuming\sthat\s"column\sIS\s?",\swhere\scolumn\sis\sdeclared\sUNIQUE,\smatches\sonly\sa\ssingle\srow\s(as\s"?"\smight\sbe\sNULL).\sFix\sfor\s[b8689402]. +D 2019-08-21T14:54:50.917 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 2fac51d2420f05ab6f644f1813d4f73f6214304836fd9b22345738d943faad9b +F src/where.c 16c649c1dbc5676ad9b1c6a9b3559b4c4ab8e916d5da59cabb461682444a9ca8 F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c e1131fe94c8728cbecc707f6455afbda9418896497bdca2d49a04ce6c57999f6 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc @@ -811,7 +811,7 @@ F test/descidx2.test 9f1a0c83fd57f8667c82310ca21b30a350888b5d F test/descidx3.test 09ddbe3f5295f482d2f8b687cf6db8bad7acd9a2 F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test a1783b960ad8c15a77cd9f207be072898db1026c -F test/distinct2.test 1a01038083535fa9431f4a22587ae58d52d0a794910c36bd2bec07ba1e0e7367 +F test/distinct2.test b854b442111bf362328981f55d39d0df13140383b112057f6e046e311f14e5c3 F test/distinctagg.test 1a6ef9c87a58669438fc771450d7a72577417376 F test/e_blobbytes.test 439a945953b35cb6948a552edaec4dc31fd70a05 F test/e_blobclose.test 4b3c8c60c2171164d472059c73e9f3c1844bb66d @@ -1836,7 +1836,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 00e9a8f2730eb7239bf7fd107c97c409e4f9fbd968510766373440a9079898eb -R 255eac821d14dded7de17c80283ba7c2 +P 4c01e0170e113ad052b6c3980beb4be9f1dc03fb3cf34132b90e8b82b23f654e +R ba43ef9ffea471302d6253c6ac41d4d7 U dan -Z f165fea3d8f5943a2e39a213216b0a66 +Z 050be14a9fe83dd49b34a7e227f313e7 diff --git a/manifest.uuid b/manifest.uuid index bc8cee914d..2b4538aa49 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4c01e0170e113ad052b6c3980beb4be9f1dc03fb3cf34132b90e8b82b23f654e \ No newline at end of file +d02490a2f0cae047087130b4ad8f55f265845c2ffb3bde3b7d507edb54acea6d \ No newline at end of file diff --git a/src/where.c b/src/where.c index a37a810a2b..ae8899e302 100644 --- a/src/where.c +++ b/src/where.c @@ -3765,15 +3765,21 @@ static i8 wherePathSatisfiesOrderBy( u16 eOp = pLoop->aLTerm[j]->eOperator; /* Skip over == and IS and ISNULL terms. (Also skip IN terms when - ** doing WHERE_ORDERBY_LIMIT processing). + ** doing WHERE_ORDERBY_LIMIT processing). Except, IS and ISNULL + ** terms imply that the index is not UNIQUE NOT NULL in which case + ** the loop need to be marked as not order-distinct because it can + ** have repeated NULL rows. ** ** If the current term is a column of an ((?,?) IN (SELECT...)) ** expression for which the SELECT returns more than one column, ** check that it is the only column used by this loop. Otherwise, ** if it is one of two or more, none of the columns can be - ** considered to match an ORDER BY term. */ + ** considered to match an ORDER BY term. + */ if( (eOp & eqOpMask)!=0 ){ - if( eOp & WO_ISNULL ){ + if( eOp & (WO_ISNULL|WO_IS) ){ + testcase( eOp & WO_ISNULL ); + testcase( eOp & WO_IS ); testcase( isOrderDistinct ); isOrderDistinct = 0; } diff --git a/test/distinct2.test b/test/distinct2.test index 634dfd72e3..c42a1c971a 100644 --- a/test/distinct2.test +++ b/test/distinct2.test @@ -274,6 +274,32 @@ do_execsql_test 2040 { two 1 1 } +#------------------------------------------------------------------------- +# +reset_db +do_execsql_test 3000 { + CREATE TABLE t0 (c0, c1 NOT NULL DEFAULT 1, c2, PRIMARY KEY (c0, c1)); + INSERT INTO t0(c2) VALUES (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL), (NULL); + INSERT INTO t0(c2) VALUES('a'); +} +do_execsql_test 3010 { + SELECT DISTINCT * FROM t0 WHERE NULL IS t0.c0; +} { + {} 1 {} + {} 1 a +} + +do_execsql_test 3020 { + ANALYZE; +} + +do_execsql_test 3030 { + SELECT DISTINCT * FROM t0 WHERE NULL IS c0; +} { + {} 1 {} + {} 1 a +} finish_test + From 37874d7dccf49e8de10341cf61184db407425eb4 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Aug 2019 17:46:34 +0000 Subject: [PATCH 038/112] Disable broken test case in expert1.test. FossilOrigin-Name: 73e30c2e92ccab274ff7cee48511c461de148786bb9d338921c1ecb193822282 --- ext/expert/expert1.test | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ext/expert/expert1.test b/ext/expert/expert1.test index 912c074c60..a0a18f6374 100644 --- a/ext/expert/expert1.test +++ b/ext/expert/expert1.test @@ -134,6 +134,7 @@ do_setup_rec_test $tn.5 { SEARCH TABLE t1 USING COVERING INDEX t1_idx_000123a7 (a=?) } +if 0 { do_setup_rec_test $tn.6 { CREATE TABLE t1(a, b, c); } { @@ -142,6 +143,7 @@ do_setup_rec_test $tn.6 { CREATE INDEX t1_idx_00000061 ON t1(a); SEARCH TABLE t1 USING COVERING INDEX t1_idx_00000061 } +} do_setup_rec_test $tn.7 { CREATE TABLE t1(a, b, c); diff --git a/manifest b/manifest index 6c483fdc14..b49de46348 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Update\sthis\sbranch\swith\slatest\strunk\schanges. -D 2019-08-21T15:41:50.875 +C Disable\sbroken\stest\scase\sin\sexpert1.test. +D 2019-08-21T17:46:34.434 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -47,7 +47,7 @@ F ext/async/sqlite3async.c 0f3070cc3f5ede78f2b9361fb3b629ce200d7d74 F ext/async/sqlite3async.h f489b080af7e72aec0e1ee6f1d98ab6cf2e4dcef F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 -F ext/expert/expert1.test 358e416877a5693fb99d5514f5d88452b5239dc2196b74e0e926718502faef6d +F ext/expert/expert1.test e2afc53a27610e8251e44c7f961806607a5490ff204b3db342740d558e052662 F ext/expert/sqlite3expert.c 3da865f2286433588260f41e796422c611bceaca3a0bbf9139a619cf7d062c19 F ext/expert/sqlite3expert.h af6354f8ee5c9e025024e63fec3bd640a802afcc3099a44d804752cf0791d811 F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 @@ -1837,7 +1837,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 0dbbb51f4d39cafb01d625d65c12dcb232a9c1da7ed5a9397bf55cfea1b980d2 d02490a2f0cae047087130b4ad8f55f265845c2ffb3bde3b7d507edb54acea6d -R 0832eeba23985db1371cd9381db27e16 +P 6153bcf41a9aa0497f8210311c99ac23846223068f2b6a3a1c2d9dec7673c7e1 +R 705b56b5be1b7e1fefeda4caba19be14 U dan -Z 6d83f96c910eba2164bcf7c8dafeccf3 +Z c64ec774c7130f6a813c233a9a841076 diff --git a/manifest.uuid b/manifest.uuid index 4890872255..f2e61edbdf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6153bcf41a9aa0497f8210311c99ac23846223068f2b6a3a1c2d9dec7673c7e1 \ No newline at end of file +73e30c2e92ccab274ff7cee48511c461de148786bb9d338921c1ecb193822282 \ No newline at end of file From f236b21f4b3dba4c104fcda5eb582297be89efe9 Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 21 Aug 2019 19:58:11 +0000 Subject: [PATCH 039/112] Add missing VdbeCoverage() macros to new code. FossilOrigin-Name: b1cbcdc6eb42cca0c42a05e0d6ba4c6c7f09adff0c59ecfc5b434a94dec07a41 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 5 +---- src/window.c | 10 ++++++++-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index b49de46348..d90e4f1fad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Disable\sbroken\stest\scase\sin\sexpert1.test. -D 2019-08-21T17:46:34.434 +C Add\smissing\sVdbeCoverage()\smacros\sto\snew\scode. +D 2019-08-21T19:58:11.253 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,11 +609,11 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c efdaf72cbae66b77fa0e5acd2036b162a9ba45e1109b64ccc72d2c69328feb35 +F src/where.c b49039ad3e7947f6a21735839ba126fc11a21861eeb2483aa5bddae03eea50a8 F src/whereInt.h 807766a6a92893dbba8a887e5b13466d2257ce07a84cf1be0aae2c41aee3bf4f F src/wherecode.c b8f285f93d53274d36d279f3aeaef67cdd28c2d899e06c5d813fb8a4ba6be1b9 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc -F src/window.c 94dccce0568dbcc65658d762e5b11c390fd5509d40e73205cb7f0c22f0051532 +F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test 34f2cf88e2a08d7a54a1fa2c9773ba81bf8b8216c0895e476118a1285540ee71 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1837,7 +1837,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 6153bcf41a9aa0497f8210311c99ac23846223068f2b6a3a1c2d9dec7673c7e1 -R 705b56b5be1b7e1fefeda4caba19be14 +P 73e30c2e92ccab274ff7cee48511c461de148786bb9d338921c1ecb193822282 +R edcea46a2acf7bb6888ff4c7d19a220b U dan -Z c64ec774c7130f6a813c233a9a841076 +Z 27ad915f85c1608e423344937ae2bcdc diff --git a/manifest.uuid b/manifest.uuid index f2e61edbdf..7acb4c891f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -73e30c2e92ccab274ff7cee48511c461de148786bb9d338921c1ecb193822282 \ No newline at end of file +b1cbcdc6eb42cca0c42a05e0d6ba4c6c7f09adff0c59ecfc5b434a94dec07a41 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 72bdc60eb1..c5733e16af 100644 --- a/src/where.c +++ b/src/where.c @@ -5218,12 +5218,9 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pLevel->regBignull ){ sqlite3VdbeResolveLabel(v, pLevel->addrBignull); addr = sqlite3VdbeAddOp1(v, OP_If, pLevel->regBignull); + VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->regBignull); sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->p2-1); - sqlite3VdbeChangeP5(v, pLevel->p5); - VdbeCoverage(v); - VdbeCoverageIf(v, pLevel->op==OP_Next); - VdbeCoverageIf(v, pLevel->op==OP_Prev); sqlite3VdbeJumpHere(v, addr); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT diff --git a/src/window.c b/src/window.c index 80dfd612c4..d3603e7a1e 100644 --- a/src/window.c +++ b/src/window.c @@ -1907,8 +1907,14 @@ static void windowCodeRangeTest( addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); switch( op ){ case OP_Ge: sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; - case OP_Gt: sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); break; - case OP_Le: sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); break; + case OP_Gt: + sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); + VdbeCoverage(v); + break; + case OP_Le: + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); + VdbeCoverage(v); + break; default: assert( op==OP_Lt ); /* no-op */ } sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); From 3e364802321c67602b2522ac4cde1fdeb2ac5d18 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Aug 2019 00:53:16 +0000 Subject: [PATCH 040/112] Fix the OP_SeekGE, OP_SeekGT, OP_SeekLE, and OP_SeekLT opcodes so that they preserve the datatype of the value in the register used as the key. Ticket [d9f584e936c7a8d0] FossilOrigin-Name: 81b9f0f55042777b37de78069f7089041a9ee21dd0a0c86b879053fb46e140b4 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/vdbe.c | 14 +++++++++----- test/where.test | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 51 insertions(+), 14 deletions(-) diff --git a/manifest b/manifest index b14d09aa2a..de21ce3956 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sassuming\sthat\s"column\sIS\s?",\swhere\scolumn\sis\sdeclared\sUNIQUE,\smatches\sonly\sa\ssingle\srow\s(as\s"?"\smight\sbe\sNULL).\sFix\sfor\s[b8689402]. -D 2019-08-21T14:54:50.917 +C Fix\sthe\sOP_SeekGE,\sOP_SeekGT,\sOP_SeekLE,\sand\sOP_SeekLT\sopcodes\sso\sthat\sthey\npreserve\sthe\sdatatype\sof\sthe\svalue\sin\sthe\sregister\sused\sas\sthe\skey.\nTicket\s[d9f584e936c7a8d0] +D 2019-08-22T00:53:16.723 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -595,7 +595,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 1041610254502572bcc79ce6f61d9364fb93c154a4935fbaeaa7fd2e158e5205 +F src/vdbe.c 7cd09c6cc4d0e0053ced392ea4d04762e7ffd1470ff1b90ba3ebd2869c849ae8 F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6 F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e @@ -1670,7 +1670,7 @@ F test/walthread.test 14b20fcfa6ae152f5d8e12f5dc8a8a724b7ef189f5d8ef1e2ceab79f2a F test/walvfs.test f1accd66c876e3a0f6b4bef5b18d13411062d0ff0a0016e32bb41570474e99fc F test/wapp.tcl b440cd8cf57953d3a49e7ee81e6a18f18efdaf113b69f7d8482b0710a64566ec F test/wapptest.tcl 3090239c59379d41e1a0644feb6683082fdb86edfab0c668973f8003f22c0e5d x -F test/where.test d640c16d33ae671c7583fd575d1a64fd55194dcc4393b877b3028db9ddba5a3b +F test/where.test 19c709c9f0f6ed12c23f909f6592aa55fba34269d5a2898537aa27a22b9ce650 F test/where2.test 478d2170637b9211f593120648858593bf2445a1 F test/where3.test 2341a294e17193a6b1699ea7f192124a5286ca6acfcc3f4b06d16c931fbcda2c F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 @@ -1836,7 +1836,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 4c01e0170e113ad052b6c3980beb4be9f1dc03fb3cf34132b90e8b82b23f654e -R ba43ef9ffea471302d6253c6ac41d4d7 -U dan -Z 050be14a9fe83dd49b34a7e227f313e7 +P d02490a2f0cae047087130b4ad8f55f265845c2ffb3bde3b7d507edb54acea6d +R 9a1f89de468f638cf6272be3b894c4f7 +U drh +Z 8cbd654fcd7e359876e90cf539c4f92a diff --git a/manifest.uuid b/manifest.uuid index 2b4538aa49..5dc70a956e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d02490a2f0cae047087130b4ad8f55f265845c2ffb3bde3b7d507edb54acea6d \ No newline at end of file +81b9f0f55042777b37de78069f7089041a9ee21dd0a0c86b879053fb46e140b4 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 0bba39a667..c50e2a0b50 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -4127,6 +4127,7 @@ case OP_SeekGT: { /* jump, in3, group */ pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; if( pC->isTable ){ + u16 flags3, newType; /* The BTREE_SEEK_EQ flag is only set on index cursors */ assert( sqlite3BtreeCursorHasHint(pC->uc.pCursor, BTREE_SEEK_EQ)==0 || CORRUPT_DB ); @@ -4135,16 +4136,19 @@ case OP_SeekGT: { /* jump, in3, group */ ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so convert it. */ pIn3 = &aMem[pOp->p3]; - if( (pIn3->flags & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ + flags3 = pIn3->flags; + if( (flags3 & (MEM_Int|MEM_Real|MEM_IntReal|MEM_Str))==MEM_Str ){ applyNumericAffinity(pIn3, 0); } - iKey = sqlite3VdbeIntValue(pIn3); + iKey = sqlite3VdbeIntValue(pIn3); /* Get the integer key value */ + newType = pIn3->flags; /* Record the type after applying numeric affinity */ + pIn3->flags = flags3; /* But convert the type back to its original */ /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ - if( (pIn3->flags & (MEM_Int|MEM_IntReal))==0 ){ - if( (pIn3->flags & MEM_Real)==0 ){ - if( (pIn3->flags & MEM_Null) || oc>=OP_SeekGE ){ + if( (newType & (MEM_Int|MEM_IntReal))==0 ){ + if( (newType & MEM_Real)==0 ){ + if( (newType & MEM_Null) || oc>=OP_SeekGE ){ VdbeBranchTaken(1,2); goto jump_to_p2; }else{ diff --git a/test/where.test b/test/where.test index 5997498839..26bf3a0402 100644 --- a/test/where.test +++ b/test/where.test @@ -1538,4 +1538,37 @@ do_catchsql_test where-25.5 { ON CONFLICT(c) DO UPDATE SET b=NULL } {1 {corrupt database}} +# 2019-08-21 Ticket https://www.sqlite.org/src/info/d9f584e936c7a8d0 +# +db close +sqlite3 db :memory: +do_execsql_test where-26.1 { + CREATE TABLE t0(c0 INTEGER PRIMARY KEY, c1 TEXT); + INSERT INTO t0(c0, c1) VALUES (1, 'a'); + CREATE TABLE t1(c0 INT PRIMARY KEY, c1 TEXT); + INSERT INTO t1(c0, c1) VALUES (1, 'a'); + SELECT * FROM t0 WHERE '-1' BETWEEN 0 AND t0.c0; +} {1 a} +do_execsql_test where-26.2 { + SELECT * FROM t1 WHERE '-1' BETWEEN 0 AND t1.c0; +} {1 a} +do_execsql_test where-26.3 { + SELECT * FROM t0 WHERE '-1'>=0 AND '-1'<=t0.c0; +} {1 a} +do_execsql_test where-26.4 { + SELECT * FROM t1 WHERE '-1'>=0 AND '-1'<=t1.c0; +} {1 a} +do_execsql_test where-26.5 { + SELECT '-1' BETWEEN 0 AND t0.c0 FROM t0; +} {1} +do_execsql_test where-26.6 { + SELECT '-1' BETWEEN 0 AND t1.c0 FROM t1; +} {1} +do_execsql_test where-26.7 { + SELECT '-1'>=0 AND '-1'<=t0.c0 FROM t0; +} {1} +do_execsql_test where-26.8 { + SELECT '-1'>=0 AND '-1'<=t1.c0 FROM t1; +} {1} + finish_test From af8664020a8f01e275e9237082d570fd25978eef Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Aug 2019 11:11:28 +0000 Subject: [PATCH 041/112] Fix a false-positive in sqlite3ExprNeedsNoAffinityChange(). Ticket [ac184eb571d5e6e0] FossilOrigin-Name: e62eddbb048cbc2c15cb8eeb5b7a907e7cb08c21a27ebba96a069f62dbcb0f30 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 10 +++++++--- test/affinity2.test | 32 ++++++++++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index de21ce3956..6c5bb1afc4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sOP_SeekGE,\sOP_SeekGT,\sOP_SeekLE,\sand\sOP_SeekLT\sopcodes\sso\sthat\sthey\npreserve\sthe\sdatatype\sof\sthe\svalue\sin\sthe\sregister\sused\sas\sthe\skey.\nTicket\s[d9f584e936c7a8d0] -D 2019-08-22T00:53:16.723 +C Fix\sa\sfalse-positive\sin\ssqlite3ExprNeedsNoAffinityChange().\nTicket\s[ac184eb571d5e6e0] +D 2019-08-22T11:11:28.880 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c abef10556e47c3fca04de6a80d802d428e008ed61b4c76dd8439c189f4cd778f +F src/expr.c 1888c5647ec7630703ce0574f6e6b351062b7e0f990667f3c069cc7e602566b1 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -615,7 +615,7 @@ F src/wherecode.c e1131fe94c8728cbecc707f6455afbda9418896497bdca2d49a04ce6c57999 F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc F src/window.c 07e1c15081a735750218185c6b17053c87ecb764d06ab2c0a1ce568a2b4688e5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 -F test/affinity2.test 34f2cf88e2a08d7a54a1fa2c9773ba81bf8b8216c0895e476118a1285540ee71 +F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1 @@ -1836,7 +1836,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 d02490a2f0cae047087130b4ad8f55f265845c2ffb3bde3b7d507edb54acea6d -R 9a1f89de468f638cf6272be3b894c4f7 +P 81b9f0f55042777b37de78069f7089041a9ee21dd0a0c86b879053fb46e140b4 +R a8ad8ca6cf470341d16a9de34fb069f4 U drh -Z 8cbd654fcd7e359876e90cf539c4f92a +Z 2534526d731ee28f45a8990ce9a4aa42 diff --git a/manifest.uuid b/manifest.uuid index 5dc70a956e..42c3c2ad9a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -81b9f0f55042777b37de78069f7089041a9ee21dd0a0c86b879053fb46e140b4 \ No newline at end of file +e62eddbb048cbc2c15cb8eeb5b7a907e7cb08c21a27ebba96a069f62dbcb0f30 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index c9deef0b6a..3c6e939756 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2159,8 +2159,12 @@ int sqlite3ExprCanBeNull(const Expr *p){ */ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ u8 op; + int unaryMinus = 0; if( aff==SQLITE_AFF_BLOB ) return 1; - while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ p = p->pLeft; } + while( p->op==TK_UPLUS || p->op==TK_UMINUS ){ + if( p->op==TK_UMINUS ) unaryMinus = 1; + p = p->pLeft; + } op = p->op; if( op==TK_REGISTER ) op = p->op2; switch( op ){ @@ -2171,10 +2175,10 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC; } case TK_STRING: { - return aff==SQLITE_AFF_TEXT; + return !unaryMinus && aff==SQLITE_AFF_TEXT; } case TK_BLOB: { - return 1; + return !unaryMinus; } case TK_COLUMN: { assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ diff --git a/test/affinity2.test b/test/affinity2.test index 033c90f448..40e442376e 100644 --- a/test/affinity2.test +++ b/test/affinity2.test @@ -85,4 +85,36 @@ do_execsql_test 440 { SELECT * FROM t3 WHERE c='0' ORDER BY a; } {2 1 0 4 1 0} +# 2019-08-22 ticket https://sqlite.org/src/info/d99f1ffe836c591ac57f +# False positive in sqlite3ExprNeedsNoAffinityChange() +# +do_execsql_test 500 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 TEXT UNIQUE, c1); + INSERT INTO t0(c0) VALUES (-1); + SELECT quote(- x'ce'), quote(t0.c0), quote(- x'ce' >= t0.c0) FROM t0; +} {0 '-1' 1} +do_execsql_test 501 { + SELECT * FROM t0 WHERE - x'ce' >= t0.c0; +} {-1 {}} +do_execsql_test 502 { + SELECT quote(+-+x'ce'), quote(t0.c0), quote(+-+x'ce' >= t0.c0) FROM t0; +} {0 '-1' 1} +do_execsql_test 503 { + SELECT * FROM t0 WHERE +-+x'ce' >= t0.c0; +} {-1 {}} +do_execsql_test 504 { + SELECT quote(- 'ce'), quote(t0.c0), quote(- 'ce' >= t0.c0) FROM t0; +} {0 '-1' 1} +do_execsql_test 505 { + SELECT * FROM t0 WHERE - 'ce' >= t0.c0; +} {-1 {}} +do_execsql_test 506 { + SELECT quote(+-+'ce'), quote(t0.c0), quote(+-+'ce' >= t0.c0) FROM t0; +} {0 '-1' 1} +do_execsql_test 507 { + SELECT * FROM t0 WHERE +-+'ce' >= t0.c0; +} {-1 {}} + + finish_test From 0d950af311f8db2c34efa5da0256477794b9c3dd Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Aug 2019 16:38:42 +0000 Subject: [PATCH 042/112] Fix the likely(), unlikely(), and likelihood() functions so that they have no affinity, just like any other function. Ticket [7e07a3dbf5a8cd26] FossilOrigin-Name: 44578865fa7baf9760e355691ca9ce753295aaba7a4ee0bba29d4f85d9335bab --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/expr.c | 26 +++++++++++++++++++------- src/resolve.c | 6 +++--- src/select.c | 2 +- src/sqliteInt.h | 1 + src/where.c | 13 +++++++------ src/whereexpr.c | 4 ++-- test/whereG.test | 42 ++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 88 insertions(+), 32 deletions(-) diff --git a/manifest b/manifest index 6c5bb1afc4..fe11de97f2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sfalse-positive\sin\ssqlite3ExprNeedsNoAffinityChange().\nTicket\s[ac184eb571d5e6e0] -D 2019-08-22T11:11:28.880 +C Fix\sthe\slikely(),\sunlikely(),\sand\slikelihood()\sfunctions\sso\sthat\sthey\shave\nno\saffinity,\sjust\slike\sany\sother\sfunction.\nTicket\s[7e07a3dbf5a8cd26] +D 2019-08-22T16:38:42.563 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 1888c5647ec7630703ce0574f6e6b351062b7e0f990667f3c069cc7e602566b1 +F src/expr.c a1a811e1e5c623a7aa7176fa781ce72944a92b06233b15a39151a743d6eaab97 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -521,14 +521,14 @@ F src/pragma.h 40962d65b645bb3f08c1f4c456effd01c6e7f073f68ea25177e0c95e181cff75 F src/prepare.c 132484635a30f873ee7eccd47f93ed1932503863b93b28423b42332d81adffaf F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 -F src/resolve.c b2733d39a22f5023ab489b8535ca6854b51ff8667ca975815d004bb7388b0e41 +F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 80b8b4c857db2f20d98f80b71ef3bb0d70cdd17bd6b00217dcff803e9b989bd8 +F src/select.c d42f1f1435c5b85a3bd48fdb196bb499c00797691bbed0d0c2b153c8b13ab742 F src/shell.c.in e0f0758b6ab506d8ab12502fd2b8c55546bb9e4bb772374344a5a1b73f5bc2b9 F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 -F src/sqliteInt.h b7d612d9c63abc8a8a7dcf7fbec5326b1770f40c81502c56f508e272154e7615 +F src/sqliteInt.h 52594e495e35649c22f650b5249e515ac8eb108d97be304d14a0e89539ed1c59 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -609,10 +609,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 16c649c1dbc5676ad9b1c6a9b3559b4c4ab8e916d5da59cabb461682444a9ca8 +F src/where.c c35ad5b77fc135a09d6b16a63076748b5c32936016b5031294508a4d6a2ddbb1 F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c e1131fe94c8728cbecc707f6455afbda9418896497bdca2d49a04ce6c57999f6 -F src/whereexpr.c 5cce1fd11876086890a27c05e0cb75ca97ba64ba6984f72154039f1cfd2e69cc +F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 07e1c15081a735750218185c6b17053c87ecb764d06ab2c0a1ce568a2b4688e5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 @@ -1685,7 +1685,7 @@ F test/whereC.test cae295158703cb3fc23bf1a108a9ab730efff0f6 F test/whereD.test 711d4df58d6d4fb9b3f5ce040b818564198be002 F test/whereE.test b3a055eef928c992b0a33198a7b8dc10eea5ad2f F test/whereF.test 3d9412b1199d3e2bed34fcb76b4c48d0bf4df95d27e3f8dd27b6f8b4716d0d89 -F test/whereG.test 0158783235a6dd82fc0e37652b8522b186b9510594ac0a4bff0c4101b4396a52 +F test/whereG.test 4cda56de49f0c7d9a4f2590a3ddc5f79a7f2a03d2229d0f5bb5d3981ce57f293 F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2 F test/whereI.test a2874062140ed4aba9ffae76e6190a3df6fc73d1373fdfa8fd632945082a5364 F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a @@ -1836,7 +1836,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 81b9f0f55042777b37de78069f7089041a9ee21dd0a0c86b879053fb46e140b4 -R a8ad8ca6cf470341d16a9de34fb069f4 +P e62eddbb048cbc2c15cb8eeb5b7a907e7cb08c21a27ebba96a069f62dbcb0f30 +R 1215bd20457039d9af85e446a05c94b4 U drh -Z 2534526d731ee28f45a8990ce9a4aa42 +Z a684ecbf66c59873a68e428c9a74f890 diff --git a/manifest.uuid b/manifest.uuid index 42c3c2ad9a..a744097ebf 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e62eddbb048cbc2c15cb8eeb5b7a907e7cb08c21a27ebba96a069f62dbcb0f30 \ No newline at end of file +44578865fa7baf9760e355691ca9ce753295aaba7a4ee0bba29d4f85d9335bab \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 3c6e939756..496abd32ce 100644 --- a/src/expr.c +++ b/src/expr.c @@ -106,10 +106,22 @@ Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){ } /* -** Skip over any TK_COLLATE operators and any unlikely() -** or likelihood() function at the root of an expression. +** Skip over any TK_COLLATE operators. */ Expr *sqlite3ExprSkipCollate(Expr *pExpr){ + while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ + assert( pExpr->op==TK_COLLATE ); + pExpr = pExpr->pLeft; + } + return pExpr; +} + +/* +** Skip over any TK_COLLATE operators and/or any unlikely() +** or likelihood() or likely() functions at the root of an +** expression. +*/ +Expr *sqlite3ExprSkipCollateAndLikely(Expr *pExpr){ while( pExpr && ExprHasProperty(pExpr, EP_Skip|EP_Unlikely) ){ if( ExprHasProperty(pExpr, EP_Unlikely) ){ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); @@ -3382,7 +3394,7 @@ void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){ ** the correct value for the expression. */ static void exprToRegister(Expr *pExpr, int iReg){ - Expr *p = sqlite3ExprSkipCollate(pExpr); + Expr *p = sqlite3ExprSkipCollateAndLikely(pExpr); p->op2 = p->op; p->op = TK_REGISTER; p->iTable = iReg; @@ -4190,7 +4202,7 @@ int sqlite3ExprCodeAtInit( */ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){ int r2; - pExpr = sqlite3ExprSkipCollate(pExpr); + pExpr = sqlite3ExprSkipCollateAndLikely(pExpr); if( ConstFactorOk(pParse) && pExpr->op!=TK_REGISTER && sqlite3ExprIsConstantNotJoin(pExpr) @@ -4933,8 +4945,8 @@ int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){ */ int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ return sqlite3ExprCompare(0, - sqlite3ExprSkipCollate(pA), - sqlite3ExprSkipCollate(pB), + sqlite3ExprSkipCollateAndLikely(pA), + sqlite3ExprSkipCollateAndLikely(pB), iTab); } @@ -5142,7 +5154,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ */ int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ Walker w; - p = sqlite3ExprSkipCollate(p); + p = sqlite3ExprSkipCollateAndLikely(p); while( p ){ if( p->op==TK_NOTNULL ){ p = p->pLeft; diff --git a/src/resolve.c b/src/resolve.c index ab22664095..b61af805b2 100644 --- a/src/resolve.c +++ b/src/resolve.c @@ -973,7 +973,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } case TK_IS: case TK_ISNOT: { - Expr *pRight = sqlite3ExprSkipCollate(pExpr->pRight); + Expr *pRight = sqlite3ExprSkipCollateAndLikely(pExpr->pRight); assert( !ExprHasProperty(pExpr, EP_Reduced) ); /* Handle special cases of "x IS TRUE", "x IS FALSE", "x IS NOT TRUE", ** and "x IS NOT FALSE". */ @@ -1184,7 +1184,7 @@ static int resolveCompoundOrderBy( int iCol = -1; Expr *pE, *pDup; if( pItem->done ) continue; - pE = sqlite3ExprSkipCollate(pItem->pExpr); + pE = sqlite3ExprSkipCollateAndLikely(pItem->pExpr); if( sqlite3ExprIsInteger(pE, &iCol) ){ if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); @@ -1363,7 +1363,7 @@ static int resolveOrderGroupBy( pParse = pNC->pParse; for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ Expr *pE = pItem->pExpr; - Expr *pE2 = sqlite3ExprSkipCollate(pE); + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pE); if( zType[0]!='G' ){ iCol = resolveAsName(pParse, pSelect->pEList, pE2); if( iCol>0 ){ diff --git a/src/select.c b/src/select.c index bd8fee87ed..9cfcddf8da 100644 --- a/src/select.c +++ b/src/select.c @@ -1960,7 +1960,7 @@ int sqlite3ColumnsFromExprList( if( (zName = pEList->a[i].zName)!=0 ){ /* If the column contains an "AS " phrase, use as the name */ }else{ - Expr *pColExpr = sqlite3ExprSkipCollate(pEList->a[i].pExpr); + Expr *pColExpr = sqlite3ExprSkipCollateAndLikely(pEList->a[i].pExpr); while( pColExpr->op==TK_DOT ){ pColExpr = pColExpr->pRight; assert( pColExpr!=0 ); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 552a435c95..f60b6f7aec 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -4274,6 +4274,7 @@ int sqlite3ExprCollSeqMatch(Parse*,Expr*,Expr*); Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int); Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*); Expr *sqlite3ExprSkipCollate(Expr*); +Expr *sqlite3ExprSkipCollateAndLikely(Expr*); int sqlite3CheckCollSeq(Parse *, CollSeq *); int sqlite3WritableSchema(sqlite3*); int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*); diff --git a/src/where.c b/src/where.c index ae8899e302..6e9d9cb9a2 100644 --- a/src/where.c +++ b/src/where.c @@ -253,7 +253,8 @@ static WhereTerm *whereScanNext(WhereScan *pScan){ ){ if( (pTerm->eOperator & WO_EQUIV)!=0 && pScan->nEquivaiCur) - && (pX = sqlite3ExprSkipCollate(pTerm->pExpr->pRight))->op==TK_COLUMN + && (pX = sqlite3ExprSkipCollateAndLikely(pTerm->pExpr->pRight))->op + ==TK_COLUMN ){ int j; for(j=0; jnEquiv; j++){ @@ -449,7 +450,7 @@ static int findIndexCol( const char *zColl = pIdx->azColl[iCol]; for(i=0; inExpr; i++){ - Expr *p = sqlite3ExprSkipCollate(pList->a[i].pExpr); + Expr *p = sqlite3ExprSkipCollateAndLikely(pList->a[i].pExpr); if( p->op==TK_COLUMN && p->iColumn==pIdx->aiColumn[iCol] && p->iTable==iBase @@ -513,7 +514,7 @@ static int isDistinctRedundant( ** current SELECT is a correlated sub-query. */ for(i=0; inExpr; i++){ - Expr *p = sqlite3ExprSkipCollate(pDistinct->a[i].pExpr); + Expr *p = sqlite3ExprSkipCollateAndLikely(pDistinct->a[i].pExpr); if( p->op==TK_COLUMN && p->iTable==iBase && p->iColumn<0 ) return 1; } @@ -2769,7 +2770,7 @@ static int indexMightHelpWithOrderBy( if( pIndex->bUnordered ) return 0; if( (pOB = pBuilder->pWInfo->pOrderBy)==0 ) return 0; for(ii=0; iinExpr; ii++){ - Expr *pExpr = sqlite3ExprSkipCollate(pOB->a[ii].pExpr); + Expr *pExpr = sqlite3ExprSkipCollateAndLikely(pOB->a[ii].pExpr); if( pExpr->op==TK_COLUMN && pExpr->iTable==iCursor ){ if( pExpr->iColumn<0 ) return 1; for(jj=0; jjnKeyCol; jj++){ @@ -3709,7 +3710,7 @@ static i8 wherePathSatisfiesOrderBy( */ for(i=0; ia[i].pExpr); + pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); if( pOBExpr->op!=TK_COLUMN ) continue; if( pOBExpr->iTable!=iCur ) continue; pTerm = sqlite3WhereFindTerm(&pWInfo->sWC, iCur, pOBExpr->iColumn, @@ -3829,7 +3830,7 @@ static i8 wherePathSatisfiesOrderBy( isMatch = 0; for(i=0; bOnce && ia[i].pExpr); + pOBExpr = sqlite3ExprSkipCollateAndLikely(pOrderBy->a[i].pExpr); testcase( wctrlFlags & WHERE_GROUPBY ); testcase( wctrlFlags & WHERE_DISTINCTBY ); if( (wctrlFlags & (WHERE_GROUPBY|WHERE_DISTINCTBY))==0 ) bOnce = 0; diff --git a/src/whereexpr.c b/src/whereexpr.c index 252d924b85..d878bdb9ec 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -84,7 +84,7 @@ static int whereClauseInsert(WhereClause *pWC, Expr *p, u16 wtFlags){ }else{ pTerm->truthProb = 1; } - pTerm->pExpr = sqlite3ExprSkipCollate(p); + pTerm->pExpr = sqlite3ExprSkipCollateAndLikely(p); pTerm->wtFlags = wtFlags; pTerm->pWC = pWC; pTerm->iParent = -1; @@ -1451,7 +1451,7 @@ static void exprAnalyze( ** all terms of the WHERE clause. */ void sqlite3WhereSplit(WhereClause *pWC, Expr *pExpr, u8 op){ - Expr *pE2 = sqlite3ExprSkipCollate(pExpr); + Expr *pE2 = sqlite3ExprSkipCollateAndLikely(pExpr); pWC->op = op; if( pE2==0 ) return; if( pE2->op!=op ){ diff --git a/test/whereG.test b/test/whereG.test index d2e6a4ee96..595de116aa 100644 --- a/test/whereG.test +++ b/test/whereG.test @@ -266,5 +266,47 @@ do_execsql_test 7.3 { SELECT coalesce(a,a), x FROM t1, t2 ORDER BY 1, 2; } {1 3 1 4 9 3 9 4} +# 2019-08-22 +# Ticket https://www.sqlite.org/src/info/7e07a3dbf5a8cd26 +# +do_execsql_test 8.1 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0 (c0); + INSERT INTO t0(c0) VALUES ('a'); + SELECT LIKELY(t0.rowid) <= '0' FROM t0; +} {1} +do_execsql_test 8.2 { + SELECT * FROM t0 WHERE LIKELY(t0.rowid) <= '0'; +} {a} +do_execsql_test 8.3 { + SELECT (t0.rowid) <= '0' FROM t0; +} {0} +do_execsql_test 8.4 { + SELECT * FROM t0 WHERE (t0.rowid) <= '0'; +} {} +do_execsql_test 8.5 { + SELECT unlikely(t0.rowid) <= '0', likelihood(t0.rowid,0.5) <= '0' FROM t0; +} {1 1} +do_execsql_test 8.6 { + SELECT * FROM t0 WHERE unlikely(t0.rowid) <= '0'; +} {a} +do_execsql_test 8.7 { + SELECT * FROM t0 WHERE likelihood(t0.rowid, 0.5) <= '0'; +} {a} +do_execsql_test 8.8 { + SELECT unlikely(t0.rowid <= '0'), + likely(t0.rowid <= '0'), + likelihood(t0.rowid <= '0',0.5) + FROM t0; +} {0 0 0} +do_execsql_test 8.9 { + SELECT * FROM t0 WHERE unlikely(t0.rowid <= '0'); +} {} +do_execsql_test 8.10 { + SELECT * FROM t0 WHERE likelihood(t0.rowid <= '0', 0.5); +} {} + + + finish_test From 505ae9def80b7b45e37a454064f1cf23df26bdf1 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 22 Aug 2019 21:13:56 +0000 Subject: [PATCH 043/112] Add additional VDBE coverage marcros. FossilOrigin-Name: d3531f5be7d3769689e2cd8bdc9bab5608759de027d44cc123996f32a4a89583 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 5b97a10ac7..d781ff2ecd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Merge\sfixes\sfrom\strunk.\s\sAlso\sfix\sa\sreference\sto\sthe\sKeyInfo.aSortOrder\sfield,\nwhich\sshould\snow\sbe\sKeyInfo.aSortFlags -D 2019-08-22T19:35:24.209 +C Add\sadditional\sVDBE\scoverage\smarcros. +D 2019-08-22T21:13:56.537 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -611,7 +611,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c e954bdbd248e755ddbe0ff54b743a7b99eeb2d852d034b2176004a905c4128bc F src/whereInt.h 807766a6a92893dbba8a887e5b13466d2257ce07a84cf1be0aae2c41aee3bf4f -F src/wherecode.c b8f285f93d53274d36d279f3aeaef67cdd28c2d899e06c5d813fb8a4ba6be1b9 +F src/wherecode.c f8005a06f78bd396216b444280a78688198e9b3aaed582c8e7fc608d111b1d93 F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1837,7 +1837,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 b1cbcdc6eb42cca0c42a05e0d6ba4c6c7f09adff0c59ecfc5b434a94dec07a41 44578865fa7baf9760e355691ca9ce753295aaba7a4ee0bba29d4f85d9335bab -R 2d835772a9b0c8de420768a9d0cab391 +P 63e625c8eb06720eef30573aa562e38c90d228a9cf493f8bb59f09e50f0e3168 +R 3b31af6d2e0a85acf1bc0e1de0094280 U drh -Z db9bead32e306ab3e60ddcd2bc746cd1 +Z 763e56944768007815dc6fe6b985fbdb diff --git a/manifest.uuid b/manifest.uuid index 7877eb59c1..34fc4dc3ee 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63e625c8eb06720eef30573aa562e38c90d228a9cf493f8bb59f09e50f0e3168 \ No newline at end of file +d3531f5be7d3769689e2cd8bdc9bab5608759de027d44cc123996f32a4a89583 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index c662c1ce56..55ac394b65 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1710,9 +1710,23 @@ Bitmask sqlite3WhereCodeOneLoopStart( start_constraints = (nConstraint>1); op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint-1); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); }else{ op = aStartOp[(start_constraints<<2) + ((!startEq)<<1) + bRev]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); } } } @@ -1762,6 +1776,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( nConstraint ){ if( regBignull ){ sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+3); + VdbeCoverage(v); } op = aEndOp[bRev*2 + endEq]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); @@ -1772,12 +1787,20 @@ Bitmask sqlite3WhereCodeOneLoopStart( } if( regBignull ){ sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+2); + VdbeCoverage(v); if( bStopAtNull ){ op = aEndOp[bRev*2 + 0]; + assert( op==OP_IdxGE || op==OP_IdxLE ); sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); }else{ op = aEndOp[bRev*2 + endEq]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint+1); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } } From 74e1b861ad749a00966583c29f0e2d8dfb510c82 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Aug 2019 13:08:49 +0000 Subject: [PATCH 044/112] Extra VDBE comments in the NULLS LAST logic provide landmarks to help understand the EXPLAIN output. FossilOrigin-Name: 649b08ead50f10a9ec0357a5e1ed020195d9f93be61ef703ea036a8e53f07a34 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 2 ++ src/whereInt.h | 2 +- src/wherecode.c | 5 ++++- 5 files changed, 16 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index d781ff2ecd..9403c98df3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sadditional\sVDBE\scoverage\smarcros. -D 2019-08-22T21:13:56.537 +C Extra\sVDBE\scomments\sin\sthe\sNULLS\sLAST\slogic\sprovide\slandmarks\sto\shelp\nunderstand\sthe\sEXPLAIN\soutput. +D 2019-08-23T13:08:49.776 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,9 +609,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c e954bdbd248e755ddbe0ff54b743a7b99eeb2d852d034b2176004a905c4128bc -F src/whereInt.h 807766a6a92893dbba8a887e5b13466d2257ce07a84cf1be0aae2c41aee3bf4f -F src/wherecode.c f8005a06f78bd396216b444280a78688198e9b3aaed582c8e7fc608d111b1d93 +F src/where.c cba20474827dfb3e6bfe7835635e0f018a67d4b8faef4c90d4f28b81b81a8915 +F src/whereInt.h cce97c33db637c027bd6f3601a5ff845bd65c833b6465e3b091d48f6a7f51268 +F src/wherecode.c 1700806bb5bb507ff3614d0836893f35a5a5c438087ee6f373f2ecdf32156d71 F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1837,7 +1837,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 63e625c8eb06720eef30573aa562e38c90d228a9cf493f8bb59f09e50f0e3168 -R 3b31af6d2e0a85acf1bc0e1de0094280 +P d3531f5be7d3769689e2cd8bdc9bab5608759de027d44cc123996f32a4a89583 +R ab23b496c06c535da116ba045bb5e66a U drh -Z 763e56944768007815dc6fe6b985fbdb +Z 115e4fb3e71b36cfad63bc3458a08668 diff --git a/manifest.uuid b/manifest.uuid index 34fc4dc3ee..729790d69c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d3531f5be7d3769689e2cd8bdc9bab5608759de027d44cc123996f32a4a89583 \ No newline at end of file +649b08ead50f10a9ec0357a5e1ed020195d9f93be61ef703ea036a8e53f07a34 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 37daab6791..00aa5f3660 100644 --- a/src/where.c +++ b/src/where.c @@ -5219,9 +5219,11 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pLevel->regBignull ){ sqlite3VdbeResolveLabel(v, pLevel->addrBignull); addr = sqlite3VdbeAddOp1(v, OP_If, pLevel->regBignull); + VdbeComment((v, "If NULL-scan done")); VdbeCoverage(v); sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->regBignull); sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->p2-1); + VdbeComment((v, "Do the NULL-scan")); sqlite3VdbeJumpHere(v, addr); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT diff --git a/src/whereInt.h b/src/whereInt.h index f402a18f8c..d1fc3515a5 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -71,7 +71,7 @@ struct WhereLevel { int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ - int regBignull; /* big-null flag register */ + int regBignull; /* big-null flag reg. True if NULLs not yet scanned */ int addrBignull; /* Jump here for next part of big-null scan */ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ diff --git a/src/wherecode.c b/src/wherecode.c index 55ac394b65..12ed0d7af0 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1550,7 +1550,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( u8 bSeekPastNull = 0; /* True to seek past initial nulls */ u8 bStopAtNull = 0; /* Add condition to terminate at NULLs */ int omitTable; /* True if we use the index only */ - int regBignull = 0; + int regBignull = 0; /* big-null flag register */ pIdx = pLoop->u.btree.pIndex; iIdxCur = pLevel->iIdxCur; @@ -1691,6 +1691,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } if( regBignull ){ sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull); + VdbeComment((v, "NULL-scan flag")); } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; @@ -1776,6 +1777,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( nConstraint ){ if( regBignull ){ sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+3); + VdbeComment((v, "If in NULL-scan")); VdbeCoverage(v); } op = aEndOp[bRev*2 + endEq]; @@ -1787,6 +1789,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } if( regBignull ){ sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+2); + VdbeComment((v, "If not in NULL-scan")); VdbeCoverage(v); if( bStopAtNull ){ op = aEndOp[bRev*2 + 0]; From ec3dda5b11f527c69f1007fa60ba2765e0a5628b Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Aug 2019 13:32:03 +0000 Subject: [PATCH 045/112] Invert the meaning of the regBignull flag so that it is 1 when doing the normal scan and 1 when scanning nulls. This enables the re-do jump at the bottom of the loop to be coded with a single OP_IfNotZero opcode, rather than a sequence of OP_If, OP_Integer, OP_Goto. FossilOrigin-Name: bf875e1a259a4167694e06349458452dc36c1d38aa6843518d9ae46ce74e5559 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/where.c | 8 +------- src/whereInt.h | 2 +- src/wherecode.c | 12 ++++++------ 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/manifest b/manifest index 9403c98df3..6962dd393e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extra\sVDBE\scomments\sin\sthe\sNULLS\sLAST\slogic\sprovide\slandmarks\sto\shelp\nunderstand\sthe\sEXPLAIN\soutput. -D 2019-08-23T13:08:49.776 +C Invert\sthe\smeaning\sof\sthe\sregBignull\sflag\sso\sthat\sit\sis\s1\swhen\sdoing\sthe\nnormal\sscan\sand\s1\swhen\sscanning\snulls.\s\sThis\senables\sthe\sre-do\sjump\sat\sthe\nbottom\sof\sthe\sloop\sto\sbe\scoded\swith\sa\ssingle\sOP_IfNotZero\sopcode,\srather\nthan\sa\ssequence\sof\sOP_If,\sOP_Integer,\sOP_Goto. +D 2019-08-23T13:32:03.306 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,9 +609,9 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c cba20474827dfb3e6bfe7835635e0f018a67d4b8faef4c90d4f28b81b81a8915 -F src/whereInt.h cce97c33db637c027bd6f3601a5ff845bd65c833b6465e3b091d48f6a7f51268 -F src/wherecode.c 1700806bb5bb507ff3614d0836893f35a5a5c438087ee6f373f2ecdf32156d71 +F src/where.c 10e21ac338582a4f87b2d09f09dd812c9bda0a0c4c456f54daeeee355afae733 +F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 +F src/wherecode.c c02ff23ea48b8980d003817bd412e3ce7ce4982159a090566a24cb6101688a9d F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1837,7 +1837,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 d3531f5be7d3769689e2cd8bdc9bab5608759de027d44cc123996f32a4a89583 -R ab23b496c06c535da116ba045bb5e66a +P 649b08ead50f10a9ec0357a5e1ed020195d9f93be61ef703ea036a8e53f07a34 +R c7fec8ea82d2ec3c4ef608bd58d88fd0 U drh -Z 115e4fb3e71b36cfad63bc3458a08668 +Z 0dcd16d55adeefa06ece8236ed711d36 diff --git a/manifest.uuid b/manifest.uuid index 729790d69c..72e2aaa811 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -649b08ead50f10a9ec0357a5e1ed020195d9f93be61ef703ea036a8e53f07a34 \ No newline at end of file +bf875e1a259a4167694e06349458452dc36c1d38aa6843518d9ae46ce74e5559 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 00aa5f3660..1dbeb0e065 100644 --- a/src/where.c +++ b/src/where.c @@ -5218,13 +5218,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeCoverageIf(v, pLevel->op==OP_VNext); if( pLevel->regBignull ){ sqlite3VdbeResolveLabel(v, pLevel->addrBignull); - addr = sqlite3VdbeAddOp1(v, OP_If, pLevel->regBignull); - VdbeComment((v, "If NULL-scan done")); - VdbeCoverage(v); - sqlite3VdbeAddOp2(v, OP_Integer, 1, pLevel->regBignull); - sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->p2-1); - VdbeComment((v, "Do the NULL-scan")); - sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeAddOp2(v, OP_IfNotZero, pLevel->regBignull, pLevel->p2-1); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); diff --git a/src/whereInt.h b/src/whereInt.h index d1fc3515a5..e63ca46d53 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -71,7 +71,7 @@ struct WhereLevel { int addrCont; /* Jump here to continue with the next loop cycle */ int addrFirst; /* First instruction of interior of the loop */ int addrBody; /* Beginning of the body of this loop */ - int regBignull; /* big-null flag reg. True if NULLs not yet scanned */ + int regBignull; /* big-null flag reg. True if a NULL-scan is needed */ int addrBignull; /* Jump here for next part of big-null scan */ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS u32 iLikeRepCntr; /* LIKE range processing counter register (times 2) */ diff --git a/src/wherecode.c b/src/wherecode.c index 12ed0d7af0..2aff70554f 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1690,8 +1690,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( sqlite3VdbeAddOp1(v, OP_SeekHit, iIdxCur); } if( regBignull ){ - sqlite3VdbeAddOp2(v, OP_Integer, 0, regBignull); - VdbeComment((v, "NULL-scan flag")); + sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); + VdbeComment((v, "NULL-scan needed flag")); } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; @@ -1776,8 +1776,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ if( regBignull ){ - sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+3); - VdbeComment((v, "If in NULL-scan")); + sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3); + VdbeComment((v, "If NULL-scan active")); VdbeCoverage(v); } op = aEndOp[bRev*2 + endEq]; @@ -1788,8 +1788,8 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } if( regBignull ){ - sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+2); - VdbeComment((v, "If not in NULL-scan")); + sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2); + VdbeComment((v, "If NULL-scan pending")); VdbeCoverage(v); if( bStopAtNull ){ op = aEndOp[bRev*2 + 0]; From 0086e078656bbdfebffdbea67f3f0131aa677b08 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Aug 2019 16:12:20 +0000 Subject: [PATCH 046/112] Simplification of the WHERE loop code generator for NULLS LAST saves a few CPU cycles and about a hundred bytes of code space. FossilOrigin-Name: e3ed2f496f51234a8f81d90d47ba603b06dbed38b8bd8f1934294379cde74d3a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 38 ++++++++++++++------------------------ 3 files changed, 21 insertions(+), 31 deletions(-) diff --git a/manifest b/manifest index 6962dd393e..46a935e609 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Invert\sthe\smeaning\sof\sthe\sregBignull\sflag\sso\sthat\sit\sis\s1\swhen\sdoing\sthe\nnormal\sscan\sand\s1\swhen\sscanning\snulls.\s\sThis\senables\sthe\sre-do\sjump\sat\sthe\nbottom\sof\sthe\sloop\sto\sbe\scoded\swith\sa\ssingle\sOP_IfNotZero\sopcode,\srather\nthan\sa\ssequence\sof\sOP_If,\sOP_Integer,\sOP_Goto. -D 2019-08-23T13:32:03.306 +C Simplification\sof\sthe\sWHERE\sloop\scode\sgenerator\sfor\sNULLS\sLAST\ssaves\sa\nfew\sCPU\scycles\sand\sabout\sa\shundred\sbytes\sof\scode\sspace. +D 2019-08-23T16:12:20.533 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -611,7 +611,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c 10e21ac338582a4f87b2d09f09dd812c9bda0a0c4c456f54daeeee355afae733 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 -F src/wherecode.c c02ff23ea48b8980d003817bd412e3ce7ce4982159a090566a24cb6101688a9d +F src/wherecode.c f8ba85888b8a6843bce84e7e21f61d6c043c21c888871ad84fb911f45671e95d F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1837,7 +1837,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 649b08ead50f10a9ec0357a5e1ed020195d9f93be61ef703ea036a8e53f07a34 -R c7fec8ea82d2ec3c4ef608bd58d88fd0 +P bf875e1a259a4167694e06349458452dc36c1d38aa6843518d9ae46ce74e5559 +R f34508d6bf0c4c450df67caf81b0a3ce U drh -Z 0dcd16d55adeefa06ece8236ed711d36 +Z 77866c600215002b5dd6dd0eeafd861f diff --git a/manifest.uuid b/manifest.uuid index 72e2aaa811..c464a63a97 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bf875e1a259a4167694e06349458452dc36c1d38aa6843518d9ae46ce74e5559 \ No newline at end of file +e3ed2f496f51234a8f81d90d47ba603b06dbed38b8bd8f1934294379cde74d3a \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 2aff70554f..c1304c8af1 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1671,10 +1671,10 @@ Bitmask sqlite3WhereCodeOneLoopStart( } bSeekPastNull = 0; }else if( bSeekPastNull ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); - nConstraint++; startEq = 0; + sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); start_constraints = 1; + nConstraint++; }else if( regBignull ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); start_constraints = 1; @@ -1705,30 +1705,20 @@ Bitmask sqlite3WhereCodeOneLoopStart( VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); + assert( bSeekPastNull==0 || bStopAtNull==0 ); if( regBignull ){ + assert( bSeekPastNull==1 || bStopAtNull==1 ); + assert( bStopAtNull==startEq ); sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); - if( bStopAtNull ){ - start_constraints = (nConstraint>1); - op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint-1); - VdbeCoverage(v); - VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); - VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); - VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); - VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); - VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); - VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); - }else{ - op = aStartOp[(start_constraints<<2) + ((!startEq)<<1) + bRev]; - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); - VdbeCoverage(v); - VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); - VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); - VdbeCoverageIf(v, op==OP_SeekGT); testcase( op==OP_SeekGT ); - VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); - VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); - VdbeCoverageIf(v, op==OP_SeekLT); testcase( op==OP_SeekLT ); - } + op = aStartOp[(nConstraint>1)*4 + 2 + bRev]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + nConstraint-startEq); + VdbeCoverage(v); + VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); + VdbeCoverageIf(v, op==OP_Last); testcase( op==OP_Last ); + VdbeCoverageIf(v, op==OP_SeekGE); testcase( op==OP_SeekGE ); + VdbeCoverageIf(v, op==OP_SeekLE); testcase( op==OP_SeekLE ); + assert( op==OP_Rewind || op==OP_Last || op==OP_SeekGE || op==OP_SeekLE); } } From 5f6a4ea2e2b5a12bc425615a8a01af920c1bc65d Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Aug 2019 17:00:22 +0000 Subject: [PATCH 047/112] Additional simplifications of the WHERE loop code generator logic for NULLS LAST. FossilOrigin-Name: 1383680d927d7d703933be7653c0019199845e7f7e82bcc76d9ca3808093e9d8 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 28 ++++++++++++++-------------- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/manifest b/manifest index 46a935e609..3fb90c2684 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplification\sof\sthe\sWHERE\sloop\scode\sgenerator\sfor\sNULLS\sLAST\ssaves\sa\nfew\sCPU\scycles\sand\sabout\sa\shundred\sbytes\sof\scode\sspace. -D 2019-08-23T16:12:20.533 +C Additional\ssimplifications\sof\sthe\sWHERE\sloop\scode\sgenerator\slogic\sfor\nNULLS\sLAST. +D 2019-08-23T17:00:22.277 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -611,7 +611,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c 10e21ac338582a4f87b2d09f09dd812c9bda0a0c4c456f54daeeee355afae733 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 -F src/wherecode.c f8ba85888b8a6843bce84e7e21f61d6c043c21c888871ad84fb911f45671e95d +F src/wherecode.c 3bed0f377aacff188575bccc2f01d45ed5df353b52e8b2c39a22ff88ae3cfc25 F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1837,7 +1837,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 bf875e1a259a4167694e06349458452dc36c1d38aa6843518d9ae46ce74e5559 -R f34508d6bf0c4c450df67caf81b0a3ce +P e3ed2f496f51234a8f81d90d47ba603b06dbed38b8bd8f1934294379cde74d3a +R 1ab18b69b8d15ca4e03875cc0023fa2f U drh -Z 77866c600215002b5dd6dd0eeafd861f +Z e7fe19284bcd51997b007393da65f48c diff --git a/manifest.uuid b/manifest.uuid index c464a63a97..80c0a7a60e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e3ed2f496f51234a8f81d90d47ba603b06dbed38b8bd8f1934294379cde74d3a \ No newline at end of file +1383680d927d7d703933be7653c0019199845e7f7e82bcc76d9ca3808093e9d8 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index c1304c8af1..9868428c5b 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1708,6 +1708,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( assert( bSeekPastNull==0 || bStopAtNull==0 ); if( regBignull ){ assert( bSeekPastNull==1 || bStopAtNull==1 ); + assert( bSeekPastNull==!bStopAtNull ); assert( bStopAtNull==startEq ); sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); op = aStartOp[(nConstraint>1)*4 + 2 + bRev]; @@ -1766,6 +1767,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( /* Check if the index cursor is past the end of the range. */ if( nConstraint ){ if( regBignull ){ + /* Except, skip the end-of-range check while doing the NULL-scan */ sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3); VdbeComment((v, "If NULL-scan active")); VdbeCoverage(v); @@ -1778,23 +1780,21 @@ Bitmask sqlite3WhereCodeOneLoopStart( testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } if( regBignull ){ + /* During a NULL-scan, check to see if we have reached the end of + ** the NULLs */ + assert( bSeekPastNull==!bStopAtNull ); + assert( bSeekPastNull+bStopAtNull==1 ); + assert( nConstraint+bSeekPastNull>0 ); sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2); VdbeComment((v, "If NULL-scan pending")); VdbeCoverage(v); - if( bStopAtNull ){ - op = aEndOp[bRev*2 + 0]; - assert( op==OP_IdxGE || op==OP_IdxLE ); - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint); - testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); - testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); - }else{ - op = aEndOp[bRev*2 + endEq]; - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint+1); - testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); - testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); - testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); - testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); - } + op = aEndOp[bRev*2 + bSeekPastNull]; + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + nConstraint+bSeekPastNull); + testcase( op==OP_IdxGT ); VdbeCoverageIf(v, op==OP_IdxGT ); + testcase( op==OP_IdxGE ); VdbeCoverageIf(v, op==OP_IdxGE ); + testcase( op==OP_IdxLT ); VdbeCoverageIf(v, op==OP_IdxLT ); + testcase( op==OP_IdxLE ); VdbeCoverageIf(v, op==OP_IdxLE ); } if( pLoop->wsFlags & WHERE_IN_EARLYOUT ){ From a31d3554c5daaff3c9e8d411879c6185b75073a0 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Aug 2019 17:09:02 +0000 Subject: [PATCH 048/112] Revise the VDBE comments for NULL-scan so that they also work make sense when reading a NULLS FIRST plan. FossilOrigin-Name: bfe793780fa6fc7a1e7d0ee60606dda272985de9573887dca118e9510fc609f2 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/wherecode.c | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 3fb90c2684..7052b4ef66 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Additional\ssimplifications\sof\sthe\sWHERE\sloop\scode\sgenerator\slogic\sfor\nNULLS\sLAST. -D 2019-08-23T17:00:22.277 +C Revise\sthe\sVDBE\scomments\sfor\sNULL-scan\sso\sthat\sthey\salso\swork\smake\nsense\swhen\sreading\sa\sNULLS\sFIRST\splan. +D 2019-08-23T17:09:02.374 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -611,7 +611,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c 10e21ac338582a4f87b2d09f09dd812c9bda0a0c4c456f54daeeee355afae733 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 -F src/wherecode.c 3bed0f377aacff188575bccc2f01d45ed5df353b52e8b2c39a22ff88ae3cfc25 +F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1837,7 +1837,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 e3ed2f496f51234a8f81d90d47ba603b06dbed38b8bd8f1934294379cde74d3a -R 1ab18b69b8d15ca4e03875cc0023fa2f +P 1383680d927d7d703933be7653c0019199845e7f7e82bcc76d9ca3808093e9d8 +R 26440ec11262a796737d9ceae9976115 U drh -Z e7fe19284bcd51997b007393da65f48c +Z 426e1e92ed37562d2a1263893c3aee0b diff --git a/manifest.uuid b/manifest.uuid index 80c0a7a60e..a5e43de7bd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -1383680d927d7d703933be7653c0019199845e7f7e82bcc76d9ca3808093e9d8 \ No newline at end of file +bfe793780fa6fc7a1e7d0ee60606dda272985de9573887dca118e9510fc609f2 \ No newline at end of file diff --git a/src/wherecode.c b/src/wherecode.c index 9868428c5b..2fbcba17e9 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -1691,7 +1691,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( } if( regBignull ){ sqlite3VdbeAddOp2(v, OP_Integer, 1, regBignull); - VdbeComment((v, "NULL-scan needed flag")); + VdbeComment((v, "NULL-scan pass ctr")); } op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; @@ -1769,7 +1769,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( if( regBignull ){ /* Except, skip the end-of-range check while doing the NULL-scan */ sqlite3VdbeAddOp2(v, OP_IfNot, regBignull, sqlite3VdbeCurrentAddr(v)+3); - VdbeComment((v, "If NULL-scan active")); + VdbeComment((v, "If NULL-scan 2nd pass")); VdbeCoverage(v); } op = aEndOp[bRev*2 + endEq]; @@ -1786,7 +1786,7 @@ Bitmask sqlite3WhereCodeOneLoopStart( assert( bSeekPastNull+bStopAtNull==1 ); assert( nConstraint+bSeekPastNull>0 ); sqlite3VdbeAddOp2(v, OP_If, regBignull, sqlite3VdbeCurrentAddr(v)+2); - VdbeComment((v, "If NULL-scan pending")); + VdbeComment((v, "If NULL-scan 1st pass")); VdbeCoverage(v); op = aEndOp[bRev*2 + bSeekPastNull]; sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, From ee6c5e5ae7193241a55dd83c8f434a5d7c5abf11 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 23 Aug 2019 20:33:01 +0000 Subject: [PATCH 049/112] Move some things in parse.y so that TK_COLUMN and TK_AGG_COLUMN are assigned the same values as they are on trunk for a very small speedup. FossilOrigin-Name: d26fdfa3bc5f8d9c4a6000462080b0dd508e5cae9a83e0d126be48195224da8c --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/parse.y | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 7052b4ef66..7dcd24ab83 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Revise\sthe\sVDBE\scomments\sfor\sNULL-scan\sso\sthat\sthey\salso\swork\smake\nsense\swhen\sreading\sa\sNULLS\sFIRST\splan. -D 2019-08-23T17:09:02.374 +C Move\ssome\sthings\sin\sparse.y\sso\sthat\sTK_COLUMN\sand\sTK_AGG_COLUMN\sare\sassigned\sthe\ssame\svalues\sas\sthey\sare\son\strunk\sfor\sa\svery\ssmall\sspeedup. +D 2019-08-23T20:33:01.837 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -512,7 +512,7 @@ F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3 -F src/parse.y 61e979ce7f860df902b21b16ed40504ddd58fe4546fb15908a51538b3062e8e0 +F src/parse.y d127bf3f79f9f5baccfdfa00c7898df3eafa027ac58c35fd673bf81b008b2374 F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848 @@ -1837,7 +1837,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 1383680d927d7d703933be7653c0019199845e7f7e82bcc76d9ca3808093e9d8 -R 26440ec11262a796737d9ceae9976115 -U drh -Z 426e1e92ed37562d2a1263893c3aee0b +P bfe793780fa6fc7a1e7d0ee60606dda272985de9573887dca118e9510fc609f2 +R 65f7f5b095c6143834951d2d50e30b05 +U dan +Z 741541dbd05afd6dd401231ece81d5cb diff --git a/manifest.uuid b/manifest.uuid index a5e43de7bd..130c1ae433 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bfe793780fa6fc7a1e7d0ee60606dda272985de9573887dca118e9510fc609f2 \ No newline at end of file +d26fdfa3bc5f8d9c4a6000462080b0dd508e5cae9a83e0d126be48195224da8c \ No newline at end of file diff --git a/src/parse.y b/src/parse.y index a919c41175..92be672a31 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1773,12 +1773,12 @@ filter_clause(A) ::= FILTER LP WHERE expr(X) RP. { A = X; } ** are synthesized and do not actually appear in the grammar: */ %token - TRUEFALSE /* True or false keyword */ - ISNOT /* Combination of IS and NOT */ - FUNCTION /* A function invocation */ COLUMN /* Reference to a table column */ AGG_FUNCTION /* An aggregate function */ AGG_COLUMN /* An aggregated column */ + TRUEFALSE /* True or false keyword */ + ISNOT /* Combination of IS and NOT */ + FUNCTION /* A function invocation */ UMINUS /* Unary minus */ UPLUS /* Unary plus */ TRUTH /* IS TRUE or IS FALSE or IS NOT TRUE or IS NOT FALSE */ From ee37f8b0a38521c892afc7ddb2810b70ba9c0283 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 23 Aug 2019 23:05:32 +0000 Subject: [PATCH 050/112] Fix the built-in edit() SQL function in the CLI so that it works with zero-length blobs. FossilOrigin-Name: e32490128684cfeeb8213baecc78a7942b8fb63d00e375edd965bf236faeed18 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index fe11de97f2..7938652485 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\slikely(),\sunlikely(),\sand\slikelihood()\sfunctions\sso\sthat\sthey\shave\nno\saffinity,\sjust\slike\sany\sother\sfunction.\nTicket\s[7e07a3dbf5a8cd26] -D 2019-08-22T16:38:42.563 +C Fix\sthe\sbuilt-in\sedit()\sSQL\sfunction\sin\sthe\sCLI\sso\sthat\sit\sworks\swith\nzero-length\sblobs. +D 2019-08-23T23:05:32.503 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,7 +524,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c d42f1f1435c5b85a3bd48fdb196bb499c00797691bbed0d0c2b153c8b13ab742 -F src/shell.c.in e0f0758b6ab506d8ab12502fd2b8c55546bb9e4bb772374344a5a1b73f5bc2b9 +F src/shell.c.in 9a0706cd539fb6f00948a6a41a84c51a893179f5338c94ea37177d5f239c7741 F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 @@ -1836,7 +1836,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 e62eddbb048cbc2c15cb8eeb5b7a907e7cb08c21a27ebba96a069f62dbcb0f30 -R 1215bd20457039d9af85e446a05c94b4 +P 44578865fa7baf9760e355691ca9ce753295aaba7a4ee0bba29d4f85d9335bab +R d576abe88102041dd107794a8906549d U drh -Z a684ecbf66c59873a68e428c9a74f890 +Z e6a2c406773297981564bcc226b2bf48 diff --git a/manifest.uuid b/manifest.uuid index a744097ebf..c235cac52f 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -44578865fa7baf9760e355691ca9ce753295aaba7a4ee0bba29d4f85d9335bab \ No newline at end of file +e32490128684cfeeb8213baecc78a7942b8fb63d00e375edd965bf236faeed18 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 0ee136389d..99a816fada 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1289,7 +1289,7 @@ static void editFunc( fseek(f, 0, SEEK_END); sz = ftell(f); rewind(f); - p = sqlite3_malloc64( sz+(bBin==0) ); + p = sqlite3_malloc64( sz+1 ); if( p==0 ){ sqlite3_result_error_nomem(context); goto edit_func_end; From 298680d15a694b4c4b5fb7f7bd5d06cb3f08016e Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 24 Aug 2019 17:11:29 +0000 Subject: [PATCH 051/112] Fix a potential buffer overrun in fts5 caused by corrupt database records. FossilOrigin-Name: 156d612800a7282fe0ebb20feb31d3fd577f4ab60fab8c00940c87143997aefb --- ext/fts5/fts5_index.c | 5 +- ext/fts5/test/fts5corrupt3.test | 125 ++++++++++++++++++++++++++++++++ manifest | 16 ++-- manifest.uuid | 2 +- 4 files changed, 138 insertions(+), 10 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 000ce98033..3fa97c2fea 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -4997,9 +4997,12 @@ static void fts5MergePrefixLists( Fts5PoslistWriter writer; memset(&writer, 0, sizeof(writer)); + /* See the earlier comment in this function for an explanation of why + ** corrupt input position lists might cause the output to consume + ** at most 20 bytes of unexpected space. */ fts5MergeAppendDocid(&out, iLastRowid, i2.iRowid); fts5BufferZero(&tmp); - sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist); + sqlite3Fts5BufferSize(&p->rc, &tmp, i1.nPoslist + i2.nPoslist + 10 + 10); if( p->rc ) break; sqlite3Fts5PoslistNext64(a1, i1.nPoslist, &iOff1, &iPos1); diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 2391d97eea..306ae9fe03 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -9367,6 +9367,131 @@ do_catchsql_test 63.3 { SELECT * FROM t1 WHERE b MATCH 'thead*thead*theSt*'; } {/*malformed database schema*/} +#--------------------------------------------------------------------------- +do_test 64.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 28672 pagesize 4096 filename crash-4470f0b94422f7.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 06 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................ +| 96: 00 00 00 00 0d 00 00 00 06 0d e2 00 0f c4 0f 6a ...............j +| 112: 0e fc 0e 9d 0e 3d 0d e2 00 00 00 00 00 01 00 00 .....=.......... +| 3552: 00 00 59 06 06 17 21 21 01 7f 74 61 62 6c 65 74 ..Y...!!..tablet +| 3568: 74 74 5f 63 6f 6e 66 69 67 74 74 74 5f 63 6f 6e tt_configttt_con +| 3584: 66 69 67 06 43 52 45 41 54 45 20 54 41 42 4c 45 fig.CREATE TABLE +| 3600: 20 27 74 74 74 5f 63 6f 6e 66 69 67 27 28 6b 20 'ttt_config'(k +| 3616: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 PRIMARY KEY, v) +| 3632: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5e 05 07 WITHOUT ROWID^.. +| 3648: 17 23 23 01 81 03 74 61 62 6c 65 74 74 74 5f 64 .##...tablettt_d +| 3664: 6f 63 73 69 7a 65 74 74 74 5f 64 6f 63 73 69 7a ocsizettt_docsiz +| 3680: 65 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 e.CREATE TABLE ' +| 3696: 74 74 74 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 ttt_docsize'(id +| 3712: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY +| 3728: 4b 45 59 2c 20 73 7a 20 42 4c 4f 42 29 5d 04 07 KEY, sz BLOB)].. +| 3744: 17 23 23 01 81 01 74 61 62 6c 65 74 74 74 5f 63 .##...tablettt_c +| 3760: 6f 6e 74 65 6e 74 74 74 74 5f 63 6f 6e 74 65 6e ontentttt_conten +| 3776: 74 04 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 t.CREATE TABLE ' +| 3792: 74 74 74 5f 63 6f 6e 74 65 6e 74 27 28 69 64 20 ttt_content'(id +| 3808: 49 4e 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 INTEGER PRIMARY +| 3824: 4b 45 59 2c 20 63 30 2c 20 63 31 29 6c 03 07 17 KEY, c0, c1)l... +| 3840: 1b 1b 01 81 2f 74 61 62 6c 65 74 74 74 5f 69 64 ..../tablettt_id +| 3856: 78 74 74 74 5f 69 64 78 03 43 52 45 41 54 45 20 xttt_idx.CREATE +| 3872: 54 41 42 4c 45 20 27 74 74 74 5f 69 64 78 27 28 TABLE 'ttt_idx'( +| 3888: 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 70 67 6e segid, term, pgn +| 3904: 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 59 28 73 o, PRIMARY KEY(s +| 3920: 65 67 69 64 2c 20 74 65 72 6d 29 29 20 57 49 54 egid, term)) WIT +| 3936: 48 4f 55 54 20 52 4f 57 49 44 58 02 07 17 1d 1d HOUT ROWIDX..... +| 3952: 01 81 03 74 61 62 6c 65 74 74 74 5f 64 61 74 61 ...tablettt_data +| 3968: 74 74 74 5f 64 61 74 61 02 43 52 45 41 54 45 20 ttt_data.CREATE +| 3984: 54 41 42 4c 45 20 27 74 74 74 5f 64 61 74 61 27 TABLE 'ttt_data' +| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM +| 4016: 41 52 59 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 ARY KEY, block B +| 4032: 4c 4f 42 29 3a 01 06 17 13 13 08 5f 74 61 62 6c LOB):......_tabl +| 4048: 65 74 74 74 74 74 74 43 52 45 41 54 45 20 56 49 ettttttCREATE VI +| 4064: 52 54 55 41 4c 20 54 41 42 4c 45 20 74 74 74 20 RTUAL TABLE ttt +| 4080: 55 53 49 4e 47 20 66 74 73 35 28 61 2c 20 62 29 USING fts5(a, b) +| page 2 offset 4096 +| 0: 0d 0f 44 00 05 0e 81 00 0f 1a 0e 81 0f af 0f 58 ..D............X +| 16: 0e 98 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 3712: 00 15 0a 03 00 30 00 00 00 00 01 03 03 00 03 01 .....0.......... +| 3728: 01 01 02 01 01 03 01 01 81 24 8c 80 80 80 80 01 .........$...... +| 3744: 04 00 82 4c 00 00 00 9b 02 30 65 03 1a 02 05 05 ...L.....0e..... +| 3760: 07 05 01 01 04 03 03 08 03 03 01 2e 02 05 05 07 ................ +| 3776: 05 07 05 07 05 01 01 04 03 03 08 03 03 08 03 03 ................ +| 3792: 07 f3 03 02 01 65 03 1e 03 05 05 04 05 05 01 00 .....e.......... +| 3808: 03 06 04 04 06 04 03 01 36 03 05 05 04 06 05 04 ........6....... +| 3824: 06 05 04 05 05 01 01 03 06 04 04 06 04 04 06 04 ................ +| 3840: 04 06 04 03 03 01 65 03 14 04 05 06 f5 05 01 01 ......e......... +| 3856: 02 08 09 01 20 04 05 07 05 07 05 07 05 05 01 00 .... ........... +| 3872: 02 08 0a 0a 0a 04 01 65 03 02 0a 01 06 0a 0a 0a .......e........ +| 3888: 05 01 65 03 06 01 01 0a 01 0a 01 01 0a 0a 0a 04 ..e............. +| 3904: 2b 31 21 0b 0f ef 00 14 2a 00 00 00 00 01 02 02 +1!.....*....... +| 3920: 00 02 01 01 01 02 01 01 50 88 80 80 80 80 01 04 ........P....... +| 3936: 00 81 24 00 00 00 47 02 30 65 02 1a 02 05 05 07 ..$...G.0e...... +| 3952: 05 01 01 04 03 03 08 03 03 02 01 65 02 1e 03 05 ...........e.... +| 3968: 05 04 05 05 01 01 03 06 04 04 06 04 03 03 01 65 ...............e +| 3984: 02 14 04 05 07 05 05 01 01 02 08 0a 04 01 65 02 ..............e. +| 4000: 02 0a 05 01 65 02 06 01 01 0a 04 12 14 0f 06 31 ....e..........1 +| 4016: 84 80 80 80 80 01 03 00 68 00 00 00 2b 02 30 65 ........h...+.0e +| 4032: 01 10 02 05 05 01 01 04 03 03 02 01 65 01 12 03 ............e... +| 4048: 05 05 01 01 03 06 04 03 03 01 65 01 0e 04 05 05 ..........e..... +| 4064: 01 01 02 08 04 0d 0e 06 01 03 00 12 04 4c 4c 00 .............LL. +| 4080: 00 00 11 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 3 offset 8192 +| 0: 0a 00 00 00 03 0f ec 00 0f 00 00 00 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 06 04 01 0c ................ +| 4080: 01 03 02 06 04 01 0c 01 02 02 05 04 09 0c 01 02 ................ +| page 4 offset 12288 +| 0: 0d 00 00 00 04 0e 1a 00 0f c7 0f 5b 0e ef 0e 1a ...........[.... +| 3600: 00 00 00 00 00 00 00 00 00 00 81 52 04 06 00 81 ...........R.... +| 3616: 5d 81 55 65 20 65 65 20 65 65 65 20 65 20 65 65 ].Ue ee eee e ee +| 3632: 20 65 65 65 20 65 20 65 65 20 65 65 65 66 20 65 eee e ee eeef e +| 3648: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e +| 3664: 20 65 65 20 65 65 65 65 20 65 65 20 65 65 65 20 ee eeee ee eee +| 3680: 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 e ee eee e ee ee +| 3696: 65 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 ee ee eee e ee e +| 3712: 65 65 20 65 20 65 65 20 65 65 65 65 65 65 20 65 ee e ee eeeeee e +| 3728: 65 20 65 20 65 20 65 20 65 65 20 65 65 65 20 65 e e e e ee eee e +| 3744: 65 20 65 65 65 65 65 20 65 65 20 65 20 65 1f 65 e eeeee ee e e.e +| 3760: 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 65 ee eee ee eeeee +| 3776: 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 65 ee e e e ee eee +| 3792: 20 65 65 20 65 65 65 65 65 20 65 65 20 65 20 65 ee eeeee ee e e +| 3808: 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 6a e ee eee ee eej +| 3824: 03 03 ff 75 71 65 20 65 65 1f 65 65 65 20 65 20 ...uqe ee.eee e +| 3840: 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 65 ee eee e ee eeee +| 3856: 20 65 65 20 65 65 65 20 65 20 65 65 20 65 65 65 ee eee e ee eee +| 3872: 20 65 20 65 65 20 65 65 65 65 65 65 20 65 65 20 e ee eeeeee ee +| 3888: 65 20 65 20 65 20 65 65 20 65 65 65 20 65 65 20 e e e ee eee ee +| 3904: 65 65 65 65 65 20 65 65 20 65 20 65 20 65 20 65 eeeee ee e e e e +| 3920: 65 20 65 65 65 20 65 65 20 65 65 6a 02 04 00 75 e eee ee eej...u +| 3936: 40 65 20 65 65 20 65 65 65 20 65 20 65 65 20 65 @e ee eee e ee e +| 3952: 65 65 20 65 20 65 65 20 65 65 65 65 20 65 65 20 ee e ee eeee ee +| 3968: 65 65 65 20 65 20 65 65 20 65 65 65 20 65 20 65 eee e ee eee e e +| 3984: 65 20 65 65 65 65 65 65 20 65 65 20 65 20 65 20 e eeeeee ee e e +| 4000: 65 20 65 65 20 65 65 65 20 65 65 20 65 65 65 65 e ee eee ee eeee +| 4016: 65 20 65 65 20 65 20 65 20 65 20 65 65 20 65 65 e ee e e e ee ee +| 4032: 65 20 65 65 20 65 65 37 01 04 00 41 3f 65 20 65 e ee ee7...A?e e +| 4048: 65 20 65 65 65 20 65 20 65 65 20 65 65 65 20 65 e eee e ee eee e +| 4064: 20 65 65 20 65 65 65 65 65 65 20 65 65 20 65 20 ee eeeeee ee e +| 4080: 65 20 65 20 65 65 20 65 65 65 20 65 65 20 65 65 e e ee eee ee ee +| page 5 offset 16384 +| 0: 0d 00 00 00 04 0f e4 00 0f f9 0f f2 0f eb 0f e4 ................ +| 4064: 00 00 00 00 05 04 03 00 10 21 21 05 03 03 00 10 .........!!..... +| 4080: 11 11 05 02 03 00 10 11 11 05 01 03 00 10 09 09 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| end crash-4470f0b94422f7.db +}]} {} + +do_catchsql_test 64.1 { + SELECT * FROM ttt('e*'); +} {1 {database disk image is malformed}} + + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index 7938652485..8fbc28972e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\sbuilt-in\sedit()\sSQL\sfunction\sin\sthe\sCLI\sso\sthat\sit\sworks\swith\nzero-length\sblobs. -D 2019-08-23T23:05:32.503 +C Fix\sa\spotential\sbuffer\soverrun\sin\sfts5\scaused\sby\scorrupt\sdatabase\srecords. +D 2019-08-24T17:11:29.099 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -116,7 +116,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7 F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 -F ext/fts5/fts5_index.c cd363c2fa3e626c04a9b7c705ff50222b4cab052704938f6a24881602ed3ed0d +F ext/fts5/fts5_index.c ada7661078752941e1d83bd42fe5aedef3350a1ccb9076c98153090ccd1d2f0d F ext/fts5/fts5_main.c b2c42f1cef9673ecdd498b22c38483a4380bcf1701d1e61b021a2945f18e42e1 F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 9517cc527a8e8a33949652d5c7b5e251f8c3d5ae3f23f01d4320e30f29a0336b F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test 99318789d84c678ed6388e61109b9f7b92c64419e87e4881093c01e219c5d397 +F ext/fts5/test/fts5corrupt3.test 1e0a557a2c33d26a516d8ae57685a77001e9887a7457abcea6be1c4ac77332e8 F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -1836,7 +1836,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 44578865fa7baf9760e355691ca9ce753295aaba7a4ee0bba29d4f85d9335bab -R d576abe88102041dd107794a8906549d -U drh -Z e6a2c406773297981564bcc226b2bf48 +P e32490128684cfeeb8213baecc78a7942b8fb63d00e375edd965bf236faeed18 +R 61cea08062816b86beb5c1f5910b0854 +U dan +Z 0284ef6b0b4932b74129e7c6ac32b7ce diff --git a/manifest.uuid b/manifest.uuid index c235cac52f..5f960bb4c8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e32490128684cfeeb8213baecc78a7942b8fb63d00e375edd965bf236faeed18 \ No newline at end of file +156d612800a7282fe0ebb20feb31d3fd577f4ab60fab8c00940c87143997aefb \ No newline at end of file From 666a42ffb3ad492e049ad3e1020299218f66a53b Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 24 Aug 2019 21:02:47 +0000 Subject: [PATCH 052/112] Minor performance improvement for balance_nonroot(). FossilOrigin-Name: d7434cae3edc321e2f1f8d340a0e656b1613b736f8400fb271a0e80f59401b9e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/btree.c | 4 +++- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 8fbc28972e..9c844a6a2b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sbuffer\soverrun\sin\sfts5\scaused\sby\scorrupt\sdatabase\srecords. -D 2019-08-24T17:11:29.099 +C Minor\sperformance\simprovement\sfor\sbalance_nonroot(). +D 2019-08-24T21:02:47.092 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -464,7 +464,7 @@ F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 8acc2f464ee76324bf13310df5692a262b801808984c1b79defb2503bbafadb6 -F src/btree.c 5cf994516c1b74928b9d15971573a8bc8595e1afec129184099976da603402de +F src/btree.c fdc4389b271bca30138db27dc2dfb9f52c2a7baaa44845aaf31a3c54663d837f F src/btree.h c11446f07ec0e9dc85af8041cb0855c52f5359c8b2a43e47e02a685282504d89 F src/btreeInt.h 6111c15868b90669f79081039d19e7ea8674013f907710baa3c814dc3f8bfd3f F src/build.c 7fb6ad35d162517d6bfa196f4fb2a1d7c3a362531e84c59f3a0479e0de511556 @@ -1836,7 +1836,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 e32490128684cfeeb8213baecc78a7942b8fb63d00e375edd965bf236faeed18 -R 61cea08062816b86beb5c1f5910b0854 +P 156d612800a7282fe0ebb20feb31d3fd577f4ab60fab8c00940c87143997aefb +R 4b6697f6c6d10128787e7bec7d1f64d6 U dan -Z 0284ef6b0b4932b74129e7c6ac32b7ce +Z 7ec145bc88468367dffb3891d93405d5 diff --git a/manifest.uuid b/manifest.uuid index 5f960bb4c8..31e578823c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -156d612800a7282fe0ebb20feb31d3fd577f4ab60fab8c00940c87143997aefb \ No newline at end of file +d7434cae3edc321e2f1f8d340a0e656b1613b736f8400fb271a0e80f59401b9e \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 6e6a9b2797..7ff91e667b 100644 --- a/src/btree.c +++ b/src/btree.c @@ -6992,7 +6992,8 @@ static int pageInsertArray( while( 1 /*Exit by break*/ ){ int sz, rc; u8 *pSlot; - sz = cachedCellSize(pCArray, i); + assert( pCArray->szCell[i]!=0 ); + sz = pCArray->szCell[i]; if( (aData[1]==0 && aData[2]==0) || (pSlot = pageFindSlot(pPg,sz,&rc))==0 ){ if( (pData - pBegin) Date: Mon, 26 Aug 2019 12:50:01 +0000 Subject: [PATCH 053/112] Enforce 80-character line discipline in the CLI. Minor improvements to the CLI built-in help. FossilOrigin-Name: 9690013a00d73a8047b25149ded50d20c74b5c62c0725eec50ed8477688e58a0 --- manifest | 14 +++--- manifest.uuid | 2 +- src/shell.c.in | 116 +++++++++++++++++++++++++------------------------ 3 files changed, 68 insertions(+), 64 deletions(-) diff --git a/manifest b/manifest index 9c844a6a2b..d84171b55a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Minor\sperformance\simprovement\sfor\sbalance_nonroot(). -D 2019-08-24T21:02:47.092 +C Enforce\s80-character\sline\sdiscipline\sin\sthe\sCLI.\s\sMinor\simprovements\sto\sthe\nCLI\sbuilt-in\shelp. +D 2019-08-26T12:50:01.892 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,7 +524,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c d42f1f1435c5b85a3bd48fdb196bb499c00797691bbed0d0c2b153c8b13ab742 -F src/shell.c.in 9a0706cd539fb6f00948a6a41a84c51a893179f5338c94ea37177d5f239c7741 +F src/shell.c.in 596e4160b6418900edc0aff4dbb8e172d8ab6c5e80e846ed8ef027ecc8612be0 F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 @@ -1836,7 +1836,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 156d612800a7282fe0ebb20feb31d3fd577f4ab60fab8c00940c87143997aefb -R 4b6697f6c6d10128787e7bec7d1f64d6 -U dan -Z 7ec145bc88468367dffb3891d93405d5 +P d7434cae3edc321e2f1f8d340a0e656b1613b736f8400fb271a0e80f59401b9e +R 04935d3cf93769475d1663473c5f261d +U drh +Z 842f41c6fd92cfd4b2a81346bcdf6611 diff --git a/manifest.uuid b/manifest.uuid index 31e578823c..91686bde2b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d7434cae3edc321e2f1f8d340a0e656b1613b736f8400fb271a0e80f59401b9e \ No newline at end of file +9690013a00d73a8047b25149ded50d20c74b5c62c0725eec50ed8477688e58a0 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 99a816fada..7144151d5d 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -1766,7 +1766,8 @@ static void eqp_render_level(ShellState *p, int iEqpId){ for(pRow = eqp_next_row(p, iEqpId, 0); pRow; pRow = pNext){ pNext = eqp_next_row(p, iEqpId, pRow); z = pRow->zText; - utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, pNext ? "|--" : "`--", z); + utf8_printf(p->out, "%s%s%s\n", p->sGraph.zPrefix, + pNext ? "|--" : "`--", z); if( n<(int)sizeof(p->sGraph.zPrefix)-7 ){ memcpy(&p->sGraph.zPrefix[n], pNext ? "| " : " ", 4); eqp_render_level(p, pRow->iEqpId); @@ -1957,7 +1958,7 @@ static int shell_callback( while( j>0 && IsSpace(z[j-1]) ){ j--; } z[j] = 0; if( strlen30(z)>=79 ){ - for(i=j=0; (c = z[i])!=0; i++){ /* Copy changes from z[i] back to z[j] */ + for(i=j=0; (c = z[i])!=0; i++){ /* Copy from z[i] back to z[j] */ if( c==cEnd ){ cEnd = 0; }else if( c=='"' || c=='\'' || c=='`' ){ @@ -2536,7 +2537,7 @@ static int display_stats( raw_printf(pArg->out, "Autoindex Inserts: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_VM_STEP, bReset); raw_printf(pArg->out, "Virtual Machine Steps: %d\n", iCur); - iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE, bReset); + iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_REPREPARE,bReset); raw_printf(pArg->out, "Reprepare operations: %d\n", iCur); iCur = sqlite3_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_RUN, bReset); raw_printf(pArg->out, "Number of times run: %d\n", iCur); @@ -3459,20 +3460,20 @@ static const char *(azHelp[]) = { ".archive ... Manage SQL archives", " Each command must have exactly one of the following options:", " -c, --create Create a new archive", - " -u, --update Add files or update files with changed mtime", - " -i, --insert Like -u but always add even if mtime unchanged", + " -u, --update Add or update files with changed mtime", + " -i, --insert Like -u but always add even if unchanged", " -t, --list List contents of archive", " -x, --extract Extract files from archive", " Optional arguments:", " -v, --verbose Print each filename as it is processed", - " -f FILE, --file FILE Operate on archive FILE (default is current db)", - " -a FILE, --append FILE Operate on FILE opened using the apndvfs VFS", - " -C DIR, --directory DIR Change to directory DIR to read/extract files", + " -f FILE, --file FILE Use archive FILE (default is current db)", + " -a FILE, --append FILE Open FILE using the apndvfs VFS", + " -C DIR, --directory DIR Read/extract files from directory DIR", " -n, --dryrun Show the SQL that would have occurred", " Examples:", - " .ar -cf archive.sar foo bar # Create archive.sar from files foo and bar", - " .ar -tf archive.sar # List members of archive.sar", - " .ar -xvf archive.sar # Verbosely extract files from archive.sar", + " .ar -cf ARCHIVE foo bar # Create ARCHIVE from files foo and bar", + " .ar -tf ARCHIVE # List members of ARCHIVE", + " .ar -xvf ARCHIVE # Verbosely extract files from ARCHIVE", " See also:", " http://sqlite.org/cli.html#sqlar_archive_support", #endif @@ -3481,7 +3482,7 @@ static const char *(azHelp[]) = { #endif ".backup ?DB? FILE Backup DB (default \"main\") to FILE", " --append Use the appendvfs", - " --async Write to FILE without a journal and without fsync()", + " --async Write to FILE without journal and fsync()", ".bail on|off Stop after hitting an error. Default OFF", ".binary on|off Turn binary output on or off. Default OFF", ".cd DIRECTORY Change the working directory to DIRECTORY", @@ -3501,15 +3502,15 @@ static const char *(azHelp[]) = { " Other Modes:", #ifdef SQLITE_DEBUG " test Show raw EXPLAIN QUERY PLAN output", - " trace Like \"full\" but also enable \"PRAGMA vdbe_trace\"", + " trace Like \"full\" but enable \"PRAGMA vdbe_trace\"", #endif " trigger Like \"full\" but also show trigger bytecode", - ".excel Display the output of next command in a spreadsheet", + ".excel Display the output of next command in spreadsheet", ".exit ?CODE? Exit this program with return-code CODE", - ".expert EXPERIMENTAL. Suggest indexes for specified queries", + ".expert EXPERIMENTAL. Suggest indexes for queries", /* Because explain mode comes on automatically now, the ".explain" mode -** is removed from the help screen. It is still supported for legacy, however */ -/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off or to automatic",*/ +** is removed from the help screen. It is still supported for legacy, however */ +/*".explain ?on|off|auto? Turn EXPLAIN output mode on or off",*/ ".filectrl CMD ... Run various sqlite3_file_control() operations", " Run \".filectrl\" with no arguments for details", ".fullschema ?--indent? Show schema and the content of sqlite_stat tables", @@ -3556,7 +3557,7 @@ static const char *(azHelp[]) = { " --append Use appendvfs to append database to the end of FILE", #ifdef SQLITE_ENABLE_DESERIALIZE " --deserialize Load into memory useing sqlite3_deserialize()", - " --hexdb Load the output of \"dbtotxt\" as an in-memory database", + " --hexdb Load the output of \"dbtotxt\" as an in-memory db", " --maxsize N Maximum size for --hexdb or --deserialized database", #endif " --new Initialize FILE to an empty database", @@ -3569,7 +3570,7 @@ static const char *(azHelp[]) = { " init Initialize the TEMP table that holds bindings", " list List the current parameter bindings", " set PARAMETER VALUE Given SQL parameter PARAMETER a value of VALUE", - " PARAMETER should start with '$', ':', '@', or '?'", + " PARAMETER should start with one of: $ : @ ?", " unset PARAMETER Remove PARAMETER from the binding table", ".print STRING... Print literal STRING", #ifndef SQLITE_OMIT_PROGRESS_CALLBACK @@ -3584,6 +3585,9 @@ static const char *(azHelp[]) = { ".read FILE Read input from FILE", #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) ".recover Recover as much data as possible from corrupt db.", + " --freelist-corrupt Assume the freelist is corrupt", + " --recovery-db NAME Store recovery metadata in database file NAME", + " --lost-and-found TABLE Alternative name for the lost-and-found table", #endif ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", ".save FILE Write in-memory database into FILE", @@ -3615,7 +3619,7 @@ static const char *(azHelp[]) = { " Options:", " --schema Also hash the sqlite_master table", " --sha3-224 Use the sha3-224 algorithm", - " --sha3-256 Use the sha3-256 algorithm. This is the default.", + " --sha3-256 Use the sha3-256 algorithm (default)", " --sha3-384 Use the sha3-384 algorithm", " --sha3-512 Use the sha3-512 algorithm", " Any other argument is a LIKE pattern for tables to hash", @@ -5523,7 +5527,7 @@ void shellReset( #endif /* !defined SQLITE_OMIT_VIRTUALTABLE */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) -/********************************************************************************* +/****************************************************************************** ** The ".archive" or ".ar" command. */ /* @@ -5721,7 +5725,8 @@ static int arParseCommand( i = n; }else{ if( iArg>=(nArg-1) ){ - return arErrorMsg(pAr, "option requires an argument: %c",z[i]); + return arErrorMsg(pAr, "option requires an argument: %c", + z[i]); } zArg = azArg[++iArg]; } @@ -6109,10 +6114,10 @@ end_ar_transaction: ** Implementation of ".ar" dot command. */ static int arDotCommand( - ShellState *pState, /* Current shell tool state */ - int fromCmdLine, /* True if -A command-line option, not .ar cmd */ - char **azArg, /* Array of arguments passed to dot command */ - int nArg /* Number of entries in azArg[] */ + ShellState *pState, /* Current shell tool state */ + int fromCmdLine, /* True if -A command-line option, not .ar cmd */ + char **azArg, /* Array of arguments passed to dot command */ + int nArg /* Number of entries in azArg[] */ ){ ArCommand cmd; int rc; @@ -6212,7 +6217,7 @@ end_ar_command: return rc; } /* End of the ".archive" or ".ar" command logic -**********************************************************************************/ +*******************************************************************************/ #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB) */ #if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_ENABLE_DBPAGE_VTAB) @@ -6604,11 +6609,8 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ zLostAndFound = azArg[i]; } else{ - raw_printf(stderr, "unexpected option: %s\n", azArg[i]); - raw_printf(stderr, "options are:\n"); - raw_printf(stderr, " --freelist-corrupt\n"); - raw_printf(stderr, " --recovery-db DATABASE\n"); - raw_printf(stderr, " --lost-and-found TABLE-NAME\n"); + utf8_printf(stderr, "unexpected option: %s\n", azArg[i]); + showHelp(pState->out, azArg[0]); return 1; } } @@ -8467,7 +8469,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( zName ){ appendText(&sSelect, " UNION ALL SELECT shell_module_schema(name)," - " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", 0); + " 'table', name, name, name, 9e+99, 'main' FROM pragma_module_list", + 0); } #endif appendText(&sSelect, ") WHERE ", 0); @@ -8566,7 +8569,8 @@ static int do_meta_command(char *zLine, ShellState *p){ if( pSession->p==0 ) goto session_not_open; out = fopen(azCmd[1], "wb"); if( out==0 ){ - utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", azCmd[1]); + utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n", + azCmd[1]); }else{ int szChng; void *pChng; @@ -8887,8 +8891,7 @@ static int do_meta_command(char *zLine, ShellState *p){ { utf8_printf(stderr, "Unknown option \"%s\" on \"%s\"\n", azArg[i], azArg[0]); - raw_printf(stderr, "Should be one of: --schema" - " --sha3-224 --sha3-256 --sha3-384 --sha3-512\n"); + showHelp(p->out, azArg[0]); rc = 1; goto meta_command_exit; } @@ -9166,26 +9169,26 @@ static int do_meta_command(char *zLine, ShellState *p){ int ctrlCode; /* Integer code for that option */ const char *zUsage; /* Usage notes */ } aCtrl[] = { - { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" }, - { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" }, - /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/ - /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/ - { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" }, - { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" }, - /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" }, */ - { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, - { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" }, - { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, - { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, - { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, + { "always", SQLITE_TESTCTRL_ALWAYS, "BOOLEAN" }, + { "assert", SQLITE_TESTCTRL_ASSERT, "BOOLEAN" }, + /*{ "benign_malloc_hooks",SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS, "" },*/ + /*{ "bitvec_test", SQLITE_TESTCTRL_BITVEC_TEST, "" },*/ + { "byteorder", SQLITE_TESTCTRL_BYTEORDER, "" }, + { "extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,"BOOLEAN" }, + /*{ "fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, "" },*/ + { "imposter", SQLITE_TESTCTRL_IMPOSTER, "SCHEMA ON/OFF ROOTPAGE"}, + { "internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, "BOOLEAN" }, + { "localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,"BOOLEAN" }, + { "never_corrupt", SQLITE_TESTCTRL_NEVER_CORRUPT, "BOOLEAN" }, + { "optimizations", SQLITE_TESTCTRL_OPTIMIZATIONS, "DISABLE-MASK" }, #ifdef YYCOVERAGE - { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" }, + { "parser_coverage", SQLITE_TESTCTRL_PARSER_COVERAGE, "" }, #endif - { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " }, - { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" }, - { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" }, - { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" }, - { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE" }, + { "pending_byte", SQLITE_TESTCTRL_PENDING_BYTE, "OFFSET " }, + { "prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE, "" }, + { "prng_save", SQLITE_TESTCTRL_PRNG_SAVE, "" }, + { "prng_seed", SQLITE_TESTCTRL_PRNG_SEED, "SEED ?db?" }, + { "reserve", SQLITE_TESTCTRL_RESERVE, "BYTES-OF-RESERVE"}, }; int testctrl = -1; int iCtrl = -1; @@ -9328,7 +9331,7 @@ static int do_meta_command(char *zLine, ShellState *p){ } } if( isOk==0 && iCtrl>=0 ){ - utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd, aCtrl[iCtrl].zUsage); + utf8_printf(p->out, "Usage: .testctrl %s %s\n", zCmd,aCtrl[iCtrl].zUsage); rc = 1; }else if( isOk==1 ){ raw_printf(p->out, "%d\n", rc2); @@ -9445,7 +9448,8 @@ static int do_meta_command(char *zLine, ShellState *p){ rc = 1; goto meta_command_exit; } - rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], strlen30(azArg[3])); + rc = sqlite3_user_authenticate(p->db, azArg[2], azArg[3], + strlen30(azArg[3])); if( rc ){ utf8_printf(stderr, "Authentication failed for user %s\n", azArg[2]); rc = 1; From d86fe44ab5a442a065935cb8b11a138b238dcf4b Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Aug 2019 13:45:49 +0000 Subject: [PATCH 054/112] Fix typo in a comment. No code changes. FossilOrigin-Name: d0cc06d8a30444125e5655f6587a6355471c3447c08a2e5f7a046a4ed5cc5f09 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d84171b55a..88f11e92f8 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enforce\s80-character\sline\sdiscipline\sin\sthe\sCLI.\s\sMinor\simprovements\sto\sthe\nCLI\sbuilt-in\shelp. -D 2019-08-26T12:50:01.892 +C Fix\stypo\sin\sa\scomment.\s\sNo\scode\schanges. +D 2019-08-26T13:45:49.721 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c a1a811e1e5c623a7aa7176fa781ce72944a92b06233b15a39151a743d6eaab97 +F src/expr.c 9962ab98d340c9d6815ce381e374ce928f7a7a2a04ca7779b10ffe93db563da0 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1836,7 +1836,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 d7434cae3edc321e2f1f8d340a0e656b1613b736f8400fb271a0e80f59401b9e -R 04935d3cf93769475d1663473c5f261d +P 9690013a00d73a8047b25149ded50d20c74b5c62c0725eec50ed8477688e58a0 +R 2f001fd65969a9ca56fabaf8851a89b5 U drh -Z 842f41c6fd92cfd4b2a81346bcdf6611 +Z b2e7fed545219961a9764335cb571eba diff --git a/manifest.uuid b/manifest.uuid index 91686bde2b..38abd08e3c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9690013a00d73a8047b25149ded50d20c74b5c62c0725eec50ed8477688e58a0 \ No newline at end of file +d0cc06d8a30444125e5655f6587a6355471c3447c08a2e5f7a046a4ed5cc5f09 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 496abd32ce..6cb2e0c348 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2859,7 +2859,7 @@ void sqlite3CodeRhsOfIN( ** ** The pExpr parameter is the SELECT or EXISTS operator to be coded. ** -** The register that holds the result. For a multi-column SELECT, +** Return the register that holds the result. For a multi-column SELECT, ** the result is stored in a contiguous array of registers and the ** return value is the register of the left-most result column. ** Return 0 if an error occurs. From 554a9dc78ab23f3831dd689fe33fb87f2d60626d Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Aug 2019 14:18:28 +0000 Subject: [PATCH 055/112] Improved detection of number of column mismatch for vector assignment in UPDATE statements. Ticket [78acc9d40f0786e8] FossilOrigin-Name: bd4bda73df3794eef424eb13e08fc7cc54347d1ac69febaeec41f6b6cb4a42bc --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 8 ++++++-- src/sqliteInt.h | 1 + test/rowvalue7.test | 10 ++++++++++ 5 files changed, 26 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 88f11e92f8..ec1710be3d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sin\sa\scomment.\s\sNo\scode\schanges. -D 2019-08-26T13:45:49.721 +C Improved\sdetection\sof\snumber\sof\scolumn\smismatch\sfor\svector\sassignment\nin\sUPDATE\sstatements.\s\sTicket\s[78acc9d40f0786e8] +D 2019-08-26T14:18:28.243 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 9962ab98d340c9d6815ce381e374ce928f7a7a2a04ca7779b10ffe93db563da0 +F src/expr.c 701e304da3f0ddf491ff6927eeafdd196b491e48c5290117dcb95e19dd3413ea F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -528,7 +528,7 @@ F src/shell.c.in 596e4160b6418900edc0aff4dbb8e172d8ab6c5e80e846ed8ef027ecc8612be F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 -F src/sqliteInt.h 52594e495e35649c22f650b5249e515ac8eb108d97be304d14a0e89539ed1c59 +F src/sqliteInt.h 9a3e2cf34d375ea74ecb9a1a60651f8b22b2bca007742a393cc87f4a3a2db0c3 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1260,7 +1260,7 @@ F test/rowvalue3.test 3068f508753af69884b12125995f023da0dbb256 F test/rowvalue4.test 02e35f7762371c2f57ebd856aa056eac56cb27ef7715a0bb31eac1895a745356 F test/rowvalue5.test c81c7d8cf36711ab37675ad7376084ae2a359cb6 F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 -F test/rowvalue7.test 5d06ff19d9e6969e574a2e662a531dd0c67801a8 +F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 F test/rowvalue9.test d8dd2c6ecac432dadaa79e41dc2434f007be1b6b F test/rowvaluefault.test 7cd9ccc6c2fbdd881672984087aad0491bb75504 @@ -1836,7 +1836,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 9690013a00d73a8047b25149ded50d20c74b5c62c0725eec50ed8477688e58a0 -R 2f001fd65969a9ca56fabaf8851a89b5 +P d0cc06d8a30444125e5655f6587a6355471c3447c08a2e5f7a046a4ed5cc5f09 +R c94e7f0fd8fde374ff7a64e52e862147 U drh -Z b2e7fed545219961a9764335cb571eba +Z 704a1e95609dba9715f49ae5f6d53285 diff --git a/manifest.uuid b/manifest.uuid index 38abd08e3c..5072ee8c39 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d0cc06d8a30444125e5655f6587a6355471c3447c08a2e5f7a046a4ed5cc5f09 \ No newline at end of file +bd4bda73df3794eef424eb13e08fc7cc54347d1ac69febaeec41f6b6cb4a42bc \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 6cb2e0c348..aac706644c 100644 --- a/src/expr.c +++ b/src/expr.c @@ -1632,6 +1632,10 @@ ExprList *sqlite3ExprListAppendVector( for(i=0; inId; i++){ Expr *pSubExpr = sqlite3ExprForVectorField(pParse, pExpr, i); + assert( pSubExpr!=0 || db->mallocFailed ); + assert( pSubExpr==0 || pSubExpr->iTable==0 ); + if( pSubExpr==0 ) continue; + pSubExpr->iTable = pColumns->nId; pList = sqlite3ExprListAppend(pParse, pList, pSubExpr); if( pList ){ assert( pList->nExpr==iFirst+i+1 ); @@ -3906,8 +3910,8 @@ expr_code_doover: pExpr->pLeft->iTable = sqlite3CodeSubselect(pParse, pExpr->pLeft); } assert( pExpr->iTable==0 || pExpr->pLeft->op==TK_SELECT ); - if( pExpr->iTable - && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) + if( pExpr->iTable!=0 + && pExpr->iTable!=(n = sqlite3ExprVectorSize(pExpr->pLeft)) ){ sqlite3ErrorMsg(pParse, "%d columns assigned %d values", pExpr->iTable, n); diff --git a/src/sqliteInt.h b/src/sqliteInt.h index f60b6f7aec..9492da17a1 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2470,6 +2470,7 @@ struct Expr { ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood + ** TK_SELECT_COLUMN: Number of columns on the LHS ** TK_SELECT: 1st register of result vector */ ynVar iColumn; /* TK_COLUMN: column index. -1 for rowid. ** TK_VARIABLE: variable number (always >= 1). diff --git a/test/rowvalue7.test b/test/rowvalue7.test index f6764f301e..03591afaf4 100644 --- a/test/rowvalue7.test +++ b/test/rowvalue7.test @@ -55,4 +55,14 @@ do_catchsql_test 2.2 { UPDATE t1 SET (b,c,d) = (SELECT x,y FROM t2 WHERE w=a); } {1 {3 columns assigned 2 values}} +# 2019-08-26 +# ticket https://www.sqlite.org/src/info/78acc9d40f0786e8 +# +do_catchsql_test 3.0 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(a,b); + INSERT INTO t1 VALUES(1,2); + UPDATE t1 SET (a,a,a,b)=(SELECT 99,100); +} {1 {4 columns assigned 2 values}} + finish_test From d790c9a1613334e2fc6b92211911e032ecbf36cf Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 26 Aug 2019 14:57:58 +0000 Subject: [PATCH 056/112] Tweak the shell tool ".recover" command so that it can recover rows that consist of a rowid and no fields. FossilOrigin-Name: 279ac7fdec0b1409cd400b7b093f89089d93c49f596f378c6a3032434a85bf83 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ec1710be3d..3ab941f551 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improved\sdetection\sof\snumber\sof\scolumn\smismatch\sfor\svector\sassignment\nin\sUPDATE\sstatements.\s\sTicket\s[78acc9d40f0786e8] -D 2019-08-26T14:18:28.243 +C Tweak\sthe\sshell\stool\s".recover"\scommand\sso\sthat\sit\scan\srecover\srows\sthat\sconsist\sof\sa\srowid\sand\sno\sfields. +D 2019-08-26T14:57:58.620 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,7 +524,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c d42f1f1435c5b85a3bd48fdb196bb499c00797691bbed0d0c2b153c8b13ab742 -F src/shell.c.in 596e4160b6418900edc0aff4dbb8e172d8ab6c5e80e846ed8ef027ecc8612be0 +F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21b F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 @@ -1836,7 +1836,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 d0cc06d8a30444125e5655f6587a6355471c3447c08a2e5f7a046a4ed5cc5f09 -R c94e7f0fd8fde374ff7a64e52e862147 -U drh -Z 704a1e95609dba9715f49ae5f6d53285 +P bd4bda73df3794eef424eb13e08fc7cc54347d1ac69febaeec41f6b6cb4a42bc +R f61d543a07f97630767d799321746763 +U dan +Z 653ee8815bcf440360f1ea49c2de4aca diff --git a/manifest.uuid b/manifest.uuid index 5072ee8c39..bcc4398929 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bd4bda73df3794eef424eb13e08fc7cc54347d1ac69febaeec41f6b6cb4a42bc \ No newline at end of file +279ac7fdec0b1409cd400b7b093f89089d93c49f596f378c6a3032434a85bf83 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 7144151d5d..9ae39a1d64 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -6712,7 +6712,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ " )" " SELECT pgno FROM p WHERE (parent IS NULL OR pgno = orig)" ") " - "FROM pages WHERE maxlen > 0 AND i NOT IN freelist;" + "FROM pages WHERE maxlen IS NOT NULL AND i NOT IN freelist;" "UPDATE recovery.map AS o SET intkey = (" " SELECT substr(data, 1, 1)==X'0D' FROM sqlite_dbpage WHERE pgno=o.pgno" ");" From 6397a78b2ba93729678ef0ea68d0765e046a360e Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Aug 2019 10:05:45 +0000 Subject: [PATCH 057/112] If a TEMP TRIGGER references an auxiliary schema, and that auxiliary schema is detached, move the trigger to reference the TEMP schema before completing the detach, so that the trigger does not hold a dangling schema pointer. FossilOrigin-Name: 069c2f4c61f06211a8981abc412afcc1536ece13380b13a70aa99123f8f527cd --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/attach.c | 13 +++++++++++++ src/trigger.c | 14 +++++++------- test/trigger1.test | 14 ++++++++++++++ 5 files changed, 44 insertions(+), 17 deletions(-) diff --git a/manifest b/manifest index 3ab941f551..19417652ab 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Tweak\sthe\sshell\stool\s".recover"\scommand\sso\sthat\sit\scan\srecover\srows\sthat\sconsist\sof\sa\srowid\sand\sno\sfields. -D 2019-08-26T14:57:58.620 +C If\sa\sTEMP\sTRIGGER\sreferences\san\sauxiliary\sschema,\sand\sthat\sauxiliary\sschema\nis\sdetached,\smove\sthe\strigger\sto\sreference\sthe\sTEMP\sschema\sbefore\scompleting\nthe\sdetach,\sso\sthat\sthe\strigger\sdoes\snot\shold\sa\sdangling\sschema\spointer. +D 2019-08-27T10:05:45.169 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -459,7 +459,7 @@ F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F src/alter.c 5c3031e45e80f79d7d54c2d32dd3c44926544d4f6a478858bfe4ee3191570190 F src/analyze.c a3f4ea45cdb4e9df78d4ea7beb87ec8a7a46f494173b641cd28512a40a97bff2 -F src/attach.c a6f108eb7922fad920e8aba0cda56fb56d89d136d519be5177cd3bd3559f2566 +F src/attach.c 3ca19504849c2d9be10fc5899d6811f9d6e848665d1a41ffb53df0cd6e7c13ed F src/auth.c a3d5bfdba83d25abed1013a8c7a5f204e2e29b0c25242a56bc02bb0c07bf1e06 F src/backup.c f70077d40c08b7787bfe934e4d1da8030cb0cc57d46b345fba2294b7d1be23ab F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 @@ -589,7 +589,7 @@ F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e -F src/trigger.c 2305271878e95addc1c01361e5e8e342e87cba5efefdd7d3032687e5d67e05d1 +F src/trigger.c f964d85935d0b9675b4aa2f74999cabee3ac1ac705f71b38a8b7e8ccd4ad474b F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 @@ -1560,7 +1560,7 @@ F test/trans.test 6e1b4c6a42dba31bd65f8fa5e61a2708e08ddde6 F test/trans2.test 62bd045bfc7a1c14c5ba83ba64d21ade31583f76 F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/transitive1.test 293300f46916569f08875cdb2fe2134be2c27677 -F test/trigger1.test 17e4b43e656c4b354df2357634a6ba887990f510c43629f4feca30e3338d2a61 +F test/trigger1.test 6be279c9d48b25320eab68c30fd5268ab787955679f4c584128f71800247fb50 F test/trigger2.test 5cd7d69a7ba1143ee045e4ae2963ff32ae4c87a6 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 @@ -1836,7 +1836,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 bd4bda73df3794eef424eb13e08fc7cc54347d1ac69febaeec41f6b6cb4a42bc -R f61d543a07f97630767d799321746763 -U dan -Z 653ee8815bcf440360f1ea49c2de4aca +P 279ac7fdec0b1409cd400b7b093f89089d93c49f596f378c6a3032434a85bf83 +R 0805c7b844001f17510379fb60166cba +U drh +Z 87dfaef8c8e67d4b9cd50025b5165f6d diff --git a/manifest.uuid b/manifest.uuid index bcc4398929..cef7eaf8a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -279ac7fdec0b1409cd400b7b093f89089d93c49f596f378c6a3032434a85bf83 \ No newline at end of file +069c2f4c61f06211a8981abc412afcc1536ece13380b13a70aa99123f8f527cd \ No newline at end of file diff --git a/src/attach.c b/src/attach.c index 61f169ed76..1dcb407edd 100644 --- a/src/attach.c +++ b/src/attach.c @@ -299,6 +299,7 @@ static void detachFunc( sqlite3 *db = sqlite3_context_db_handle(context); int i; Db *pDb = 0; + HashElem *pEntry; char zErr[128]; UNUSED_PARAMETER(NotUsed); @@ -323,6 +324,18 @@ static void detachFunc( goto detach_error; } + /* If any TEMP triggers reference the schema being detached, move those + ** triggers to reference the TEMP schema itself. */ + assert( db->aDb[1].pSchema ); + pEntry = sqliteHashFirst(&db->aDb[1].pSchema->trigHash); + while( pEntry ){ + Trigger *pTrig = (Trigger*)sqliteHashData(pEntry); + if( pTrig->pTabSchema==pDb->pSchema ){ + pTrig->pTabSchema = pTrig->pSchema; + } + pEntry = sqliteHashNext(pEntry); + } + sqlite3BtreeClose(pDb->pBt); pDb->pBt = 0; pDb->pSchema = 0; diff --git a/src/trigger.c b/src/trigger.c index 989df9678a..16cc57b40c 100644 --- a/src/trigger.c +++ b/src/trigger.c @@ -618,10 +618,9 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ iDb = sqlite3SchemaToIndex(pParse->db, pTrigger->pSchema); assert( iDb>=0 && iDbnDb ); pTable = tableOfTrigger(pTrigger); - assert( pTable ); - assert( pTable->pSchema==pTrigger->pSchema || iDb==1 ); + assert( (pTable && pTable->pSchema==pTrigger->pSchema) || iDb==1 ); #ifndef SQLITE_OMIT_AUTHORIZATION - { + if( pTable ){ int code = SQLITE_DROP_TRIGGER; const char *zDb = db->aDb[iDb].zDbSName; const char *zTab = SCHEMA_TABLE(iDb); @@ -635,7 +634,6 @@ void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ /* Generate code to destroy the database record of the trigger. */ - assert( pTable!=0 ); if( (v = sqlite3GetVdbe(pParse))!=0 ){ sqlite3NestedParse(pParse, "DELETE FROM %Q.%s WHERE name=%Q AND type='trigger'", @@ -659,9 +657,11 @@ void sqlite3UnlinkAndDeleteTrigger(sqlite3 *db, int iDb, const char *zName){ if( ALWAYS(pTrigger) ){ if( pTrigger->pSchema==pTrigger->pTabSchema ){ Table *pTab = tableOfTrigger(pTrigger); - Trigger **pp; - for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); - *pp = (*pp)->pNext; + if( pTab ){ + Trigger **pp; + for(pp=&pTab->pTrigger; *pp!=pTrigger; pp=&((*pp)->pNext)); + *pp = (*pp)->pNext; + } } sqlite3DeleteTrigger(db, pTrigger); db->mDbFlags |= DBFLAG_SchemaChange; diff --git a/test/trigger1.test b/test/trigger1.test index 8946cd85c9..ddb40e3adb 100644 --- a/test/trigger1.test +++ b/test/trigger1.test @@ -768,4 +768,18 @@ do_execsql_test trigger1-19.1 { SELECT * FROM t19; } {1 2 2} +# 2019-08-26 Chromium sqlite3_fts3_lpm_fuzzer find. +# +db close +sqlite3 db :memory: +do_execsql_test trigger1-20.1 { + CREATE TABLE t20_1(x); + ATTACH ':memory:' AS aux; + CREATE TABLE aux.t20_2(y); + CREATE TABLE aux.t20_3(z); + CREATE TEMP TRIGGER r20_3 AFTER INSERT ON t20_2 BEGIN UPDATE t20_3 SET z=z+1; END; + DETACH aux; + DROP TRIGGER r20_3; +} {} + finish_test From 790b37a2403eb479fcb9e33e0d7622b78524c579 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Aug 2019 17:01:07 +0000 Subject: [PATCH 058/112] Omit the "x IN (y)" to "x==y" optimization of check-in [e68b427afbc82e20] (and ticket [e39d032577df6942]) as it causes difficult affinity problems as demonstrated by ticket [dbaf8a6820be1ece] and the original assertion fault is no longer a factor due to countless other changes of the previous 5 years. FossilOrigin-Name: 7f5168a76a400fc2e1e40c6950470b1bfb38a0be54fc5518c17c29fdae7d8f1f --- manifest | 24 ++++++++++++------------ manifest.uuid | 2 +- src/expr.c | 2 -- src/parse.y | 27 --------------------------- src/select.c | 3 --- src/sqliteInt.h | 2 +- src/vdbe.c | 7 ++++--- src/where.c | 2 -- test/in4.test | 13 ++++++++----- 9 files changed, 26 insertions(+), 56 deletions(-) diff --git a/manifest b/manifest index 19417652ab..88f2172882 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sa\sTEMP\sTRIGGER\sreferences\san\sauxiliary\sschema,\sand\sthat\sauxiliary\sschema\nis\sdetached,\smove\sthe\strigger\sto\sreference\sthe\sTEMP\sschema\sbefore\scompleting\nthe\sdetach,\sso\sthat\sthe\strigger\sdoes\snot\shold\sa\sdangling\sschema\spointer. -D 2019-08-27T10:05:45.169 +C Omit\sthe\s"x\sIN\s(y)"\sto\s"x==y"\soptimization\sof\scheck-in\s[e68b427afbc82e20]\n(and\sticket\s[e39d032577df6942])\sas\sit\scauses\sdifficult\saffinity\sproblems\nas\sdemonstrated\sby\sticket\s[dbaf8a6820be1ece]\sand\sthe\soriginal\sassertion\sfault\nis\sno\slonger\sa\sfactor\sdue\sto\scountless\sother\schanges\sof\sthe\sprevious\s5\syears. +D 2019-08-27T17:01:07.813 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 701e304da3f0ddf491ff6927eeafdd196b491e48c5290117dcb95e19dd3413ea +F src/expr.c 18b6d8b5fea8151fae6d67fb12f2fff1f3abe8d5fe70365ecb3671a0aaf51c27 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -512,7 +512,7 @@ F src/os_win.c 035a813cbd17f355bdcad7ab894af214a9c13a1db8aeac902365350b98cd45a7 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a F src/pager.c 422fd8cfa59fb9173eff36a95878904a0eeb0dcc62ba49350acc8b1e51c4dc7b F src/pager.h 217921e81eb5fe455caa5cda96061959706bcdd29ddb57166198645ef7822ac3 -F src/parse.y 6d03a24bc0dcd15b93c480ea8a87f7ccd25313fe826485726d9ef13b82f2378d +F src/parse.y 152a72755398be8f36e097bbab9fd3eeebc638b31ed1ec134e49284f9d7f013a F src/pcache.c 385ff064bca69789d199a98e2169445dc16e4291fa807babd61d4890c3b34177 F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586 F src/pcache1.c 62714cbd1b7299a6e6a27a587b66b4fd3a836a84e1181e7f96f5c34a50917848 @@ -523,12 +523,12 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c d42f1f1435c5b85a3bd48fdb196bb499c00797691bbed0d0c2b153c8b13ab742 +F src/select.c c1dfbd699a6dce14c2e6f30370a57753294d6b725cc75551b26146e0c1d25076 F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21b F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 -F src/sqliteInt.h 9a3e2cf34d375ea74ecb9a1a60651f8b22b2bca007742a393cc87f4a3a2db0c3 +F src/sqliteInt.h ce52cf59718f4affee3057381f5cf7acefe42d2ab6b43c6da93f4b1f6a3c704b F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -595,7 +595,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 7cd09c6cc4d0e0053ced392ea4d04762e7ffd1470ff1b90ba3ebd2869c849ae8 +F src/vdbe.c cdd90f4c4773a08504c66815faa505570257619a0bafcc9b486a24844be51357 F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6 F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c c35ad5b77fc135a09d6b16a63076748b5c32936016b5031294508a4d6a2ddbb1 +F src/where.c 6cc2708ab9a386c0aef3fa50ed0f5bdfed22848e492960a4504eb25bdb79c8d1 F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c e1131fe94c8728cbecc707f6455afbda9418896497bdca2d49a04ce6c57999f6 F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f @@ -1028,7 +1028,7 @@ F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 F test/in.test 63e642e97bc22c8fd970752fb4f0b3992a957003ea87524fe69e5a700500c500 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 -F test/in4.test d2b38cba404bc4320f4fe1b595b3d163f212c068 +F test/in4.test 0f77b0ff371549e6a119d0356be10bdba72258162e9701e83527a560482f5e98 F test/in5.test b32ce7f4a93f44c5dee94af16886d922cc16ebe33c8e1765c73d4049d0f4b40f F test/in6.test 62d943a02f722948f4410ee0b53c3cb39acd7c41afb083df8d7004238fe90a20 F test/incrblob.test c9b96afc292aeff43d6687bcb09b0280aa599822 @@ -1836,7 +1836,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 279ac7fdec0b1409cd400b7b093f89089d93c49f596f378c6a3032434a85bf83 -R 0805c7b844001f17510379fb60166cba +P 069c2f4c61f06211a8981abc412afcc1536ece13380b13a70aa99123f8f527cd +R 1d1745df08bf23742595db0b843b9c5f U drh -Z 87dfaef8c8e67d4b9cd50025b5165f6d +Z ead76a2ee397baa2df21935f693c9dfe diff --git a/manifest.uuid b/manifest.uuid index cef7eaf8a2..40a6660d4e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -069c2f4c61f06211a8981abc412afcc1536ece13380b13a70aa99123f8f527cd \ No newline at end of file +7f5168a76a400fc2e1e40c6950470b1bfb38a0be54fc5518c17c29fdae7d8f1f \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index aac706644c..fbb5ffafaf 100644 --- a/src/expr.c +++ b/src/expr.c @@ -44,7 +44,6 @@ char sqlite3TableColumnAffinity(Table *pTab, int iCol){ */ char sqlite3ExprAffinity(Expr *pExpr){ int op; - if( pExpr->flags & EP_Generic ) return 0; while( ExprHasProperty(pExpr, EP_Skip) ){ assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; @@ -156,7 +155,6 @@ CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ Expr *p = pExpr; while( p ){ int op = p->op; - if( p->flags & EP_Generic ) break; if( op==TK_REGISTER ) op = p->op2; if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_TRIGGER) && p->y.pTab!=0 diff --git a/src/parse.y b/src/parse.y index 648e79d9e3..e84a9a18e6 100644 --- a/src/parse.y +++ b/src/parse.y @@ -1176,33 +1176,6 @@ expr(A) ::= expr(A) between_op(N) expr(X) AND expr(Y). [BETWEEN] { */ sqlite3ExprUnmapAndDelete(pParse, A); A = sqlite3ExprAlloc(pParse->db, TK_INTEGER,&sqlite3IntTokens[N],1); - }else if( Y->nExpr==1 ){ - /* Expressions of the form: - ** - ** expr1 IN (?1) - ** expr1 NOT IN (?2) - ** - ** with exactly one value on the RHS can be simplified to something - ** like this: - ** - ** expr1 == ?1 - ** expr1 <> ?2 - ** - ** But, the RHS of the == or <> is marked with the EP_Generic flag - ** so that it may not contribute to the computation of comparison - ** affinity or the collating sequence to use for comparison. Otherwise, - ** the semantics would be subtly different from IN or NOT IN. - */ - Expr *pRHS = Y->a[0].pExpr; - Y->a[0].pExpr = 0; - sqlite3ExprListDelete(pParse->db, Y); - /* pRHS cannot be NULL because a malloc error would have been detected - ** before now and control would have never reached this point */ - if( ALWAYS(pRHS) ){ - pRHS->flags &= ~EP_Collate; - pRHS->flags |= EP_Generic; - } - A = sqlite3PExpr(pParse, N ? TK_NE : TK_EQ, A, pRHS); }else{ A = sqlite3PExpr(pParse, TK_IN, A, 0); if( A ){ diff --git a/src/select.c b/src/select.c index 9cfcddf8da..af87e4d2be 100644 --- a/src/select.c +++ b/src/select.c @@ -3476,9 +3476,6 @@ static Expr *substExpr( pNew->iRightJoinTable = pExpr->iRightJoinTable; ExprSetProperty(pNew, EP_FromJoin); } - if( pNew && ExprHasProperty(pExpr,EP_Generic) ){ - ExprSetProperty(pNew, EP_Generic); - } sqlite3ExprDelete(db, pExpr); pExpr = pNew; } diff --git a/src/sqliteInt.h b/src/sqliteInt.h index 9492da17a1..70b2f0ba77 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -2508,7 +2508,7 @@ struct Expr { #define EP_DblQuoted 0x000040 /* token.z was originally in "..." */ #define EP_InfixFunc 0x000080 /* True for an infix function: LIKE, GLOB, etc */ #define EP_Collate 0x000100 /* Tree contains a TK_COLLATE operator */ -#define EP_Generic 0x000200 /* Ignore COLLATE or affinity on this tree */ + /* 0x000200 Available for reuse */ #define EP_IntValue 0x000400 /* Integer value contained in u.iValue */ #define EP_xIsSelect 0x000800 /* x.pSelect is valid (otherwise x.pList is) */ #define EP_Skip 0x001000 /* Operator does not contribute to affinity */ diff --git a/src/vdbe.c b/src/vdbe.c index c50e2a0b50..8c5c684af7 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -5444,11 +5444,12 @@ case OP_Next: /* jump */ ** The Prev opcode is only used after SeekLT, SeekLE, and Last. */ assert( pOp->opcode!=OP_Next || pC->seekOp==OP_SeekGT || pC->seekOp==OP_SeekGE - || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found - || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid); + || pC->seekOp==OP_Rewind || pC->seekOp==OP_Found + || pC->seekOp==OP_NullRow|| pC->seekOp==OP_SeekRowid + || pC->seekOp==OP_IfNoHope); assert( pOp->opcode!=OP_Prev || pC->seekOp==OP_SeekLT || pC->seekOp==OP_SeekLE - || pC->seekOp==OP_Last + || pC->seekOp==OP_Last || pC->seekOp==OP_IfNoHope || pC->seekOp==OP_NullRow); rc = pOp->p4.xAdvance(pC->uc.pCursor, pOp->p3); diff --git a/src/where.c b/src/where.c index 6e9d9cb9a2..e566e9e689 100644 --- a/src/where.c +++ b/src/where.c @@ -2517,8 +2517,6 @@ static int whereLoopAddBtreeIndex( }else if( ALWAYS(pExpr->x.pList && pExpr->x.pList->nExpr) ){ /* "x IN (value, value, ...)" */ nIn = sqlite3LogEst(pExpr->x.pList->nExpr); - assert( nIn>0 ); /* RHS always has 2 or more terms... The parser - ** changes "x IN (?)" into "x=?". */ } if( pProbe->hasStat1 ){ LogEst M, logK, safetyMargin; diff --git a/test/in4.test b/test/in4.test index a89961f82b..787b9ea36c 100644 --- a/test/in4.test +++ b/test/in4.test @@ -226,10 +226,13 @@ do_execsql_test in4-3.42 { do_execsql_test in4-3.43 { SELECT * FROM t3 WHERE x IN (10); } {10 10 10} -do_execsql_test in4-3.44 { - EXPLAIN - SELECT * FROM t3 WHERE x IN (10); -} {~/OpenEphemeral/} + +# This test would verify that the "X IN (Y)" -> "X==Y" optimization +# was working. But we have now taken that optimization out. +#do_execsql_test in4-3.44 { +# EXPLAIN +# SELECT * FROM t3 WHERE x IN (10); +#} {~/OpenEphemeral/} do_execsql_test in4-3.45 { SELECT * FROM t3 WHERE x NOT IN (10,11,99999); } {1 1 1} @@ -326,7 +329,7 @@ do_execsql_test in4-6.1 { do_execsql_test in4-6.1-eqp { EXPLAIN QUERY PLAN SELECT * FROM t6a, t6b WHERE a=3 AND b IN (c); -} {~/SCAN/} +} {~/SCAN TABLE t6a/} do_execsql_test in4-6.2 { SELECT * FROM t6a, t6b WHERE a=3 AND c IN (b); } {3 4 4 44} From 7ec796d00228854511e3e19772a477e19c99aaac Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Aug 2019 17:28:05 +0000 Subject: [PATCH 059/112] Add ALWAYS() to an always true conditional that results from the previous check-in. Add a test case for ticket [dbaf8a6820be1ece] to supplement those already checked into TH3. FossilOrigin-Name: aff209804722ac902c7abfde80ad2677e0f51beb2c7f28f65d51105d984a1640 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/in.test | 10 ++++++++++ 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 88f2172882..448d1500ae 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Omit\sthe\s"x\sIN\s(y)"\sto\s"x==y"\soptimization\sof\scheck-in\s[e68b427afbc82e20]\n(and\sticket\s[e39d032577df6942])\sas\sit\scauses\sdifficult\saffinity\sproblems\nas\sdemonstrated\sby\sticket\s[dbaf8a6820be1ece]\sand\sthe\soriginal\sassertion\sfault\nis\sno\slonger\sa\sfactor\sdue\sto\scountless\sother\schanges\sof\sthe\sprevious\s5\syears. -D 2019-08-27T17:01:07.813 +C Add\sALWAYS()\sto\san\salways\strue\sconditional\sthat\sresults\sfrom\sthe\nprevious\scheck-in.\s\sAdd\sa\stest\scase\sfor\sticket\s[dbaf8a6820be1ece]\sto\nsupplement\sthose\salready\schecked\sinto\sTH3. +D 2019-08-27T17:28:05.799 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 6cc2708ab9a386c0aef3fa50ed0f5bdfed22848e492960a4504eb25bdb79c8d1 +F src/where.c b33215cc1c69518b3c99a95cd8340eabd8e65213529e578659701401bfbcaa24 F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c e1131fe94c8728cbecc707f6455afbda9418896497bdca2d49a04ce6c57999f6 F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f @@ -1025,7 +1025,7 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 -F test/in.test 63e642e97bc22c8fd970752fb4f0b3992a957003ea87524fe69e5a700500c500 +F test/in.test 1f82966f8c3f380c0a2d5a04e4111a333c3f46d96f40fb540e022c70ace85c11 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test 0f77b0ff371549e6a119d0356be10bdba72258162e9701e83527a560482f5e98 @@ -1836,7 +1836,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 069c2f4c61f06211a8981abc412afcc1536ece13380b13a70aa99123f8f527cd -R 1d1745df08bf23742595db0b843b9c5f +P 7f5168a76a400fc2e1e40c6950470b1bfb38a0be54fc5518c17c29fdae7d8f1f +R e976ee574a610781e94b063fc639c3bb U drh -Z ead76a2ee397baa2df21935f693c9dfe +Z 4e7308a6b92cf40c1732223a6962408d diff --git a/manifest.uuid b/manifest.uuid index 40a6660d4e..27ec395e67 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -7f5168a76a400fc2e1e40c6950470b1bfb38a0be54fc5518c17c29fdae7d8f1f \ No newline at end of file +aff209804722ac902c7abfde80ad2677e0f51beb2c7f28f65d51105d984a1640 \ No newline at end of file diff --git a/src/where.c b/src/where.c index e566e9e689..1eafcc87d8 100644 --- a/src/where.c +++ b/src/where.c @@ -802,7 +802,7 @@ static void constructAutomaticIndex( idxCols |= cMask; pIdx->aiColumn[n] = pTerm->u.leftColumn; pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); - pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; + pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : sqlite3StrBINARY; n++; } } diff --git a/test/in.test b/test/in.test index c247f2e070..f96dfcc11e 100644 --- a/test/in.test +++ b/test/in.test @@ -750,4 +750,14 @@ do_execsql_test in-17.4 { SELECT 1 IN (CAST('1' AS text) COLLATE nocase); } 0 +# 2019-08-27 ticket https://sqlite.org/src/info/dbaf8a6820be1ece +# +do_execsql_test in-18.1 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 INT UNIQUE); + INSERT INTO t0(c0) VALUES (1); + SELECT * FROM t0 WHERE '1' IN (t0.c0); +} {} + + finish_test From e893759cac17443c63fd0bc0bfce198985da7aa5 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 27 Aug 2019 17:59:01 +0000 Subject: [PATCH 060/112] The ALWAYS() added by the previous check-in was incorrect. Take it back out. FossilOrigin-Name: 336235db2b1167cdb2feb64b47eb6368c97c43ee9641b7bfccc5775a41dd0d0e --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 448d1500ae..3ecba933a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sALWAYS()\sto\san\salways\strue\sconditional\sthat\sresults\sfrom\sthe\nprevious\scheck-in.\s\sAdd\sa\stest\scase\sfor\sticket\s[dbaf8a6820be1ece]\sto\nsupplement\sthose\salready\schecked\sinto\sTH3. -D 2019-08-27T17:28:05.799 +C The\sALWAYS()\sadded\sby\sthe\sprevious\scheck-in\swas\sincorrect.\s\sTake\sit\sback\sout. +D 2019-08-27T17:59:01.529 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c b33215cc1c69518b3c99a95cd8340eabd8e65213529e578659701401bfbcaa24 +F src/where.c 6cc2708ab9a386c0aef3fa50ed0f5bdfed22848e492960a4504eb25bdb79c8d1 F src/whereInt.h 2082fc2bd1eb66cb236a1a3c4b250e33d2bad9e43a0486a2cf9e4e211c58f3eb F src/wherecode.c e1131fe94c8728cbecc707f6455afbda9418896497bdca2d49a04ce6c57999f6 F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f @@ -1836,7 +1836,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 7f5168a76a400fc2e1e40c6950470b1bfb38a0be54fc5518c17c29fdae7d8f1f -R e976ee574a610781e94b063fc639c3bb +P aff209804722ac902c7abfde80ad2677e0f51beb2c7f28f65d51105d984a1640 +R ab1237ad66e99f2406a94be2d43ffa7b U drh -Z 4e7308a6b92cf40c1732223a6962408d +Z 919069f1dca2ee3915ff3c6a1bd5e156 diff --git a/manifest.uuid b/manifest.uuid index 27ec395e67..60f2eca16a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -aff209804722ac902c7abfde80ad2677e0f51beb2c7f28f65d51105d984a1640 \ No newline at end of file +336235db2b1167cdb2feb64b47eb6368c97c43ee9641b7bfccc5775a41dd0d0e \ No newline at end of file diff --git a/src/where.c b/src/where.c index 1eafcc87d8..e566e9e689 100644 --- a/src/where.c +++ b/src/where.c @@ -802,7 +802,7 @@ static void constructAutomaticIndex( idxCols |= cMask; pIdx->aiColumn[n] = pTerm->u.leftColumn; pColl = sqlite3BinaryCompareCollSeq(pParse, pX->pLeft, pX->pRight); - pIdx->azColl[n] = ALWAYS(pColl) ? pColl->zName : sqlite3StrBINARY; + pIdx->azColl[n] = pColl ? pColl->zName : sqlite3StrBINARY; n++; } } From 2e51716b1520fc6e681e9578d681e2e60ae6590f Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Aug 2019 02:09:47 +0000 Subject: [PATCH 061/112] Increase the size of the yy_lookahead table so that it is never necessary to down bounds checking on the index. FossilOrigin-Name: bafd872398e58766e996963372c7acc03a1e20a6d39a3867ca45d3ea0ed2ac1d --- manifest | 20 +++++++++++--------- manifest.uuid | 2 +- tool/lemon.c | 19 ++++++++++++++++++- tool/lempar.c | 6 ++++-- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index e3c0e4ca6c..2e8403bc0f 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\ssupport\sfor\s"ORDER\sBY\s...\sNULLS\sFIRST"\sand\s"ORDER\sBY\s...\sNULLS\sLAST".\sUse\sthis\sto\sfix\sticket\s[f8a7060e]. -D 2019-08-27T19:59:21.714 +C Increase\sthe\ssize\sof\sthe\syy_lookahead\stable\sso\sthat\sit\sis\snever\snecessary\sto\ndown\sbounds\schecking\son\sthe\sindex. +D 2019-08-28T02:09:47.441 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1756,8 +1756,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c cc43148d2793ab93668e74a6a6319bb71c2e65c1ffcd6deeaa59e12be9362a43 -F tool/lempar.c 4b868d0a5eb9a67cd1b546274227c0d449dad073c663b331b686fa2253e1c86f +F tool/lemon.c 3b40d248784ada53b1210fb389ebfc149f3043eebcfbe477646430137071798b +F tool/lempar.c be669a41410f127485e7d52b0c50f5b449c745aa23e06940b9d1a9c9eda58633 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1837,8 +1837,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 336235db2b1167cdb2feb64b47eb6368c97c43ee9641b7bfccc5775a41dd0d0e ad816d01d4bd3908ff2c574d79d1a29b6d732df308f2f1b1cdf7c0bc7c1bd7cf -R 5139358becb963924affc3638fcd0d5e -T +closed ad816d01d4bd3908ff2c574d79d1a29b6d732df308f2f1b1cdf7c0bc7c1bd7cf -U dan -Z 534b1b1d3945585b80108a8c2d91a394 +P 94085fb3e756bc984237b74b6e29c68462ad860870c64dcb5124feaeec387660 +R 622629c7f73f36222c78d3454b5494fa +T *branch * lemon-optimization +T *sym-lemon-optimization * +T -sym-trunk * +U drh +Z 2510adf038772aa7dc037a8992922686 diff --git a/manifest.uuid b/manifest.uuid index 12718058d1..24efefb261 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -94085fb3e756bc984237b74b6e29c68462ad860870c64dcb5124feaeec387660 \ No newline at end of file +bafd872398e58766e996963372c7acc03a1e20a6d39a3867ca45d3ea0ed2ac1d \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 4416f67bb2..3daa6d38cf 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -4153,6 +4153,7 @@ void ReportTable( struct rule *rp; struct acttab *pActtab; int i, j, n, sz; + int nLookAhead; int szActionType; /* sizeof(YYACTIONTYPE) */ int szCodeType; /* sizeof(YYCODETYPE) */ const char *name; @@ -4403,13 +4404,29 @@ void ReportTable( if( la<0 ) la = lemp->nsymbol; if( j==0 ) fprintf(out," /* %5d */ ", i); fprintf(out, " %4d,", la); - if( j==9 || i==n-1 ){ + if( j==9 ){ fprintf(out, "\n"); lineno++; j = 0; }else{ j++; } } + /* Add extra entries to the end of the yy_lookahead[] table so that + ** yy_shift_ofst[]+iToken will always be a valid index into the array, + ** even for the largest possible value of yy_shift_ofst[] and iToken. */ + nLookAhead = lemp->nterminal + lemp->nactiontab; + while( interminal); + if( j==9 ){ + fprintf(out, "\n"); lineno++; + j = 0; + }else{ + j++; + } + i++; + } + if( j>0 ) fprintf(out, "\n"); lineno++; fprintf(out, "};\n"); lineno++; /* Output the yy_shift_ofst[] table */ diff --git a/tool/lempar.c b/tool/lempar.c index 1c088080d4..baf6a217df 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -521,11 +521,13 @@ static YYACTIONTYPE yy_find_shift_action( do{ i = yy_shift_ofst[stateno]; assert( i>=0 ); - /* assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); */ + assert( i<=YY_ACTTAB_COUNT ); + assert( i+YYNTOKEN<=(int)YY_NLOOKAHEAD ); assert( iLookAhead!=YYNOCODE ); assert( iLookAhead < YYNTOKEN ); i += iLookAhead; - if( i>=YY_NLOOKAHEAD || yy_lookahead[i]!=iLookAhead ){ + assert( i<(int)YY_NLOOKAHEAD ); + if( yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ if( iLookAhead Date: Wed, 28 Aug 2019 11:31:11 +0000 Subject: [PATCH 062/112] Further improvements to parser speed by enlarging lookup tables to eliminate the need to do range checking on the index prior to lookup. FossilOrigin-Name: 47d3e091ae49eb7947af5abef9b5b96b16b86d349e51fe0677795649be6db473 --- manifest | 17 +++++++---------- manifest.uuid | 2 +- tool/lemon.c | 4 +++- tool/lempar.c | 17 +++++------------ 4 files changed, 16 insertions(+), 24 deletions(-) diff --git a/manifest b/manifest index 2e8403bc0f..167921e6c3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Increase\sthe\ssize\sof\sthe\syy_lookahead\stable\sso\sthat\sit\sis\snever\snecessary\sto\ndown\sbounds\schecking\son\sthe\sindex. -D 2019-08-28T02:09:47.441 +C Further\simprovements\sto\sparser\sspeed\sby\senlarging\slookup\stables\sto\seliminate\nthe\sneed\sto\sdo\srange\schecking\son\sthe\sindex\sprior\sto\slookup. +D 2019-08-28T11:31:11.959 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1756,8 +1756,8 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c 3b40d248784ada53b1210fb389ebfc149f3043eebcfbe477646430137071798b -F tool/lempar.c be669a41410f127485e7d52b0c50f5b449c745aa23e06940b9d1a9c9eda58633 +F tool/lemon.c c9848ef9694689d244a5097238ca1f83df85cc52c80ad149a4cf49595a0ee9c2 +F tool/lempar.c 5d1b20f2e9d7d6e3e1f5e1c11dba455c798bf0097634f5aef7c68a1ae7bc7d86 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1837,10 +1837,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 94085fb3e756bc984237b74b6e29c68462ad860870c64dcb5124feaeec387660 -R 622629c7f73f36222c78d3454b5494fa -T *branch * lemon-optimization -T *sym-lemon-optimization * -T -sym-trunk * +P bafd872398e58766e996963372c7acc03a1e20a6d39a3867ca45d3ea0ed2ac1d +R 958bf9b2f74079dc6a59cf74943d64b1 U drh -Z 2510adf038772aa7dc037a8992922686 +Z 3fa2b314bcffff2187af5dcc971ba8ee diff --git a/manifest.uuid b/manifest.uuid index 24efefb261..2c14daf263 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -bafd872398e58766e996963372c7acc03a1e20a6d39a3867ca45d3ea0ed2ac1d \ No newline at end of file +47d3e091ae49eb7947af5abef9b5b96b16b86d349e51fe0677795649be6db473 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 3daa6d38cf..893e1d18b9 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -4506,7 +4506,9 @@ void ReportTable( */ if( lemp->has_fallback ){ int mx = lemp->nterminal - 1; - while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } + /* 2019-08-28: Generate fallback entries for every token to avoid + ** having to do a range check on the index */ + /* while( mx>0 && lemp->symbols[mx]->fallback==0 ){ mx--; } */ lemp->tablesize += (mx+1)*szCodeType; for(i=0; i<=mx; i++){ struct symbol *p = lemp->symbols[i]; diff --git a/tool/lempar.c b/tool/lempar.c index baf6a217df..9d5b19f465 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -530,8 +530,9 @@ static YYACTIONTYPE yy_find_shift_action( if( yy_lookahead[i]!=iLookAhead ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ - if( iLookAhead %s\n", @@ -546,16 +547,8 @@ static YYACTIONTYPE yy_find_shift_action( #ifdef YYWILDCARD { int j = i - iLookAhead + YYWILDCARD; - if( -#if YY_SHIFT_MIN+YYWILDCARD<0 - j>=0 && -#endif -#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT - j0 - ){ + assert( j<(int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0])) ); + if( yy_lookahead[j]==YYWILDCARD && iLookAhead>0 ){ #ifndef NDEBUG if( yyTraceFILE ){ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n", From 6ee3fa87fd7ca53713cffb9ff662a61f797b760d Mon Sep 17 00:00:00 2001 From: drh Date: Wed, 28 Aug 2019 11:49:45 +0000 Subject: [PATCH 063/112] Fix an unreachable branch in sqlite3ParserFallback() FossilOrigin-Name: e059178b47109caee2c2211b2db6e594c014af636677118a64e10edf01ac017d --- manifest | 12 ++++++------ manifest.uuid | 2 +- tool/lempar.c | 5 ++--- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 167921e6c3..23b6a28b23 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Further\simprovements\sto\sparser\sspeed\sby\senlarging\slookup\stables\sto\seliminate\nthe\sneed\sto\sdo\srange\schecking\son\sthe\sindex\sprior\sto\slookup. -D 2019-08-28T11:31:11.959 +C Fix\san\sunreachable\sbranch\sin\ssqlite3ParserFallback() +D 2019-08-28T11:49:45.616 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1757,7 +1757,7 @@ F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f F tool/lemon.c c9848ef9694689d244a5097238ca1f83df85cc52c80ad149a4cf49595a0ee9c2 -F tool/lempar.c 5d1b20f2e9d7d6e3e1f5e1c11dba455c798bf0097634f5aef7c68a1ae7bc7d86 +F tool/lempar.c eb2841e2a7fd484cf44b1f526b06e7ab0f216d2f41818bf9485e8f38e3d1db19 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c 11346aa019e2e77a00902aa7d0cabd27bd2e8cca @@ -1837,7 +1837,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 bafd872398e58766e996963372c7acc03a1e20a6d39a3867ca45d3ea0ed2ac1d -R 958bf9b2f74079dc6a59cf74943d64b1 +P 47d3e091ae49eb7947af5abef9b5b96b16b86d349e51fe0677795649be6db473 +R eed84f5af5dd0a6ce743afeb00c4b4e4 U drh -Z 3fa2b314bcffff2187af5dcc971ba8ee +Z 0c74ffec3ce3109c0e0f66d709525f70 diff --git a/manifest.uuid b/manifest.uuid index 2c14daf263..1d045fd59e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47d3e091ae49eb7947af5abef9b5b96b16b86d349e51fe0677795649be6db473 \ No newline at end of file +e059178b47109caee2c2211b2db6e594c014af636677118a64e10edf01ac017d \ No newline at end of file diff --git a/tool/lempar.c b/tool/lempar.c index 9d5b19f465..f75ad51c39 100644 --- a/tool/lempar.c +++ b/tool/lempar.c @@ -1064,9 +1064,8 @@ void Parse( */ int ParseFallback(int iToken){ #ifdef YYFALLBACK - if( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ){ - return yyFallback[iToken]; - } + assert( iToken<(int)(sizeof(yyFallback)/sizeof(yyFallback[0])) ); + return yyFallback[iToken]; #else (void)iToken; #endif From 50b3ea2daf855d61d3a56562d3e2bfc843e06823 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Aug 2019 14:25:44 +0000 Subject: [PATCH 064/112] Fix a potential buffer overrun in fts5 caused by corrupted database records. FossilOrigin-Name: c465d0eb478e42045e08efe8b6fa64d4bd4d747cdf743beae4608562b014169e --- ext/fts5/fts5_index.c | 6 + ext/fts5/test/fts5corrupt3.test | 211 +++++++++++++++++++++++++++++++- manifest | 17 ++- manifest.uuid | 2 +- 4 files changed, 222 insertions(+), 14 deletions(-) diff --git a/ext/fts5/fts5_index.c b/ext/fts5/fts5_index.c index 3fa97c2fea..c0f7ac551a 100644 --- a/ext/fts5/fts5_index.c +++ b/ext/fts5/fts5_index.c @@ -5050,6 +5050,12 @@ static void fts5MergePrefixLists( } /* WRITEPOSLISTSIZE */ + assert_nc( tmp.n<=i1.nPoslist+i2.nPoslist ); + assert( tmp.n<=i1.nPoslist+i2.nPoslist+10+10 ); + if( tmp.n>i1.nPoslist+i2.nPoslist ){ + if( p->rc==SQLITE_OK ) p->rc = FTS5_CORRUPT; + break; + } fts5BufferSafeAppendVarint(&out, tmp.n * 2); fts5BufferSafeAppendBlob(&out, tmp.p, tmp.n); fts5DoclistIterNext(&i1); diff --git a/ext/fts5/test/fts5corrupt3.test b/ext/fts5/test/fts5corrupt3.test index 306ae9fe03..a7da137b11 100644 --- a/ext/fts5/test/fts5corrupt3.test +++ b/ext/fts5/test/fts5corrupt3.test @@ -6908,7 +6908,7 @@ do_catchsql_test 50.1 { #------------------------------------------------------------------------- reset_db -do_execsql_test 51.1 { +do_execsql_test 51.0 { BEGIN TRANSACTION; PRAGMA writable_schema=ON; CREATE VIRTUAL TABLE t1 USING fts5(a,b,c); @@ -6976,7 +6976,7 @@ COMMIT; do_catchsql_test 51.1 { SELECT max(rowid)==0 FROM t1('e*'); -} {0 0} +} {1 {database disk image is malformed}} #-------------------------------------------------------------------------- reset_db @@ -8544,7 +8544,7 @@ do_test 59.0 { do_catchsql_test 59.1 { SELECT (matchinfo(591,t1)) FROM t1 WHERE t1 MATCH 'e*eŸ' -} {0 {}} +} {1 {database disk image is malformed}} #------------------------------------------------------------------------- do_test 60.0 { @@ -8750,7 +8750,7 @@ do_test 60.0 { do_catchsql_test 60.2 { SELECT (matchinfo(t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ' -} {0 {}} +} {1 {database disk image is malformed}} #------------------------------------------------------------------------- do_test 61.0 { @@ -9491,6 +9491,209 @@ do_catchsql_test 64.1 { SELECT * FROM ttt('e*'); } {1 {database disk image is malformed}} +#--------------------------------------------------------------------------- +do_test 65.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 28672 pagesize 4096 filename crash-3aef66940ace0c.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00 .....@ ........ +| 96: 00 00 00 00 0d 0f c7 00 07 0d 92 00 0f 8d 0f 36 ...............6 +| 112: 0e cb 0e 6b 0e 0e 0d b6 0d 92 00 00 00 00 00 00 ...k............ +| 3472: 00 00 22 08 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3488: 32 74 32 08 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3504: 20 74 32 28 78 29 56 07 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3520: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3536: 6f 6e 66 69 67 07 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3552: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3568: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3584: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 06 WITHOUT ROWID[. +| 3600: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3616: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3632: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3648: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3664: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3680: 59 2c 20 73 7a 20 42 4c 4f 42 29 5e 05 07 17 21 Y, sz BLOB)^...! +| 3696: 21 01 81 07 74 61 62 6c 65 74 31 5f 63 6f 6e 74 !...tablet1_cont +| 3712: 65 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 05 43 52 entt1_content.CR +| 3728: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 EATE TABLE 't1_c +| 3744: 6f 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 ontent'(id INTEG +| 3760: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 ER PRIMARY KEY, +| 3776: 63 30 2c 20 63 31 2c d6 63 32 29 69 04 07 17 19 c0, c1,.c2)i.... +| 3792: 19 01 81 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 ...-tablet1_idxt +| 3808: 31 5f 69 64 78 04 43 52 45 41 54 45 20 54 41 42 1_idx.CREATE TAB +| 3824: 4c 45 20 27 74 31 5f 69 64 78 27 28 73 65 67 69 LE 't1_idx'(segi +| 3840: 64 2c 20 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 d, term, pgno, P +| 3856: 52 49 4d 41 52 59 20 4b 45 59 28 73 65 67 69 64 RIMARY KEY(segid +| 3872: 2c 20 74 65 72 6d 29 29 20 57 49 54 48 4f 55 54 , term)) WITHOUT +| 3888: 20 52 4f 57 49 44 55 03 07 17 1b 1b 01 81 01 74 ROWIDU........t +| 3904: 61 62 6c 65 74 31 5f 64 61 74 61 74 31 5f 64 61 ablet1_datat1_da +| 3920: 74 61 03 43 52 45 41 54 45 20 54 41 42 4c 45 20 ta.CREATE TABLE +| 3936: 27 74 31 5f 64 61 74 61 27 28 69 64 20 49 4e 54 't1_data'(id INT +| 3952: 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 EGER PRIMARY KEY +| 3968: 2c 20 62 6c 6f 63 6b 20 42 4c 4f 42 29 38 02 06 , block BLOB)8.. +| 3984: 17 11 11 08 5f 74 61 62 6c 65 74 31 74 31 43 52 ...._tablet1t1CR +| 4000: 45 41 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 EATE VIRTUAL TAB +| 4016: 4c 45 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 LE t1 USING fts5 +| 4032: 28 61 2c 62 2c 63 29 00 00 00 00 00 00 00 00 00 (a,b,c)......... +| page 3 offset 8192 +| 0: 0d 00 00 00 03 0c 93 ff 0f e6 0f ef 0c 94 00 00 ................ +| 3216: 00 00 00 00 86 4a 84 80 80 80 80 01 04 00 8d 18 .....J.......... +| 3232: 00 00 03 2b 02 30 30 01 02 06 01 02 06 01 02 06 ...+.00......... +| 3248: 1f 02 03 01 02 03 01 02 03 01 08 32 31 31 36 30 ...........21160 +| 3264: 36 30 39 01 02 07 01 02 07 01 02 07 01 01 33 f1 609...........3. +| 3280: 02 05 01 02 05 01 02 05 01 01 35 01 02 03 01 02 ..........5..... +| 3296: 04 01 02 04 02 07 30 30 30 30 30 30 30 1c 02 3d ......0000000..= +| 3312: 01 02 04 01 02 04 01 06 62 69 6e 61 72 79 03 06 ........binary.. +| 3328: 01 02 02 03 06 01 01 f2 03 06 4e 02 02 03 06 01 ..........N..... +| 3344: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3360: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3376: 03 06 01 02 02 03 06 01 02 02 01 08 63 6f 6d 70 ............comp +| 3392: 69 6c 65 72 01 02 02 01 02 02 01 02 02 01 06 64 iler...........d +| 3408: 62 73 74 61 74 07 02 03 01 02 13 01 02 03 02 04 bstat........... +| 3424: 65 62 75 67 04 02 02 01 02 02 01 02 02 01 07 65 ebug...........e +| 3440: 6e 61 62 6c 65 07 02 02 01 02 02 01 02 02 01 02 nable........... +| 3456: 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 02 ................ +| 3472: 01 02 02 01 02 01 f1 02 02 01 02 02 01 02 02 01 ................ +| 3488: 02 02 01 02 02 01 02 02 01 02 02 01 02 02 01 02 ................ +| 3504: 02 01 02 02 02 08 76 b4 65 6e 73 69 6f 6e 1f 02 ......v.ension.. +| 3520: 04 01 02 04 01 02 04 01 04 66 74 73 34 0a 02 03 .........fts4... +| 3536: 01 02 03 01 02 03 04 01 25 0d 02 03 01 02 03 01 ........%....... +| 3552: 02 03 01 03 67 63 63 01 02 03 01 02 03 01 02 03 ....gcc......... +| 3568: 02 06 65 6f 70 6f 6c 79 0f f2 03 01 02 03 01 02 ..eopoly........ +| 3584: 03 01 05 6a 73 6f 6e 31 13 02 03 01 02 03 01 02 ...json1........ +| 3600: 03 01 04 6c 6f 61 64 1f 02 03 01 02 03 01 02 03 ...load......... +| 3616: 00 03 6d 61 78 1c 02 0c 01 02 02 01 02 02 02 05 ..max........... +| 3632: 65 6d 6f 72 79 1c 02 03 01 02 03 01 02 03 04 04 emory........... +| 3648: 73 79 73 35 16 02 03 01 02 03 01 02 03 01 06 6e sys5...........n +| 3664: 6f 63 61 73 65 02 06 01 02 02 13 06 00 f2 02 03 ocase........... +| 3680: 06 01 12 02 13 06 01 02 02 03 06 01 02 02 03 06 ................ +| 3696: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3712: 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 ................ +| 3728: 02 01 04 6f 6d 69 74 1f 02 02 01 02 02 01 02 02 ...omit......... +| 3744: 01 05 72 74 72 65 65 19 02 03 01 02 03 01 02 03 ..rtree......... +| 3760: 04 02 69 6d 01 06 01 02 02 03 06 01 02 02 03 06 ..im............ +| 3776: 01 02 02 03 06 01 02 02 03 06 01 02 02 03 06 01 ................ +| 3792: 02 02 03 06 01 02 02 03 06 01 02 02 8e 06 01 02 ................ +| 3808: 02 03 06 01 02 02 03 06 01 02 02 03 06 01 02 02 ................ +| 3824: 01 0a 74 68 72 65 61 64 73 61 66 65 22 02 02 01 ..threadsafe.... +| 3840: 02 02 01 02 02 01 04 76 74 61 62 07 02 04 01 02 .......vtab..... +| 3856: 04 01 02 04 01 01 78 01 06 01 01 02 01 06 01 01 ......x......... +| 3872: 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 ................ +| 3888: 01 06 01 11 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3904: 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 3920: 01 01 02 01 06 01 01 01 01 06 01 01 02 01 06 01 ................ +| 3936: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 3952: 02 01 06 01 01 01 f1 06 01 01 02 ad 06 01 01 02 ................ +| 3968: 01 06 01 01 02 01 06 01 01 02 01 06 01 01 02 01 ................ +| 3984: 06 01 01 01 01 06 01 01 02 01 06 01 01 02 01 06 ................ +| 4000: 01 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 ................ +| 4016: 01 02 01 06 01 01 02 01 06 01 01 02 01 06 01 01 ................ +| 4032: 02 01 06 01 01 02 01 06 01 01 02 04 15 13 0c 0c ................ +| 4048: 12 44 13 11 0f 47 13 0e fc 0e 11 10 0f 0e 10 0f .D...G.......... +| 4064: 44 0f 10 40 15 0f 07 01 03 00 14 24 5a 24 24 0f D..@.......$Z$$. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 01 ...$............ +| page 4 offset 12288 +| 0: 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 5 offset 16384 +| 0: 0d 00 00 00 24 0c 0a 00 00 00 00 00 00 00 00 00 ....$........... +| 3072: 00 00 00 00 00 00 00 00 00 00 18 24 05 00 25 0f ...........$..%. +| 3088: 19 54 48 52 45 41 44 53 41 46 45 3d 30 58 42 49 .THREADSAFE=0XBI +| 3104: 4e 41 52 59 18 23 05 00 25 0f 19 54 48 52 45 41 NARY.#..%..THREA +| 3120: 44 53 41 46 45 3d 30 58 4e 4f 43 41 53 45 17 8f DSAFE=0XNOCASE.. +| 3136: 05 00 25 0f 17 54 48 52 45 41 44 43 41 46 45 3d ..%..THREADCAFE= +| 3152: 30 58 52 54 52 49 4d 1f 21 05 00 33 0f 19 4f 4d 0XRTRIM.!..3..OM +| 3168: 49 54 20 4b 4f 41 44 21 45 58 54 45 4e 53 49 4f IT KOAD!EXTENSIO +| 3184: 4e 58 42 49 4e 41 52 59 1f 20 05 00 33 0f 19 4f NXBINARY. ..3..O +| 3200: 4d 49 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 49 MIT LOAD EXTENSI +| 3216: 4f 4e 58 4e 4f 43 41 53 45 1e 1f 05 00 33 0f 17 ONXNOCASE....3.. +| 3232: 4f 4d 59 54 20 4c 4f 41 44 20 45 58 54 45 4e 53 OMYT LOAD EXTENS +| 3248: 49 4f 4e 58 52 54 56 a9 4d 1f 1e 05 00 33 0f 19 IONXRTV.M....3.. +| 3264: 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 30 MAX MEMORY=50000 +| 3280: 30 30 30 57 42 49 4e 31 52 59 1f 1d 05 00 33 0f 000WBIN1RY....3. +| 3296: 19 4d 41 58 20 4d 45 4d 4f 52 59 3d 35 30 30 30 .MAX MEMORY=5000 +| 3312: 30 30 30 30 58 4e 4f 43 41 53 45 1e 1c 05 00 32 0000XNOCASE....2 +| 3328: 0f 17 4e 41 58 20 4d 45 4d 4f 52 59 2d 35 30 30 ..NAX MEMORY-500 +| 3344: 30 30 30 30 30 58 52 54 52 49 4d 18 1b 05 00 25 00000XRTRIM....% +| 3360: 0f 19 45 4e 41 42 4c 45 20 52 54 52 45 45 58 42 ..ENABLE RTREEXB +| 3376: 49 4e 41 52 59 18 1a 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3392: 4c 45 20 52 54 52 45 45 59 4e 4f 43 41 53 45 17 LE RTREEYNOCASE. +| 3408: 19 66 00 25 0f 17 45 4e 41 42 4c 45 20 52 54 52 .f.%..ENABLE RTR +| 3424: 45 45 58 52 54 52 49 4d 1a 18 05 00 29 0f 19 45 EEXRTRIM....)..E +| 3440: 4e 41 42 4c 45 20 4d 45 4d 53 59 53 35 58 42 49 NABLE MEMSYS5XBI +| 3456: 4e 41 52 59 1a 17 05 00 29 0f 19 45 4e 41 42 4c NARY....)..ENABL +| 3472: 45 20 4d 45 4d 53 59 53 35 58 4e 4f 43 41 53 45 E MEMSYS5XNOCASE +| 3488: 19 16 05 00 29 0f 17 45 4e 41 42 4c 45 20 4d 45 ....)..ENABLE ME +| 3504: 4d 53 59 53 35 58 52 54 52 49 4d 18 15 05 10 25 MSYS5XRTRIM....% +| 3520: 0f 19 45 4e 40 42 4c 45 20 4a 53 4f 4e 31 58 42 ..EN@BLE JSON1XB +| 3536: 49 4e 41 52 59 18 14 05 00 25 0f 19 45 4e 41 42 INARY....%..ENAB +| 3552: 4c 45 20 4a 53 4f 4e 32 58 4e 4f 43 41 53 45 17 LE JSON2XNOCASE. +| 3568: 13 05 00 25 0f 17 45 4d 41 42 4c 45 20 4a 53 4f ...%..EMABLE JSO +| 3584: 4e 31 58 52 54 52 49 4d 1a 12 05 00 29 0f 19 45 N1XRTRIM....)..E +| 3600: 4e 41 42 4c 45 20 47 45 4f 50 4f 4c 59 58 42 49 NABLE GEOPOLYXBI +| 3616: 4e 41 52 59 1a 11 05 00 29 0f 19 45 4f 81 42 4c NARY....)..EO.BL +| 3632: 45 20 47 45 4f 50 4f 4c 59 58 4e 4f 43 51 53 45 E GEOPOLYXNOCQSE +| 3648: 19 10 05 00 29 0f 17 45 4e 41 42 4c 45 20 47 45 ....)..ENABLE GE +| 3664: 4f 50 4f 4c 59 58 52 54 52 49 4d 17 0f 05 00 23 OPOLYXRTRIM....# +| 3680: 0f 1a 45 4e 41 42 4c 45 20 46 54 53 35 58 42 49 ..ENABLE FTS5XBI +| 3696: 4e 41 52 59 17 0e 05 00 23 0f 19 45 4e 41 42 4c NARY....#..ENABL +| 3712: 45 20 46 54 53 35 48 4e 4f 43 41 53 45 16 1d 05 E FTS5HNOCASE... +| 3728: 00 23 0f a4 45 4e 41 42 4c 45 20 46 54 53 35 58 .#..ENABLE FTS5X +| 3744: 52 54 52 49 4d 17 0c 05 00 23 0f 19 45 4e 41 42 RTRIM....#..ENAB +| 3760: 4c 45 20 46 55 53 34 58 42 49 4e 41 52 59 17 0b LE FUS4XBINARY.. +| 3776: 05 00 23 0f 19 45 4e 41 42 4c 45 20 46 54 53 34 ..#..ENABLE FTS4 +| 3792: 57 4e 4f 43 41 53 45 16 0a 05 00 23 0f 17 45 4e WNOCASE....#..EN +| 3808: 41 42 4c 45 20 46 54 53 34 05 52 54 52 49 4d 1e ABLE FTS4.RTRIM. +| 3824: 09 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3840: 54 41 54 20 56 54 41 42 58 42 49 4e 41 52 59 1e TAT VTABXBINARY. +| 3856: 08 05 00 31 0f 19 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3872: 54 41 54 20 56 54 41 42 58 4e 4f 43 41 53 45 1d TAT VTABXNOCASE. +| 3888: 07 05 00 31 0f 17 45 4e 41 42 4c 45 20 44 42 53 ...1..ENABLE DBS +| 3904: 54 41 54 20 56 54 41 42 58 52 54 52 49 4d 11 06 TAT VTABXRTRIM.. +| 3920: 05 00 17 0f 19 44 45 42 55 47 58 42 8a 4e 41 52 .....DEBUGXB.NAR +| 3936: 59 11 05 05 00 17 0f 19 44 45 42 55 47 58 4e 4f Y.......DEBUGXNO +| 3952: 43 41 53 45 10 04 05 00 17 0f 17 44 45 42 55 47 CASE.......DEBUG +| 3968: 58 52 54 52 49 4d 27 03 05 00 43 0f 19 43 4f 4d XRTRIM'...C..COM +| 3984: 50 49 4c 45 52 3d 67 63 63 2d 35 2e 34 2e 30 20 PILER=gcc-5.4.0 +| 4000: 32 30 31 36 30 36 30 39 58 42 49 4e 41 52 59 27 20160609XBINARY' +| 4016: 02 05 00 43 0f 19 43 4f 4d 50 49 4c 45 52 3f 87 ...C..COMPILER?. +| 4032: 63 63 2d 35 2e 34 2e 30 20 32 30 31 36 30 36 30 cc-5.4.0 2016060 +| 4048: 39 58 4e 4f 43 41 53 45 26 01 05 00 43 0f 17 43 9XNOCASE&...C..C +| 4064: 45 0d 60 59 4c 45 52 3d 67 63 63 2d 35 2e 34 2d E.`YLER=gcc-5.4- +| 4080: 30 20 32 30 31 36 30 36 30 39 00 00 00 00 00 00 0 20160609...... +| page 6 offset 20480 +| 3808: 06 24 03 00 12 02 01 01 06 23 03 00 12 02 01 01 .$.......#...... +| 3824: 06 22 03 01 12 02 01 01 06 21 03 00 12 03 01 01 .........!...... +| 3840: 06 20 03 00 12 03 01 01 06 1f 03 00 12 03 02 01 . .............. +| 3856: 06 1e 03 00 12 03 01 01 06 1d 03 00 12 03 01 01 ................ +| 3872: 06 1c 03 00 12 03 01 01 06 1b 03 00 12 02 01 01 ................ +| 3888: 06 1a 03 00 12 02 01 01 06 19 03 00 12 02 01 01 ................ +| 3904: 06 18 03 00 12 02 01 01 06 17 03 00 12 02 01 01 ................ +| 3920: 06 16 03 00 12 02 01 01 06 15 03 00 12 02 01 01 ................ +| 3936: 06 14 03 00 12 02 01 01 06 13 03 00 12 02 01 01 ................ +| 3952: 06 12 03 00 12 02 01 01 06 11 03 00 12 02 01 01 ................ +| 3968: 06 00 03 00 12 02 01 01 06 0f 03 00 12 02 01 01 ................ +| 3984: 06 0e 03 00 12 02 01 01 06 0d 03 00 12 02 01 01 ................ +| 4000: 06 0c 03 00 12 02 01 01 06 0b 03 00 12 02 01 01 ................ +| 4016: 06 0a 03 00 12 02 01 01 06 09 03 00 12 03 01 01 ................ +| 4032: 06 08 03 00 12 03 01 01 06 07 03 00 12 03 01 01 ................ +| 4048: 06 06 03 00 12 01 01 01 06 05 03 00 12 01 01 01 ................ +| 4064: 06 04 03 00 12 01 01 01 06 03 03 00 12 06 01 01 ................ +| 4080: 06 02 03 00 12 06 01 01 06 01 03 00 12 06 01 01 ................ +| page 7 offset 24576 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| end crash-3aef66940ace0c.db +}]} {} + +do_catchsql_test 65.1 { + SELECT ( MATCH (t1,591)) FROM t1 WHERE t1 MATCH 'e*eŸ' +} {1 {database disk image is malformed}} + + sqlite3_fts5_may_be_corrupt 0 finish_test diff --git a/manifest b/manifest index af8d219242..1294681dce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\sLemon\sso\sthat\sit\senlarges\ssome\sof\sits\stables\sslightly\sin\sorder\sto\navoid\shaving\sto\sindex\srange\schecks\son\stable\slookups\sfor\sa\sperformance\nincrease. -D 2019-08-29T00:27:12.377 +C Fix\sa\spotential\sbuffer\soverrun\sin\sfts5\scaused\sby\scorrupted\sdatabase\srecords. +D 2019-08-29T14:25:44.718 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -116,7 +116,7 @@ F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6 F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7 F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 -F ext/fts5/fts5_index.c ada7661078752941e1d83bd42fe5aedef3350a1ccb9076c98153090ccd1d2f0d +F ext/fts5/fts5_index.c b062bdb836e195656aac8d6684e943585cff4bf7d7c593c80cb67c3b6cfef7ee F ext/fts5/fts5_main.c b2c42f1cef9673ecdd498b22c38483a4380bcf1701d1e61b021a2945f18e42e1 F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 @@ -157,7 +157,7 @@ F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c0 F ext/fts5/test/fts5content.test 9517cc527a8e8a33949652d5c7b5e251f8c3d5ae3f23f01d4320e30f29a0336b F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f -F ext/fts5/test/fts5corrupt3.test 1e0a557a2c33d26a516d8ae57685a77001e9887a7457abcea6be1c4ac77332e8 +F ext/fts5/test/fts5corrupt3.test f326d70e08acffcbd8a551edd72b5723db7d3a902d288d958014c81a111cae21 F ext/fts5/test/fts5corrupt4.test ea805c4d7c68b5f185b9db5d2060a7ae5875339738dd48203c92162f41e7ca91 F ext/fts5/test/fts5delete.test cbf87e3b8867c4d5cfcaed975c7475fd3f99d072bce2075fcedf43d1f82af775 F ext/fts5/test/fts5detail.test 31b240dbf6d44ac3507e2f8b65f29fdc12465ffd531212378c7ce1066766f54e @@ -1837,8 +1837,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 94085fb3e756bc984237b74b6e29c68462ad860870c64dcb5124feaeec387660 e059178b47109caee2c2211b2db6e594c014af636677118a64e10edf01ac017d -R eed84f5af5dd0a6ce743afeb00c4b4e4 -T +closed e059178b47109caee2c2211b2db6e594c014af636677118a64e10edf01ac017d -U drh -Z adf3ddab2b496435d84f7dc30e6d3ae7 +P 4be6a23a188bd1fea445283d6dcc2f5c3470c28852dc4895d63117ad0c773fcf +R 12af26efe518d88efce12e7278408573 +U dan +Z dfc696063c3b6a7085f401f76e6517be diff --git a/manifest.uuid b/manifest.uuid index cd30b15e13..06e243d03c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4be6a23a188bd1fea445283d6dcc2f5c3470c28852dc4895d63117ad0c773fcf \ No newline at end of file +c465d0eb478e42045e08efe8b6fa64d4bd4d747cdf743beae4608562b014169e \ No newline at end of file From 1cd382e3500588126a91692377254bb807276d83 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Aug 2019 15:06:35 +0000 Subject: [PATCH 065/112] Avoid assuming that for "~ (? OR TRUE)" to be true, "?" must not be NULL, just as we do for "NOT (? OR TRUE)". Fix for ticket [c0390363]. FossilOrigin-Name: 84ae41fd2f50cb7c0c3f6522d0f94817e1bbf96eae5316279e3e32cee4e46e91 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- test/indexexpr2.test | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 1294681dce..ac91ec3f1e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\sbuffer\soverrun\sin\sfts5\scaused\sby\scorrupted\sdatabase\srecords. -D 2019-08-29T14:25:44.718 +C Avoid\sassuming\sthat\sfor\s"~\s(?\sOR\sTRUE)"\sto\sbe\strue,\s"?"\smust\snot\sbe\sNULL,\sjust\sas\swe\sdo\sfor\s"NOT\s(?\sOR\sTRUE)".\sFix\sfor\sticket\s[c0390363]. +D 2019-08-29T15:06:35.023 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 0f3aaaac5c1bd6a34fece3308ad572ef846c1601c58957902dc2a36f75373364 +F src/expr.c 33c1d88c98968fb6407d73da056af50dbc6045fcbf2641e99edb8974f0e19adc F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1053,7 +1053,7 @@ F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e F test/indexexpr1.test 0f293369ed6f56764cfc3db05685d45469d9e685ba87e3698527049ba359ae24 -F test/indexexpr2.test d319e7d1b1043403f39a20c892d512e02b5549c6004806b977030f2430c60208 +F test/indexexpr2.test efffd39a278d8d9e8c5e9f82ef23178970951df9d725e4aea6d304bf81be6678 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 72004f6a900a25bd3f1ce9a72e73d02749644666a8ce6d6d2dba061137e5aa63 @@ -1837,7 +1837,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 4be6a23a188bd1fea445283d6dcc2f5c3470c28852dc4895d63117ad0c773fcf -R 12af26efe518d88efce12e7278408573 +P c465d0eb478e42045e08efe8b6fa64d4bd4d747cdf743beae4608562b014169e +R b17ceb5c6a3471208662929e8aee416b U dan -Z dfc696063c3b6a7085f401f76e6517be +Z 68262acbccebad319b476c344a9d0307 diff --git a/manifest.uuid b/manifest.uuid index 06e243d03c..1d7a1cb2a2 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c465d0eb478e42045e08efe8b6fa64d4bd4d747cdf743beae4608562b014169e \ No newline at end of file +84ae41fd2f50cb7c0c3f6522d0f94817e1bbf96eae5316279e3e32cee4e46e91 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 365f60665f..d83e18eb26 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5027,7 +5027,6 @@ static int exprImpliesNotNull( } case TK_SPAN: case TK_COLLATE: - case TK_BITNOT: case TK_UPLUS: case TK_UMINUS: { return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); @@ -5037,6 +5036,7 @@ static int exprImpliesNotNull( if( p->op2!=TK_IS ) return 0; return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); } + case TK_BITNOT: case TK_NOT: { return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } diff --git a/test/indexexpr2.test b/test/indexexpr2.test index a3a685fb3d..589a0589ab 100644 --- a/test/indexexpr2.test +++ b/test/indexexpr2.test @@ -295,6 +295,23 @@ do_execsql_test 7.3 { REINDEX; } {} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 8.0 { + CREATE TABLE t0(c0); + CREATE INDEX i0 ON t0(c0) WHERE c0 NOT NULL; + INSERT INTO t0(c0) VALUES (NULL); +} + +breakpoint +do_execsql_test 8.1 { + SELECT * FROM t0 WHERE ~('' BETWEEN t0.c0 AND TRUE); +} {{}} + +do_execsql_test 8.2 { + SELECT ~('' BETWEEN t0.c0 AND TRUE) FROM t0; +} {-1} + finish_test From b6a9121bb383f37c78b8d8d99e6f1d8dd3b6b4e3 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Aug 2019 15:50:16 +0000 Subject: [PATCH 066/112] Fix another case where SQLite assumes that if "~(? AND FALSE)" is true, "?" must be non-null. FossilOrigin-Name: 616f5663b3dbd0929128c0990fc6d8bba1513c7ae196b87c450ac0b3b3203ecd --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 1 + test/join.test | 7 ++++++- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index ac91ec3f1e..7ed3408640 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Avoid\sassuming\sthat\sfor\s"~\s(?\sOR\sTRUE)"\sto\sbe\strue,\s"?"\smust\snot\sbe\sNULL,\sjust\sas\swe\sdo\sfor\s"NOT\s(?\sOR\sTRUE)".\sFix\sfor\sticket\s[c0390363]. -D 2019-08-29T15:06:35.023 +C Fix\sanother\scase\swhere\sSQLite\sassumes\sthat\sif\s"~(?\sAND\sFALSE)"\sis\strue,\s"?"\smust\sbe\snon-null. +D 2019-08-29T15:50:16.698 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 33c1d88c98968fb6407d73da056af50dbc6045fcbf2641e99edb8974f0e19adc +F src/expr.c c54fcc18ff7a9206524c44a3ebfaffcf71bae1fda063bdf254cfe2d4820ee71e F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1077,7 +1077,7 @@ F test/ioerr4.test f130fe9e71008577b342b8874d52984bd04ede2c F test/ioerr5.test 2edfa4fb0f896f733071303b42224df8bedd9da4 F test/ioerr6.test a395a6ab144b26a9e3e21059a1ab6a7149cca65b F test/istrue.test 75327829744e65cc8700e69340b8e6c192e10e39dfae7ccb0e970d3c4f49090a -F test/join.test f505c78a793b0c807d534c1cacf71c7bf96aa734f78d091721f2a6859077b7e8 +F test/join.test 6ce8296a08e78632c322cde0add78a7ce05466c3d9ec7d5130b38b5b489e7c27 F test/join2.test 10f7047e723ebd68b2f47189be8eed20451a6f665d8bf46f1774c640d1062417 F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 @@ -1837,7 +1837,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 c465d0eb478e42045e08efe8b6fa64d4bd4d747cdf743beae4608562b014169e -R b17ceb5c6a3471208662929e8aee416b +P 84ae41fd2f50cb7c0c3f6522d0f94817e1bbf96eae5316279e3e32cee4e46e91 +R c76b8e8761ede59ea3d32402ab062564 U dan -Z 68262acbccebad319b476c344a9d0307 +Z abbce93de6b15f66332b49534306a771 diff --git a/manifest.uuid b/manifest.uuid index 1d7a1cb2a2..84eab99b18 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -84ae41fd2f50cb7c0c3f6522d0f94817e1bbf96eae5316279e3e32cee4e46e91 \ No newline at end of file +616f5663b3dbd0929128c0990fc6d8bba1513c7ae196b87c450ac0b3b3203ecd \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index d83e18eb26..80bc002d7f 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5103,6 +5103,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ switch( pExpr->op ){ case TK_ISNOT: case TK_NOT: + case TK_BITNOT: case TK_ISNULL: case TK_NOTNULL: case TK_IS: diff --git a/test/join.test b/test/join.test index 25c31705c8..f53a90c84a 100644 --- a/test/join.test +++ b/test/join.test @@ -812,11 +812,16 @@ do_execsql_test join-15.105 { FROM t1 LEFT JOIN t2 WHERE a IN (1,3,x,y); } {1 2 {} {} x 3 4 {} {} x} -do_execsql_test join-15.106 { +do_execsql_test join-15.106a { SELECT *, 'x' FROM t1 LEFT JOIN t2 WHERE NOT ( 'x'='y' AND t2.y=1 ); } {1 2 {} {} x 3 4 {} {} x} +do_execsql_test join-15.106b { + SELECT *, 'x' + FROM t1 LEFT JOIN t2 + WHERE ~ ( 'x'='y' AND t2.y=1 ); +} {1 2 {} {} x 3 4 {} {} x} do_execsql_test join-15.107 { SELECT *, 'x' FROM t1 LEFT JOIN t2 From f76ccb7d5486a2664127dec004dd52835f600a81 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Aug 2019 16:17:59 +0000 Subject: [PATCH 067/112] Remove an unreachable branch in the NULLS LAST logic of RANGE window functions. FossilOrigin-Name: 47cd634c98b502d40a493455ba6d73cbd0dae74944f9cf06fcbcd025f4b49d6e --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/window.c | 12 +++++------- 3 files changed, 13 insertions(+), 15 deletions(-) diff --git a/manifest b/manifest index 7ed3408640..516f0b90a6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sanother\scase\swhere\sSQLite\sassumes\sthat\sif\s"~(?\sAND\sFALSE)"\sis\strue,\s"?"\smust\sbe\snon-null. -D 2019-08-29T15:50:16.698 +C Remove\san\sunreachable\sbranch\sin\sthe\sNULLS\sLAST\slogic\sof\sRANGE\swindow\nfunctions. +D 2019-08-29T16:17:59.802 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,7 +613,7 @@ F src/where.c 6f8bd0b4ade152571e960504a3042a31fd80e8adcef834db0717af3fbac4acb5 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f -F src/window.c 3ea716bb0dd5ffc8cdbaa48baffc525958b51bc61b2afd73a56baccfcd7ceb2f +F src/window.c 7d74882b41db7f44300489b3513f94f3f95684725e6d8e4e8cede44f015bb4b0 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1837,7 +1837,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 84ae41fd2f50cb7c0c3f6522d0f94817e1bbf96eae5316279e3e32cee4e46e91 -R c76b8e8761ede59ea3d32402ab062564 -U dan -Z abbce93de6b15f66332b49534306a771 +P 616f5663b3dbd0929128c0990fc6d8bba1513c7ae196b87c450ac0b3b3203ecd +R 9f9103695325eba7c86630a81c46d881 +U drh +Z 7097a40260a07e3670128a93ad17b767 diff --git a/manifest.uuid b/manifest.uuid index 84eab99b18..d6076d12ea 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -616f5663b3dbd0929128c0990fc6d8bba1513c7ae196b87c450ac0b3b3203ecd \ No newline at end of file +47cd634c98b502d40a493455ba6d73cbd0dae74944f9cf06fcbcd025f4b49d6e \ No newline at end of file diff --git a/src/window.c b/src/window.c index d3603e7a1e..ac8d1080fb 100644 --- a/src/window.c +++ b/src/window.c @@ -1864,7 +1864,7 @@ static void windowIfNewPeer( */ static void windowCodeRangeTest( WindowCodeArg *p, - int op, /* OP_Ge or OP_Gt */ + int op, /* OP_Ge, OP_Gt, or OP_Le */ int csr1, int regVal, int csr2, @@ -1908,14 +1908,12 @@ static void windowCodeRangeTest( switch( op ){ case OP_Ge: sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; case OP_Gt: - sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); - VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); VdbeCoverage(v); break; - case OP_Le: - sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); - VdbeCoverage(v); + default: + assert( op==OP_Le ); + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); break; - default: assert( op==OP_Lt ); /* no-op */ } sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); sqlite3VdbeJumpHere(v, addr); From db586e48432ac81c81d454af4f5e879743dd9f7b Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Aug 2019 16:48:10 +0000 Subject: [PATCH 068/112] Add a missing VdbeCoverage() macro. FossilOrigin-Name: 33da6092d3d04b6eb6ab396b8c4f668e3529e26bf11e26f5fcb9b61fe3470197 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/where.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 516f0b90a6..a38e9488a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sunreachable\sbranch\sin\sthe\sNULLS\sLAST\slogic\sof\sRANGE\swindow\nfunctions. -D 2019-08-29T16:17:59.802 +C Add\sa\smissing\sVdbeCoverage()\smacro. +D 2019-08-29T16:48:10.044 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 6f8bd0b4ade152571e960504a3042a31fd80e8adcef834db0717af3fbac4acb5 +F src/where.c 0a573a77eff9ab22edfbac0519b2147fce414f52af838497b5eb376f1fe60ef5 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f @@ -1837,7 +1837,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 616f5663b3dbd0929128c0990fc6d8bba1513c7ae196b87c450ac0b3b3203ecd -R 9f9103695325eba7c86630a81c46d881 +P 47cd634c98b502d40a493455ba6d73cbd0dae74944f9cf06fcbcd025f4b49d6e +R 82040bfc52a0536ad402b4608c120103 U drh -Z 7097a40260a07e3670128a93ad17b767 +Z 90dda46f03caf5162d829380d2711d0e diff --git a/manifest.uuid b/manifest.uuid index d6076d12ea..4597b323cb 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -47cd634c98b502d40a493455ba6d73cbd0dae74944f9cf06fcbcd025f4b49d6e \ No newline at end of file +33da6092d3d04b6eb6ab396b8c4f668e3529e26bf11e26f5fcb9b61fe3470197 \ No newline at end of file diff --git a/src/where.c b/src/where.c index 3d1d8418f1..d250990db2 100644 --- a/src/where.c +++ b/src/where.c @@ -5217,6 +5217,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ if( pLevel->regBignull ){ sqlite3VdbeResolveLabel(v, pLevel->addrBignull); sqlite3VdbeAddOp2(v, OP_IfNotZero, pLevel->regBignull, pLevel->p2-1); + VdbeCoverage(v); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT if( addrSeek ) sqlite3VdbeJumpHere(v, addrSeek); From 9d23ea74d44f458f39b51ae39a9b0d617947a90d Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Aug 2019 19:34:29 +0000 Subject: [PATCH 069/112] Fix other problems similar to ticket [c0390363]. FossilOrigin-Name: 96ff2ba9c4bb71d5f7c6f359986a76a5364b7ac3e1a612441543a9eabecf31df --- manifest | 16 +++++------ manifest.uuid | 2 +- src/expr.c | 27 +++++++++++++----- test/indexexpr2.test | 67 +++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 92 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index a38e9488a1..68a3beac9d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sa\smissing\sVdbeCoverage()\smacro. -D 2019-08-29T16:48:10.044 +C Fix\sother\sproblems\ssimilar\sto\sticket\s[c0390363]. +D 2019-08-29T19:34:29.959 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c c54fcc18ff7a9206524c44a3ebfaffcf71bae1fda063bdf254cfe2d4820ee71e +F src/expr.c 13cbe4b8af90685aa1359e6866c8b86177049f9c273a3c9bc47dda473f843977 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1053,7 +1053,7 @@ F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e F test/indexexpr1.test 0f293369ed6f56764cfc3db05685d45469d9e685ba87e3698527049ba359ae24 -F test/indexexpr2.test efffd39a278d8d9e8c5e9f82ef23178970951df9d725e4aea6d304bf81be6678 +F test/indexexpr2.test b580f378423bca443ffab47ada677203cfcf8a60f48a8aa20065f27c8f7739b5 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 F test/insert.test 72004f6a900a25bd3f1ce9a72e73d02749644666a8ce6d6d2dba061137e5aa63 @@ -1837,7 +1837,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 47cd634c98b502d40a493455ba6d73cbd0dae74944f9cf06fcbcd025f4b49d6e -R 82040bfc52a0536ad402b4608c120103 -U drh -Z 90dda46f03caf5162d829380d2711d0e +P 33da6092d3d04b6eb6ab396b8c4f668e3529e26bf11e26f5fcb9b61fe3470197 +R fddd1b4f06a264ef0d3ea52604d276ee +U dan +Z 0c2c6f276dc80545da616e6fc4335cce diff --git a/manifest.uuid b/manifest.uuid index 4597b323cb..4548ec71ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -33da6092d3d04b6eb6ab396b8c4f668e3529e26bf11e26f5fcb9b61fe3470197 \ No newline at end of file +96ff2ba9c4bb71d5f7c6f359986a76a5364b7ac3e1a612441543a9eabecf31df \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 80bc002d7f..fbed5f9921 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5014,14 +5014,16 @@ static int exprImpliesNotNull( case TK_GE: case TK_PLUS: case TK_MINUS: + case TK_BITOR: + case TK_LSHIFT: + case TK_RSHIFT: + case TK_CONCAT: + seenNot = 1; + /* Fall thru */ case TK_STAR: case TK_REM: case TK_BITAND: - case TK_BITOR: - case TK_SLASH: - case TK_LSHIFT: - case TK_RSHIFT: - case TK_CONCAT: { + case TK_SLASH: { if( exprImpliesNotNull(pParse, p->pRight, pNN, iTab, seenNot) ) return 1; /* Fall thru into the next case */ } @@ -5102,8 +5104,6 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ if( ExprHasProperty(pExpr, EP_FromJoin) ) return WRC_Prune; switch( pExpr->op ){ case TK_ISNOT: - case TK_NOT: - case TK_BITNOT: case TK_ISNULL: case TK_NOTNULL: case TK_IS: @@ -5128,6 +5128,18 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ } return WRC_Prune; + case TK_AND: + if( sqlite3ExprImpliesNonNullRow(pExpr->pLeft, pWalker->u.iCur) + && sqlite3ExprImpliesNonNullRow(pExpr->pRight, pWalker->u.iCur) + ){ + pWalker->eCode = 1; + } + return WRC_Prune; + + case TK_BETWEEN: + sqlite3WalkExpr(pWalker, pExpr->pLeft); + return WRC_Prune; + /* Virtual tables are allowed to use constraints like x=NULL. So ** a term of the form x=y does not prove that y is not null if x ** is the column of a virtual table */ @@ -5148,6 +5160,7 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ ){ return WRC_Prune; } + default: return WRC_Continue; } diff --git a/test/indexexpr2.test b/test/indexexpr2.test index 589a0589ab..5d387c7523 100644 --- a/test/indexexpr2.test +++ b/test/indexexpr2.test @@ -303,15 +303,74 @@ do_execsql_test 8.0 { INSERT INTO t0(c0) VALUES (NULL); } -breakpoint -do_execsql_test 8.1 { +do_execsql_test 8.1.1 { SELECT * FROM t0 WHERE ~('' BETWEEN t0.c0 AND TRUE); } {{}} - -do_execsql_test 8.2 { +do_execsql_test 8.1.2 { SELECT ~('' BETWEEN t0.c0 AND TRUE) FROM t0; } {-1} +foreach {tn expr} { + 1 " 0 == (34 BETWEEN c0 AND 33)" + 2 " 1 != (34 BETWEEN c0 AND 33)" + 3 "-1 < (34 BETWEEN c0 AND 33)" + 4 "-1 <= (34 BETWEEN c0 AND 33)" + 5 " 1 > (34 BETWEEN c0 AND 33)" + 6 " 1 >= (34 BETWEEN c0 AND 33)" + 7 " 1 - (34 BETWEEN c0 AND 33)" + 8 "-1 + (34 BETWEEN c0 AND 33)" + 9 " 1 | (34 BETWEEN c0 AND 33)" + 10 " 1 << (34 BETWEEN c0 AND 33)" + 11 " 1 >> (34 BETWEEN c0 AND 33)" + 12 " 1 || (34 BETWEEN c0 AND 33)" +} { + do_execsql_test 8.3.$tn.1 "SELECT * FROM t0 WHERE $expr ORDER BY c0" { {} } + do_execsql_test 8.3.$tn.2 "SELECT ($expr) IS TRUE FROM t0" { 1 } +} +do_execsql_test 8.4 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 2), (3, 4); + CREATE TABLE t2(x, y); +} + +foreach {tn expr} { + 1 " 0 == (a=0 AND y=1)" + 2 " 1 != (a=0 AND y=1)" + 3 "-1 < (a=0 AND y=1)" + 4 "-1 <= (a=0 AND y=1)" + 5 " 1 > (a=0 AND y=1)" + 6 " 1 >= (a=0 AND y=1)" + 7 " 1 - (a=0 AND y=1)" + 8 "-1 + (a=0 AND y=1)" + 9 " 1 | (a=0 AND y=1)" + 10 "1 << (a=0 AND y=1)" + 11 "1 >> (a=0 AND y=1)" + 12 "1 || (a=0 AND y=1)" + + 13 " 0 == (10 BETWEEN y AND b)" + 14 " 1 != (10 BETWEEN y AND b)" + 15 "-1 < (10 BETWEEN y AND b)" + 16 "-1 <= (10 BETWEEN y AND b)" + 17 " 1 > (10 BETWEEN y AND b)" + 18 " 1 >= (10 BETWEEN y AND b)" + 19 " 1 - (10 BETWEEN y AND b)" + 20 "-1 + (10 BETWEEN y AND b)" + 21 " 1 | (10 BETWEEN y AND b)" + 22 " 1 << (10 BETWEEN y AND b)" + 23 " 1 >> (10 BETWEEN y AND b)" + 24 " 1 || (10 BETWEEN y AND b)" + + 25 " 1 || (10 BETWEEN y AND b)" +} { + do_execsql_test 8.5.$tn.1 " + SELECT * FROM t1 LEFT JOIN t2 WHERE $expr + " {1 2 {} {} 3 4 {} {}} + + do_execsql_test 8.5.$tn.2 " + SELECT ($expr) IS TRUE FROM t1 LEFT JOIN t2 + " {1 1} +} finish_test + From bd717a4d2e5797027b8203a6f68af24be78e4f93 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 29 Aug 2019 21:16:46 +0000 Subject: [PATCH 070/112] Improve vdbe branch coverage of NULLS LAST code. FossilOrigin-Name: e8e9f77d52974f6ba0a536d05837b280a996745deb3a2169bb29379f10e49df4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/where.c | 2 +- test/nulls1.test | 11 +++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 68a3beac9d..2d9f39f93c 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sother\sproblems\ssimilar\sto\sticket\s[c0390363]. -D 2019-08-29T19:34:29.959 +C Improve\svdbe\sbranch\scoverage\sof\sNULLS\sLAST\scode. +D 2019-08-29T21:16:46.523 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -609,7 +609,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c 0a573a77eff9ab22edfbac0519b2147fce414f52af838497b5eb376f1fe60ef5 +F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f @@ -1182,7 +1182,7 @@ F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934 F test/notnull.test a37b663d5bb728d66fc182016613fb8e4a0a4bbf3d75b8876a7527f7d4ed3f18 F test/null.test 0dcce4f04284ec66108c503327ad6d224c0752b3 -F test/nulls1.test 5b978fbae9c73b497608c16f2636a2f71de6e2c914e4c78955cf022e39b7a0d5 +F test/nulls1.test 725fb4d99db2ddcce59ca6bf847cd92db8f1af861785918892f84ac3bcd4223d F test/numcast.test 5d126f7f581432e86a90d1e35cac625164aec4a1 F test/numindex1.test 20a5450d4b056e48cd5db30e659f13347a099823 F test/offset1.test f06b83657bcf26f9ce805e67450e189e282143b2 @@ -1837,7 +1837,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 33da6092d3d04b6eb6ab396b8c4f668e3529e26bf11e26f5fcb9b61fe3470197 -R fddd1b4f06a264ef0d3ea52604d276ee +P 96ff2ba9c4bb71d5f7c6f359986a76a5364b7ac3e1a612441543a9eabecf31df +R 586f9989c33ac2fc3f97f5c8be86f8ca U dan -Z 0c2c6f276dc80545da616e6fc4335cce +Z 3e69d63d2ff40a29da3ca94aaeb78df7 diff --git a/manifest.uuid b/manifest.uuid index 4548ec71ce..5e6d961dc6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -96ff2ba9c4bb71d5f7c6f359986a76a5364b7ac3e1a612441543a9eabecf31df \ No newline at end of file +e8e9f77d52974f6ba0a536d05837b280a996745deb3a2169bb29379f10e49df4 \ No newline at end of file diff --git a/src/where.c b/src/where.c index d250990db2..b51d4485c4 100644 --- a/src/where.c +++ b/src/where.c @@ -5216,7 +5216,7 @@ void sqlite3WhereEnd(WhereInfo *pWInfo){ VdbeCoverageIf(v, pLevel->op==OP_VNext); if( pLevel->regBignull ){ sqlite3VdbeResolveLabel(v, pLevel->addrBignull); - sqlite3VdbeAddOp2(v, OP_IfNotZero, pLevel->regBignull, pLevel->p2-1); + sqlite3VdbeAddOp2(v, OP_DecrJumpZero, pLevel->regBignull, pLevel->p2-1); VdbeCoverage(v); } #ifndef SQLITE_DISABLE_SKIPAHEAD_DISTINCT diff --git a/test/nulls1.test b/test/nulls1.test index 75d398782d..98fc6ab37d 100644 --- a/test/nulls1.test +++ b/test/nulls1.test @@ -236,6 +236,17 @@ do_eqp_test 6.2.2 { `--SEARCH TABLE t5 USING COVERING INDEX t5ab (a=?) } +#------------------------------------------------------------------------- +do_execsql_test 7.0 { + CREATE TABLE t71(a, b, c); + CREATE INDEX t71abc ON t71(a, b, c); + + SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c NULLS LAST; + SELECT * FROM t71 WHERE a=1 AND b=2 ORDER BY c DESC NULLS FIRST; + + SELECT * FROM t71 ORDER BY a NULLS LAST; + SELECT * FROM t71 ORDER BY a DESC NULLS FIRST; +} finish_test From f4d9c9822df99cbf29b49a3af6f183aa4992fb36 Mon Sep 17 00:00:00 2001 From: drh Date: Thu, 29 Aug 2019 23:24:18 +0000 Subject: [PATCH 071/112] Remove a faulty testcase() macro. FossilOrigin-Name: 80124ae55246b79023d23d3f55487ac3c0b40e8ff301c5daf4dd0631de8ddb29 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 1 - 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 2d9f39f93c..e1e281ccd7 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improve\svdbe\sbranch\scoverage\sof\sNULLS\sLAST\scode. -D 2019-08-29T21:16:46.523 +C Remove\sa\sfaulty\stestcase()\smacro. +D 2019-08-29T23:24:18.476 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 13cbe4b8af90685aa1359e6866c8b86177049f9c273a3c9bc47dda473f843977 +F src/expr.c 6b62b44b9210cc4abfb6ca0d58b613824a0dc39e907b10361641bb95e8eec8a3 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1837,7 +1837,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 96ff2ba9c4bb71d5f7c6f359986a76a5364b7ac3e1a612441543a9eabecf31df -R 586f9989c33ac2fc3f97f5c8be86f8ca -U dan -Z 3e69d63d2ff40a29da3ca94aaeb78df7 +P e8e9f77d52974f6ba0a536d05837b280a996745deb3a2169bb29379f10e49df4 +R 8060576dea17cd03f198b51c19488720 +U drh +Z 568c53db6ad05332ec202be9ff627c3b diff --git a/manifest.uuid b/manifest.uuid index 5e6d961dc6..a94e571162 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e8e9f77d52974f6ba0a536d05837b280a996745deb3a2169bb29379f10e49df4 \ No newline at end of file +80124ae55246b79023d23d3f55487ac3c0b40e8ff301c5daf4dd0631de8ddb29 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index fbed5f9921..b6b204a063 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5112,7 +5112,6 @@ static int impliesNotNullRow(Walker *pWalker, Expr *pExpr){ case TK_IN: case TK_FUNCTION: testcase( pExpr->op==TK_ISNOT ); - testcase( pExpr->op==TK_NOT ); testcase( pExpr->op==TK_ISNULL ); testcase( pExpr->op==TK_NOTNULL ); testcase( pExpr->op==TK_IS ); From 38cefc83c81842f4d4c1c92958e688c3bac14b79 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 13:07:06 +0000 Subject: [PATCH 072/112] The expression "(x IS FALSE) IS FALSE" does not imply that X is not NULL. Ticket [a6408d42b9f44462] FossilOrigin-Name: 45ff2b1f2693bb0231a864a511bb82cf2a5945ab3d806a5bbaf1517ecb287883 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- test/index6.test | 11 +++++++++++ 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e1e281ccd7..c05dfbf9f0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\sa\sfaulty\stestcase()\smacro. -D 2019-08-29T23:24:18.476 +C The\sexpression\s"(x\sIS\sFALSE)\sIS\sFALSE"\sdoes\snot\simply\sthat\sX\sis\snot\sNULL.\nTicket\s[a6408d42b9f44462] +D 2019-08-30T13:07:06.147 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 6b62b44b9210cc4abfb6ca0d58b613824a0dc39e907b10361641bb95e8eec8a3 +F src/expr.c 5f9d677be65dd8f636eedb598e3c68c9a72bc39fa753d952df2adea96ade17be F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1047,7 +1047,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 7883c35749e3f38282572194ffdbe7d025b1e2938c1e67da2d408ff3c27d9a46 +F test/index6.test 4286a391c34586bc4d6cc0f68c6505c7b0f5b9afe8cb98fe415eefffb2384cb4 F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 @@ -1837,7 +1837,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 e8e9f77d52974f6ba0a536d05837b280a996745deb3a2169bb29379f10e49df4 -R 8060576dea17cd03f198b51c19488720 +P 80124ae55246b79023d23d3f55487ac3c0b40e8ff301c5daf4dd0631de8ddb29 +R cd2bfff061492eccfe83623c7f6b6353 U drh -Z 568c53db6ad05332ec202be9ff627c3b +Z 295dda45dc991784101709d0169e56ad diff --git a/manifest.uuid b/manifest.uuid index a94e571162..d23972f86e 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -80124ae55246b79023d23d3f55487ac3c0b40e8ff301c5daf4dd0631de8ddb29 \ No newline at end of file +45ff2b1f2693bb0231a864a511bb82cf2a5945ab3d806a5bbaf1517ecb287883 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index b6b204a063..46aea5f3d0 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5036,7 +5036,7 @@ static int exprImpliesNotNull( case TK_TRUTH: { if( seenNot ) return 0; if( p->op2!=TK_IS ) return 0; - return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } case TK_BITNOT: case TK_NOT: { diff --git a/test/index6.test b/test/index6.test index 5faf0f02ac..09b8e1cf92 100644 --- a/test/index6.test +++ b/test/index6.test @@ -437,4 +437,15 @@ do_execsql_test index6-14.2 { SELECT * FROM t0 WHERE CASE c0 WHEN 0 THEN 0 ELSE 1 END; } {{} row} +# 2019-08-30 +# Ticket https://www.sqlite.org/src/info/a6408d42b9f44462 +# +do_execsql_test index6-15.1 { + DROP TABLE t0; + CREATE TABLE t0(c0); + INSERT INTO t0(c0) VALUES (NULL); + CREATE INDEX i0 ON t0(1) WHERE c0 NOT NULL; + SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) IS FALSE; +} {1} + finish_test From 7a231b49738d82582d9f4c31da18da90928d6f10 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 15:11:08 +0000 Subject: [PATCH 073/112] The expression "(X IS FALSE) BETWEEN FALSE AND TRUE" does not implie that X is not NULL. Ticket [fba33c8b1df6a915] FossilOrigin-Name: 057fb8b1809b8b9c8fff0fd0804153b9644f0545c23c6ddc4758bda3381094b9 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 11 +++++++---- test/index6.test | 10 ++++++++++ 4 files changed, 25 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index c05dfbf9f0..e12f380013 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sexpression\s"(x\sIS\sFALSE)\sIS\sFALSE"\sdoes\snot\simply\sthat\sX\sis\snot\sNULL.\nTicket\s[a6408d42b9f44462] -D 2019-08-30T13:07:06.147 +C The\sexpression\s"(X\sIS\sFALSE)\sBETWEEN\sFALSE\sAND\sTRUE"\sdoes\snot\simplie\sthat\nX\sis\snot\sNULL.\s\sTicket\s[fba33c8b1df6a915] +D 2019-08-30T15:11:08.913 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 5f9d677be65dd8f636eedb598e3c68c9a72bc39fa753d952df2adea96ade17be +F src/expr.c e1d261e3d2ddd29d49d645bf2b919f37b842fa5fc41a936b2dcc3e5a309d58c0 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1047,7 +1047,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 4286a391c34586bc4d6cc0f68c6505c7b0f5b9afe8cb98fe415eefffb2384cb4 +F test/index6.test 5b016266f0e823b2a27724da25c18fe38feb474006f9604d9d5f996bfef75b68 F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 @@ -1837,7 +1837,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 80124ae55246b79023d23d3f55487ac3c0b40e8ff301c5daf4dd0631de8ddb29 -R cd2bfff061492eccfe83623c7f6b6353 +P 45ff2b1f2693bb0231a864a511bb82cf2a5945ab3d806a5bbaf1517ecb287883 +R 9c64b300fe2525056b87d63bc987465b U drh -Z 295dda45dc991784101709d0169e56ad +Z 75ee72b9565e384807e78e8394c68f11 diff --git a/manifest.uuid b/manifest.uuid index d23972f86e..0f4dbf8996 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -45ff2b1f2693bb0231a864a511bb82cf2a5945ab3d806a5bbaf1517ecb287883 \ No newline at end of file +057fb8b1809b8b9c8fff0fd0804153b9644f0545c23c6ddc4758bda3381094b9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 46aea5f3d0..27929767c9 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4974,13 +4974,16 @@ int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){ /* ** Return non-zero if Expr p can only be true if pNN is not NULL. +** +** Or if seenNot is true, return non-zero if Expr p can only be +** non-NULL if pNN is not NULL */ static int exprImpliesNotNull( Parse *pParse, /* Parsing context */ Expr *p, /* The expression to be checked */ Expr *pNN, /* The expression that is NOT NULL */ int iTab, /* Table being evaluated */ - int seenNot /* True if p is an operand of NOT */ + int seenNot /* Return true only if p can be any non-NULL value */ ){ assert( p ); assert( pNN ); @@ -4999,12 +5002,12 @@ static int exprImpliesNotNull( assert( pList!=0 ); assert( pList->nExpr==2 ); if( seenNot ) return 0; - if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, seenNot) - || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, seenNot) + if( exprImpliesNotNull(pParse, pList->a[0].pExpr, pNN, iTab, 1) + || exprImpliesNotNull(pParse, pList->a[1].pExpr, pNN, iTab, 1) ){ return 1; } - return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } case TK_EQ: case TK_NE: diff --git a/test/index6.test b/test/index6.test index 09b8e1cf92..d32e909e10 100644 --- a/test/index6.test +++ b/test/index6.test @@ -439,6 +439,7 @@ do_execsql_test index6-14.2 { # 2019-08-30 # Ticket https://www.sqlite.org/src/info/a6408d42b9f44462 +# Ticket https://www.sqlite.org/src/info/fba33c8b1df6a915 # do_execsql_test index6-15.1 { DROP TABLE t0; @@ -447,5 +448,14 @@ do_execsql_test index6-15.1 { CREATE INDEX i0 ON t0(1) WHERE c0 NOT NULL; SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) IS FALSE; } {1} +do_execsql_test index6-15.2 { + SELECT 1 FROM t0 WHERE (t0.c0 IS FALSE) BETWEEN FALSE AND TRUE; +} {1} +do_execsql_test index6-15.3 { + SELECT 1 FROM t0 WHERE TRUE BETWEEN (t0.c0 IS FALSE) AND TRUE; +} {1} +do_execsql_test index6-15.4 { + SELECT 1 FROM t0 WHERE FALSE BETWEEN FALSE AND (t0.c0 IS FALSE); +} {1} finish_test From ae144a1c9fc092e8756f66cd8d60b80dbbd1e010 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 16:00:58 +0000 Subject: [PATCH 074/112] The expression "(X IS FALSE) IN (FALSE)" does not imply that X is NOT NULL. Ticket [f8f472cbc77ba9c9] FossilOrigin-Name: dd66134817ecbda01c59a05ad0d6ac44bee700ab10cd2119c869dd69af293fe2 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 2 +- test/index6.test | 5 +++++ 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index e12f380013..f9cae012c2 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sexpression\s"(X\sIS\sFALSE)\sBETWEEN\sFALSE\sAND\sTRUE"\sdoes\snot\simplie\sthat\nX\sis\snot\sNULL.\s\sTicket\s[fba33c8b1df6a915] -D 2019-08-30T15:11:08.913 +C The\sexpression\s"(X\sIS\sFALSE)\sIN\s(FALSE)"\sdoes\snot\simply\sthat\sX\sis\sNOT\sNULL.\nTicket\s[f8f472cbc77ba9c9] +D 2019-08-30T16:00:58.750 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c e1d261e3d2ddd29d49d645bf2b919f37b842fa5fc41a936b2dcc3e5a309d58c0 +F src/expr.c e1b74116375bb88c1b4b90b635d417dcd0643ac46bacf5a3caefef60c8e5e115 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1047,7 +1047,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test 5b016266f0e823b2a27724da25c18fe38feb474006f9604d9d5f996bfef75b68 +F test/index6.test bae04b456a1845d8d48af751ac5b9bba5571551b96ef39d2b5b1db48cadd0fac F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 @@ -1837,7 +1837,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 45ff2b1f2693bb0231a864a511bb82cf2a5945ab3d806a5bbaf1517ecb287883 -R 9c64b300fe2525056b87d63bc987465b +P 057fb8b1809b8b9c8fff0fd0804153b9644f0545c23c6ddc4758bda3381094b9 +R dbd65dd02f8837e1f86624f44fe9aa97 U drh -Z 75ee72b9565e384807e78e8394c68f11 +Z 96ee8b9606bd233ac998576dd644ea25 diff --git a/manifest.uuid b/manifest.uuid index 0f4dbf8996..98bf5de4ce 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -057fb8b1809b8b9c8fff0fd0804153b9644f0545c23c6ddc4758bda3381094b9 \ No newline at end of file +dd66134817ecbda01c59a05ad0d6ac44bee700ab10cd2119c869dd69af293fe2 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 27929767c9..e87ff70507 100644 --- a/src/expr.c +++ b/src/expr.c @@ -4995,7 +4995,7 @@ static int exprImpliesNotNull( if( seenNot && ExprHasProperty(p, EP_xIsSelect) ) return 0; assert( ExprHasProperty(p,EP_xIsSelect) || (p->x.pList!=0 && p->x.pList->nExpr>0) ); - return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, seenNot); + return exprImpliesNotNull(pParse, p->pLeft, pNN, iTab, 1); } case TK_BETWEEN: { ExprList *pList = p->x.pList; diff --git a/test/index6.test b/test/index6.test index d32e909e10..d5bc77c0db 100644 --- a/test/index6.test +++ b/test/index6.test @@ -440,6 +440,7 @@ do_execsql_test index6-14.2 { # 2019-08-30 # Ticket https://www.sqlite.org/src/info/a6408d42b9f44462 # Ticket https://www.sqlite.org/src/info/fba33c8b1df6a915 +# https://sqlite.org/src/info/bac716244fddac1fe841 # do_execsql_test index6-15.1 { DROP TABLE t0; @@ -457,5 +458,9 @@ do_execsql_test index6-15.3 { do_execsql_test index6-15.4 { SELECT 1 FROM t0 WHERE FALSE BETWEEN FALSE AND (t0.c0 IS FALSE); } {1} +do_execsql_test index6-15.5 { + SELECT 1 FROM t0 WHERE (c0 IS FALSE) IN (FALSE); +} {1} + finish_test From 8b47f5208247277ee6eaf532e547d4995f56114b Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Aug 2019 16:14:58 +0000 Subject: [PATCH 075/112] Fix a bug in RANGE window functions that use "ORDER BY DESC NULLS FIRST" as the window-frame ORDER BY clause. FossilOrigin-Name: 39b4cad4a51bb5116d62ffb16ac36d96a9280321b049eb2d008605392f52a459 --- manifest | 18 ++++---- manifest.uuid | 2 +- src/window.c | 106 +++++++++++++++++++++++++++++++++++----------- test/window8.tcl | 13 ++++++ test/window8.test | 15 +++++++ 5 files changed, 119 insertions(+), 35 deletions(-) diff --git a/manifest b/manifest index f9cae012c2..69eb8d41dd 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C The\sexpression\s"(X\sIS\sFALSE)\sIN\s(FALSE)"\sdoes\snot\simply\sthat\sX\sis\sNOT\sNULL.\nTicket\s[f8f472cbc77ba9c9] -D 2019-08-30T16:00:58.750 +C Fix\sa\sbug\sin\sRANGE\swindow\sfunctions\sthat\suse\s"ORDER\sBY\s\sDESC\sNULLS\sFIRST"\sas\sthe\swindow-frame\sORDER\sBY\sclause. +D 2019-08-30T16:14:58.448 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,7 +613,7 @@ F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f -F src/window.c 7d74882b41db7f44300489b3513f94f3f95684725e6d8e4e8cede44f015bb4b0 +F src/window.c 701bea99097fd9f2c49e0af54446c986853e639fa297248ea62fac5e3f3b8dba F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1711,8 +1711,8 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652 F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32 F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd -F test/window8.tcl 5884cc884f9605bf88c0d18a534894bf9342f72687bf1bc43ed0cab4c8af7973 -F test/window8.test 48590f3737d17eec503d77769c13ead15d12e8819820b1dc68afe8a3c5bc3250 +F test/window8.tcl 3b63931d608b6f00a9d26368207a7ffc9370c96e3e137ae2aff35284ade69d13 +F test/window8.test 4531204bfb5d833efbd8a5a1527c9871e62f8ae479386f42a7b55bdb5be39df3 F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b @@ -1837,7 +1837,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 057fb8b1809b8b9c8fff0fd0804153b9644f0545c23c6ddc4758bda3381094b9 -R dbd65dd02f8837e1f86624f44fe9aa97 -U drh -Z 96ee8b9606bd233ac998576dd644ea25 +P dd66134817ecbda01c59a05ad0d6ac44bee700ab10cd2119c869dd69af293fe2 +R f9d7b459685c1da5bc61b772c0f2da65 +U dan +Z 05bbd4877d54c35c485e8a33829586c4 diff --git a/manifest.uuid b/manifest.uuid index 98bf5de4ce..7d6528b578 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -dd66134817ecbda01c59a05ad0d6ac44bee700ab10cd2119c869dd69af293fe2 \ No newline at end of file +39b4cad4a51bb5116d62ffb16ac36d96a9280321b049eb2d008605392f52a459 \ No newline at end of file diff --git a/src/window.c b/src/window.c index ac8d1080fb..4537559953 100644 --- a/src/window.c +++ b/src/window.c @@ -1854,31 +1854,42 @@ static void windowIfNewPeer( /* ** This function is called as part of generating VM programs for RANGE ** offset PRECEDING/FOLLOWING frame boundaries. Assuming "ASC" order for -** the ORDER BY term in the window, it generates code equivalent to: +** the ORDER BY term in the window, and that argument op is OP_Ge, it generates +** code equivalent to: ** ** if( csr1.peerVal + regVal >= csr2.peerVal ) goto lbl; ** -** A special type of arithmetic is used such that if csr.peerVal is not -** a numeric type (real or integer), then the result of the addition is -** a copy of csr1.peerVal. +** The value of parameter op may also be OP_Gt or OP_Le. In these cases the +** operator in the above pseudo-code is replaced with ">" or "<=", respectively. +** +** If the sort-order for the ORDER BY term in the window is DESC, then the +** comparison is reversed. Instead of adding regVal to csr1.peerVal, it is +** subtracted. And the comparison operator is inverted to - ">=" becomes "<=", +** ">" becomes "<", and so on. So, with DESC sort order, if the argument op +** is OP_Ge, the generated code is equivalent to: +** +** if( csr1.peerVal - regVal <= csr2.peerVal ) goto lbl; +** +** A special type of arithmetic is used such that if csr1.peerVal is not +** a numeric type (real or integer), then the result of the addition addition +** or subtraction is a a copy of csr1.peerVal. */ static void windowCodeRangeTest( WindowCodeArg *p, int op, /* OP_Ge, OP_Gt, or OP_Le */ - int csr1, - int regVal, - int csr2, - int lbl + int csr1, /* Cursor number for cursor 1 */ + int regVal, /* Register containing non-negative number */ + int csr2, /* Cursor number for cursor 2 */ + int lbl /* Jump destination if the condition is true */ ){ Parse *pParse = p->pParse; Vdbe *v = sqlite3GetVdbe(pParse); - int reg1 = sqlite3GetTempReg(pParse); - int reg2 = sqlite3GetTempReg(pParse); - int arith = OP_Add; - int addrGe; - ExprList *pOrderBy = p->pMWin->pOrderBy; - - int regString = ++pParse->nMem; + ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for this window */ + int reg1 = sqlite3GetTempReg(pParse); /* Register for csr1.peerVal+regVal */ + int reg2 = sqlite3GetTempReg(pParse); /* Regiser for csr2.peerVal */ + int regString = ++pParse->nMem; /* Register for constant value '' */ + int arith = OP_Add; /* OP_Add or OP_Subtract */ + int addrGe; /* Jump destination */ assert( op==OP_Ge || op==OP_Gt || op==OP_Le ); assert( pOrderBy && pOrderBy->nExpr==1 ); @@ -1891,47 +1902,92 @@ static void windowCodeRangeTest( arith = OP_Subtract; } + /* Read the peer-value from each cursor into a register */ windowReadPeerValues(p, csr1, reg1); windowReadPeerValues(p, csr2, reg2); - /* Check if the peer value for csr1 value is a text or blob by comparing - ** it to the smallest possible string - ''. If it is, jump over the - ** OP_Add or OP_Subtract operation and proceed directly to the comparison. */ + VdbeModuleComment((v, "CodeRangeTest: if( R%d %s R%d %s R%d ) goto lbl", + reg1, (arith==OP_Add ? "+" : "-"), regVal, + ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2 + )); + + /* Register reg1 currently contains csr1.peerVal (the peer-value from csr1). + ** This block adds (or subtracts for DESC) the numeric value in regVal + ** from it. Or, if reg1 is not numeric (it is a NULL, a text value or a blob), + ** then leave reg1 as it is. In pseudo-code, this is implemented as: + ** + ** if( reg1>='' ) goto addrGe; + ** reg1 = reg1 +/- regVal + ** addrGe: + ** + ** Since all strings and blobs are greater-than-or-equal-to an empty string, + ** the add/subtract is skipped for these, as required. If reg1 is a NULL, + ** then the arithmetic is performed, but since adding or subtracting from + ** NULL is always NULL anyway, this case is handled as required too. */ sqlite3VdbeAddOp4(v, OP_String8, 0, regString, 0, "", P4_STATIC); addrGe = sqlite3VdbeAddOp3(v, OP_Ge, regString, 0, reg1); VdbeCoverage(v); sqlite3VdbeAddOp3(v, arith, regVal, reg1, reg1); sqlite3VdbeJumpHere(v, addrGe); + + /* If the BIGNULL flag is set for the ORDER BY, then it is required to + ** consider NULL values to be larger than all other values, instead of + ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this + ** (and adding that capability causes a performance regression), so + ** instead if the BIGNULL flag is set then cases where either reg1 or + ** reg2 are NULL are handled separately in the following block. The code + ** generated is equivalent to: + ** + ** if( reg1 IS NULL ){ + ** if( op==OP_Gt ) goto lbl; + ** if( op==OP_Ge && reg2 IS NOT NULL ) goto lbl; + ** if( op==OP_Le && reg2 IS NULL ) goto lbl; + ** }else if( reg2 IS NULL ){ + ** if( op==OP_Le ) goto lbl; + ** } + ** + ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is + ** not taken, control jumps over the comparison operator coded below this + ** block. */ if( pOrderBy->a[0].sortFlags & KEYINFO_ORDER_BIGNULL ){ - int addr; - addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); + /* This block runs if reg1 contains a NULL. */ + int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); switch( op ){ - case OP_Ge: sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; + case OP_Ge: + sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); + break; case OP_Gt: sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); VdbeCoverage(v); break; - default: - assert( op==OP_Le ); + default: assert( op==OP_Le ); sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); break; } - sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); + + /* This block runs if reg1 is not NULL, but reg2 is. */ sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); if( op==OP_Gt || op==OP_Ge ){ sqlite3VdbeChangeP2(v, -1, sqlite3VdbeCurrentAddr(v)+1); } } + + /* Compare registers reg2 and reg1, taking the jump if required. Note that + ** control skips over this test if the BIGNULL flag is set and either + ** reg1 or reg2 contain a NULL value. */ sqlite3VdbeAddOp3(v, op, reg2, lbl, reg1); VdbeCoverage(v); sqlite3VdbeChangeP5(v, SQLITE_NULLEQ); + assert( op==OP_Ge || op==OP_Gt || op==OP_Lt || op==OP_Le ); testcase(op==OP_Ge); VdbeCoverageIf(v, op==OP_Ge); testcase(op==OP_Lt); VdbeCoverageIf(v, op==OP_Lt); testcase(op==OP_Le); VdbeCoverageIf(v, op==OP_Le); testcase(op==OP_Gt); VdbeCoverageIf(v, op==OP_Gt); - sqlite3ReleaseTempReg(pParse, reg1); sqlite3ReleaseTempReg(pParse, reg2); + + VdbeModuleComment((v, "CodeRangeTest: end")); } /* diff --git a/test/window8.tcl b/test/window8.tcl index 64fd98aea9..d881fd8e4b 100644 --- a/test/window8.tcl +++ b/test/window8.tcl @@ -247,6 +247,18 @@ execsql_test 4.4.4 { ) FROM t1 ORDER BY 1 NULLS LAST; } +execsql_test 4.5.1 { + SELECT sum(b) OVER ( + ORDER BY a ASC NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} +execsql_test 4.5.2 { + SELECT sum(b) OVER ( + ORDER BY a DESC NULLS FIRST RANGE + BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} + ========== execsql_test 5.0 { @@ -329,6 +341,7 @@ execsql_test 6.2 { FROM t2 } +========== finish_test diff --git a/test/window8.test b/test/window8.test index e149979cd4..53d3e30027 100644 --- a/test/window8.test +++ b/test/window8.test @@ -3579,6 +3579,19 @@ do_execsql_test 4.4.4 { ) FROM t1 ORDER BY 1 NULLS LAST; } {5 6 8 9 10} +do_execsql_test 4.5.1 { + SELECT sum(b) OVER ( + ORDER BY a ASC NULLS LAST RANGE BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} {9 9 15 15 15} + +do_execsql_test 4.5.2 { + SELECT sum(b) OVER ( + ORDER BY a DESC NULLS FIRST RANGE + BETWEEN UNBOUNDED PRECEDING AND 10 FOLLOWING + ) FROM t1 ORDER BY 1 NULLS LAST; +} {6 6 6 15 15} + #========================================================================== do_execsql_test 5.0 { @@ -6190,4 +6203,6 @@ do_execsql_test 6.2 { FROM t2 } {{} A.B A.B} +#========================================================================== + finish_test From ac6627327c01a1f9655e7ac33cb3adab45abc761 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 16:46:12 +0000 Subject: [PATCH 076/112] New test cases for window functions with RANGE BETWEEN and DESC NULLS FIRST. FossilOrigin-Name: f7002f86c780e279c9f8a6268f317586519c059c9de2115ff6f1cad272570c29 --- manifest | 13 ++- manifest.uuid | 2 +- test/windowA.test | 292 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 300 insertions(+), 7 deletions(-) create mode 100644 test/windowA.test diff --git a/manifest b/manifest index 69eb8d41dd..c858e4eba1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sin\sRANGE\swindow\sfunctions\sthat\suse\s"ORDER\sBY\s\sDESC\sNULLS\sFIRST"\sas\sthe\swindow-frame\sORDER\sBY\sclause. -D 2019-08-30T16:14:58.448 +C New\stest\scases\sfor\swindow\sfunctions\swith\sRANGE\sBETWEEN\sand\sDESC\sNULLS\sFIRST. +D 2019-08-30T16:46:12.848 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1714,6 +1714,7 @@ F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af4 F test/window8.tcl 3b63931d608b6f00a9d26368207a7ffc9370c96e3e137ae2aff35284ade69d13 F test/window8.test 4531204bfb5d833efbd8a5a1527c9871e62f8ae479386f42a7b55bdb5be39df3 F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 +F test/windowA.test 5cd7c8dc3b2fcdfc6ea122c81a35726106880ae75afd097f62061839aff13b71 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 @@ -1837,7 +1838,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 dd66134817ecbda01c59a05ad0d6ac44bee700ab10cd2119c869dd69af293fe2 -R f9d7b459685c1da5bc61b772c0f2da65 -U dan -Z 05bbd4877d54c35c485e8a33829586c4 +P 39b4cad4a51bb5116d62ffb16ac36d96a9280321b049eb2d008605392f52a459 +R 5b7566c6e8c614d220a50ba45c732f15 +U drh +Z 7f59914616f53a7b55c42685c9ae4ee5 diff --git a/manifest.uuid b/manifest.uuid index 7d6528b578..00e9822a33 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39b4cad4a51bb5116d62ffb16ac36d96a9280321b049eb2d008605392f52a459 \ No newline at end of file +f7002f86c780e279c9f8a6268f317586519c059c9de2115ff6f1cad272570c29 \ No newline at end of file diff --git a/test/windowA.test b/test/windowA.test new file mode 100644 index 0000000000..20c904eee2 --- /dev/null +++ b/test/windowA.test @@ -0,0 +1,292 @@ +# 2019-08-30 +# +# 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. +# +#*********************************************************************** +# Test cases for RANGE BETWEEN and especially with NULLS LAST +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix windowA + +ifcapable !windowfunc { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b CHAR(1), d FLOAT); + INSERT INTO t1 VALUES + (1, 'A', 5.4), + (2, 'B', 5.55), + (3, 'C', 8.0), + (4, 'D', 10.25), + (5, 'E', 10.26), + (6, 'N', NULL), + (7, 'N', NULL); +} {} + +do_execsql_test 1.1 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN 2.50 PRECEDING AND 2.25 FOLLOWING) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 ED \ + 4 D 10.25 EDC \ + 3 C 8.0 EDC \ + 2 B 5.55 CBA \ + 1 A 5.4 BA \ + 6 N NULL NN \ + 7 N NULL NN \ +] + +do_execsql_test 1.2 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN 2.50 PRECEDING AND 2.25 FOLLOWING) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NN \ + 7 N NULL NN \ + 5 E 10.26 ED \ + 4 D 10.25 EDC \ + 3 C 8.0 EDC \ + 2 B 5.55 CBA \ + 1 A 5.4 BA \ +] + +do_execsql_test 1.3 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN 2.50 PRECEDING AND UNBOUNDED FOLLOWING) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 EDCBANN \ + 4 D 10.25 EDCBANN \ + 3 C 8.0 EDCBANN \ + 2 B 5.55 CBANN \ + 1 A 5.4 BANN \ + 6 N NULL NN \ + 7 N NULL NN \ +] + +do_execsql_test 1.4 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN 2.50 PRECEDING AND UNBOUNDED FOLLOWING) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NNEDCBA \ + 7 N NULL NNEDCBA \ + 5 E 10.26 EDCBA \ + 4 D 10.25 EDCBA \ + 3 C 8.0 EDCBA \ + 2 B 5.55 CBA \ + 1 A 5.4 BA \ +] + +do_execsql_test 1.5 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN 2.50 PRECEDING AND CURRENT ROW) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 E \ + 4 D 10.25 ED \ + 3 C 8.0 EDC \ + 2 B 5.55 CB \ + 1 A 5.4 BA \ + 6 N NULL NN \ + 7 N NULL NN \ +] + +do_execsql_test 1.6 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN 2.50 PRECEDING AND CURRENT ROW) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NN \ + 7 N NULL NN \ + 5 E 10.26 E \ + 4 D 10.25 ED \ + 3 C 8.0 EDC \ + 2 B 5.55 CB \ + 1 A 5.4 BA \ +] + +do_execsql_test 2.1 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN UNBOUNDED PRECEDING AND 2.25 FOLLOWING) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 ED \ + 4 D 10.25 EDC \ + 3 C 8.0 EDC \ + 2 B 5.55 EDCBA \ + 1 A 5.4 EDCBA \ + 6 N NULL EDCBANN \ + 7 N NULL EDCBANN \ +] + +do_execsql_test 2.2 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN UNBOUNDED PRECEDING AND 2.25 FOLLOWING) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NN \ + 7 N NULL NN \ + 5 E 10.26 NNED \ + 4 D 10.25 NNEDC \ + 3 C 8.0 NNEDC \ + 2 B 5.55 NNEDCBA \ + 1 A 5.4 NNEDCBA \ +] + +do_execsql_test 2.3 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 EDCBANN \ + 4 D 10.25 EDCBANN \ + 3 C 8.0 EDCBANN \ + 2 B 5.55 EDCBANN \ + 1 A 5.4 EDCBANN \ + 6 N NULL EDCBANN \ + 7 N NULL EDCBANN \ +] + +do_execsql_test 2.4 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NNEDCBA \ + 7 N NULL NNEDCBA \ + 5 E 10.26 NNEDCBA \ + 4 D 10.25 NNEDCBA \ + 3 C 8.0 NNEDCBA \ + 2 B 5.55 NNEDCBA \ + 1 A 5.4 NNEDCBA \ +] + +do_execsql_test 2.5 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 E \ + 4 D 10.25 ED \ + 3 C 8.0 EDC \ + 2 B 5.55 EDCB \ + 1 A 5.4 EDCBA \ + 6 N NULL EDCBANN \ + 7 N NULL EDCBANN \ +] + +do_execsql_test 2.6 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NN \ + 7 N NULL NN \ + 5 E 10.26 NNE \ + 4 D 10.25 NNED \ + 3 C 8.0 NNEDC \ + 2 B 5.55 NNEDCB \ + 1 A 5.4 NNEDCBA \ +] + + +do_execsql_test 3.1 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN CURRENT ROW AND 2.25 FOLLOWING) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 ED \ + 4 D 10.25 DC \ + 3 C 8.0 C \ + 2 B 5.55 BA \ + 1 A 5.4 A \ + 6 N NULL NN \ + 7 N NULL NN \ +] + +do_execsql_test 3.2 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN CURRENT ROW AND 2.25 FOLLOWING) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NN \ + 7 N NULL NN \ + 5 E 10.26 ED \ + 4 D 10.25 DC \ + 3 C 8.0 C \ + 2 B 5.55 BA \ + 1 A 5.4 A \ +] + +do_execsql_test 3.3 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS LAST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + ORDER BY +d DESC NULLS LAST, +a; +} [list \ + 5 E 10.26 EDCBANN \ + 4 D 10.25 DCBANN \ + 3 C 8.0 CBANN \ + 2 B 5.55 BANN \ + 1 A 5.4 ANN \ + 6 N NULL NN \ + 7 N NULL NN \ +] + +do_execsql_test 3.4 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NNEDCBA \ + 7 N NULL NNEDCBA \ + 5 E 10.26 EDCBA \ + 4 D 10.25 DCBA \ + 3 C 8.0 CBA \ + 2 B 5.55 BA \ + 1 A 5.4 A \ +] + +finish_test From 1cac1766df5515b4984e001a9aabccbd506f3dda Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Aug 2019 17:28:55 +0000 Subject: [PATCH 077/112] Add further comments to window.c. FossilOrigin-Name: 900464567b2a5ce0c278a3297e4be1968f609258608aa0fbe2fc67709aa22a4b --- manifest | 14 ++++---- manifest.uuid | 2 +- src/window.c | 95 +++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 85 insertions(+), 26 deletions(-) diff --git a/manifest b/manifest index c858e4eba1..e990056a98 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C New\stest\scases\sfor\swindow\sfunctions\swith\sRANGE\sBETWEEN\sand\sDESC\sNULLS\sFIRST. -D 2019-08-30T16:46:12.848 +C Add\sfurther\scomments\sto\swindow.c. +D 2019-08-30T17:28:55.760 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,7 +613,7 @@ F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f -F src/window.c 701bea99097fd9f2c49e0af54446c986853e639fa297248ea62fac5e3f3b8dba +F src/window.c ff37ca403ad3c47bb1e60b0e88c546aa5194524dc20d7f75e866187a093ae5d7 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1838,7 +1838,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 39b4cad4a51bb5116d62ffb16ac36d96a9280321b049eb2d008605392f52a459 -R 5b7566c6e8c614d220a50ba45c732f15 -U drh -Z 7f59914616f53a7b55c42685c9ae4ee5 +P f7002f86c780e279c9f8a6268f317586519c059c9de2115ff6f1cad272570c29 +R 717428315655334cbf16abae9c8648f7 +U dan +Z e01e05b9266977bc594b107aacdc1011 diff --git a/manifest.uuid b/manifest.uuid index 00e9822a33..e5c97e32cd 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f7002f86c780e279c9f8a6268f317586519c059c9de2115ff6f1cad272570c29 \ No newline at end of file +900464567b2a5ce0c278a3297e4be1968f609258608aa0fbe2fc67709aa22a4b \ No newline at end of file diff --git a/src/window.c b/src/window.c index 4537559953..fbb60b9c40 100644 --- a/src/window.c +++ b/src/window.c @@ -1499,19 +1499,78 @@ static void windowAggStep( typedef struct WindowCodeArg WindowCodeArg; typedef struct WindowCsrAndReg WindowCsrAndReg; + +/* +** See comments above struct WindowCodeArg. +*/ struct WindowCsrAndReg { - int csr; - int reg; + int csr; /* Cursor number */ + int reg; /* First in array of peer values */ }; +/* +** A single instance of this structure is allocated on the stack by +** sqlite3WindowCodeStep() and a pointer to it passed to the various helper +** routines. This is to reduce the number of arguments required by each +** helper function. +** +** regArg: +** Each window function requires an accumulator register (just as an +** ordinary aggregate function does). This variable is set to the first +** in an array of accumulator registers - one for each window function +** in the WindowCodeArg.pMWin list. +** +** eDelete: +** The window functions implementation sometimes caches the input rows +** that it processes in a temporary table. If it is not zero, this +** variable indicates when rows may be removed from the temp table (in +** order to reduce memory requirements - it would always be safe just +** to leave them there). Possible values for eDelete are: +** +** WINDOW_RETURN_ROW: +** An input row can be discarded after it is returned to the caller. +** +** WINDOW_AGGINVERSE: +** An input row can be discarded after the window functions xInverse() +** callbacks have been invoked in it. +** +** WINDOW_AGGSTEP: +** An input row can be discarded after the window functions xStep() +** callbacks have been invoked in it. +** +** start,current,end +** Consider a window-frame similar to the following: +** +** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) +** +** The windows functions implmentation caches the input rows in a temp +** table, sorted by "a, b" (it actually populates the cache lazily, and +** aggressively removes rows once they are no longer required, but that's +** a mere detail). It keeps three cursors open on the temp table. One +** (current) that points to the next row to return to the query engine +** once its window function values have been calculated. Another (end) +** points to the next row to call the xStep() method of each window function +** on (so that it is 2 groups ahead of current). And a third (start) that +** points to the next row to call the xInverse() method of each window +** function on. +** +** Each cursor (start, current and end) consists of a VDBE cursor +** (WindowCsrAndReg.csr) and an array of registers (starting at +** WindowCodeArg.reg) that always contains a copy of the peer values +** read from the corresponding cursor. +** +** Depending on the window-frame in question, all three cursors may not +** be required. In this case both WindowCodeArg.csr and reg are set to +** 0. +*/ struct WindowCodeArg { - Parse *pParse; - Window *pMWin; - Vdbe *pVdbe; - int regGosub; - int addrGosub; - int regArg; - int eDelete; + Parse *pParse; /* Parse context */ + Window *pMWin; /* First in list of functions being processed */ + Vdbe *pVdbe; /* VDBE object */ + int addrGosub; /* OP_Gosub to this address to return one row */ + int regGosub; /* Register used with OP_Gosub(addrGosub) */ + int regArg; /* First in array of accumulator registers */ + int eDelete; /* See above */ WindowCsrAndReg start; WindowCsrAndReg current; @@ -1876,18 +1935,18 @@ static void windowIfNewPeer( */ static void windowCodeRangeTest( WindowCodeArg *p, - int op, /* OP_Ge, OP_Gt, or OP_Le */ - int csr1, /* Cursor number for cursor 1 */ - int regVal, /* Register containing non-negative number */ - int csr2, /* Cursor number for cursor 2 */ - int lbl /* Jump destination if the condition is true */ + int op, /* OP_Ge, OP_Gt, or OP_Le */ + int csr1, /* Cursor number for cursor 1 */ + int regVal, /* Register containing non-negative number */ + int csr2, /* Cursor number for cursor 2 */ + int lbl /* Jump destination if condition is true */ ){ Parse *pParse = p->pParse; Vdbe *v = sqlite3GetVdbe(pParse); - ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for this window */ - int reg1 = sqlite3GetTempReg(pParse); /* Register for csr1.peerVal+regVal */ - int reg2 = sqlite3GetTempReg(pParse); /* Regiser for csr2.peerVal */ - int regString = ++pParse->nMem; /* Register for constant value '' */ + ExprList *pOrderBy = p->pMWin->pOrderBy; /* ORDER BY clause for window */ + int reg1 = sqlite3GetTempReg(pParse); /* Reg. for csr1.peerVal+regVal */ + int reg2 = sqlite3GetTempReg(pParse); /* Reg. for csr2.peerVal */ + int regString = ++pParse->nMem; /* Reg. for constant value '' */ int arith = OP_Add; /* OP_Add or OP_Subtract */ int addrGe; /* Jump destination */ From db3a32ed1cfb3b90cc5baa9df54e48afa9b18ee6 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 18:02:49 +0000 Subject: [PATCH 078/112] Back out the change at [47cd634c98b502d4] which was incorrect. Add a test case so that we don't accidently back out that change again. FossilOrigin-Name: 596ac2a4eab28b74f4050fb4eb71883f2a1421fdbccf302413e4653391bb52c9 --- manifest | 17 +++++++++-------- manifest.uuid | 2 +- src/window.c | 9 ++++++--- test/windowA.test | 17 +++++++++++++++++ 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e990056a98..9688a40bb9 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sfurther\scomments\sto\swindow.c. -D 2019-08-30T17:28:55.760 +C Back\sout\sthe\schange\sat\s[47cd634c98b502d4]\swhich\swas\sincorrect.\s\sAdd\sa\stest\ncase\sso\sthat\swe\sdon't\saccidently\sback\sout\sthat\schange\sagain. +D 2019-08-30T18:02:49.143 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,7 +613,7 @@ F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f -F src/window.c ff37ca403ad3c47bb1e60b0e88c546aa5194524dc20d7f75e866187a093ae5d7 +F src/window.c 9f55b65411e1d37fa51b78afdeed16b73c73f1d97a052ee58c91c724a1b615d8 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1714,7 +1714,7 @@ F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af4 F test/window8.tcl 3b63931d608b6f00a9d26368207a7ffc9370c96e3e137ae2aff35284ade69d13 F test/window8.test 4531204bfb5d833efbd8a5a1527c9871e62f8ae479386f42a7b55bdb5be39df3 F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 -F test/windowA.test 5cd7c8dc3b2fcdfc6ea122c81a35726106880ae75afd097f62061839aff13b71 +F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 @@ -1838,7 +1838,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P f7002f86c780e279c9f8a6268f317586519c059c9de2115ff6f1cad272570c29 -R 717428315655334cbf16abae9c8648f7 -U dan -Z e01e05b9266977bc594b107aacdc1011 +P 900464567b2a5ce0c278a3297e4be1968f609258608aa0fbe2fc67709aa22a4b +Q -47cd634c98b502d40a493455ba6d73cbd0dae74944f9cf06fcbcd025f4b49d6e +R 29d0b25ea3e14a5d62e6dc7f8a60e5a3 +U drh +Z 198db2b82ee9fb9cef5cc67ca7c92ad8 diff --git a/manifest.uuid b/manifest.uuid index e5c97e32cd..aa386daac4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -900464567b2a5ce0c278a3297e4be1968f609258608aa0fbe2fc67709aa22a4b \ No newline at end of file +596ac2a4eab28b74f4050fb4eb71883f2a1421fdbccf302413e4653391bb52c9 \ No newline at end of file diff --git a/src/window.c b/src/window.c index fbb60b9c40..ad709bb036 100644 --- a/src/window.c +++ b/src/window.c @@ -2016,11 +2016,14 @@ static void windowCodeRangeTest( sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; case OP_Gt: - sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); VdbeCoverage(v); + sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); + VdbeCoverage(v); break; - default: assert( op==OP_Le ); - sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); VdbeCoverage(v); + case OP_Le: + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); + VdbeCoverage(v); break; + default: assert( op==OP_Lt ); /* no-op */ break; } sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+3); diff --git a/test/windowA.test b/test/windowA.test index 20c904eee2..e94ae57e43 100644 --- a/test/windowA.test +++ b/test/windowA.test @@ -289,4 +289,21 @@ do_execsql_test 3.4 { 1 A 5.4 A \ ] +do_execsql_test 4.0 { + SELECT a, b, quote(d), group_concat(b,'') OVER w1 FROM t1 + WINDOW w1 AS + (ORDER BY d DESC NULLS FIRST + RANGE BETWEEN 2.50 PRECEDING AND 0.5 PRECEDING) + ORDER BY +d DESC NULLS FIRST, +a; +} [list \ + 6 N NULL NN \ + 7 N NULL NN \ + 5 E 10.26 {} \ + 4 D 10.25 {} \ + 3 C 8.0 ED \ + 2 B 5.55 C \ + 1 A 5.4 {} \ +] + + finish_test From 9889ede28dd20ca1a2093a125cb38160eeb2c01a Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 30 Aug 2019 19:45:03 +0000 Subject: [PATCH 079/112] Add test case to window8.test. Also fix an error in a comment in window.c. FossilOrigin-Name: 2925bfa5971c8557ecaa6ac18df0825ebbbd1622017509e83451d90640146fa8 --- manifest | 19 +++++++++---------- manifest.uuid | 2 +- src/window.c | 4 ++-- test/window8.tcl | 16 ++++++++++++++++ test/window8.test | 17 +++++++++++++++++ 5 files changed, 45 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 9688a40bb9..5830119222 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Back\sout\sthe\schange\sat\s[47cd634c98b502d4]\swhich\swas\sincorrect.\s\sAdd\sa\stest\ncase\sso\sthat\swe\sdon't\saccidently\sback\sout\sthat\schange\sagain. -D 2019-08-30T18:02:49.143 +C Add\stest\scase\sto\swindow8.test.\sAlso\sfix\san\serror\sin\sa\scomment\sin\swindow.c. +D 2019-08-30T19:45:03.375 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -613,7 +613,7 @@ F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f -F src/window.c 9f55b65411e1d37fa51b78afdeed16b73c73f1d97a052ee58c91c724a1b615d8 +F src/window.c 96b0c033d33408f16ac8b177eac6362ee53a23d9b6d7a51a04289ab2f956bb77 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1711,8 +1711,8 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652 F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32 F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd -F test/window8.tcl 3b63931d608b6f00a9d26368207a7ffc9370c96e3e137ae2aff35284ade69d13 -F test/window8.test 4531204bfb5d833efbd8a5a1527c9871e62f8ae479386f42a7b55bdb5be39df3 +F test/window8.tcl 112bdc96dd310cfef93119fc5e4e9108c322080676fdb006ccc98d67d41c8acb +F test/window8.test 85ad3bd55615482c7a93f5286f0b0968f86ad0d62df5bca2f0ea50699e5aef31 F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 @@ -1838,8 +1838,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 900464567b2a5ce0c278a3297e4be1968f609258608aa0fbe2fc67709aa22a4b -Q -47cd634c98b502d40a493455ba6d73cbd0dae74944f9cf06fcbcd025f4b49d6e -R 29d0b25ea3e14a5d62e6dc7f8a60e5a3 -U drh -Z 198db2b82ee9fb9cef5cc67ca7c92ad8 +P 596ac2a4eab28b74f4050fb4eb71883f2a1421fdbccf302413e4653391bb52c9 +R 94fb5a9c76dec8423f58b92f29509529 +U dan +Z c980e1f35bfd2a5c73fbb1e591fe4935 diff --git a/manifest.uuid b/manifest.uuid index aa386daac4..a68d49dff1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -596ac2a4eab28b74f4050fb4eb71883f2a1421fdbccf302413e4653391bb52c9 \ No newline at end of file +2925bfa5971c8557ecaa6ac18df0825ebbbd1622017509e83451d90640146fa8 \ No newline at end of file diff --git a/src/window.c b/src/window.c index ad709bb036..7cb86e58be 100644 --- a/src/window.c +++ b/src/window.c @@ -1998,8 +1998,8 @@ static void windowCodeRangeTest( ** generated is equivalent to: ** ** if( reg1 IS NULL ){ - ** if( op==OP_Gt ) goto lbl; - ** if( op==OP_Ge && reg2 IS NOT NULL ) goto lbl; + ** if( op==OP_Ge ) goto lbl; + ** if( op==OP_Gt && reg2 IS NOT NULL ) goto lbl; ** if( op==OP_Le && reg2 IS NULL ) goto lbl; ** }else if( reg2 IS NULL ){ ** if( op==OP_Le ) goto lbl; diff --git a/test/window8.tcl b/test/window8.tcl index d881fd8e4b..aa934a8267 100644 --- a/test/window8.tcl +++ b/test/window8.tcl @@ -343,6 +343,22 @@ execsql_test 6.2 { ========== +execsql_test 7.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER, b INTEGER); + + INSERT INTO t2 VALUES(1, 65); + INSERT INTO t2 VALUES(2, NULL); + INSERT INTO t2 VALUES(3, NULL); + INSERT INTO t2 VALUES(4, NULL); +} + +execsql_test 7.1 { + SELECT sum(a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING + ); +} finish_test diff --git a/test/window8.test b/test/window8.test index 53d3e30027..0c7656b9a1 100644 --- a/test/window8.test +++ b/test/window8.test @@ -6205,4 +6205,21 @@ do_execsql_test 6.2 { #========================================================================== +do_execsql_test 7.0 { + DROP TABLE IF EXISTS t2; + CREATE TABLE t2(a INTEGER, b INTEGER); + + INSERT INTO t2 VALUES(1, 65); + INSERT INTO t2 VALUES(2, NULL); + INSERT INTO t2 VALUES(3, NULL); + INSERT INTO t2 VALUES(4, NULL); +} {} + +do_execsql_test 7.1 { + SELECT sum(a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING + ); +} {9 9 9 9} + finish_test From efb5f9a173e45a1cfb4e03f5680a6307f6e3f17c Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 21:52:13 +0000 Subject: [PATCH 080/112] Improvements to VDBE tracing. No changes to code in normal deliverables. FossilOrigin-Name: 54553bf16fabd72d1967acef317beb518e086707ccd45890b7c7256b8da08b75 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/vdbe.c | 8 +++++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index 5830119222..fd489fe4af 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\stest\scase\sto\swindow8.test.\sAlso\sfix\san\serror\sin\sa\scomment\sin\swindow.c. -D 2019-08-30T19:45:03.375 +C Improvements\sto\sVDBE\stracing.\s\sNo\schanges\sto\scode\sin\snormal\sdeliverables. +D 2019-08-30T21:52:13.928 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -595,7 +595,7 @@ F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c fca0f3762bc5cb7698a0bf754886503e703f66bf28013479c2177345053cab17 +F src/vdbe.c 351129b483cfbf4776fdb989dc92b460c8e9d4aa24a3ad553a2e18e4489fdca2 F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6 F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e @@ -1838,7 +1838,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 596ac2a4eab28b74f4050fb4eb71883f2a1421fdbccf302413e4653391bb52c9 -R 94fb5a9c76dec8423f58b92f29509529 -U dan -Z c980e1f35bfd2a5c73fbb1e591fe4935 +P 2925bfa5971c8557ecaa6ac18df0825ebbbd1622017509e83451d90640146fa8 +R e59b4dfec90afc7f1bc13be5998e1a64 +U drh +Z d085179c5e728bf4a41ae90b0a515b06 diff --git a/manifest.uuid b/manifest.uuid index a68d49dff1..0792ed6856 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2925bfa5971c8557ecaa6ac18df0825ebbbd1622017509e83451d90640146fa8 \ No newline at end of file +54553bf16fabd72d1967acef317beb518e086707ccd45890b7c7256b8da08b75 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index 25b0cb3dd0..f931da3805 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -485,11 +485,12 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ *(zCsr++) = c; sqlite3_snprintf(100, zCsr, "%d[", pMem->n); zCsr += sqlite3Strlen30(zCsr); - for(i=0; i<16 && in; i++){ + for(i=0; i<25 && in; i++){ sqlite3_snprintf(100, zCsr, "%02X", ((int)pMem->z[i] & 0xFF)); zCsr += sqlite3Strlen30(zCsr); } - for(i=0; i<16 && in; i++){ + *zCsr++ = '|'; + for(i=0; i<25 && in; i++){ char z = pMem->z[i]; if( z<32 || z>126 ) *zCsr++ = '.'; else *zCsr++ = z; @@ -519,7 +520,7 @@ void sqlite3VdbeMemPrettyPrint(Mem *pMem, char *zBuf){ sqlite3_snprintf(100, &zBuf[k], "%d", pMem->n); k += sqlite3Strlen30(&zBuf[k]); zBuf[k++] = '['; - for(j=0; j<15 && jn; j++){ + for(j=0; j<25 && jn; j++){ u8 c = pMem->z[j]; if( c>=0x20 && c<0x7f ){ zBuf[k++] = c; @@ -1832,6 +1833,7 @@ case OP_RealAffinity: { /* in1 */ testcase( pIn1->flags & MEM_Int ); testcase( pIn1->flags & MEM_IntReal ); sqlite3VdbeMemRealify(pIn1); + REGISTER_TRACE(pOp->p1, pIn1); } break; } From a7ce167e5b89e45d203014fc6ad0dbbfa3d44346 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 23:15:00 +0000 Subject: [PATCH 081/112] Make sure OP_RealAffinity has been applied to all columns of type REAL in the excluded.* pseudo-table of an UPSERT. Ticket [5a3dba8104421320] FossilOrigin-Name: 67381dadede98a55d8d9e085d021e6fa6473071978967b6302e03b28cf2245e1 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/upsert.c | 8 +++++++- test/upsert1.test | 10 ++++++++++ 4 files changed, 25 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index fd489fe4af..25379034a1 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sVDBE\stracing.\s\sNo\schanges\sto\scode\sin\snormal\sdeliverables. -D 2019-08-30T21:52:13.928 +C Make\ssure\sOP_RealAffinity\shas\sbeen\sapplied\sto\sall\scolumns\sof\stype\sREAL\nin\sthe\sexcluded.*\spseudo-table\sof\san\sUPSERT.\nTicket\s[5a3dba8104421320] +D 2019-08-30T23:15:00.679 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -591,7 +591,7 @@ F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1 F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 -F src/upsert.c 0dd81b40206841814d46942a7337786932475f085716042d0cb2fc7791bf8ca4 +F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf @@ -1593,7 +1593,7 @@ F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test ffeea7747d5ba962a8009a20b7e53d68cbae05b063604c68702c5998eb50c981 F test/update.test 1148de8d913e9817717990603aadeca07aab9ddbb10a30f167cbfd8d3a3ccb60 F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3 -F test/upsert1.test 994bde41800bb77dbe32fcd2e1f6c4b49cc9f2c6cd345731c774dff02b51c110 +F test/upsert1.test 9b115320149e6d72db64511a373c522746c2a2156efdbdb52add33504f66c989 F test/upsert2.test 9c3cdbb1a890227f6504ce4b0e3de68f4cdfa16bb21d8641208a9239896c5a09 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 @@ -1838,7 +1838,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 2925bfa5971c8557ecaa6ac18df0825ebbbd1622017509e83451d90640146fa8 -R e59b4dfec90afc7f1bc13be5998e1a64 +P 54553bf16fabd72d1967acef317beb518e086707ccd45890b7c7256b8da08b75 +R cef0df55cd7685f2b9e620402ed17caf U drh -Z d085179c5e728bf4a41ae90b0a515b06 +Z 1f2b76474aa0bfdfd3021ea753e61c50 diff --git a/manifest.uuid b/manifest.uuid index 0792ed6856..164a8fc461 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -54553bf16fabd72d1967acef317beb518e086707ccd45890b7c7256b8da08b75 \ No newline at end of file +67381dadede98a55d8d9e085d021e6fa6473071978967b6302e03b28cf2245e1 \ No newline at end of file diff --git a/src/upsert.c b/src/upsert.c index 850ae863b9..7beb9ffaec 100644 --- a/src/upsert.c +++ b/src/upsert.c @@ -205,6 +205,7 @@ void sqlite3UpsertDoUpdate( sqlite3 *db = pParse->db; SrcList *pSrc; /* FROM clause for the UPDATE */ int iDataCur; + int i; assert( v!=0 ); assert( pUpsert!=0 ); @@ -221,7 +222,6 @@ void sqlite3UpsertDoUpdate( Index *pPk = sqlite3PrimaryKeyIndex(pTab); int nPk = pPk->nKeyCol; int iPk = pParse->nMem+1; - int i; pParse->nMem += nPk; for(i=0; ipUpsertSrc, 0); + /* excluded.* columns of type REAL need to be converted to a hard real */ + for(i=0; inCol; i++){ + if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, pUpsert->regData+i); + } + } sqlite3Update(pParse, pSrc, pUpsert->pUpsertSet, pUpsert->pUpsertWhere, OE_Abort, 0, 0, pUpsert); pUpsert->pUpsertSet = 0; /* Will have been deleted by sqlite3Update() */ diff --git a/test/upsert1.test b/test/upsert1.test index 0d13cd8543..006af438dc 100644 --- a/test/upsert1.test +++ b/test/upsert1.test @@ -210,5 +210,15 @@ do_execsql_test upsert1-780 { SELECT * FROM t1; } {1 2 33 4 5} +# 2019-08-30 ticket https://sqlite.org/src/info/5a3dba8104421320 +do_execsql_test upsert1-800 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 REAL UNIQUE, c1); + CREATE UNIQUE INDEX test800i0 ON t0(0 || c1); + INSERT INTO t0(c0, c1) VALUES (1, 2), (2, 1); + INSERT INTO t0(c0) VALUES (1) ON CONFLICT(c0) DO UPDATE SET c1=excluded.c0; + PRAGMA integrity_check; + REINDEX; +} {ok} finish_test From 7314495ff82c0ed4ac6f2776121282e3a8fe566a Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 30 Aug 2019 23:56:34 +0000 Subject: [PATCH 082/112] When the affinity of a table column is INT or REAL, make the affinity of corresponding index columns NUMERIC. This increases the precision of index lookups for large numbers so that it matches the precision of ordinary comparison operators. Ticket [40812aea1fde9594] FossilOrigin-Name: e0d909c740b774d8a46731696e33342be83206cc4a95d07f42fdb3d8cc2d7a8e --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/insert.c | 1 + src/wherecode.c | 1 + test/affinity2.test | 11 +++++++++++ 5 files changed, 22 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 25379034a1..3d36562265 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Make\ssure\sOP_RealAffinity\shas\sbeen\sapplied\sto\sall\scolumns\sof\stype\sREAL\nin\sthe\sexcluded.*\spseudo-table\sof\san\sUPSERT.\nTicket\s[5a3dba8104421320] -D 2019-08-30T23:15:00.679 +C When\sthe\saffinity\sof\sa\stable\scolumn\sis\sINT\sor\sREAL,\smake\sthe\saffinity\sof\ncorresponding\sindex\scolumns\sNUMERIC.\s\sThis\sincreases\sthe\sprecision\sof\nindex\slookups\sfor\slarge\snumbers\sso\sthat\sit\smatches\sthe\sprecision\sof\nordinary\scomparison\soperators.\s\sTicket\s[40812aea1fde9594] +D 2019-08-30T23:56:34.003 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -484,7 +484,7 @@ F src/hash.c 8d7dda241d0ebdafb6ffdeda3149a412d7df75102cecfc1021c98d6219823b19 F src/hash.h 9d56a9079d523b648774c1784b74b89bd93fac7b365210157482e4319a468f38 F src/hwtime.h 747c1bbe9df21a92e9c50f3bbec1de841dc5e5da F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c 81eec6acf4fbf0942bbab6804fe50df3e109acba40b8bbfb00fec9a14d0715a6 +F src/insert.c 40557ebd69f4115e7a273f9304a8ab637a47ce44f3c6923396928f023967b5e8 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c a045bb3425a9a633cc0f78e93d9beda6866f4c0f15bfdee735aba7c6b39f5cc4 F src/main.c 51c55eb579eac4180bfcc6242741084710911350d2cd0c3fdd0f9fde55442128 @@ -611,11 +611,11 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 -F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b +F src/wherecode.c b27b95cbd901c50ff4b26835eb249f57845193615861742bd1056e6d2e40b40c F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 96b0c033d33408f16ac8b177eac6362ee53a23d9b6d7a51a04289ab2f956bb77 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 -F test/affinity2.test b03930d288e38b07f55023a58538ad174605695e98934bdab1facf6bd9ecc436 +F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1 @@ -1838,7 +1838,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 54553bf16fabd72d1967acef317beb518e086707ccd45890b7c7256b8da08b75 -R cef0df55cd7685f2b9e620402ed17caf +P 67381dadede98a55d8d9e085d021e6fa6473071978967b6302e03b28cf2245e1 +R 81c5159f885099a08c3a032048c494b3 U drh -Z 1f2b76474aa0bfdfd3021ea753e61c50 +Z df65619bddc85917641870cd10c4e180 diff --git a/manifest.uuid b/manifest.uuid index 164a8fc461..9793ee6e7a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -67381dadede98a55d8d9e085d021e6fa6473071978967b6302e03b28cf2245e1 \ No newline at end of file +e0d909c740b774d8a46731696e33342be83206cc4a95d07f42fdb3d8cc2d7a8e \ No newline at end of file diff --git a/src/insert.c b/src/insert.c index 04d3d580f5..d9078b89db 100644 --- a/src/insert.c +++ b/src/insert.c @@ -99,6 +99,7 @@ const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){ aff = sqlite3ExprAffinity(pIdx->aColExpr->a[n].pExpr); } if( affSQLITE_AFF_NUMERIC) aff = SQLITE_AFF_NUMERIC; pIdx->zColAff[n] = aff; } pIdx->zColAff[n] = 0; diff --git a/src/wherecode.c b/src/wherecode.c index 2fbcba17e9..22ed905f4e 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -755,6 +755,7 @@ static int codeAllEqualityTerms( if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ zAff[j] = SQLITE_AFF_BLOB; } + if( zAff[j]==SQLITE_AFF_REAL ) zAff[j] = SQLITE_AFF_NUMERIC; } } } diff --git a/test/affinity2.test b/test/affinity2.test index 40e442376e..acdf91c062 100644 --- a/test/affinity2.test +++ b/test/affinity2.test @@ -116,5 +116,16 @@ do_execsql_test 507 { SELECT * FROM t0 WHERE +-+'ce' >= t0.c0; } {-1 {}} +# 2019-08-30 ticket https://www.sqlite.org/src/info/40812aea1fde9594 +# +do_execsql_test 600 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 REAL UNIQUE); + INSERT INTO t0(c0) VALUES (3175546974276630385); + SELECT 3175546974276630385 < c0 FROM t0; +} {1} +do_execsql_test 601 { + SELECT 1 FROM t0 WHERE 3175546974276630385 < c0; +} {1} finish_test From 6a19865ff2f39ed313462da7e0e204b6ff3eb8b0 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Aug 2019 01:33:19 +0000 Subject: [PATCH 083/112] Remove some affinity tests that became unreachable due to the prior change. FossilOrigin-Name: e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 7 +++---- src/wherecode.c | 1 - 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 3d36562265..6bede4ab76 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sthe\saffinity\sof\sa\stable\scolumn\sis\sINT\sor\sREAL,\smake\sthe\saffinity\sof\ncorresponding\sindex\scolumns\sNUMERIC.\s\sThis\sincreases\sthe\sprecision\sof\nindex\slookups\sfor\slarge\snumbers\sso\sthat\sit\smatches\sthe\sprecision\sof\nordinary\scomparison\soperators.\s\sTicket\s[40812aea1fde9594] -D 2019-08-30T23:56:34.003 +C Remove\ssome\saffinity\stests\sthat\sbecame\sunreachable\sdue\sto\sthe\sprior\schange. +D 2019-08-31T01:33:19.183 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c e1b74116375bb88c1b4b90b635d417dcd0643ac46bacf5a3caefef60c8e5e115 +F src/expr.c 60cf8c778c3291220487bea46667339160f15bbddaef57c1a703c56d5fc76c52 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -611,7 +611,7 @@ F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 -F src/wherecode.c b27b95cbd901c50ff4b26835eb249f57845193615861742bd1056e6d2e40b40c +F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f F src/window.c 96b0c033d33408f16ac8b177eac6362ee53a23d9b6d7a51a04289ab2f956bb77 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 @@ -1838,7 +1838,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 67381dadede98a55d8d9e085d021e6fa6473071978967b6302e03b28cf2245e1 -R 81c5159f885099a08c3a032048c494b3 +P e0d909c740b774d8a46731696e33342be83206cc4a95d07f42fdb3d8cc2d7a8e +R fb7480045131ad29a415b8e551946237 U drh -Z df65619bddc85917641870cd10c4e180 +Z 73deec9d190744adeeaa8d20a010bc12 diff --git a/manifest.uuid b/manifest.uuid index 9793ee6e7a..9ee4cd5bb4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e0d909c740b774d8a46731696e33342be83206cc4a95d07f42fdb3d8cc2d7a8e \ No newline at end of file +e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index e87ff70507..0332dc3e53 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2203,10 +2203,10 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ if( op==TK_REGISTER ) op = p->op2; switch( op ){ case TK_INTEGER: { - return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC; + return aff>=SQLITE_AFF_NUMERIC; } case TK_FLOAT: { - return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC; + return aff>=SQLITE_AFF_NUMERIC; } case TK_STRING: { return !unaryMinus && aff==SQLITE_AFF_TEXT; @@ -2216,8 +2216,7 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){ } case TK_COLUMN: { assert( p->iTable>=0 ); /* p cannot be part of a CHECK constraint */ - return p->iColumn<0 - && (aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC); + return aff>=SQLITE_AFF_NUMERIC && p->iColumn<0; } default: { return 0; diff --git a/src/wherecode.c b/src/wherecode.c index 22ed905f4e..2fbcba17e9 100644 --- a/src/wherecode.c +++ b/src/wherecode.c @@ -755,7 +755,6 @@ static int codeAllEqualityTerms( if( sqlite3ExprNeedsNoAffinityChange(pRight, zAff[j]) ){ zAff[j] = SQLITE_AFF_BLOB; } - if( zAff[j]==SQLITE_AFF_REAL ) zAff[j] = SQLITE_AFF_NUMERIC; } } } From f66bfcb740c823c9c6ffce1f7f0d0c2bb811046a Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 31 Aug 2019 17:14:35 +0000 Subject: [PATCH 084/112] If a DELETE trigger fired by an UPDATE OR REPLACE statement deletes the row being updated, do not attempt to proceed with the original UPDATE operation. Fix for [d6a0fbc1]. FossilOrigin-Name: 4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93 --- manifest | 17 ++++++------ manifest.uuid | 2 +- src/update.c | 24 ++++++++-------- test/conflict3.test | 68 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 6bede4ab76..7d0e3d14ee 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\ssome\saffinity\stests\sthat\sbecame\sunreachable\sdue\sto\sthe\sprior\schange. -D 2019-08-31T01:33:19.183 +C If\sa\sDELETE\strigger\sfired\sby\san\sUPDATE\sOR\sREPLACE\sstatement\sdeletes\sthe\srow\sbeing\supdated,\sdo\snot\sattempt\sto\sproceed\swith\sthe\soriginal\sUPDATE\soperation.\sFix\sfor\s[d6a0fbc1]. +D 2019-08-31T17:14:35.569 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -590,7 +590,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e -F src/update.c 3cb9150d2cf661d938e2f1b1749945f3faa767f88febdb739ab1793bbf895ff2 +F src/update.c ce478c8ad297833d1acc825891e35d82a99f5986cfce1e92f44c3b0d54670114 F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 @@ -745,7 +745,7 @@ F test/colmeta.test 2c765ea61ee37bc43bbe6d6047f89004e6508eb1 F test/colname.test 87ad5458bb8709312dac0d6755fd30e8e4ca83298d0a9ef6e5c24277a3c3390e F test/conflict.test c7cc007e2af151516ddf38f7412fe10d473a694f55e3df437e2c7b31c2590e8d F test/conflict2.test bb0b94cf7196c64a3cbd815c66d3ee98c2fecd9c -F test/conflict3.test a83db76a6c3503b2fa057c7bfb08c318d8a422202d8bc5b86226e078e5b49ff9 +F test/conflict3.test 56d18aedfa521a7ebffadb8254cfff10caf4e49cd8659cb54da39513aed478ba F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3 F test/corrupt2.test bb50042cf9a1f1023d73af325d47eb02a6bb11e3c52f8812644b220c5d4bca35 @@ -1838,7 +1838,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P e0d909c740b774d8a46731696e33342be83206cc4a95d07f42fdb3d8cc2d7a8e -R fb7480045131ad29a415b8e551946237 -U drh -Z 73deec9d190744adeeaa8d20a010bc12 +P e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af +R 1a919c61b513d8917573ee41d8ce4c15 +T +closed 2a0152c9f5f2ca56734189521b3b114ad6ba7ee7941d0f22d262081125436f72 +U dan +Z 6965309018f410a0aa2e8d19660bb27e diff --git a/manifest.uuid b/manifest.uuid index 9ee4cd5bb4..5a00355cf9 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af \ No newline at end of file +4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93 \ No newline at end of file diff --git a/src/update.c b/src/update.c index bbeaa3d5ce..05cef6f58e 100644 --- a/src/update.c +++ b/src/update.c @@ -715,28 +715,29 @@ void sqlite3Update( } if( !isView ){ - int addr1 = 0; /* Address of jump instruction */ - /* Do constraint checks. */ assert( regOldRowid>0 ); sqlite3GenerateConstraintChecks(pParse, pTab, aRegIdx, iDataCur, iIdxCur, regNewRowid, regOldRowid, chngKey, onError, labelContinue, &bReplace, aXRef, 0); + /* If REPLACE conflict handling may have been used, or if the PK of the + ** row is changing, then the GenerateConstraintChecks() above may have + ** moved cursor iDataCur. Reseek it. */ + if( bReplace || chngKey ){ + if( pPk ){ + sqlite3VdbeAddOp4Int(v, OP_NotFound,iDataCur,labelContinue,regKey,nKey); + }else{ + sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); + } + } + /* Do FK constraint checks. */ if( hasFK ){ sqlite3FkCheck(pParse, pTab, regOldRowid, 0, aXRef, chngKey); } /* Delete the index entries associated with the current record. */ - if( bReplace || chngKey ){ - if( pPk ){ - addr1 = sqlite3VdbeAddOp4Int(v, OP_NotFound, iDataCur, 0, regKey, nKey); - }else{ - addr1 = sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, 0, regOldRowid); - } - VdbeCoverageNeverTaken(v); - } sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur, aRegIdx, -1); /* If changing the rowid value, or if there are foreign key constraints @@ -766,9 +767,6 @@ void sqlite3Update( sqlite3VdbeAddOp2(v, OP_Delete, iDataCur, 0); } #endif - if( bReplace || chngKey ){ - sqlite3VdbeJumpHere(v, addr1); - } if( hasFK ){ sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); diff --git a/test/conflict3.test b/test/conflict3.test index 751a442685..413e8241fe 100644 --- a/test/conflict3.test +++ b/test/conflict3.test @@ -366,5 +366,73 @@ do_execsql_test 12.3 { SELECT * FROM t2; } {111 111B 112 112} +#------------------------------------------------------------------------- +ifcapable trigger { + reset_db + do_execsql_test 13.1.0 { + PRAGMA recursive_triggers = true; + CREATE TABLE t0 (c0 UNIQUE, c1 UNIQUE); + CREATE TRIGGER tr0 AFTER DELETE ON t0 BEGIN + DELETE FROM t0; + END; + + INSERT INTO t0 VALUES(1, NULL); + INSERT INTO t0 VALUES(0, NULL); + } + + do_execsql_test 13.1.1 { + UPDATE OR REPLACE t0 SET c1 = 1; + } + + integrity_check 13.1.2 + + do_execsql_test 13.1.3 { + SELECT * FROM t0 + } {} + + do_execsql_test 13.2.0 { + CREATE TABLE t2 (a PRIMARY KEY, b UNIQUE, c UNIQUE) WITHOUT ROWID; + CREATE TRIGGER tr3 AFTER DELETE ON t2 BEGIN + DELETE FROM t2; + END; + + INSERT INTO t2 VALUES(1, 1, 1); + INSERT INTO t2 VALUES(2, 2, 2); + } + + do_execsql_test 13.2.1 { + UPDATE OR REPLACE t2 SET c = 0; + } + + integrity_check 13.2.2 + + do_execsql_test 13.2.3 { + SELECT * FROM t2 + } {} + + do_execsql_test 13.3.0 { + CREATE TABLE t1(a, b); + CREATE TABLE log(x); + CREATE INDEX i1 ON t1(a); + INSERT INTO t1 VALUES(1, 2); + + CREATE TRIGGER tb BEFORE UPDATE ON t1 BEGIN + DELETE FROM t1; + END; + CREATE TRIGGER ta AFTER UPDATE ON t1 BEGIN + INSERT INTO log VALUES('fired!'); + END; + + UPDATE t1 SET b=3; + } + + do_execsql_test 13.3.1 { + SELECT * FROM t1; + } {} + do_execsql_test 13.3.2 { + SELECT * FROM log; + } {} +} finish_test + From 80f6bfc064eac13c408aa7e46e2e154d1d40f297 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Aug 2019 20:13:30 +0000 Subject: [PATCH 085/112] Improvements to the algorithm that determines which SELECT in a sequence of nested SELECT statements that an aggregate function belongs to. This resolves an issue identified by dbsqlfuzz. FossilOrigin-Name: d768007473f4ed40abbdf2c7e501b580b1cc37c1620c7cb90af1f208a8c35145 --- manifest | 17 ++++++++--------- manifest.uuid | 2 +- src/expr.c | 8 ++++++-- test/aggnested.test | 30 +++++++++++++++++++++++++++++- 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 7d0e3d14ee..388d7e7892 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C If\sa\sDELETE\strigger\sfired\sby\san\sUPDATE\sOR\sREPLACE\sstatement\sdeletes\sthe\srow\sbeing\supdated,\sdo\snot\sattempt\sto\sproceed\swith\sthe\soriginal\sUPDATE\soperation.\sFix\sfor\s[d6a0fbc1]. -D 2019-08-31T17:14:35.569 +C Improvements\sto\sthe\salgorithm\sthat\sdetermines\swhich\sSELECT\sin\sa\ssequence\nof\snested\sSELECT\sstatements\sthat\san\saggregate\sfunction\sbelongs\sto.\s\sThis\nresolves\san\sissue\sidentified\sby\sdbsqlfuzz. +D 2019-08-31T20:13:30.510 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 60cf8c778c3291220487bea46667339160f15bbddaef57c1a703c56d5fc76c52 +F src/expr.c eb9b2e8b19d28ff58d20585964052166c0d38620593a8ab5c66214415f850261 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -618,7 +618,7 @@ F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 -F test/aggnested.test 18b00de006597e960a6b27ccec51474ac66cf1070a87c1933e5694dc02190ef1 +F test/aggnested.test 12106f0748e8e9bfc1a8e6840e203e051eae06a26ed13fc9fd5db108a8d6db54 F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 F test/alter.test 16ed8d2470193f34bc711e51506ff1211ebfab8025ca3b9510ff2aef139874cb @@ -1838,8 +1838,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 e2db1123faac26c0e0b6a1ebef1685ea7633bfcafd1ff743ba5380700f7745af -R 1a919c61b513d8917573ee41d8ce4c15 -T +closed 2a0152c9f5f2ca56734189521b3b114ad6ba7ee7941d0f22d262081125436f72 -U dan -Z 6965309018f410a0aa2e8d19660bb27e +P 4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93 +R 30aae3120e96fb727d9d30a86d181e41 +U drh +Z e2cf69056f38cf2141131156d9461b54 diff --git a/manifest.uuid b/manifest.uuid index 5a00355cf9..cef6b58a19 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93 \ No newline at end of file +d768007473f4ed40abbdf2c7e501b580b1cc37c1620c7cb90af1f208a8c35145 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 0332dc3e53..ba464f9af6 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5297,7 +5297,10 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){ } if( inThis++; - }else{ + }else if( nSrc==0 || pExpr->iTablea[0].iCursor ){ + /* In a well-formed parse tree (no name resolution errors), + /* TK_COLUMN nodes with smaller Expr.iTable values are in an + ** outer context. Those are the only ones to count as "other" */ p->nOther++; } } @@ -5314,8 +5317,9 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){ Walker w; struct SrcCount cnt; assert( pExpr->op==TK_AGG_FUNCTION ); + memset(&w, 0, sizeof(w)); w.xExprCallback = exprSrcCount; - w.xSelectCallback = 0; + w.xSelectCallback = sqlite3SelectWalkNoop; w.u.pSrcCount = &cnt; cnt.pSrc = pSrcList; cnt.nThis = 0; diff --git a/test/aggnested.test b/test/aggnested.test index 91de63b768..d712c840f1 100644 --- a/test/aggnested.test +++ b/test/aggnested.test @@ -1,4 +1,4 @@ -# 2012 August 23 +# 2012-08-23 # # The author disclaims copyright to this source code. In place of # a legal notice, here is a blessing: @@ -232,6 +232,34 @@ do_test aggnested-3.16 { GROUP BY id1; } } {12 2 34 4} + +# 2019-08-31 +# Problem found by dbsqlfuzz +# +do_execsql_test aggnested-4.1 { + DROP TABLE IF EXISTS aa; + DROP TABLE IF EXISTS bb; + CREATE TABLE aa(x INT); INSERT INTO aa(x) VALUES(123); + CREATE TABLE bb(y INT); INSERT INTO bb(y) VALUES(456); + SELECT (SELECT sum(x+(SELECT y)) FROM bb) FROM aa; +} {579} +do_execsql_test aggnested-4.2 { + SELECT (SELECT sum(x+y) FROM bb) FROM aa; +} {579} +do_execsql_test aggnested-4.3 { + DROP TABLE IF EXISTS tx; + DROP TABLE IF EXISTS ty; + CREATE TABLE tx(x INT); + INSERT INTO tx VALUES(1),(2),(3),(4),(5); + CREATE TABLE ty(y INT); + INSERT INTO ty VALUES(91),(92),(93); + SELECT min((SELECT count(y) FROM ty)) FROM tx; +} {3} +do_execsql_test aggnested-4.4 { + SELECT max((SELECT a FROM (SELECT count(*) AS a FROM ty) AS s)) FROM tx; +} {3} + + finish_test From 81d25cf53d27a4b352de086347850c69cf476aee Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Aug 2019 20:26:06 +0000 Subject: [PATCH 086/112] Mark new VDBE branches never taken. FossilOrigin-Name: 83c2adffbfb6dcdddb38ad9f888647b0e39fa24dc0bff344238e1f75a6c7d2ed --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/update.c | 1 + 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/manifest b/manifest index 388d7e7892..5d235eecce 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Improvements\sto\sthe\salgorithm\sthat\sdetermines\swhich\sSELECT\sin\sa\ssequence\nof\snested\sSELECT\sstatements\sthat\san\saggregate\sfunction\sbelongs\sto.\s\sThis\nresolves\san\sissue\sidentified\sby\sdbsqlfuzz. -D 2019-08-31T20:13:30.510 +C Mark\snew\sVDBE\sbranches\snever\staken. +D 2019-08-31T20:26:06.446 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -590,7 +590,7 @@ F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e -F src/update.c ce478c8ad297833d1acc825891e35d82a99f5986cfce1e92f44c3b0d54670114 +F src/update.c 7f05fad5e145248a00048aeb0bac78b8fdb4ed17216e14a6eb24c55596e87ee7 F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 @@ -1838,7 +1838,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 4145b3e05051ba6729105157a876793ad14a05d895fc10fe704f437eab16ea93 -R 30aae3120e96fb727d9d30a86d181e41 +P d768007473f4ed40abbdf2c7e501b580b1cc37c1620c7cb90af1f208a8c35145 +R 9655a2998ad4a94ca8d98590cef37323 U drh -Z e2cf69056f38cf2141131156d9461b54 +Z 4aa7a42c2ffc1c24ddf2d50e02e27484 diff --git a/manifest.uuid b/manifest.uuid index cef6b58a19..f08227ab52 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -d768007473f4ed40abbdf2c7e501b580b1cc37c1620c7cb90af1f208a8c35145 \ No newline at end of file +83c2adffbfb6dcdddb38ad9f888647b0e39fa24dc0bff344238e1f75a6c7d2ed \ No newline at end of file diff --git a/src/update.c b/src/update.c index 05cef6f58e..458550b95d 100644 --- a/src/update.c +++ b/src/update.c @@ -730,6 +730,7 @@ void sqlite3Update( }else{ sqlite3VdbeAddOp3(v, OP_NotExists, iDataCur, labelContinue,regOldRowid); } + VdbeCoverageNeverTaken(v); } /* Do FK constraint checks. */ From 35a38e0836e64f9df6ab487a6844724e94fadce3 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 31 Aug 2019 20:29:28 +0000 Subject: [PATCH 087/112] Fix a harmless compiler warning. FossilOrigin-Name: 63c67a54b4d3e501f3059dcdfc6bb50c6b8dad63a34eb773e4408d9e4e780d7a --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 5d235eecce..e8b9c179d0 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Mark\snew\sVDBE\sbranches\snever\staken. -D 2019-08-31T20:26:06.446 +C Fix\sa\sharmless\scompiler\swarning. +D 2019-08-31T20:29:28.511 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c eb9b2e8b19d28ff58d20585964052166c0d38620593a8ab5c66214415f850261 +F src/expr.c 150acd113edf50e807c70eedf1629b1d94b1177b8a56497e23d8ccf1e1e2a74f F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1838,7 +1838,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 d768007473f4ed40abbdf2c7e501b580b1cc37c1620c7cb90af1f208a8c35145 -R 9655a2998ad4a94ca8d98590cef37323 +P 83c2adffbfb6dcdddb38ad9f888647b0e39fa24dc0bff344238e1f75a6c7d2ed +R 37932a778dd889046a85359e8b20b826 U drh -Z 4aa7a42c2ffc1c24ddf2d50e02e27484 +Z d8bf046d3fa628e5022d569bcd7f67c8 diff --git a/manifest.uuid b/manifest.uuid index f08227ab52..353e3b4bbc 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83c2adffbfb6dcdddb38ad9f888647b0e39fa24dc0bff344238e1f75a6c7d2ed \ No newline at end of file +63c67a54b4d3e501f3059dcdfc6bb50c6b8dad63a34eb773e4408d9e4e780d7a \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ba464f9af6..61b45b9923 100644 --- a/src/expr.c +++ b/src/expr.c @@ -5299,7 +5299,7 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){ p->nThis++; }else if( nSrc==0 || pExpr->iTablea[0].iCursor ){ /* In a well-formed parse tree (no name resolution errors), - /* TK_COLUMN nodes with smaller Expr.iTable values are in an + ** TK_COLUMN nodes with smaller Expr.iTable values are in an ** outer context. Those are the only ones to count as "other" */ p->nOther++; } From cc80db69e9c52304b50209a4aca66b1ae908b602 Mon Sep 17 00:00:00 2001 From: drh Date: Sun, 1 Sep 2019 23:36:33 +0000 Subject: [PATCH 088/112] Remove an obsolete paragraph from the OP_Column documentation. No code changes. FossilOrigin-Name: f6d8956cf8b5993a4332b9330e89d5c3d5f8872ea5a2ce3d2e91127406cc1839 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/vdbe.c | 5 ----- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/manifest b/manifest index e8b9c179d0..6b305d6bfc 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sharmless\scompiler\swarning. -D 2019-08-31T20:29:28.511 +C Remove\san\sobsolete\sparagraph\sfrom\sthe\sOP_Column\sdocumentation.\s\sNo\scode\nchanges. +D 2019-09-01T23:36:33.093 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -595,7 +595,7 @@ F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10 F src/utf.c 2f0fac345c7660d5c5bd3df9e9d8d33d4c27f366bcfb09e07443064d751a0507 F src/util.c fffdfa627be74d69ef425f92db124e7148af449bb8a3286e79577c42bca84061 F src/vacuum.c 82dcec9e7b1afa980288718ad11bc499651c722d7b9f32933c4d694d91cb6ebf -F src/vdbe.c 351129b483cfbf4776fdb989dc92b460c8e9d4aa24a3ad553a2e18e4489fdca2 +F src/vdbe.c 145e417fda9377a809d9c754d4098de9a9620aec1bc3e4d2d4ca8f8d525dace3 F src/vdbe.h 3f2b571e702e77e6bf031f0236e554aedfae643e991f69000320f481408455cf F src/vdbeInt.h e95de5129124d77f01439e6635012adfaf23c0017bff47296126143cf18bd0c6 F src/vdbeapi.c 95001d0f84ee3cda344fed98ca0d7961deb4fc836b83495630d0af1f7cc4789e @@ -1838,7 +1838,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 83c2adffbfb6dcdddb38ad9f888647b0e39fa24dc0bff344238e1f75a6c7d2ed -R 37932a778dd889046a85359e8b20b826 +P 63c67a54b4d3e501f3059dcdfc6bb50c6b8dad63a34eb773e4408d9e4e780d7a +R c1da51105a0bd41bcf8b282b1f2a62fa U drh -Z d8bf046d3fa628e5022d569bcd7f67c8 +Z 7a37af4640fc76b6e62eb0e6e9abd09a diff --git a/manifest.uuid b/manifest.uuid index 353e3b4bbc..22f0b4591b 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -63c67a54b4d3e501f3059dcdfc6bb50c6b8dad63a34eb773e4408d9e4e780d7a \ No newline at end of file +f6d8956cf8b5993a4332b9330e89d5c3d5f8872ea5a2ce3d2e91127406cc1839 \ No newline at end of file diff --git a/src/vdbe.c b/src/vdbe.c index f931da3805..89adc31bf5 100644 --- a/src/vdbe.c +++ b/src/vdbe.c @@ -2527,11 +2527,6 @@ case OP_Offset: { /* out3 */ ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. ** -** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, -** then the cache of the cursor is reset prior to extracting the column. -** The first OP_Column against a pseudo-table after the value of the content -** register has changed should have this bit set. -** ** If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then ** the result is guaranteed to only be used as the argument of a length() ** or typeof() function, respectively. The loading of large blobs can be From bffdd636339b32c706253e8c791ccca8b3f88f19 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Sep 2019 00:58:44 +0000 Subject: [PATCH 089/112] When computing an expression value for an index-on-expression or a CHECK constraint and the expressions uses a REAL table column, but the value of that column is an integer (in other words, when it is using the store-real-as-integer optimization) be sure to promote the value to real before evaluating the expression. Ticket [57af00b6642ecd68]. FossilOrigin-Name: 0658c16e311393c8a347b1bd41fa5dbfd2e184aa75d84c011aa8dbac79b632e9 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 14 +++++++++++++- test/check.test | 14 ++++++++++++++ test/indexexpr1.test | 24 ++++++++++++++++++++++++ 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index 6b305d6bfc..487542d132 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Remove\san\sobsolete\sparagraph\sfrom\sthe\sOP_Column\sdocumentation.\s\sNo\scode\nchanges. -D 2019-09-01T23:36:33.093 +C When\scomputing\san\sexpression\svalue\sfor\san\sindex-on-expression\sor\sa\sCHECK\nconstraint\sand\sthe\sexpressions\suses\sa\sREAL\stable\scolumn,\sbut\sthe\svalue\sof\nthat\scolumn\sis\san\sinteger\s(in\sother\swords,\swhen\sit\sis\susing\sthe\s\nstore-real-as-integer\soptimization)\sbe\ssure\sto\spromote\sthe\svalue\sto\sreal\nbefore\sevaluating\sthe\sexpression.\s\sTicket\s[57af00b6642ecd68]. +D 2019-09-02T00:58:44.169 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 150acd113edf50e807c70eedf1629b1d94b1177b8a56497e23d8ccf1e1e2a74f +F src/expr.c dcf6eb84656d3c5b41d6755cdb55a264a3f6f8f12e68bf87fa27bdd33e263ee3 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -724,7 +724,7 @@ F test/capi3d.test aba917805573a03deed961a21f07a5a84505ad0a616f7e3fc1508844a15bc F test/capi3e.test 3d49c01ef2a1a55f41d73cba2b23b5059ec460fe F test/cast.test 3619f0c58c2e4b2a94aa86e75607e497d34ef40ab74418e71aef7b4ca5155895 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/check.test e6527bed2b5557ffdbf5680765c4ae6fe61e9b68b7ee69a7f776787a4527b5da +F test/check.test 4b57ecbbb300336382ca21ef983dfa70b291a70ae430690494d13f1629f45a38 F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760 F test/close.test eccbad8ecd611d974cbf47278c3d4e5874faf02d811338d5d348af42d56d647c @@ -1052,7 +1052,7 @@ F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 F test/indexedby.test a52c8c6abfae4fbfb51d99440de4ca1840dbacc606b05e29328a2a8ba7cd914e -F test/indexexpr1.test 0f293369ed6f56764cfc3db05685d45469d9e685ba87e3698527049ba359ae24 +F test/indexexpr1.test fb56f0b9a9d147b38979d154176f150b5e45fdd5d0162fab639a7f9478134fa3 F test/indexexpr2.test b580f378423bca443ffab47ada677203cfcf8a60f48a8aa20065f27c8f7739b5 F test/indexfault.test 98d78a8ff1f5335628b62f886a1cb7c7dac1ef6d48fa39c51ec871c87dce9811 F test/init.test 15c823093fdabbf7b531fe22cf037134d09587a7 @@ -1838,7 +1838,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 63c67a54b4d3e501f3059dcdfc6bb50c6b8dad63a34eb773e4408d9e4e780d7a -R c1da51105a0bd41bcf8b282b1f2a62fa +P f6d8956cf8b5993a4332b9330e89d5c3d5f8872ea5a2ce3d2e91127406cc1839 +R cad500c6656aba1cd58b9ed6ead8c93d U drh -Z 7a37af4640fc76b6e62eb0e6e9abd09a +Z 159d6991963aae3d8bb85f2594c26695 diff --git a/manifest.uuid b/manifest.uuid index 22f0b4591b..73fff4cb11 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f6d8956cf8b5993a4332b9330e89d5c3d5f8872ea5a2ce3d2e91127406cc1839 \ No newline at end of file +0658c16e311393c8a347b1bd41fa5dbfd2e184aa75d84c011aa8dbac79b632e9 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 61b45b9923..622024eb22 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3532,7 +3532,19 @@ expr_code_doover: if( iTab<0 ){ if( pParse->iSelfTab<0 ){ /* Generating CHECK constraints or inserting into partial index */ - return pExpr->iColumn - pParse->iSelfTab; + assert( pExpr->y.pTab!=0 ); + assert( pExpr->iColumn>=XN_ROWID ); + assert( pExpr->iColumny.pTab->nCol ); + if( pExpr->iColumn>=0 + && pExpr->y.pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL + ){ + sqlite3VdbeAddOp2(v, OP_SCopy, pExpr->iColumn - pParse->iSelfTab, + target); + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + return target; + }else{ + return pExpr->iColumn - pParse->iSelfTab; + } }else{ /* Coding an expression that is part of an index where column names ** in the index refer to the table to which the index belongs */ diff --git a/test/check.test b/test/check.test index b703c75b00..e23043eb04 100644 --- a/test/check.test +++ b/test/check.test @@ -123,6 +123,11 @@ do_test check-2.1 { y REAL CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ), z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' ) ); + CREATE TABLE t2n( + x INTEGER CONSTRAINT one CHECK( typeof(coalesce(x,0))=="integer" ), + y NUMERIC CONSTRAINT two CHECK( typeof(coalesce(y,0.1))=='real' ), + z TEXT CONSTRAINT three CHECK( typeof(coalesce(z,''))=='text' ) + ); PRAGMA writable_schema = 0; } } {} @@ -146,9 +151,17 @@ do_test check-2.4 { } } {1 {CHECK constraint failed: one}} do_test check-2.5 { + # The 5 gets automatically promoted to 5.0 because the column type is REAL catchsql { INSERT INTO t2 VALUES(NULL, 5, NULL); } +} {0 {}} +do_test check-2.5b { + # This time the column type is NUMERIC, so not automatic promption to REAL + # occurs and the constraint fails. + catchsql { + INSERT INTO t2n VALUES(NULL, 5, NULL); + } } {1 {CHECK constraint failed: two}} do_test check-2.6 { catchsql { @@ -195,6 +208,7 @@ do_test check-2.cleanup { execsql { DROP TABLE IF EXISTS t2b; DROP TABLE IF EXISTS t2c; + DROP TABLE IF EXISTS t2n; } } {} diff --git a/test/indexexpr1.test b/test/indexexpr1.test index ed7d9ffbc2..353792875b 100644 --- a/test/indexexpr1.test +++ b/test/indexexpr1.test @@ -457,4 +457,28 @@ do_execsql_test indexexpr-1700 { SELECT * FROM t0 WHERE ((NULL IS FALSE) IS FALSE); } {0} +# 2019-09-02 https://www.sqlite.org/src/tktview/57af00b6642ecd6848 +# When the expression of an an index-on-expression references a +# table column of type REAL that is actually holding an MEM_IntReal +# value, be sure to use the REAL value and not the INT value when +# computing the expression. +# +do_execsql_test indexexpr-1800 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 REAL, c1 TEXT); + CREATE INDEX i0 ON t0(+c0, c0); + INSERT INTO t0(c0) VALUES(0); + SELECT CAST(+ t0.c0 AS BLOB) LIKE 0 FROM t0; +} {0} +do_execsql_test indexexpr-1810 { + SELECT CAST(+ t0.c0 AS BLOB) LIKE '0.0' FROM t0; +} {1} +do_execsql_test indexexpr-1820 { + DROP TABLE IF EXISTS t1; + CREATE TABLE t1(x REAL); + CREATE INDEX t1x ON t1(x, +x); + INSERT INTO t1(x) VALUES(2); + SELECT +x FROM t1 WHERE x=2; +} {2.0} + finish_test From 0167ef202b2279af622956a4a1a073531759c216 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Sep 2019 01:25:07 +0000 Subject: [PATCH 090/112] Fix an obsolete comment that defines the meaning of one of the parameters to the sqlite3FindInIndex() subroutine. No changes to code. FossilOrigin-Name: 0c946f0846b2835f8facca806a4d4ecc2b2e97343de245a0d91716d998b2a829 --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/expr.c | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 487542d132..2a6ffeaf7b 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\scomputing\san\sexpression\svalue\sfor\san\sindex-on-expression\sor\sa\sCHECK\nconstraint\sand\sthe\sexpressions\suses\sa\sREAL\stable\scolumn,\sbut\sthe\svalue\sof\nthat\scolumn\sis\san\sinteger\s(in\sother\swords,\swhen\sit\sis\susing\sthe\s\nstore-real-as-integer\soptimization)\sbe\ssure\sto\spromote\sthe\svalue\sto\sreal\nbefore\sevaluating\sthe\sexpression.\s\sTicket\s[57af00b6642ecd68]. -D 2019-09-02T00:58:44.169 +C Fix\san\sobsolete\scomment\sthat\sdefines\sthe\smeaning\sof\sone\sof\sthe\sparameters\nto\sthe\ssqlite3FindInIndex()\ssubroutine.\s\sNo\schanges\sto\scode. +D 2019-09-02T01:25:07.870 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c dcf6eb84656d3c5b41d6755cdb55a264a3f6f8f12e68bf87fa27bdd33e263ee3 +F src/expr.c 1deee9370bc77f62445ce1b08ff69cdd54392f5cf612115f7abb98c0d49aa01b F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1838,7 +1838,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 f6d8956cf8b5993a4332b9330e89d5c3d5f8872ea5a2ce3d2e91127406cc1839 -R cad500c6656aba1cd58b9ed6ead8c93d +P 0658c16e311393c8a347b1bd41fa5dbfd2e184aa75d84c011aa8dbac79b632e9 +R b2ce2af57b181c2a5634330a829a5023 U drh -Z 159d6991963aae3d8bb85f2594c26695 +Z 59d1e18494dcde88177cbb1d6f2d9350 diff --git a/manifest.uuid b/manifest.uuid index 73fff4cb11..bf91deb6a3 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0658c16e311393c8a347b1bd41fa5dbfd2e184aa75d84c011aa8dbac79b632e9 \ No newline at end of file +0c946f0846b2835f8facca806a4d4ecc2b2e97343de245a0d91716d998b2a829 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index 622024eb22..fabb99cda5 100644 --- a/src/expr.c +++ b/src/expr.c @@ -2399,7 +2399,7 @@ static int sqlite3InRhsIsConstant(Expr *pIn){ #ifndef SQLITE_OMIT_SUBQUERY int sqlite3FindInIndex( Parse *pParse, /* Parsing context */ - Expr *pX, /* The right-hand side (RHS) of the IN operator */ + Expr *pX, /* The IN expression */ u32 inFlags, /* IN_INDEX_LOOP, _MEMBERSHIP, and/or _NOOP_OK */ int *prRhsHasNull, /* Register holding NULL status. See notes */ int *aiMap, /* Mapping from Index fields to RHS fields */ From dd668c26b5d7a7526638e39239844e01a1d251e0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Sep 2019 02:21:58 +0000 Subject: [PATCH 091/112] When applying the IN_INDEX_NOOP optimization and the LHS has REAL affinity, also apply REAL affinity to each element of the RHS. Ticket [2841e99d104c6436]. FossilOrigin-Name: 88833a9c2849c959a37a80e0e4d2b211ce3c83a48319724c89b172b060c876b4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/expr.c | 5 +++++ test/in.test | 16 ++++++++++++++++ 4 files changed, 29 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index 2a6ffeaf7b..6823b43838 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\san\sobsolete\scomment\sthat\sdefines\sthe\smeaning\sof\sone\sof\sthe\sparameters\nto\sthe\ssqlite3FindInIndex()\ssubroutine.\s\sNo\schanges\sto\scode. -D 2019-09-02T01:25:07.870 +C When\sapplying\sthe\sIN_INDEX_NOOP\soptimization\sand\sthe\sLHS\shas\sREAL\saffinity,\nalso\sapply\sREAL\saffinity\sto\seach\selement\sof\sthe\sRHS.\nTicket\s[2841e99d104c6436]. +D 2019-09-02T02:21:58.055 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -475,7 +475,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 1deee9370bc77f62445ce1b08ff69cdd54392f5cf612115f7abb98c0d49aa01b +F src/expr.c 718634de1cb95ffbeaa1c08416a2bcd250b5586552a3360c667a56c77dd8ade3 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1025,7 +1025,7 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 -F test/in.test 1f82966f8c3f380c0a2d5a04e4111a333c3f46d96f40fb540e022c70ace85c11 +F test/in.test 47b0666a90e3a60798e202f0abf98b43e595ba2a6352b0ffdf1fbd0cae3ab0a4 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test 0f77b0ff371549e6a119d0356be10bdba72258162e9701e83527a560482f5e98 @@ -1838,7 +1838,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 0658c16e311393c8a347b1bd41fa5dbfd2e184aa75d84c011aa8dbac79b632e9 -R b2ce2af57b181c2a5634330a829a5023 +P 0c946f0846b2835f8facca806a4d4ecc2b2e97343de245a0d91716d998b2a829 +R b383caec03caa1393be330eb632af662 U drh -Z 59d1e18494dcde88177cbb1d6f2d9350 +Z 55e1775d24543874635834b1ff207b49 diff --git a/manifest.uuid b/manifest.uuid index bf91deb6a3..b19fb06e09 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -0c946f0846b2835f8facca806a4d4ecc2b2e97343de245a0d91716d998b2a829 \ No newline at end of file +88833a9c2849c959a37a80e0e4d2b211ce3c83a48319724c89b172b060c876b4 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index fabb99cda5..ac3d1c8e21 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3124,13 +3124,18 @@ static void sqlite3ExprCodeIN( int r2, regToFree; int regCkNull = 0; int ii; + int bLhsReal; /* True if the LHS of the IN has REAL affinity */ assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); if( destIfNull!=destIfFalse ){ regCkNull = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_BitAnd, rLhs, rLhs, regCkNull); } + bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL; for(ii=0; iinExpr; ii++){ r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); + if( bLhsReal ){ + sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC); + } if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); } diff --git a/test/in.test b/test/in.test index f96dfcc11e..bd1209fb67 100644 --- a/test/in.test +++ b/test/in.test @@ -759,5 +759,21 @@ do_execsql_test in-18.1 { SELECT * FROM t0 WHERE '1' IN (t0.c0); } {} +# 2019-09-02 ticket https://www.sqlite.org/src/info/2841e99d104c6436 +# For the IN_INDEX_NOOP optimization, apply REAL affinity to the LHS +# values prior to comparison if the RHS has REAL affinity. +# +do_execsql_test in-19.1 { + DROP TABLE IF EXISTS t0; + CREATE TABLE t0(c0 REAL UNIQUE); + INSERT INTO t0(c0) VALUES(2.07093491255203046E18); + SELECT 1 FROM t0 WHERE c0 IN ('2070934912552030444'); +} {1} +do_execsql_test in-19.2 { + SELECT c0 IN ('2070934912552030444') FROM t0; +} {1} +do_execsql_test in-19.3 { + SELECT c0 IN ('2070934912552030444',2,3) FROM t0; +} {1} finish_test From 229ae1ae72d3693e675703be2b986f62fb536cb1 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 2 Sep 2019 14:46:12 +0000 Subject: [PATCH 092/112] Fix a potential crash in fts5 caused by using an auxiliary function on a "special" query like '*id' or '*reads'. FossilOrigin-Name: 9490683ae883561fa347cbe54ebdd61188d849b4852d904b508250ba5d0807ef --- ext/fts5/fts5_main.c | 6 ++-- ext/fts5/test/fts5misc.test | 63 +++++++++++++++++++++++++++++++++++++ manifest | 15 ++++----- manifest.uuid | 2 +- 4 files changed, 75 insertions(+), 11 deletions(-) create mode 100644 ext/fts5/test/fts5misc.test diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 4bb3a9965f..da5deef846 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -988,10 +988,10 @@ static int fts5SpecialMatch( assert( pTab->p.base.zErrMsg==0 ); pCsr->ePlan = FTS5_PLAN_SPECIAL; - if( 0==sqlite3_strnicmp("reads", z, n) ){ + if( n==5 && 0==sqlite3_strnicmp("reads", z, n) ){ pCsr->iSpecial = sqlite3Fts5IndexReads(pTab->p.pIndex); } - else if( 0==sqlite3_strnicmp("id", z, n) ){ + else if( n==2 && 0==sqlite3_strnicmp("id", z, n) ){ pCsr->iSpecial = pCsr->iCsrId; } else{ @@ -2239,7 +2239,7 @@ static void fts5ApiCallback( iCsrId = sqlite3_value_int64(argv[0]); pCsr = fts5CursorFromCsrid(pAux->pGlobal, iCsrId); - if( pCsr==0 ){ + if( pCsr==0 || pCsr->ePlan==0 ){ char *zErr = sqlite3_mprintf("no such cursor: %lld", iCsrId); sqlite3_result_error(context, zErr, -1); sqlite3_free(zErr); diff --git a/ext/fts5/test/fts5misc.test b/ext/fts5/test/fts5misc.test new file mode 100644 index 0000000000..009f578dce --- /dev/null +++ b/ext/fts5/test/fts5misc.test @@ -0,0 +1,63 @@ +# 2019 September 02 +# +# 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. The +# focus of this script is testing the FTS5 module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5misc + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a); +} + +do_catchsql_test 1.1.1 { + SELECT highlight(t1, 4, '', '') FROM t1('*'); +} {1 {unknown special query: }} +do_catchsql_test 1.1.2 { + SELECT a FROM t1 + WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*')); +} {1 {unknown special query: }} + +do_catchsql_test 1.2.1 { + SELECT highlight(t1, 4, '', '') FROM t1('*id'); +} {0 {{}}} + +do_catchsql_test 1.2.2 { + SELECT a FROM t1 + WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*id')); +} {0 {}} + +do_catchsql_test 1.3.1 { + SELECT highlight(t1, 4, '', '') FROM t1('*reads'); +} {1 {no such cursor: 1}} + +do_catchsql_test 1.3.2 { + SELECT a FROM t1 + WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*reads')); +} {1 {no such cursor: 1}} + +db close +sqlite3 db test.db + +do_catchsql_test 1.3.3 { + SELECT a FROM t1 + WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*reads')); +} {1 {no such cursor: 1}} + +finish_test + diff --git a/manifest b/manifest index 6823b43838..f5fececbb6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C When\sapplying\sthe\sIN_INDEX_NOOP\soptimization\sand\sthe\sLHS\shas\sREAL\saffinity,\nalso\sapply\sREAL\saffinity\sto\seach\selement\sof\sthe\sRHS.\nTicket\s[2841e99d104c6436]. -D 2019-09-02T02:21:58.055 +C Fix\sa\spotential\scrash\sin\sfts5\scaused\sby\susing\san\sauxiliary\sfunction\son\sa\s"special"\squery\slike\s'*id'\sor\s'*reads'. +D 2019-09-02T14:46:12.332 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,7 +117,7 @@ F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1 F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 F ext/fts5/fts5_index.c b062bdb836e195656aac8d6684e943585cff4bf7d7c593c80cb67c3b6cfef7ee -F ext/fts5/fts5_main.c b2c42f1cef9673ecdd498b22c38483a4380bcf1701d1e61b021a2945f18e42e1 +F ext/fts5/fts5_main.c 15dc14ea594ff2ea183f5e79c8f6fea14640ac7c4bd5d93ad1d506a4db80c998 F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -189,6 +189,7 @@ F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc27826807405 F ext/fts5/test/fts5matchinfo.test 79129ff6c9a2d86943b287a5a8caa7ee639f6dcf004d8975d15c279374e82e35 F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 +F ext/fts5/test/fts5misc.test 5becd134b66f7370042968a2b127b92ea7748e249f16cb6a996f450812e89eec F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da @@ -1838,7 +1839,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 0c946f0846b2835f8facca806a4d4ecc2b2e97343de245a0d91716d998b2a829 -R b383caec03caa1393be330eb632af662 -U drh -Z 55e1775d24543874635834b1ff207b49 +P 88833a9c2849c959a37a80e0e4d2b211ce3c83a48319724c89b172b060c876b4 +R ecf23e7895e522aa6db47033eb1fe1d8 +U dan +Z 9a0d4ac9ca62f38c69e05c62c21dab75 diff --git a/manifest.uuid b/manifest.uuid index b19fb06e09..d58c001b4c 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -88833a9c2849c959a37a80e0e4d2b211ce3c83a48319724c89b172b060c876b4 \ No newline at end of file +9490683ae883561fa347cbe54ebdd61188d849b4852d904b508250ba5d0807ef \ No newline at end of file From 4fc836546e035fc18a4bf66c3bb895dc5af10fa0 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 2 Sep 2019 22:13:06 +0000 Subject: [PATCH 093/112] Fix a bug introduced earlier today by check-in [88833a9c2849c959]. Ticket [29f635e0af71234b] FossilOrigin-Name: 6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73 --- manifest | 16 ++++++++-------- manifest.uuid | 2 +- src/expr.c | 5 ++++- test/in.test | 9 +++++++++ 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index f5fececbb6..8a800c1dc3 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\spotential\scrash\sin\sfts5\scaused\sby\susing\san\sauxiliary\sfunction\son\sa\s"special"\squery\slike\s'*id'\sor\s'*reads'. -D 2019-09-02T14:46:12.332 +C Fix\sa\sbug\sintroduced\searlier\stoday\sby\scheck-in\s[88833a9c2849c959].\nTicket\s[29f635e0af71234b] +D 2019-09-02T22:13:06.403 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -476,7 +476,7 @@ F src/date.c e1d8ac7102f3f283e63e13867acb0efa33861cf34f0faf4cdbaf9fa7a1eb7041 F src/dbpage.c 135eb3b5e74f9ef74bde5cec2571192c90c86984fa534c88bf4a055076fa19b7 F src/dbstat.c c12833de69cb655751487d2c5a59607e36be1c58ba1f4bd536609909ad47b319 F src/delete.c d08c9e01a2664afd12edcfa3a9c6578517e8ff8735f35509582693adbe0edeaf -F src/expr.c 718634de1cb95ffbeaa1c08416a2bcd250b5586552a3360c667a56c77dd8ade3 +F src/expr.c 10d90c4676047a75276446779d18fb3f7d3a1f9debc8b322e3772d2bd51f52ff F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 F src/fkey.c 6b79f4c2447691aa9ac86e2a6a774b65f3b3dd053d4220a4893051a0de20f82e F src/func.c 4ee36219698d50d672a28eca4adb0fd6b92e607a1883d318315e0d2fd5044467 @@ -1026,7 +1026,7 @@ F test/hook2.test b9ff3b8c6519fb67f33192f1afe86e7782ee4ac8 F test/icu.test 41aa8847745a879b897a7febea0f8f9efc8e67fe8bf680589b6e07c7b0a1569a F test/ieee754.test 806fc0ce7f305f57e3331eaceeddcfec9339e607 F test/imposter1.test c3f1db2d3db2c24611a6596a3fc0ffc14f1466c8 -F test/in.test 47b0666a90e3a60798e202f0abf98b43e595ba2a6352b0ffdf1fbd0cae3ab0a4 +F test/in.test 3e9bd58597a444123a40a9ac94cae0fec8897e17e9f519b02fc370bcf5ba5175 F test/in2.test 5d4c61d17493c832f7d2d32bef785119e87bde75 F test/in3.test 3cbf58c87f4052cee3a58b37b6389777505aa0c0 F test/in4.test 0f77b0ff371549e6a119d0356be10bdba72258162e9701e83527a560482f5e98 @@ -1839,7 +1839,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 88833a9c2849c959a37a80e0e4d2b211ce3c83a48319724c89b172b060c876b4 -R ecf23e7895e522aa6db47033eb1fe1d8 -U dan -Z 9a0d4ac9ca62f38c69e05c62c21dab75 +P 9490683ae883561fa347cbe54ebdd61188d849b4852d904b508250ba5d0807ef +R 931628c07078d6a1ec560a2e18a3f53f +U drh +Z 31499ded87036041191e77b0df0459dc diff --git a/manifest.uuid b/manifest.uuid index d58c001b4c..d9a9e049c6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9490683ae883561fa347cbe54ebdd61188d849b4852d904b508250ba5d0807ef \ No newline at end of file +6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73 \ No newline at end of file diff --git a/src/expr.c b/src/expr.c index ac3d1c8e21..949758b10e 100644 --- a/src/expr.c +++ b/src/expr.c @@ -3132,9 +3132,12 @@ static void sqlite3ExprCodeIN( } bLhsReal = sqlite3ExprAffinity(pExpr->pLeft)==SQLITE_AFF_REAL; for(ii=0; iinExpr; ii++){ - r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); if( bLhsReal ){ + r2 = regToFree = sqlite3GetTempReg(pParse); + sqlite3ExprCode(pParse, pList->a[ii].pExpr, r2); sqlite3VdbeAddOp4(v, OP_Affinity, r2, 1, 0, "E", P4_STATIC); + }else{ + r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, ®ToFree); } if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){ sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull); diff --git a/test/in.test b/test/in.test index bd1209fb67..4595d5fd19 100644 --- a/test/in.test +++ b/test/in.test @@ -763,6 +763,8 @@ do_execsql_test in-18.1 { # For the IN_INDEX_NOOP optimization, apply REAL affinity to the LHS # values prior to comparison if the RHS has REAL affinity. # +# Also ticket https://sqlite.org/src/info/29f635e0af71234b +# do_execsql_test in-19.1 { DROP TABLE IF EXISTS t0; CREATE TABLE t0(c0 REAL UNIQUE); @@ -775,5 +777,12 @@ do_execsql_test in-19.2 { do_execsql_test in-19.3 { SELECT c0 IN ('2070934912552030444',2,3) FROM t0; } {1} +do_execsql_test in-19.4 { + DROP TABLE t0; + CREATE TABLE t0(c0 TEXT, c1 REAL, c2, PRIMARY KEY(c2, c0, c1)); + CREATE INDEX i0 ON t0(c1 IN (c0)); + INSERT INTO t0(c0, c2) VALUES (0, NULL) ON CONFLICT(c2, c1, c0) DO NOTHING; + PRAGMA integrity_check; +} {ok} finish_test From c7d12f4ad4283f1b3a09d140c489319c9d2eb8f8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Sep 2019 14:27:25 +0000 Subject: [PATCH 094/112] When we play games with COLLATE in order to commute an operator in the WHERE clause processing, be sure not to use the commuted operator to qualify a partial index, as insufficient COLLATE information is preserved to verify that the expression will correctly qualify the index. Ticket [767a8cbc6d20bd68] FossilOrigin-Name: 5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a --- manifest | 18 +++++++++--------- manifest.uuid | 2 +- src/where.c | 4 +++- src/whereInt.h | 1 + src/whereexpr.c | 13 +++++++++++-- test/index6.test | 18 ++++++++++++++++++ 6 files changed, 43 insertions(+), 13 deletions(-) diff --git a/manifest b/manifest index 8a800c1dc3..05386d4075 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sbug\sintroduced\searlier\stoday\sby\scheck-in\s[88833a9c2849c959].\nTicket\s[29f635e0af71234b] -D 2019-09-02T22:13:06.403 +C When\swe\splay\sgames\swith\sCOLLATE\sin\sorder\sto\scommute\san\soperator\sin\sthe\nWHERE\sclause\sprocessing,\sbe\ssure\snot\sto\suse\sthe\scommuted\soperator\sto\squalify\na\spartial\sindex,\sas\sinsufficient\sCOLLATE\sinformation\sis\spreserved\sto\sverify\nthat\sthe\sexpression\swill\scorrectly\squalify\sthe\sindex.\nTicket\s[767a8cbc6d20bd68] +D 2019-09-03T14:27:25.935 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -610,10 +610,10 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c bbd6838bd79c0a32144d482fb0b6a9d2d1a252fb3b16d5005ec30f2f80413b0d F src/wal.h 606292549f5a7be50b6227bd685fa76e3a4affad71bb8ac5ce4cb5c79f6a176a F src/walker.c d5a94907dcac990e31976be9dc769d17f6a806782593d6aec9d760ee01ec22cd -F src/where.c fb546afbdbedc77a6193a236db92f6f85bc8e17412ec596230dd8aee03a93716 -F src/whereInt.h 4a296fd4fa79fdcbc2b5e8c1b898901617655811223e1082b899c23ecb092217 +F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64 +F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b -F src/whereexpr.c 2757afbd5cfdbb420f9d0392e1bd5f5c0e33dee50a8c692befc7e502308e449f +F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4 F src/window.c 96b0c033d33408f16ac8b177eac6362ee53a23d9b6d7a51a04289ab2f956bb77 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e @@ -1048,7 +1048,7 @@ F test/index2.test f835d5e13ca163bd78c4459ca15fd2e4ed487407 F test/index3.test 51685f39345462b84fcf77eb8537af847fdf438cc96b05c45d6aaca4e473ade0 F test/index4.test ab92e736d5946840236cd61ac3191f91a7856bf6 F test/index5.test 8621491915800ec274609e42e02a97d67e9b13e7 -F test/index6.test bae04b456a1845d8d48af751ac5b9bba5571551b96ef39d2b5b1db48cadd0fac +F test/index6.test 4d1dd3cab97fba2ddf30bb70afc82eab35bd6e61788b3ac941e55263f81ef7e9 F test/index7.test 1d764c0cca45f5a76150b08e127ccc8d52492cfa788b5fafed4be784a351b020 F test/index8.test bc2e3db70e8e62459aaa1bd7e4a9b39664f8f9d7 F test/index9.test 0aa3e509dddf81f93380396e40e9bb386904c1054924ba8fa9bcdfe85a8e7721 @@ -1839,7 +1839,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 9490683ae883561fa347cbe54ebdd61188d849b4852d904b508250ba5d0807ef -R 931628c07078d6a1ec560a2e18a3f53f +P 6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73 +R f93cc76f663e94933b1f2f65b53349fd U drh -Z 31499ded87036041191e77b0df0459dc +Z 391da90ad359183d92b0ba19729274a1 diff --git a/manifest.uuid b/manifest.uuid index d9a9e049c6..63c1adf712 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73 \ No newline at end of file +5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a \ No newline at end of file diff --git a/src/where.c b/src/where.c index b51d4485c4..8c7874dc57 100644 --- a/src/where.c +++ b/src/where.c @@ -2800,7 +2800,9 @@ static int whereUsablePartialIndex(int iTab, WhereClause *pWC, Expr *pWhere){ } if( pParse->db->flags & SQLITE_EnableQPSG ) pParse = 0; for(i=0, pTerm=pWC->a; inTerm; i++, pTerm++){ - Expr *pExpr = pTerm->pExpr; + Expr *pExpr; + if( pTerm->wtFlags & TERM_NOPARTIDX ) continue; + pExpr = pTerm->pExpr; if( (!ExprHasProperty(pExpr, EP_FromJoin) || pExpr->iRightJoinTable==iTab) && sqlite3ExprImpliesExpr(pParse, pExpr, pWhere, iTab) ){ diff --git a/src/whereInt.h b/src/whereInt.h index e63ca46d53..64978cf110 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -291,6 +291,7 @@ struct WhereTerm { #define TERM_LIKE 0x400 /* The original LIKE operator */ #define TERM_IS 0x800 /* Term.pExpr is an IS operator */ #define TERM_VARSELECT 0x1000 /* Term.pExpr contains a correlated sub-query */ +#define TERM_NOPARTIDX 0x2000 /* Not for use to enable a partial index */ /* ** An instance of the WhereScan object is used as an iterator for locating diff --git a/src/whereexpr.c b/src/whereexpr.c index d878bdb9ec..f6f966b9e1 100644 --- a/src/whereexpr.c +++ b/src/whereexpr.c @@ -117,10 +117,16 @@ static int allowedOp(int op){ ** the left hand side of a comparison overrides any collation sequence ** attached to the right. For the same reason the EP_Collate flag ** is not commuted. +** +** The return value is extra flags that are added to the WhereTerm object +** after it is commuted. The only extra flag ever added is TERM_NOPARTIDX +** which prevents the term from being used to enable a partial index if +** COLLATE changes have been made. */ -static void exprCommute(Parse *pParse, Expr *pExpr){ +static u16 exprCommute(Parse *pParse, Expr *pExpr){ u16 expRight = (pExpr->pRight->flags & EP_Collate); u16 expLeft = (pExpr->pLeft->flags & EP_Collate); + u16 wtFlags = 0; assert( allowedOp(pExpr->op) && pExpr->op!=TK_IN ); if( expRight==expLeft ){ /* Either X and Y both have COLLATE operator or neither do */ @@ -128,11 +134,13 @@ static void exprCommute(Parse *pParse, Expr *pExpr){ /* Both X and Y have COLLATE operators. Make sure X is always ** used by clearing the EP_Collate flag from Y. */ pExpr->pRight->flags &= ~EP_Collate; + wtFlags |= TERM_NOPARTIDX; }else if( sqlite3ExprCollSeq(pParse, pExpr->pLeft)!=0 ){ /* Neither X nor Y have COLLATE operators, but X has a non-default ** collating sequence. So add the EP_Collate marker on X to cause ** it to be searched first. */ pExpr->pLeft->flags |= EP_Collate; + wtFlags |= TERM_NOPARTIDX; } } SWAP(Expr*,pExpr->pRight,pExpr->pLeft); @@ -144,6 +152,7 @@ static void exprCommute(Parse *pParse, Expr *pExpr){ assert( pExpr->op>=TK_GT && pExpr->op<=TK_GE ); pExpr->op = ((pExpr->op-TK_GT)^2)+TK_GT; } + return wtFlags; } /* @@ -1140,7 +1149,7 @@ static void exprAnalyze( pDup = pExpr; pNew = pTerm; } - exprCommute(pParse, pDup); + pNew->wtFlags |= exprCommute(pParse, pDup); pNew->leftCursor = aiCurCol[0]; pNew->u.leftColumn = aiCurCol[1]; testcase( (prereqLeft | extraRight) != prereqLeft ); diff --git a/test/index6.test b/test/index6.test index d5bc77c0db..976c49fb86 100644 --- a/test/index6.test +++ b/test/index6.test @@ -462,5 +462,23 @@ do_execsql_test index6-15.5 { SELECT 1 FROM t0 WHERE (c0 IS FALSE) IN (FALSE); } {1} +# 2019-09-03 +# Ticket https://sqlite.org/src/info/767a8cbc6d20bd68 +do_execsql_test index6-16.1 { + DROP TABLE t0; + CREATE TABLE t0(c0 COLLATE NOCASE, c1); + CREATE INDEX i0 ON t0(0) WHERE c0 >= c1; + INSERT INTO t0 VALUES('a', 'B'); + SELECT c1 <= c0, c0 >= c1 FROM t0; +} {1 0} +do_execsql_test index6-16.2 { + SELECT 2 FROM t0 WHERE c0 >= c1; +} {} +do_execsql_test index6-16.3 { + SELECT 3 FROM t0 WHERE c1 <= c0; +} {3} + + + finish_test From 7dc3547eeb691d5397e9dc55206daab0927937d8 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 3 Sep 2019 16:23:41 +0000 Subject: [PATCH 095/112] Updates to the default settings in Makefile.linux-gcc. FossilOrigin-Name: 3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d --- Makefile.linux-gcc | 26 +++++++++----------------- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/Makefile.linux-gcc b/Makefile.linux-gcc index 1491a4b02a..ad5d4dd093 100644 --- a/Makefile.linux-gcc +++ b/Makefile.linux-gcc @@ -19,7 +19,7 @@ TOP = ../sqlite #### C Compiler and options for use in building executables that # will run on the platform that is doing the build. # -BCC = gcc -g -O2 +BCC = gcc -g -O0 #BCC = /opt/ancic/bin/c89 -0 #### If the target operating system supports the "usleep()" system @@ -38,8 +38,8 @@ THREADSAFE = -DTHREADSAFE=0 #### Specify any extra linker options needed to make the library # thread safe # -#THREADLIB = -lpthread -THREADLIB = +THREADLIB = -lpthread -lm -ldl +#THREADLIB = #### Specify any extra libraries needed to access required functions. # @@ -54,11 +54,9 @@ TLIBS = # You can make the library go almost twice as fast if you compile # with -DNDEBUG=1 # -#OPTS = -DSQLITE_DEBUG=2 -#OPTS = -DSQLITE_DEBUG=1 -#OPTS = -OPTS = -DNDEBUG=1 -OPTS += -DHAVE_FDATASYNC=1 +OPTS += -DSQLITE_DEBUG=1 +OPTS += -DSQLITE_ENABLE_WHERETRACE +OPTS += -DSQLITE_ENABLE_SELECTTRACE #### The suffix to add to executable files. ".exe" for windows. # Nothing for unix. @@ -70,7 +68,7 @@ EXE = # will run on the target platform. This is usually the same # as BCC, unless you are cross-compiling. # -TCC = gcc -O6 +TCC = gcc -O0 #TCC = gcc -g -O0 -Wall #TCC = gcc -g -O0 -Wall -fprofile-arcs -ftest-coverage #TCC = /opt/mingw/bin/i386-mingw32-gcc -O6 @@ -91,18 +89,12 @@ SHPREFIX = lib #### Extra compiler options needed for programs that use the TCL library. # -#TCL_FLAGS = -#TCL_FLAGS = -DSTATIC_BUILD=1 -TCL_FLAGS = -I/home/drh/tcltk/8.5linux -#TCL_FLAGS = -I/home/drh/tcltk/8.5win -DSTATIC_BUILD=1 -#TCL_FLAGS = -I/home/drh/tcltk/8.3hpux +TCL_FLAGS = -I/home/drh/tcl/include/tcl8.6 #### Linker options needed to link against the TCL library. # #LIBTCL = -ltcl -lm -ldl -LIBTCL = /home/drh/tcltk/8.5linux/libtcl8.5g.a -lm -ldl -#LIBTCL = /home/drh/tcltk/8.5win/libtcl85s.a -lmsvcrt -#LIBTCL = /home/drh/tcltk/8.3hpux/libtcl8.3.a -ldld -lm -lc +LIBTCL = /home/drh/tcl/lib/libtcl8.6.a -lm -lpthread -ldl -lz #### Additional objects for SQLite library when TCL support is enabled. #TCLOBJ = diff --git a/manifest b/manifest index 05386d4075..3921cbfbc9 100644 --- a/manifest +++ b/manifest @@ -1,10 +1,10 @@ -C When\swe\splay\sgames\swith\sCOLLATE\sin\sorder\sto\scommute\san\soperator\sin\sthe\nWHERE\sclause\sprocessing,\sbe\ssure\snot\sto\suse\sthe\scommuted\soperator\sto\squalify\na\spartial\sindex,\sas\sinsufficient\sCOLLATE\sinformation\sis\spreserved\sto\sverify\nthat\sthe\sexpression\swill\scorrectly\squalify\sthe\sindex.\nTicket\s[767a8cbc6d20bd68] -D 2019-09-03T14:27:25.935 +C Updates\sto\sthe\sdefault\ssettings\sin\sMakefile.linux-gcc. +D 2019-09-03T16:23:41.278 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 F Makefile.in 578f123620087ea459aa08fa872810a25ca7c0aaf16331de985bfcddb5f1e747 -F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434 +F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 F Makefile.msc a463dca3c50d8a36094fe5c8c39077907f530b54edfc5388c66c85e2cfc8dc04 F README.md 1514a365ffca3c138e00c5cc839906108a01011a6b082bad19b09781e3aa498a F VERSION 4c516d84c2a5f26c477ed34c09ac4136630f71c68139631f2eb591b22eea7cf1 @@ -1839,7 +1839,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 6e7b4527d32cc1be0294614b9d7363d4b59cf654a954b86515b3f6888975ce73 -R f93cc76f663e94933b1f2f65b53349fd +P 5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a +R 925cc947a7aaed39ac73d111ffc8ed4f U drh -Z 391da90ad359183d92b0ba19729274a1 +Z 4a725e18713a18c2d331c90a708c61ac diff --git a/manifest.uuid b/manifest.uuid index 63c1adf712..c360ee3192 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a \ No newline at end of file +3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d \ No newline at end of file From 1a97c413f8c26670d3bbf122a6eaa88dea0a0b5c Mon Sep 17 00:00:00 2001 From: dan Date: Wed, 4 Sep 2019 06:56:43 +0000 Subject: [PATCH 096/112] Fix handling of NULL, text and blob values in window queries that use "RANGE BETWEEN A FOLLOWING AND B FOLLOWING", or "B PRECEDING AND A PRECEDING", where A>B. FossilOrigin-Name: cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0 --- manifest | 19 ++-- manifest.uuid | 2 +- src/window.c | 2 +- test/window8.tcl | 64 +++++++++++- test/window8.test | 253 +++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 324 insertions(+), 16 deletions(-) diff --git a/manifest b/manifest index 3921cbfbc9..ad787c3946 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Updates\sto\sthe\sdefault\ssettings\sin\sMakefile.linux-gcc. -D 2019-09-03T16:23:41.278 +C Fix\shandling\sof\sNULL,\stext\sand\sblob\svalues\sin\swindow\squeries\sthat\suse\s"RANGE\sBETWEEN\sA\sFOLLOWING\sAND\sB\sFOLLOWING",\sor\s"B\sPRECEDING\sAND\sA\sPRECEDING",\swhere\sA>B. +D 2019-09-04T06:56:43.134 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -614,7 +614,7 @@ F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64 F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4 -F src/window.c 96b0c033d33408f16ac8b177eac6362ee53a23d9b6d7a51a04289ab2f956bb77 +F src/window.c b1e56b1281538b5cdd796b4f6c6281549bef6f977aab63e2493704a2a9f31937 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1712,8 +1712,8 @@ F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652 F test/window6.test f8d674254b23289cc17c84d79dec7eda7caa1dfb7836c43122cfdf3640d1df32 F test/window7.tcl 6a1210f05d40ec89c22960213a22cd3f98d4e2f2eb20646c83c8c30d4d76108f F test/window7.test 1d31276961ae7801edc72173edaf7593e3cbc79c06d1f1f09e20d8418af403cd -F test/window8.tcl 112bdc96dd310cfef93119fc5e4e9108c322080676fdb006ccc98d67d41c8acb -F test/window8.test 85ad3bd55615482c7a93f5286f0b0968f86ad0d62df5bca2f0ea50699e5aef31 +F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1ce2 +F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 @@ -1839,7 +1839,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 5351e920f489562f959ab8a376ff720f845ea165e0cdc7c3a271aac53c2aa64a -R 925cc947a7aaed39ac73d111ffc8ed4f -U drh -Z 4a725e18713a18c2d331c90a708c61ac +P 3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d +R 8115b1008885358de7df7c995955e272 +T +closed 91875000a76cad5b7615ea87aafb2d1fec09441592b37424da4f51e7e025cbfd +U dan +Z 35e89c49c4707a04ab0cfaf64c9b5bb4 diff --git a/manifest.uuid b/manifest.uuid index c360ee3192..8dd06dd0f1 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d \ No newline at end of file +cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0 \ No newline at end of file diff --git a/src/window.c b/src/window.c index 7cb86e58be..ed2e32079f 100644 --- a/src/window.c +++ b/src/window.c @@ -2745,7 +2745,7 @@ void sqlite3WindowCodeStep( windowCheckValue(pParse, regEnd, 1 + (pMWin->eFrmType==TK_RANGE ? 3 : 0)); } - if( pMWin->eStart==pMWin->eEnd && regStart ){ + if( pMWin->eFrmType!=TK_RANGE && pMWin->eStart==pMWin->eEnd && regStart ){ int op = ((pMWin->eStart==TK_FOLLOWING) ? OP_Ge : OP_Le); int addrGe = sqlite3VdbeAddOp3(v, op, regStart, 0, regEnd); VdbeCoverageNeverNullIf(v, op==OP_Ge); /* NeverNull because bound */ diff --git a/test/window8.tcl b/test/window8.tcl index aa934a8267..a8333f1907 100644 --- a/test/window8.tcl +++ b/test/window8.tcl @@ -351,15 +351,75 @@ execsql_test 7.0 { INSERT INTO t2 VALUES(2, NULL); INSERT INTO t2 VALUES(3, NULL); INSERT INTO t2 VALUES(4, NULL); + INSERT INTO t2 VALUES(5, 66); + INSERT INTO t2 VALUES(6, 67); } -execsql_test 7.1 { - SELECT sum(a) OVER win FROM t2 +foreach {tn f ex} { + 1 sum "" + 2 min "" + 3 sum "EXCLUDE CURRENT ROW" + 4 max "EXCLUDE CURRENT ROW" +} { +execsql_test 7.$tn.1 " + SELECT $f (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING ); +" +execsql_test 7.$tn.2 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +" +execsql_test 7.$tn.3 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +" +execsql_test 7.$tn.4 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +" +execsql_test 7.$tn.5 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +" + +execsql_test 7.$tn.6 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING + ); +" +execsql_test 7.$tn.7 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +" +execsql_test 7.$tn.8 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING + ); +" +execsql_test 7.$tn.9 " + SELECT $f (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +" } + + finish_test diff --git a/test/window8.test b/test/window8.test index 0c7656b9a1..ed720ebd41 100644 --- a/test/window8.test +++ b/test/window8.test @@ -6213,13 +6213,260 @@ do_execsql_test 7.0 { INSERT INTO t2 VALUES(2, NULL); INSERT INTO t2 VALUES(3, NULL); INSERT INTO t2 VALUES(4, NULL); + INSERT INTO t2 VALUES(5, 66); + INSERT INTO t2 VALUES(6, 67); } {} -do_execsql_test 7.1 { - SELECT sum(a) OVER win FROM t2 +do_execsql_test 7.1.1 { + SELECT sum (a) OVER win FROM t2 WINDOW win AS ( ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING ); -} {9 9 9 9} +} {9 9 9 9 9 9} + +do_execsql_test 7.1.2 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {{} {} {} 9 9 9} + +do_execsql_test 7.1.3 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {{} {} {} 9 9 9} + +do_execsql_test 7.1.4 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.1.5 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.1.6 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING + ); +} {{} {} 1 9 9 9} + +do_execsql_test 7.1.7 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {{} {} {} 9 9 9} + +do_execsql_test 7.1.8 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.1.9 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.2.1 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING + ); +} {2 2 2 2 2 2} + +do_execsql_test 7.2.2 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {{} {} {} 2 2 2} + +do_execsql_test 7.2.3 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {{} {} {} 2 2 2} + +do_execsql_test 7.2.4 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {2 2 2 {} {} {}} + +do_execsql_test 7.2.5 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {2 2 2 {} {} {}} + +do_execsql_test 7.2.6 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING + ); +} {{} {} 1 2 2 2} + +do_execsql_test 7.2.7 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {{} {} {} 2 2 2} + +do_execsql_test 7.2.8 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING + ); +} {2 2 2 {} {} {}} + +do_execsql_test 7.2.9 { + SELECT min (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {2 2 2 {} {} {}} + +do_execsql_test 7.3.1 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING + ); +} {9 9 9 9 9 9} + +do_execsql_test 7.3.2 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {{} {} {} 9 9 9} + +do_execsql_test 7.3.3 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {{} {} {} 9 9 9} + +do_execsql_test 7.3.4 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.3.5 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.3.6 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING + ); +} {{} {} 1 9 9 9} + +do_execsql_test 7.3.7 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {{} {} {} 9 9 9} + +do_execsql_test 7.3.8 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.3.9 { + SELECT sum (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {9 9 9 {} {} {}} + +do_execsql_test 7.4.1 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 6 FOLLOWING AND UNBOUNDED FOLLOWING + ); +} {4 4 4 4 4 4} + +do_execsql_test 7.4.2 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {{} {} {} 4 4 4} + +do_execsql_test 7.4.3 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {{} {} {} 4 4 4} + +do_execsql_test 7.4.4 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING + ); +} {4 4 4 {} {} {}} + +do_execsql_test 7.4.5 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2 FOLLOWING AND 1 FOLLOWING + ); +} {4 4 4 {} {} {}} + +do_execsql_test 7.4.6 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 1000 PRECEDING AND 2 PRECEDING + ); +} {{} {} 1 4 4 4} + +do_execsql_test 7.4.7 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS LAST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {{} {} {} 4 4 4} + +do_execsql_test 7.4.8 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 1000 PRECEDING AND 2000 PRECEDING + ); +} {4 4 4 {} {} {}} + +do_execsql_test 7.4.9 { + SELECT max (a) OVER win FROM t2 + WINDOW win AS ( + ORDER BY b NULLS FIRST RANGE BETWEEN 2000 FOLLOWING AND 1000 FOLLOWING + ); +} {4 4 4 {} {} {}} finish_test From e2ba6df9f0bbbf084db504c9559e7a5c7ebe023d Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 7 Sep 2019 18:20:43 +0000 Subject: [PATCH 097/112] Add the SQLITE_SUBTYPE flag, which can be passed to sqlite3_create_function() and similar to indicate to the core that a user function is likely to use sqlite3_result_subtype(). FossilOrigin-Name: 6aa438ce41d460a6782ae63503128b9140c28ff59c2b2eed48b004acf83e0560 --- ext/misc/json1.c | 6 +-- manifest | 25 ++++++----- manifest.uuid | 2 +- src/main.c | 2 +- src/sqlite.h.in | 5 +++ src/sqliteInt.h | 2 + src/window.c | 47 ++++++++++++++++++-- test/windowB.test | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 176 insertions(+), 19 deletions(-) create mode 100644 test/windowB.test diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 3a9d10331c..1c63c3e409 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -2504,9 +2504,9 @@ int sqlite3Json1Init(sqlite3 *db){ #endif for(i=0; iB. -D 2019-09-04T06:56:43.134 +C Add\sthe\sSQLITE_SUBTYPE\sflag,\swhich\scan\sbe\spassed\sto\ssqlite3_create_function()\sand\ssimilar\sto\sindicate\sto\sthe\score\sthat\sa\suser\sfunction\sis\slikely\sto\suse\ssqlite3_result_subtype(). +D 2019-09-07T18:20:43.736 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -294,7 +294,7 @@ F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09 F ext/misc/fossildelta.c 7708651072eb5620ab21bbfb518d184f27b2c29c0131b09b9a2d8852a8016430 F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 71ce4e39793b743fc7e4790bc3bab15598e95cab57ad8da4326fa640ae5e5310 +F ext/misc/json1.c 5a2525f7a2268840e7fe6b44a06e2522f5f065a06ba95495ec2de127fb6f92f2 F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567 @@ -488,7 +488,7 @@ F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 F src/insert.c 40557ebd69f4115e7a273f9304a8ab637a47ce44f3c6923396928f023967b5e8 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa F src/loadext.c a045bb3425a9a633cc0f78e93d9beda6866f4c0f15bfdee735aba7c6b39f5cc4 -F src/main.c 51c55eb579eac4180bfcc6242741084710911350d2cd0c3fdd0f9fde55442128 +F src/main.c 3851950717170ade4f6d718c18c6c7400ef5994c2a654679af2cff2ffd0fb2b9 F src/malloc.c 0f9da2a66b230a5785af94b9672126845099b57b70a32c987d04ac28c69da990 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de @@ -526,10 +526,10 @@ F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c e4fe08c3da81a38061454fb7de2c1b31c36ed76cd1a4bbefd2b5fc4ebb472a5b F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21b -F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 +F src/sqlite.h.in aa8eab4a0ad30e10be68223469edbc9add18a6d01bd25ef63015379cabe572ec F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 -F src/sqliteInt.h b1fca535f01f02ae6927dd44e760c6ab54c7a181e88f813d16b55a1bc95d13c0 +F src/sqliteInt.h 34cc038470f74a961ce9c1155df4c3926c2c88d784631272943ae0b7e9bd2aa2 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -614,7 +614,7 @@ F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64 F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4 -F src/window.c b1e56b1281538b5cdd796b4f6c6281549bef6f977aab63e2493704a2a9f31937 +F src/window.c b85ce577416ddd9cdbe42222120e2f496a631f0835feccf860e3df0dc0917702 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1716,6 +1716,7 @@ F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be +F test/windowB.test 24daa26628291b6e584064efd34b1914aa69058280ece8a512b2e59ba71b6f02 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 @@ -1839,8 +1840,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 3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d -R 8115b1008885358de7df7c995955e272 -T +closed 91875000a76cad5b7615ea87aafb2d1fec09441592b37424da4f51e7e025cbfd +P cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0 +R d1b9853f176533fc61f0716439115fae +T *branch * window-functions-subtype-fix +T *sym-window-functions-subtype-fix * +T -sym-trunk * U dan -Z 35e89c49c4707a04ab0cfaf64c9b5bb4 +Z 3b4f60d3aa156d677d66f1a5addfe61e diff --git a/manifest.uuid b/manifest.uuid index 8dd06dd0f1..fa760b9d20 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0 \ No newline at end of file +6aa438ce41d460a6782ae63503128b9140c28ff59c2b2eed48b004acf83e0560 \ No newline at end of file diff --git a/src/main.c b/src/main.c index a8c1d4dc63..3ef3a3d9fb 100644 --- a/src/main.c +++ b/src/main.c @@ -1719,7 +1719,7 @@ int sqlite3CreateFunc( assert( SQLITE_FUNC_CONSTANT==SQLITE_DETERMINISTIC ); assert( SQLITE_FUNC_DIRECT==SQLITE_DIRECTONLY ); - extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY); + extraFlags = enc & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY|SQLITE_SUBTYPE); enc &= (SQLITE_FUNC_ENCMASK|SQLITE_ANY); #ifndef SQLITE_OMIT_UTF16 diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 521ddffdb4..8136889ee1 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -4987,9 +4987,14 @@ int sqlite3_create_window_function( ** ** The SQLITE_DIRECTONLY flag means that the function may only be invoked ** from top-level SQL, and cannot be used in VIEWs or TRIGGERs. +** +** The SQLITE_SUBTYPE flag indicates to SQLite that the function may call +** [sqlite3_result_subtype()] in order to configure its return value with +** a sub-type. */ #define SQLITE_DETERMINISTIC 0x000000800 #define SQLITE_DIRECTONLY 0x000080000 +#define SQLITE_SUBTYPE 0x000100000 /* ** CAPI3REF: Deprecated Functions diff --git a/src/sqliteInt.h b/src/sqliteInt.h index d3f7ffe260..e7c1d9c1f2 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -1686,6 +1686,7 @@ struct FuncDestructor { #define SQLITE_FUNC_WINDOW 0x00010000 /* Built-in window-only function */ #define SQLITE_FUNC_INTERNAL 0x00040000 /* For use by NestedParse() only */ #define SQLITE_FUNC_DIRECT 0x00080000 /* Not for use in TRIGGERs or VIEWs */ +#define SQLITE_FUNC_SUBTYPE 0x00100000 /* Result likely to have sub-type */ /* ** The following three macros, FUNCTION(), LIKEFUNC() and AGGREGATE() are @@ -3611,6 +3612,7 @@ struct Window { int regOne; /* Register containing constant value 1 */ int regStartRowid; int regEndRowid; + u8 bExprArgs; }; #ifndef SQLITE_OMIT_WINDOWFUNC diff --git a/src/window.c b/src/window.c index ed2e32079f..b889930444 100644 --- a/src/window.c +++ b/src/window.c @@ -868,6 +868,32 @@ static void selectWindowRewriteEList( *ppSub = sRewrite.pSub; } +/* +** Return true if the top-level of list pList contains an SQL function +** with the SQLITE_FUNC_SUBTYPE flag set. Return false otherwise. +*/ +int exprListContainsSubtype(Parse *pParse, ExprList *pList){ + if( pList ){ + sqlite3 *db = pParse->db; + int i; + for(i=0; inExpr; i++){ + Expr *p = pList->a[i].pExpr; + if( p->op==TK_FUNCTION ){ + FuncDef *pDef; + int nArg = 0; + if( !ExprHasProperty(p, EP_TokenOnly) && p->x.pList ){ + nArg = p->x.pList->nExpr; + } + pDef = sqlite3FindFunction(db, p->u.zToken, nArg, db->enc, 0); + if( pDef && (pDef->funcFlags & SQLITE_FUNC_SUBTYPE) ){ + return 1; + } + } + } + } + return 0; +} + /* ** Append a copy of each expression in expression-list pAppend to ** expression list pList. Return a pointer to the result list. @@ -965,8 +991,15 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ ** window function - one for the accumulator, another for interim ** results. */ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ - pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); - pSublist = exprListAppendList(pParse, pSublist, pWin->pOwner->x.pList, 0); + ExprList *pArgs = pWin->pOwner->x.pList; + if( exprListContainsSubtype(pParse, pArgs) ){ + selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pWin->bExprArgs = 1; + }else{ + pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); + pSublist = exprListAppendList(pParse, pSublist, pArgs, 0); + } if( pWin->pFilter ){ Expr *pFilter = sqlite3ExprDup(db, pWin->pFilter, 0); pSublist = sqlite3ExprListAppend(pParse, pSublist, pFilter); @@ -1432,7 +1465,7 @@ static void windowAggStep( for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ FuncDef *pFunc = pWin->pFunc; int regArg; - int nArg = windowArgCount(pWin); + int nArg = pWin->bExprArgs ? 0 : windowArgCount(pWin); int i; assert( bInverse==0 || pWin->eStart!=TK_UNBOUNDED ); @@ -1482,6 +1515,11 @@ static void windowAggStep( VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, regTmp); } + if( pWin->bExprArgs ){ + nArg = pWin->pOwner->x.pList->nExpr; + regArg = sqlite3GetTempRange(pParse, nArg); + sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); + } if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ CollSeq *pColl; assert( nArg>0 ); @@ -1492,6 +1530,9 @@ static void windowAggStep( bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); + if( pWin->bExprArgs ){ + sqlite3ReleaseTempRange(pParse, regArg, nArg); + } if( addrIf ) sqlite3VdbeJumpHere(v, addrIf); } } diff --git a/test/windowB.test b/test/windowB.test new file mode 100644 index 0000000000..0c242acc70 --- /dev/null +++ b/test/windowB.test @@ -0,0 +1,106 @@ +# 2019-08-30 +# +# 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. +# +#*********************************************************************** +# Test cases for RANGE BETWEEN and especially with NULLS LAST +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix windowB + +ifcapable !windowfunc { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(NULL, 1); + INSERT INTO t1 VALUES(NULL, 2); + INSERT INTO t1 VALUES(NULL, 3); +} {} + +foreach {tn win} { + 1 { ORDER BY a RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } + 2 { ORDER BY a NULLS LAST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } + 3 { ORDER BY a DESC RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } + 4 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING } + + 5 { ORDER BY a NULLS LAST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING } + 6 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 FOLLOWING AND 2 FOLLOWING } + + 7 { ORDER BY a NULLS LAST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING } + 8 { ORDER BY a DESC NULLS FIRST RANGE BETWEEN 2 PRECEDING AND 1 PRECEDING } +} { + do_execsql_test 1.$tn " + SELECT sum(b) OVER win FROM t1 + WINDOW win AS ( $win ) + " {6 6 6} +} + +do_execsql_test 1.2 { + SELECT sum(b) OVER win FROM t1 + WINDOW win AS ( + ORDER BY a DESC NULLS FIRST RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) +} {6 6 6} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, NULL); + INSERT INTO t1 VALUES(2, 45); + INSERT INTO t1 VALUES(3, 66.2); + INSERT INTO t1 VALUES(4, 'hello world'); + INSERT INTO t1 VALUES(5, 'hello world'); + INSERT INTO t1 VALUES(6, X'1234'); + INSERT INTO t1 VALUES(7, X'1234'); + INSERT INTO t1 VALUES(8, NULL); +} + +foreach {tn win} { + 1 "ORDER BY b RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING" + 2 "ORDER BY b RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING" + 3 "ORDER BY b NULLS LAST RANGE BETWEEN 1 PRECEDING AND 2 PRECEDING" + 4 "ORDER BY b NULLS LAST RANGE BETWEEN 2 FOLLOWING AND 2 FOLLOWING" +} { + do_execsql_test 2.1.$tn " + SELECT a, sum(a) OVER win FROM t1 + WINDOW win AS ( $win ) + ORDER BY 1 + " {1 9 2 {} 3 {} 4 9 5 9 6 13 7 13 8 9} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT); + INSERT INTO testjson VALUES(1, '{"a":1}'); + INSERT INTO testjson VALUES(2, '{"b":2}'); +} + +do_execsql_test 3.1 { + SELECT json_group_array(json(j)) FROM testjson; +} { + {[{"a":1},{"b":2}]} +} + +breakpoint +do_execsql_test 3.2 { + SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson; +} { + {[{"a":1}]} + {[{"a":1},{"b":2}]} +} + + +finish_test + From e08663946ee6d0f5c8429aa035c9db2186ed4766 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 9 Sep 2019 19:49:42 +0000 Subject: [PATCH 098/112] Ensure the columns of views and sub-selects in the FROM clause of a select are always assigned implicit collation sequences, just as table columns are. Possible fix for [a7debbe0]. FossilOrigin-Name: 1863b7bf12521bdd2b51c5b8d3a4634bff3e15d3713e0b5343952df7da02f794 --- manifest | 17 ++++--- manifest.uuid | 2 +- src/select.c | 15 ++++++ test/tkt-a7debbe0.test | 103 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 8 deletions(-) create mode 100644 test/tkt-a7debbe0.test diff --git a/manifest b/manifest index ad787c3946..df599d99d4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\shandling\sof\sNULL,\stext\sand\sblob\svalues\sin\swindow\squeries\sthat\suse\s"RANGE\sBETWEEN\sA\sFOLLOWING\sAND\sB\sFOLLOWING",\sor\s"B\sPRECEDING\sAND\sA\sPRECEDING",\swhere\sA>B. -D 2019-09-04T06:56:43.134 +C Ensure\sthe\scolumns\sof\sviews\sand\ssub-selects\sin\sthe\sFROM\sclause\sof\sa\sselect\sare\salways\sassigned\simplicit\scollation\ssequences,\sjust\sas\stable\scolumns\sare.\sPossible\sfix\sfor\s[a7debbe0]. +D 2019-09-09T19:49:42.715 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,7 +524,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c e4fe08c3da81a38061454fb7de2c1b31c36ed76cd1a4bbefd2b5fc4ebb472a5b +F src/select.c 8685adae94dffa6e4542e2194e491d69e27d5b79fe72b219e9255b08e56eaf76 F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21b F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -1448,6 +1448,7 @@ F test/tkt-9a8b09f8e6.test b2ef151d0984b2ebf237760dbeaa50724e5a0667 F test/tkt-9d68c883.test 16f7cb96781ba579bc2e19bb14b4ad609d9774b6 F test/tkt-9f2eb3abac.test cb6123ac695a08b4454c3792fbe85108f67fabf8 F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4 +F test/tkt-a7debbe0.test 27b977fea9d42021d9ef67e5811bdc56fd0b9599517e0244c528dddd3264ed4e F test/tkt-a8a0d2996a.test 002e1cde8fc30c39611b52cf981c88200b858765748556822da72e0d32fac73e F test/tkt-b1d3a2e531.test 8f7576e41ca179289ee1a8fee28386fd8e4b0550 F test/tkt-b351d95f9.test d14a503c414c5c58fdde3e80f9a3cfef986498c0 @@ -1839,8 +1840,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 3044cf6917ea8324175fc91657e9a5978af9748f72e1914bc361753f0b2d897d -R 8115b1008885358de7df7c995955e272 -T +closed 91875000a76cad5b7615ea87aafb2d1fec09441592b37424da4f51e7e025cbfd +P cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0 +R 8499ff2bdbcbd0ce456fbfc5655f865d +T *branch * tkt-a7debbe0. +T *sym-tkt-a7debbe0. * +T -sym-trunk * U dan -Z 35e89c49c4707a04ab0cfaf64c9b5bb4 +Z b93432e9313cfc8d7991fd66b06bef63 diff --git a/manifest.uuid b/manifest.uuid index 8dd06dd0f1..9e8c7a5c15 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0 \ No newline at end of file +1863b7bf12521bdd2b51c5b8d3a4634bff3e15d3713e0b5343952df7da02f794 \ No newline at end of file diff --git a/src/select.c b/src/select.c index 0bf5451834..f446a89f10 100644 --- a/src/select.c +++ b/src/select.c @@ -3418,6 +3418,7 @@ typedef struct SubstContext { int iNewTable; /* New table number */ int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ ExprList *pEList; /* Replacement expressions */ + int bFlattener; /* True for query-flattener, false otherwise */ } SubstContext; /* Forward Declarations */ @@ -3478,6 +3479,18 @@ static Expr *substExpr( } sqlite3ExprDelete(db, pExpr); pExpr = pNew; + + /* If this call is part of query-flattening, ensure that the + ** new expression has an implicit collation sequence. */ + if( pSubst->bFlattener && pExpr ){ + if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ + CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); + pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, + (pColl ? pColl->zName : "BINARY") + ); + } + ExprClearProperty(pExpr, EP_Collate); + } } } }else{ @@ -4043,6 +4056,7 @@ static int flattenSubquery( x.iNewTable = iNewParent; x.isLeftJoin = isLeftJoin; x.pEList = pSub->pEList; + x.bFlattener = 1; substSelect(&x, pParent, 0); } @@ -4368,6 +4382,7 @@ static int pushDownWhereTerms( x.iNewTable = iCursor; x.isLeftJoin = 0; x.pEList = pSubq->pEList; + x.bFlattener = 0; pNew = substExpr(&x, pNew); if( pSubq->selFlags & SF_Aggregate ){ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); diff --git a/test/tkt-a7debbe0.test b/test/tkt-a7debbe0.test new file mode 100644 index 0000000000..a49a0bac88 --- /dev/null +++ b/test/tkt-a7debbe0.test @@ -0,0 +1,103 @@ +# 2019 September 10 +# +# 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. In particular, +# that problems related to ticket a7debbe0ad1 have been fixed. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix tkt-a7debbe0 + +foreach tn {1 2} { + reset_db + if {$tn==1} { + # Disable the flattener + optimization_control db query-flattener 0 + } else { + # Enable the flattener + optimization_control db query-flattener 1 + } + + do_execsql_test $tn.1.0 { + CREATE TABLE t0(xyz INTEGER); + INSERT INTO t0(xyz) VALUES(456); + CREATE VIEW v2(a, B) AS + SELECT 'a', 'B' COLLATE NOCASE FROM t0; + CREATE TABLE t2(a, B COLLATE NOCASE); + INSERT INTO t2 VALUES('a', 'B'); + CREATE VIEW v3(a, B) AS + SELECT 'a' COLLATE BINARY, 'B' COLLATE NOCASE FROM t0; + + CREATE VIEW v4(a, B) AS + SELECT 'a', +CAST('B' COLLATE NOCASE AS TEXT) FROM t0; + + CREATE VIEW v5(a, B) AS + SELECT 'a', ('B' COLLATE NOCASE) || '' FROM t0; + } + + # Table t2 and views v2 through v5 should all be equivalent. + do_execsql_test $tn.1.1.1 { SELECT a >= B FROM t2; } 1 + do_execsql_test $tn.1.1.2 { SELECT 'a' >= 'B' COLLATE NOCASE } 0 + do_execsql_test $tn.1.1.3 { SELECT a >= B FROM v2 } 1 + do_execsql_test $tn.1.1.4 { SELECT a >= B FROM v3 } 1 + do_execsql_test $tn.1.1.5 { SELECT a >= B FROM v4 } 1 + do_execsql_test $tn.1.1.6 { SELECT a >= B FROM v5 } 1 + + do_execsql_test $tn.1.2.1 { SELECT B < a FROM t2 } 0 + do_execsql_test $tn.1.2.2 { SELECT 'B' COLLATE NOCASE < 'a' } 0 + do_execsql_test $tn.1.2.3 { SELECT B < a FROM v2 } 0 + do_execsql_test $tn.1.2.4 { SELECT B < a FROM v3 } 0 + do_execsql_test $tn.1.2.5 { SELECT a < B FROM v4 } 0 + do_execsql_test $tn.1.2.6 { SELECT a < B FROM v5 } 0 + + #------------------------------------------------------------------------- + do_execsql_test 2.0 { + CREATE TABLE t5(a, b COLLATE NOCASE); + INSERT INTO t5 VALUES(1, 'XYZ'); + } + + # Result should be 0, as column "xyz" from the sub-query has implicit + # collation sequence BINARY. + do_execsql_test 2.1 { + SELECT xyz==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5; + } {0} + + # Result should be 1, as literal 'xyz' has no collation sequence, so + # the comparison uses the implicit collation sequence of the RHS - NOCASE. + do_execsql_test 2.2 { + SELECT 'xyz'==b FROM ( SELECT a, 'xyz' AS xyz FROM t5 ), t5; + } {1} + + #----------------------------------------------------------------------- + # The test case submitted with the ticket. + # + do_execsql_test 3.0 { + DROP TABLE t0; + DROP VIEW v2; + + CREATE TABLE t0(c0); + INSERT INTO t0(c0) VALUES(''); + CREATE VIEW v2(c0, c1) AS + SELECT 'B' COLLATE NOCASE, 'a' FROM t0 ORDER BY t0.c0; + SELECT SUM(count) FROM ( + SELECT v2.c1 BETWEEN v2.c0 AND v2.c1 as count FROM v2 + ); + } 1 + + # The result is 1, as the collation used is the implicit collation sequence + # of v2.c1 - BINARY. + do_execsql_test 3.1 { + SELECT v2.c1 BETWEEN v2.c0 AND v2.c1 as count FROM v2; + } 1 +} + +finish_test + From fa5083491497d7c3bfade8a115007a1f88bc7cc7 Mon Sep 17 00:00:00 2001 From: dan Date: Tue, 10 Sep 2019 15:33:52 +0000 Subject: [PATCH 099/112] Ensure the columns of views and sub-queries maintain their implicit collation sequences when the "push-down" optimization is applied. Fix for [18458b1a]. FossilOrigin-Name: 36997c4ade2ef3a274cd1ac52b44118fb3a05325adb650b7b338ecb43d060575 --- manifest | 16 ++++++------- manifest.uuid | 2 +- src/select.c | 9 +++---- src/test1.c | 1 + test/tkt-18458b1a.test | 53 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 66 insertions(+), 15 deletions(-) create mode 100644 test/tkt-18458b1a.test diff --git a/manifest b/manifest index 41eb8b12cd..bc79f4017a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthe\scolumns\sof\sviews\sand\ssub-selects\sin\sthe\sFROM\sclause\sof\sa\sselect\sare\salways\sassigned\simplicit\scollation\ssequences,\sjust\sas\stable\scolumns\sare.\sFix\sfor\s[a7debbe0]. -D 2019-09-09T20:17:24.283 +C Ensure\sthe\scolumns\sof\sviews\sand\ssub-queries\smaintain\stheir\simplicit\scollation\ssequences\swhen\sthe\s"push-down"\soptimization\sis\sapplied.\sFix\sfor\s[18458b1a]. +D 2019-09-10T15:33:52.829 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -524,7 +524,7 @@ F src/printf.c 9be6945837c839ba57837b4bc3af349eba630920fa5532aa518816defe42a7d4 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 -F src/select.c 8685adae94dffa6e4542e2194e491d69e27d5b79fe72b219e9255b08e56eaf76 +F src/select.c e2c870548541d33d090a066e89ab2e7943299006e2827c1abfae39561041fc0b F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21b F src/sqlite.h.in 50fc0914ccd347437db9a0278a47d7541df3a45eb6e641e9680750c6f98dad27 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 @@ -534,7 +534,7 @@ F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6 F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 F src/tclsqlite.c 50c93be3e1c03b4e6cf6756e5197afcfe7f5cd0497d83a7ac317cde09e19b290 -F src/test1.c 8ce455da8dcec886a0e1e608da0fee7de67c8195b14517a8824a2a40c2d11fbf +F src/test1.c 07d774ae3fcd3aed48248483d550cef55cfb417bddab54f4c616b3ac8faa8e32 F src/test2.c 3efb99ab7f1fc8d154933e02ae1378bac9637da5 F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 F src/test4.c 405834f6a93ec395cc4c9bb8ecebf7c3d8079e7ca16ae65e82d01afd229694bb @@ -1413,6 +1413,7 @@ F test/threadtest3.c 38a612ea62854349ed66372f330a40d73c5cf956 F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c +F test/tkt-18458b1a.test c543c4b8e8c7c2200579a635e72c15bc374a92d44eddb1d588d4fdeca9cca532 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 F test/tkt-2a5629202f.test 0521bd25658428baa26665aa53ffed9367d33af2 F test/tkt-2d1a5c67d.test be1326f3061caec85085f4c9ee4490561ca037c0 @@ -1840,8 +1841,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 cb3e2be674316e1d39968eb6567f1fe1b72f9d89af49640a9e83f944979c4cf0 1863b7bf12521bdd2b51c5b8d3a4634bff3e15d3713e0b5343952df7da02f794 -R 9270371da6f28852caf725eea0dfbe33 -T +closed 1863b7bf12521bdd2b51c5b8d3a4634bff3e15d3713e0b5343952df7da02f794 +P b9ec72203c19c2b95e648ac1dfad74eec98d4ff82581cdc10dc4221ba551728f +R cd3dfdd19ee61439a8f3dafd644637dd U dan -Z e9dd23bc0c9ea40830f2a6e0c2945039 +Z 5c236b65c054109c04d341f131258a9f diff --git a/manifest.uuid b/manifest.uuid index bfa3f56c30..4cebedacd4 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -b9ec72203c19c2b95e648ac1dfad74eec98d4ff82581cdc10dc4221ba551728f \ No newline at end of file +36997c4ade2ef3a274cd1ac52b44118fb3a05325adb650b7b338ecb43d060575 \ No newline at end of file diff --git a/src/select.c b/src/select.c index f446a89f10..811671dd69 100644 --- a/src/select.c +++ b/src/select.c @@ -3418,7 +3418,6 @@ typedef struct SubstContext { int iNewTable; /* New table number */ int isLeftJoin; /* Add TK_IF_NULL_ROW opcodes on each replacement */ ExprList *pEList; /* Replacement expressions */ - int bFlattener; /* True for query-flattener, false otherwise */ } SubstContext; /* Forward Declarations */ @@ -3480,9 +3479,9 @@ static Expr *substExpr( sqlite3ExprDelete(db, pExpr); pExpr = pNew; - /* If this call is part of query-flattening, ensure that the - ** new expression has an implicit collation sequence. */ - if( pSubst->bFlattener && pExpr ){ + /* Ensure that the expression now has an implicit collation sequence, + ** just as it did when it was a column of a view or sub-query. */ + if( pExpr ){ if( pExpr->op!=TK_COLUMN && pExpr->op!=TK_COLLATE ){ CollSeq *pColl = sqlite3ExprCollSeq(pSubst->pParse, pExpr); pExpr = sqlite3ExprAddCollateString(pSubst->pParse, pExpr, @@ -4056,7 +4055,6 @@ static int flattenSubquery( x.iNewTable = iNewParent; x.isLeftJoin = isLeftJoin; x.pEList = pSub->pEList; - x.bFlattener = 1; substSelect(&x, pParent, 0); } @@ -4382,7 +4380,6 @@ static int pushDownWhereTerms( x.iNewTable = iCursor; x.isLeftJoin = 0; x.pEList = pSubq->pEList; - x.bFlattener = 0; pNew = substExpr(&x, pNew); if( pSubq->selFlags & SF_Aggregate ){ pSubq->pHaving = sqlite3ExprAnd(pParse, pSubq->pHaving, pNew); diff --git a/src/test1.c b/src/test1.c index c6c9e17afe..6de1ff57f2 100644 --- a/src/test1.c +++ b/src/test1.c @@ -7200,6 +7200,7 @@ static int SQLITE_TCLAPI optimization_control( { "omit-noop-join", SQLITE_OmitNoopJoin }, { "stat4", SQLITE_Stat4 }, { "skip-scan", SQLITE_SkipScan }, + { "push-down", SQLITE_PushDown }, }; if( objc!=4 ){ diff --git a/test/tkt-18458b1a.test b/test/tkt-18458b1a.test new file mode 100644 index 0000000000..996ca88451 --- /dev/null +++ b/test/tkt-18458b1a.test @@ -0,0 +1,53 @@ +# 2019 September 10 +# +# 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. In particular, +# that problems related to ticket [18458b1a] have been fixed. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix tkt-18458b1a + +foreach tn {1 2} { + reset_db + if {$tn==1} { + # Disable the flattener and push-down optimizations + optimization_control db query-flattener 0 + optimization_control db push-down 0 + } else { + # Enable them + optimization_control db query-flattener 1 + optimization_control db push-down 1 + } + + db cache size 0 + + do_execsql_test $tn.1.1 { + CREATE TABLE t0(c0 COLLATE NOCASE); + INSERT INTO t0(c0) VALUES ('B'); + CREATE VIEW v0(c0, c1) AS SELECT DISTINCT t0.c0, 'a' FROM t0; + } + + do_execsql_test $tn.1.2 { + SELECT count(*) FROM v0 WHERE c1 >= c0; + } 1 + + do_execsql_test $tn.1.3 { + SELECT count(*) FROM v0 WHERE NOT NOT (c1 >= c0); + } 1 + + do_execsql_test $tn.1.4 { + SELECT count(*) FROM v0 WHERE ((c1 >= c0) OR 0+0); + } 1 +} + +finish_test + From c204d81a6c043305cfae10e7e9c9338d3702d1a6 Mon Sep 17 00:00:00 2001 From: drh Date: Tue, 10 Sep 2019 17:51:27 +0000 Subject: [PATCH 100/112] Enhance treeview to show SOFT-COLLATE for TK_COLLATE operators that omit the EP_Collate flag. FossilOrigin-Name: a97804620a27acc30bebd2aaa04e38f2f36de48b0931038ca8bdc9cb0c36b8f4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/treeview.c | 8 +++++++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index bc79f4017a..22c156a669 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthe\scolumns\sof\sviews\sand\ssub-queries\smaintain\stheir\simplicit\scollation\ssequences\swhen\sthe\s"push-down"\soptimization\sis\sapplied.\sFix\sfor\s[18458b1a]. -D 2019-09-10T15:33:52.829 +C Enhance\streeview\sto\sshow\sSOFT-COLLATE\sfor\sTK_COLLATE\soperators\sthat\somit\nthe\sEP_Collate\sflag. +D 2019-09-10T17:51:27.783 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -589,7 +589,7 @@ F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394 F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c F src/tokenize.c d3615f0cbe4db5949503bf5916f3cd4fa5de855d5b4ef560f3b6dd5629423a1e -F src/treeview.c fc8c6c0a8a26afb3a97e3f844d65403dd27cf1450baf4415034fa4ccf00c4d7e +F src/treeview.c dd92b189d8c0623d6cf59cf2e136e4c3b2389ded133eaa15ca51d4714866ebb4 F src/trigger.c 845ccc08f60716c58aa28fe6470385c18ef8c4e1d88c93dcf449bc13d464eb2e F src/update.c 7f05fad5e145248a00048aeb0bac78b8fdb4ed17216e14a6eb24c55596e87ee7 F src/upsert.c 710c91bb13e3c3fed5b6fe17cb13e09560bdd003ad8b8c51e6b16c80cfc48b10 @@ -1841,7 +1841,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 b9ec72203c19c2b95e648ac1dfad74eec98d4ff82581cdc10dc4221ba551728f -R cd3dfdd19ee61439a8f3dafd644637dd -U dan -Z 5c236b65c054109c04d341f131258a9f +P 36997c4ade2ef3a274cd1ac52b44118fb3a05325adb650b7b338ecb43d060575 +R f5a1c0f164d27201c013c3daaa104b97 +U drh +Z 4233ce0b10c0fb1f5285adf400752dbf diff --git a/manifest.uuid b/manifest.uuid index 4cebedacd4..7f2e23c390 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -36997c4ade2ef3a274cd1ac52b44118fb3a05325adb650b7b338ecb43d060575 \ No newline at end of file +a97804620a27acc30bebd2aaa04e38f2f36de48b0931038ca8bdc9cb0c36b8f4 \ No newline at end of file diff --git a/src/treeview.c b/src/treeview.c index 6dfdccd7ee..dcc81b8767 100644 --- a/src/treeview.c +++ b/src/treeview.c @@ -536,7 +536,13 @@ void sqlite3TreeViewExpr(TreeView *pView, const Expr *pExpr, u8 moreToFollow){ } case TK_COLLATE: { - sqlite3TreeViewLine(pView, "COLLATE %Q", pExpr->u.zToken); + /* COLLATE operators without the EP_Collate flag are intended to + ** emulate collation associated with a table column. Explicit + ** COLLATE operators that appear in the original SQL always have + ** the EP_Collate bit set */ + sqlite3TreeViewLine(pView, "%sCOLLATE %Q%s", + !ExprHasProperty(pExpr, EP_Collate) ? "SOFT-" : "", + pExpr->u.zToken, zFlgs); sqlite3TreeViewExpr(pView, pExpr->pLeft, 0); break; } From acf6e08d20a663de5d4012effba666675bd23fe9 Mon Sep 17 00:00:00 2001 From: mistachkin Date: Wed, 11 Sep 2019 15:25:26 +0000 Subject: [PATCH 101/112] Fix typo for one instance of line number handling in the Lemon tool. FossilOrigin-Name: 980be1730dc1239c63a107923bf2e32b4ec7d4bc31b9190e711cc35f18cc2bb4 --- manifest | 14 +++++++------- manifest.uuid | 2 +- tool/lemon.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/manifest b/manifest index 22c156a669..dccb38d831 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Enhance\streeview\sto\sshow\sSOFT-COLLATE\sfor\sTK_COLLATE\soperators\sthat\somit\nthe\sEP_Collate\sflag. -D 2019-09-10T17:51:27.783 +C Fix\stypo\sfor\sone\sinstance\sof\sline\snumber\shandling\sin\sthe\sLemon\stool. +D 2019-09-11T15:25:26.595 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1760,7 +1760,7 @@ F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c 9ec344d29cbeb03fdc0fce668eedfb7495792170de933adf95cf8d6904a166ad F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c c9848ef9694689d244a5097238ca1f83df85cc52c80ad149a4cf49595a0ee9c2 +F tool/lemon.c 61d5f0af1eff8f754b75ddca668c9897fd30759e389bfffb42ce9e4d38fd4746 F tool/lempar.c eb2841e2a7fd484cf44b1f526b06e7ab0f216d2f41818bf9485e8f38e3d1db19 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 @@ -1841,7 +1841,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 36997c4ade2ef3a274cd1ac52b44118fb3a05325adb650b7b338ecb43d060575 -R f5a1c0f164d27201c013c3daaa104b97 -U drh -Z 4233ce0b10c0fb1f5285adf400752dbf +P a97804620a27acc30bebd2aaa04e38f2f36de48b0931038ca8bdc9cb0c36b8f4 +R 5065e0b2c7f4ffc5b218b4bab44bb95f +U mistachkin +Z 05d39d001f8aeefdace9f8a8f5ba54b9 diff --git a/manifest.uuid b/manifest.uuid index 7f2e23c390..70e92dabd6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a97804620a27acc30bebd2aaa04e38f2f36de48b0931038ca8bdc9cb0c36b8f4 \ No newline at end of file +980be1730dc1239c63a107923bf2e32b4ec7d4bc31b9190e711cc35f18cc2bb4 \ No newline at end of file diff --git a/tool/lemon.c b/tool/lemon.c index 893e1d18b9..6efc6af301 100644 --- a/tool/lemon.c +++ b/tool/lemon.c @@ -4426,7 +4426,7 @@ void ReportTable( } i++; } - if( j>0 ) fprintf(out, "\n"); lineno++; + if( j>0 ){ fprintf(out, "\n"); lineno++; } fprintf(out, "};\n"); lineno++; /* Output the yy_shift_ofst[] table */ From 685b2ee0c3e4cfafe0e3e8d121fb302d673d011f Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 12 Sep 2019 19:38:40 +0000 Subject: [PATCH 102/112] Allow fts5 to filter on multiple MATCH clauses in a single scan. FossilOrigin-Name: 9d418a7a491761eeb38a70898677a493e2631e5d62e75ee88431f52d3dfd2344 --- ext/fts5/fts5Int.h | 1 + ext/fts5/fts5_config.c | 2 +- ext/fts5/fts5_expr.c | 36 +++++ ext/fts5/fts5_main.c | 261 +++++++++++++++++++++------------- ext/fts5/test/fts5faultB.test | 22 +++ ext/fts5/test/fts5multi.test | 99 +++++++++++++ ext/fts5/test/fts5plan.test | 6 +- ext/fts5/test/fts5simple.test | 13 ++ manifest | 27 ++-- manifest.uuid | 2 +- 10 files changed, 349 insertions(+), 120 deletions(-) create mode 100644 ext/fts5/test/fts5multi.test diff --git a/ext/fts5/fts5Int.h b/ext/fts5/fts5Int.h index d0bb543e4c..c29b42b7ad 100644 --- a/ext/fts5/fts5Int.h +++ b/ext/fts5/fts5Int.h @@ -695,6 +695,7 @@ int sqlite3Fts5ExprEof(Fts5Expr*); i64 sqlite3Fts5ExprRowid(Fts5Expr*); void sqlite3Fts5ExprFree(Fts5Expr*); +int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2); /* Called during startup to register a UDF with SQLite */ int sqlite3Fts5ExprInit(Fts5Global*, sqlite3*); diff --git a/ext/fts5/fts5_config.c b/ext/fts5/fts5_config.c index 7a16e38c93..4e1707b3f4 100644 --- a/ext/fts5/fts5_config.c +++ b/ext/fts5/fts5_config.c @@ -683,7 +683,7 @@ int sqlite3Fts5ConfigDeclareVtab(Fts5Config *pConfig){ rc = sqlite3_declare_vtab(pConfig->db, zSql); sqlite3_free(zSql); } - + return rc; } diff --git a/ext/fts5/fts5_expr.c b/ext/fts5/fts5_expr.c index f1bf3f2abc..ce462af0f0 100644 --- a/ext/fts5/fts5_expr.c +++ b/ext/fts5/fts5_expr.c @@ -309,6 +309,42 @@ void sqlite3Fts5ExprFree(Fts5Expr *p){ } } +int sqlite3Fts5ExprAnd(Fts5Expr **pp1, Fts5Expr *p2){ + Fts5Parse sParse; + memset(&sParse, 0, sizeof(sParse)); + + if( *pp1 ){ + Fts5Expr *p1 = *pp1; + int nPhrase = p1->nPhrase + p2->nPhrase; + + p1->pRoot = sqlite3Fts5ParseNode(&sParse, FTS5_AND, p1->pRoot, p2->pRoot,0); + p2->pRoot = 0; + + if( sParse.rc==SQLITE_OK ){ + Fts5ExprPhrase **ap = (Fts5ExprPhrase**)sqlite3_realloc( + p1->apExprPhrase, nPhrase * sizeof(Fts5ExprPhrase*) + ); + if( ap==0 ){ + sParse.rc = SQLITE_NOMEM; + }else{ + int i; + memmove(&ap[p2->nPhrase], ap, p1->nPhrase*sizeof(Fts5ExprPhrase*)); + for(i=0; inPhrase; i++){ + ap[i] = p2->apExprPhrase[i]; + } + p1->nPhrase = nPhrase; + p1->apExprPhrase = ap; + } + } + sqlite3_free(p2->apExprPhrase); + sqlite3_free(p2); + }else{ + *pp1 = p2; + } + + return sParse.rc; +} + /* ** Argument pTerm must be a synonym iterator. Return the current rowid ** that it points to. diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index da5deef846..c073135c86 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -465,17 +465,39 @@ static void fts5SetUniqueFlag(sqlite3_index_info *pIdxInfo){ ** Implementation of the xBestIndex method for FTS5 tables. Within the ** WHERE constraint, it searches for the following: ** -** 1. A MATCH constraint against the special column. +** 1. A MATCH constraint against the table column. ** 2. A MATCH constraint against the "rank" column. -** 3. An == constraint against the rowid column. -** 4. A < or <= constraint against the rowid column. -** 5. A > or >= constraint against the rowid column. +** 3. A MATCH constraint against some other column. +** 4. An == constraint against the rowid column. +** 5. A < or <= constraint against the rowid column. +** 6. A > or >= constraint against the rowid column. ** -** Within the ORDER BY, either: +** Within the ORDER BY, the following are supported: ** ** 5. ORDER BY rank [ASC|DESC] ** 6. ORDER BY rowid [ASC|DESC] ** +** Information for the xFilter call is passed via both the idxNum and +** idxStr variables. Specifically, idxNum is a bitmask of the following +** flags used to encode the ORDER BY clause: +** +** FTS5_BI_ORDER_RANK +** FTS5_BI_ORDER_ROWID +** FTS5_BI_ORDER_DESC +** +** idxStr is used to encode data from the WHERE clause. For each argument +** passed to the xFilter method, the following is appended to idxStr: +** +** Match against table column: "m" +** Match against rank column: "r" +** Match against other column: "" +** Equality constraint against the rowid: "=" +** A < or <= against the rowid: "<" +** A > or >= against the rowid: ">" +** +** This function ensures that there is at most one "r" or "=". And that if +** there exists an "=" then there is no "<" or ">". +** ** Costs are assigned as follows: ** ** a) If an unusable MATCH operator is present in the WHERE clause, the @@ -503,32 +525,18 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ Fts5Config *pConfig = pTab->pConfig; const int nCol = pConfig->nCol; int idxFlags = 0; /* Parameter passed through to xFilter() */ - int bHasMatch; - int iNext; int i; - struct Constraint { - int op; /* Mask against sqlite3_index_constraint.op */ - int fts5op; /* FTS5 mask for idxFlags */ - int iCol; /* 0==rowid, 1==tbl, 2==rank */ - int omit; /* True to omit this if found */ - int iConsIndex; /* Index in pInfo->aConstraint[] */ - } aConstraint[] = { - {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, - FTS5_BI_MATCH, 1, 1, -1}, - {SQLITE_INDEX_CONSTRAINT_MATCH|SQLITE_INDEX_CONSTRAINT_EQ, - FTS5_BI_RANK, 2, 1, -1}, - {SQLITE_INDEX_CONSTRAINT_EQ, FTS5_BI_ROWID_EQ, 0, 0, -1}, - {SQLITE_INDEX_CONSTRAINT_LT|SQLITE_INDEX_CONSTRAINT_LE, - FTS5_BI_ROWID_LE, 0, 0, -1}, - {SQLITE_INDEX_CONSTRAINT_GT|SQLITE_INDEX_CONSTRAINT_GE, - FTS5_BI_ROWID_GE, 0, 0, -1}, - }; + char *idxStr; + int iIdxStr = 0; + int iCons = 0; + + int bSeenEq = 0; + int bSeenGt = 0; + int bSeenLt = 0; + int bSeenMatch = 0; + int bSeenRank = 0; - int aColMap[3]; - aColMap[0] = -1; - aColMap[1] = nCol; - aColMap[2] = nCol+1; assert( SQLITE_INDEX_CONSTRAINT_EQnConstraint * 6 + 1); + if( idxStr==0 ) return SQLITE_NOMEM; + pInfo->idxStr = idxStr; + pInfo->needToFreeIdxStr = 1; + for(i=0; inConstraint; i++){ struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; int iCol = p->iColumn; - - if( (p->op==SQLITE_INDEX_CONSTRAINT_MATCH && iCol>=0 && iCol<=nCol) - || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol==nCol) + if( p->op==SQLITE_INDEX_CONSTRAINT_MATCH + || (p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol>=nCol) ){ /* A MATCH operator or equivalent */ - if( p->usable ){ - idxFlags = (idxFlags & 0xFFFF) | FTS5_BI_MATCH | (iCol << 16); - aConstraint[0].iConsIndex = i; - }else{ + if( p->usable==0 || iCol<0 ){ /* As there exists an unusable MATCH constraint this is an ** unusable plan. Set a prohibitively high cost. */ pInfo->estimatedCost = 1e50; return SQLITE_OK; + }else{ + if( iCol==nCol+1 ){ + if( bSeenRank ) continue; + idxStr[iIdxStr++] = 'r'; + bSeenRank = 1; + }else{ + bSeenMatch = 1; + idxStr[iIdxStr++] = 'm'; + if( iColaConstraintUsage[i].argvIndex = ++iCons; + pInfo->aConstraintUsage[i].omit = 1; } - }else if( p->op<=SQLITE_INDEX_CONSTRAINT_MATCH ){ - int j; - for(j=1; jiCol] && (p->op & pC->op) && p->usable ){ - pC->iConsIndex = i; - idxFlags |= pC->fts5op; + } + else if( p->usable && bSeenEq==0 + && p->op==SQLITE_INDEX_CONSTRAINT_EQ && iCol<0 + ){ + idxStr[iIdxStr++] = '='; + bSeenEq = 1; + pInfo->aConstraintUsage[i].argvIndex = ++iCons; + } + } + + if( bSeenEq==0 ){ + for(i=0; inConstraint; i++){ + struct sqlite3_index_constraint *p = &pInfo->aConstraint[i]; + if( p->iColumn<0 && p->usable ){ + int op = p->op; + if( op==SQLITE_INDEX_CONSTRAINT_LT || op==SQLITE_INDEX_CONSTRAINT_LE ){ + if( bSeenLt ) continue; + idxStr[iIdxStr++] = '<'; + pInfo->aConstraintUsage[i].argvIndex = ++iCons; + bSeenLt = 1; + }else + if( op==SQLITE_INDEX_CONSTRAINT_GT || op==SQLITE_INDEX_CONSTRAINT_GE ){ + if( bSeenGt ) continue; + idxStr[iIdxStr++] = '>'; + pInfo->aConstraintUsage[i].argvIndex = ++iCons; + bSeenGt = 1; } } } } + idxStr[iIdxStr] = '\0'; /* Set idxFlags flags for the ORDER BY clause */ if( pInfo->nOrderBy==1 ){ int iSort = pInfo->aOrderBy[0].iColumn; - if( iSort==(pConfig->nCol+1) && BitFlagTest(idxFlags, FTS5_BI_MATCH) ){ + if( iSort==(pConfig->nCol+1) && bSeenMatch ){ idxFlags |= FTS5_BI_ORDER_RANK; }else if( iSort==-1 ){ idxFlags |= FTS5_BI_ORDER_ROWID; @@ -590,26 +634,15 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ } /* Calculate the estimated cost based on the flags set in idxFlags. */ - bHasMatch = BitFlagTest(idxFlags, FTS5_BI_MATCH); - if( BitFlagTest(idxFlags, FTS5_BI_ROWID_EQ) ){ - pInfo->estimatedCost = bHasMatch ? 100.0 : 10.0; - if( bHasMatch==0 ) fts5SetUniqueFlag(pInfo); - }else if( BitFlagAllTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){ - pInfo->estimatedCost = bHasMatch ? 500.0 : 250000.0; - }else if( BitFlagTest(idxFlags, FTS5_BI_ROWID_LE|FTS5_BI_ROWID_GE) ){ - pInfo->estimatedCost = bHasMatch ? 750.0 : 750000.0; + if( bSeenEq ){ + pInfo->estimatedCost = bSeenMatch ? 100.0 : 10.0; + if( bSeenMatch==0 ) fts5SetUniqueFlag(pInfo); + }else if( bSeenLt && bSeenGt ){ + pInfo->estimatedCost = bSeenMatch ? 500.0 : 250000.0; + }else if( bSeenLt || bSeenGt ){ + pInfo->estimatedCost = bSeenMatch ? 750.0 : 750000.0; }else{ - pInfo->estimatedCost = bHasMatch ? 1000.0 : 1000000.0; - } - - /* Assign argvIndex values to each constraint in use. */ - iNext = 1; - for(i=0; iiConsIndex>=0 ){ - pInfo->aConstraintUsage[pC->iConsIndex].argvIndex = iNext++; - pInfo->aConstraintUsage[pC->iConsIndex].omit = (unsigned char)pC->omit; - } + pInfo->estimatedCost = bSeenMatch ? 1000.0 : 1000000.0; } pInfo->idxNum = idxFlags; @@ -1132,7 +1165,7 @@ static i64 fts5GetRowidLimit(sqlite3_value *pVal, i64 iDefault){ static int fts5FilterMethod( sqlite3_vtab_cursor *pCursor, /* The cursor used for this query */ int idxNum, /* Strategy index */ - const char *zUnused, /* Unused */ + const char *idxStr, /* Unused */ int nVal, /* Number of elements in apVal */ sqlite3_value **apVal /* Arguments for the indexing scheme */ ){ @@ -1140,7 +1173,6 @@ static int fts5FilterMethod( Fts5Config *pConfig = pTab->p.pConfig; Fts5Cursor *pCsr = (Fts5Cursor*)pCursor; int rc = SQLITE_OK; /* Error code */ - int iVal = 0; /* Counter for apVal[] */ int bDesc; /* True if ORDER BY [rank|rowid] DESC */ int bOrderByRank; /* True if ORDER BY rank */ sqlite3_value *pMatch = 0; /* MATCH ? expression (or NULL) */ @@ -1150,9 +1182,9 @@ static int fts5FilterMethod( sqlite3_value *pRowidGe = 0; /* rowid >= ? expression (or NULL) */ int iCol; /* Column on LHS of MATCH operator */ char **pzErrmsg = pConfig->pzErrmsg; - - UNUSED_PARAM(zUnused); - UNUSED_PARAM(nVal); + int i; + int iIdxStr = 0; + Fts5Expr *pExpr = 0; if( pCsr->ePlan ){ fts5FreeCursorComponents(pCsr); @@ -1165,23 +1197,60 @@ static int fts5FilterMethod( assert( pCsr->pRank==0 ); assert( pCsr->zRank==0 ); assert( pCsr->zRankArgs==0 ); + assert( pTab->pSortCsr==0 || nVal==0 ); assert( pzErrmsg==0 || pzErrmsg==&pTab->p.base.zErrMsg ); pConfig->pzErrmsg = &pTab->p.base.zErrMsg; - /* Decode the arguments passed through to this function. - ** - ** Note: The following set of if(...) statements must be in the same - ** order as the corresponding entries in the struct at the top of - ** fts5BestIndexMethod(). */ - if( BitFlagTest(idxNum, FTS5_BI_MATCH) ) pMatch = apVal[iVal++]; - if( BitFlagTest(idxNum, FTS5_BI_RANK) ) pRank = apVal[iVal++]; - if( BitFlagTest(idxNum, FTS5_BI_ROWID_EQ) ) pRowidEq = apVal[iVal++]; - if( BitFlagTest(idxNum, FTS5_BI_ROWID_LE) ) pRowidLe = apVal[iVal++]; - if( BitFlagTest(idxNum, FTS5_BI_ROWID_GE) ) pRowidGe = apVal[iVal++]; - iCol = (idxNum>>16); - assert( iCol>=0 && iCol<=pConfig->nCol ); - assert( iVal==nVal ); + /* Decode the arguments passed through to this function. */ + for(i=0; i='0' && idxStr[iIdxStr]<='9' ){ + iCol = 0; + do{ + iCol = iCol*10 + (idxStr[iIdxStr]-'0'); + iIdxStr++; + }while( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ); + }else{ + iCol = pConfig->nCol; + } + + if( zText[0]=='*' ){ + /* The user has issued a query of the form "MATCH '*...'". This + ** indicates that the MATCH expression is not a full text query, + ** but a request for an internal parameter. */ + rc = fts5SpecialMatch(pTab, pCsr, &zText[1]); + goto filter_out; + }else{ + char **pzErr = &pTab->p.base.zErrMsg; + rc = sqlite3Fts5ExprNew(pConfig, iCol, zText, &pExpr, pzErr); + if( rc==SQLITE_OK ){ + rc = sqlite3Fts5ExprAnd(&pCsr->pExpr, pExpr); + pExpr = 0; + } + if( rc!=SQLITE_OK ) goto filter_out; + } + + break; + } + case '=': + pRowidEq = apVal[i]; + break; + case '<': + pRowidLe = apVal[i]; + break; + default: assert( idxStr[iIdxStr-1]=='>' ); + pRowidGe = apVal[i]; + break; + } + } bOrderByRank = ((idxNum & FTS5_BI_ORDER_RANK) ? 1 : 0); pCsr->bDesc = bDesc = ((idxNum & FTS5_BI_ORDER_DESC) ? 1 : 0); @@ -1221,29 +1290,15 @@ static int fts5FilterMethod( pCsr->ePlan = FTS5_PLAN_SOURCE; pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); - }else if( pMatch ){ - const char *zExpr = (const char*)sqlite3_value_text(apVal[0]); - if( zExpr==0 ) zExpr = ""; - + }else if( pCsr->pExpr ){ rc = fts5CursorParseRank(pConfig, pCsr, pRank); if( rc==SQLITE_OK ){ - if( zExpr[0]=='*' ){ - /* The user has issued a query of the form "MATCH '*...'". This - ** indicates that the MATCH expression is not a full text query, - ** but a request for an internal parameter. */ - rc = fts5SpecialMatch(pTab, pCsr, &zExpr[1]); + if( bOrderByRank ){ + pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; + rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); }else{ - char **pzErr = &pTab->p.base.zErrMsg; - rc = sqlite3Fts5ExprNew(pConfig, iCol, zExpr, &pCsr->pExpr, pzErr); - if( rc==SQLITE_OK ){ - if( bOrderByRank ){ - pCsr->ePlan = FTS5_PLAN_SORTED_MATCH; - rc = fts5CursorFirstSorted(pTab, pCsr, bDesc); - }else{ - pCsr->ePlan = FTS5_PLAN_MATCH; - rc = fts5CursorFirst(pTab, pCsr, bDesc); - } - } + pCsr->ePlan = FTS5_PLAN_MATCH; + rc = fts5CursorFirst(pTab, pCsr, bDesc); } } }else if( pConfig->zContent==0 ){ @@ -1260,7 +1315,7 @@ static int fts5FilterMethod( ); if( rc==SQLITE_OK ){ if( pCsr->ePlan==FTS5_PLAN_ROWID ){ - sqlite3_bind_value(pCsr->pStmt, 1, apVal[0]); + sqlite3_bind_value(pCsr->pStmt, 1, pRowidEq); }else{ sqlite3_bind_int64(pCsr->pStmt, 1, pCsr->iFirstRowid); sqlite3_bind_int64(pCsr->pStmt, 2, pCsr->iLastRowid); @@ -1269,6 +1324,8 @@ static int fts5FilterMethod( } } + filter_out: + sqlite3Fts5ExprFree(pExpr); pConfig->pzErrmsg = pzErrmsg; return rc; } diff --git a/ext/fts5/test/fts5faultB.test b/ext/fts5/test/fts5faultB.test index 2faec706d5..e5fc514d09 100644 --- a/ext/fts5/test/fts5faultB.test +++ b/ext/fts5/test/fts5faultB.test @@ -147,5 +147,27 @@ do_faultsim_test 5.1 -faults oom* -body { faultsim_test_result {0 {1 4}} } +#------------------------------------------------------------------------- +# Test OOM injection in a query with two MATCH expressions +# +reset_db +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a); + INSERT INTO t1 VALUES('a b c d'); -- 1 + INSERT INTO t1 VALUES('d a b c'); -- 2 + INSERT INTO t1 VALUES('c d a b'); -- 3 + INSERT INTO t1 VALUES('b c d a'); -- 4 +} +do_faultsim_test 6.1 -faults oom* -body { + execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a' AND t1 MATCH 'b' } +} -test { + faultsim_test_result {0 {1 2 3 4}} +} +do_faultsim_test 6.2 -faults oom* -body { + execsql { SELECT rowid FROM t1 WHERE t1 MATCH 'a OR b' AND t1 MATCH 'c OR d' } +} -test { + faultsim_test_result {0 {1 2 3 4}} +} + finish_test diff --git a/ext/fts5/test/fts5multi.test b/ext/fts5/test/fts5multi.test new file mode 100644 index 0000000000..7878cede7e --- /dev/null +++ b/ext/fts5/test/fts5multi.test @@ -0,0 +1,99 @@ +# 2014 September 13 +# +# 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. The +# focus of this script is testing the FTS5 module. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5multi + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +fts5_aux_test_functions db + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, c); + INSERT INTO t1 VALUES('gg bb bb' ,'gg ff gg' ,'ii ii'); + INSERT INTO t1 VALUES('dd dd hh kk','jj' ,'aa'); + INSERT INTO t1 VALUES('kk gg ee' ,'hh cc' ,'hh jj aa cc'); + INSERT INTO t1 VALUES('hh' ,'bb jj cc' ,'kk ii'); + INSERT INTO t1 VALUES('kk dd kk ii','aa ee aa' ,'ee'); + INSERT INTO t1 VALUES('ee' ,'ff gg kk aa','ee ff ee'); + INSERT INTO t1 VALUES('ff jj' ,'gg ee' ,'kk ee gg kk'); + INSERT INTO t1 VALUES('ff ee dd hh','kk ee' ,'gg dd'); + INSERT INTO t1 VALUES('bb' ,'aa' ,'bb aa'); + INSERT INTO t1 VALUES('hh cc bb' ,'ff bb' ,'cc'); + INSERT INTO t1 VALUES('jj' ,'ff dd bb aa','dd dd ff ff'); + INSERT INTO t1 VALUES('ff dd gg dd','gg aa bb ff','cc'); + INSERT INTO t1 VALUES('ff aa cc jj','kk' ,'ii dd'); + INSERT INTO t1 VALUES('jj dd' ,'cc' ,'ii hh ee aa'); + INSERT INTO t1 VALUES('ff ii hh' ,'dd' ,'gg'); + INSERT INTO t1 VALUES('ff dd gg hh','hh' ,'ff dd'); + INSERT INTO t1 VALUES('cc cc' ,'ff dd ff' ,'bb'); + INSERT INTO t1 VALUES('ii' ,'bb ii' ,'jj kk'); + INSERT INTO t1 VALUES('ff hh' ,'hh bb' ,'bb dd ee'); + INSERT INTO t1 VALUES('jj kk' ,'jj' ,'gg ff cc'); + INSERT INTO t1 VALUES('dd kk' ,'ii gg' ,'dd'); + INSERT INTO t1 VALUES('cc' ,'aa ff' ,'ii'); + INSERT INTO t1 VALUES('bb ff bb ii','bb kk bb aa','hh ff ii dd'); + INSERT INTO t1 VALUES('aa' ,'ee bb jj jj','dd'); + INSERT INTO t1 VALUES('kk dd cc' ,'aa jj' ,'ee aa ff'); + INSERT INTO t1 VALUES('aa gg aa' ,'jj' ,'ii kk hh gg'); + INSERT INTO t1 VALUES('ff hh aa' ,'jj ii' ,'hh dd bb jj'); + INSERT INTO t1 VALUES('hh' ,'aa gg kk' ,'bb ee'); + INSERT INTO t1 VALUES('bb' ,'ee' ,'gg'); + INSERT INTO t1 VALUES('dd kk' ,'kk bb aa' ,'ee'); +} + +foreach {tn c1 e1 c2 e2} { + 1 t1 aa t1 bb + 2 a aa b bb + 3 a "aa OR bb OR cc" b "jj OR ii OR hh" + 4 t1 "aa AND bb" t1 "cc" + 5 c "kk" b "aa OR bb OR cc OR dd OR ee" +} { + if {$c1=="t1"} { + set lhs "( $e1 )" + } else { + set lhs "$c1 : ( $e1 )" + } + if {$c2=="t1"} { + set rhs "( $e2 )" + } else { + set rhs "$c2 : ( $e2 )" + } + + set q1 "t1 MATCH '($lhs) AND ($rhs)'" + set q2 "$c1 MATCH '$e1' AND $c2 MATCH '$e2'" + + set ret [execsql "SELECT rowid FROM t1 WHERE $q1"] + set N [llength $ret] + do_execsql_test 1.$tn.1.($N) "SELECT rowid FROM t1 WHERE $q2" $ret + + set ret [execsql "SELECT fts5_test_poslist(t1) FROM t1 WHERE $q1"] + do_execsql_test 1.$tn.2.($N) " + SELECT fts5_test_poslist(t1) FROM t1 WHERE $q2 + " $ret +} + +do_catchsql_test 2.1.1 { + SELECT rowid FROM t1 WHERE t1 MATCH '(NOT' AND t1 MATCH 'aa bb'; +} {1 {fts5: syntax error near "NOT"}} +do_catchsql_test 2.1.2 { + SELECT rowid FROM t1 WHERE t1 MATCH 'aa bb' AND t1 MATCH '(NOT'; +} {1 {fts5: syntax error near "NOT"}} + +finish_test + diff --git a/ext/fts5/test/fts5plan.test b/ext/fts5/test/fts5plan.test index 8f57e39a81..46ac234ff7 100644 --- a/ext/fts5/test/fts5plan.test +++ b/ext/fts5/test/fts5plan.test @@ -31,7 +31,7 @@ do_eqp_test 1.1 { } { QUERY PLAN |--SCAN TABLE t1 - `--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537: + `--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m } do_eqp_test 1.2 { @@ -46,7 +46,7 @@ do_eqp_test 1.3 { SELECT * FROM f1 WHERE f1 MATCH ? ORDER BY ff } { QUERY PLAN - |--SCAN TABLE f1 VIRTUAL TABLE INDEX 65537: + |--SCAN TABLE f1 VIRTUAL TABLE INDEX 0:m `--USE TEMP B-TREE FOR ORDER BY } @@ -60,6 +60,6 @@ do_eqp_test 1.4 { do_eqp_test 1.5 { SELECT * FROM f1 WHERE rank MATCH ? -} {SCAN TABLE f1 VIRTUAL TABLE INDEX 2:} +} {SCAN TABLE f1 VIRTUAL TABLE INDEX 0:r} finish_test diff --git a/ext/fts5/test/fts5simple.test b/ext/fts5/test/fts5simple.test index 7fb0681dc8..936bbb2549 100644 --- a/ext/fts5/test/fts5simple.test +++ b/ext/fts5/test/fts5simple.test @@ -467,4 +467,17 @@ do_execsql_test 21.3 { SELECT rowid FROM x1($doc); } {11112} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 22.0 { + CREATE VIRTUAL TABLE x1 USING fts5(x); + INSERT INTO x1(x) VALUES('a b c'); + INSERT INTO x1(x) VALUES('x y z'); + INSERT INTO x1(x) VALUES('c b a'); + INSERT INTO x1(x) VALUES('z y x'); +} + +do_catchsql_test 22.1 {SELECT * FROM x1('')} {1 {fts5: syntax error near ""}} +do_catchsql_test 22.2 {SELECT * FROM x1(NULL)} {1 {fts5: syntax error near ""}} + finish_test diff --git a/manifest b/manifest index dccb38d831..242da89195 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\stypo\sfor\sone\sinstance\sof\sline\snumber\shandling\sin\sthe\sLemon\stool. -D 2019-09-11T15:25:26.595 +C Allow\sfts5\sto\sfilter\son\smultiple\sMATCH\sclauses\sin\sa\ssingle\sscan. +D 2019-09-12T19:38:40.141 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -110,14 +110,14 @@ F ext/fts3/unicode/mkunicode.tcl bf7fcaa6d68e6d38223467983785d054f1cff4d9e3905dd F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 F ext/fts5/fts5.h 7c9da96f2b9dcfa4dd94081fb2d87ec418d8cdb35b25df56756c334b6b558fd7 -F ext/fts5/fts5Int.h d87fb17d12296613cdec2d1f4213ecd8840d3deb34837b6d3889b830d06baac4 +F ext/fts5/fts5Int.h 0ec19a906a54c0e53f8a380c0ff70f11a866aa259490bc13aa39f8d2491800fd F ext/fts5/fts5_aux.c dcc627d8b6e3fc773db528ff67b39955dab7b51628f9dba8e15849e5bedfd7fa F ext/fts5/fts5_buffer.c 5a5fe0159752c0fb0a5a93c722e9db2662822709490769d482b76a6dc8aaca70 -F ext/fts5/fts5_config.c d7523cba5e66da077233c023aecbc3e6a37978ff75a18131c5ab5b1229d5bac7 -F ext/fts5/fts5_expr.c 840c88d55e78083a5e61a35968df877712ae28791b347eced1e98e3b337d2d3c +F ext/fts5/fts5_config.c 606a29f2962a8f4508923e6ad833974b32a3ab4093f63fd6de0fb33a87eed54c +F ext/fts5/fts5_expr.c 5661fe64f4f5a499710df9561075de84b743f01e808af46df4130a9ec343a0fd F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 F ext/fts5/fts5_index.c b062bdb836e195656aac8d6684e943585cff4bf7d7c593c80cb67c3b6cfef7ee -F ext/fts5/fts5_main.c 15dc14ea594ff2ea183f5e79c8f6fea14640ac7c4bd5d93ad1d506a4db80c998 +F ext/fts5/fts5_main.c e6db945454a0dae2dafcf29905d7d5272b64b00da34a43bd4ce732e2079a159d F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -176,7 +176,7 @@ F ext/fts5/test/fts5fault7.test 0acbec416edb24b8881f154e99c31e9ccf73f539cfcd1640 F ext/fts5/test/fts5fault8.test 318238659d35f82ad215ecb57ca4c87486ea85d45dbeedaee42f148ff5105ee2 F ext/fts5/test/fts5fault9.test 098e6b894bbdf9b2192f994a30f4043673fb3f338b6b8ab1624c704422f39119 F ext/fts5/test/fts5faultA.test be4487576bff8c22cee6597d1893b312f306504a8c6ccd3c53ca85af12290c8c -F ext/fts5/test/fts5faultB.test e6d04f9ea7b21be1d89abb8df2cb4baf65b0453b744d5a805fcd3ef45ff86a7e +F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5 F ext/fts5/test/fts5faultD.test cc5d1225556e356615e719c612e845d41bff7d5a F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079 F ext/fts5/test/fts5full.test 49b565da02918c06e58f51f0b953b0302b96f155aa68baba24782b81570685e2 @@ -190,12 +190,13 @@ F ext/fts5/test/fts5matchinfo.test 79129ff6c9a2d86943b287a5a8caa7ee639f6dcf004d8 F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 F ext/fts5/test/fts5misc.test 5becd134b66f7370042968a2b127b92ea7748e249f16cb6a996f450812e89eec +F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581 F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1 F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b -F ext/fts5/test/fts5plan.test 00dc4c974938b509db7cb3680407f068ee6e9cc824f492f68cb741a7b679fe41 +F ext/fts5/test/fts5plan.test 771b999d161e24fd803ce0290adb7c6e7c9b9cc2c6a0adb344813fb89473aa32 F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15 F ext/fts5/test/fts5porter2.test 0d251a673f02fa13ca7f011654873b3add20745f7402f108600a23e52d8c7457 F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056 @@ -204,7 +205,7 @@ F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7 F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415 F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6 -F ext/fts5/test/fts5simple.test 313ad28ef38ebe25f0a1673dd18f2fac446e25feb15bbb0c223a65ea00594f72 +F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d0585f68f146a0da603f0 F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb @@ -1841,7 +1842,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 a97804620a27acc30bebd2aaa04e38f2f36de48b0931038ca8bdc9cb0c36b8f4 -R 5065e0b2c7f4ffc5b218b4bab44bb95f -U mistachkin -Z 05d39d001f8aeefdace9f8a8f5ba54b9 +P 980be1730dc1239c63a107923bf2e32b4ec7d4bc31b9190e711cc35f18cc2bb4 +R f455101857a1853760c9098b8cd2af2d +U dan +Z 191c94e283a8422844a9aa5307aa3f27 diff --git a/manifest.uuid b/manifest.uuid index 70e92dabd6..505907fee0 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -980be1730dc1239c63a107923bf2e32b4ec7d4bc31b9190e711cc35f18cc2bb4 \ No newline at end of file +9d418a7a491761eeb38a70898677a493e2631e5d62e75ee88431f52d3dfd2344 \ No newline at end of file From fbb9a5b1e377224f8f409bec03d3947188417623 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Sep 2019 12:24:58 +0000 Subject: [PATCH 103/112] Fix harmless compiler warnings. FossilOrigin-Name: a8927d14f88c44828e794787bab080455ab62705c93f65ce7d8db83478aa5a8e --- ext/fts5/fts5_main.c | 5 ++--- manifest | 14 +++++++------- manifest.uuid | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index c073135c86..09041ba494 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -1175,7 +1175,6 @@ static int fts5FilterMethod( int rc = SQLITE_OK; /* Error code */ int bDesc; /* True if ORDER BY [rank|rowid] DESC */ int bOrderByRank; /* True if ORDER BY rank */ - sqlite3_value *pMatch = 0; /* MATCH ? expression (or NULL) */ sqlite3_value *pRank = 0; /* rank MATCH ? expression (or NULL) */ sqlite3_value *pRowidEq = 0; /* rowid = ? expression (or NULL) */ sqlite3_value *pRowidLe = 0; /* rowid <= ? expression (or NULL) */ @@ -1209,7 +1208,7 @@ static int fts5FilterMethod( pRank = apVal[i]; break; case 'm': { - char *zText = sqlite3_value_text(apVal[i]); + const char *zText = (const char*)sqlite3_value_text(apVal[i]); if( zText==0 ) zText = ""; if( idxStr[iIdxStr]>='0' && idxStr[iIdxStr]<='9' ){ @@ -1277,7 +1276,7 @@ static int fts5FilterMethod( ** (pCursor) is used to execute the query issued by function ** fts5CursorFirstSorted() above. */ assert( pRowidEq==0 && pRowidLe==0 && pRowidGe==0 && pRank==0 ); - assert( nVal==0 && pMatch==0 && bOrderByRank==0 && bDesc==0 ); + assert( nVal==0 && bOrderByRank==0 && bDesc==0 ); assert( pCsr->iLastRowid==LARGEST_INT64 ); assert( pCsr->iFirstRowid==SMALLEST_INT64 ); if( pTab->pSortCsr->bDesc ){ diff --git a/manifest b/manifest index 242da89195..6420f20d18 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Allow\sfts5\sto\sfilter\son\smultiple\sMATCH\sclauses\sin\sa\ssingle\sscan. -D 2019-09-12T19:38:40.141 +C Fix\sharmless\scompiler\swarnings. +D 2019-09-13T12:24:58.472 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,7 +117,7 @@ F ext/fts5/fts5_config.c 606a29f2962a8f4508923e6ad833974b32a3ab4093f63fd6de0fb33 F ext/fts5/fts5_expr.c 5661fe64f4f5a499710df9561075de84b743f01e808af46df4130a9ec343a0fd F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 F ext/fts5/fts5_index.c b062bdb836e195656aac8d6684e943585cff4bf7d7c593c80cb67c3b6cfef7ee -F ext/fts5/fts5_main.c e6db945454a0dae2dafcf29905d7d5272b64b00da34a43bd4ce732e2079a159d +F ext/fts5/fts5_main.c c589c81760579fd5cc3ed6c5c31eb6059b4d61a89770b7003f749a30d10c36f2 F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -1842,7 +1842,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 980be1730dc1239c63a107923bf2e32b4ec7d4bc31b9190e711cc35f18cc2bb4 -R f455101857a1853760c9098b8cd2af2d -U dan -Z 191c94e283a8422844a9aa5307aa3f27 +P 9d418a7a491761eeb38a70898677a493e2631e5d62e75ee88431f52d3dfd2344 +R 081d79e579f06000a847b33f6c7ba7a5 +U drh +Z 573c86de16a248cef196a4da7e7449bd diff --git a/manifest.uuid b/manifest.uuid index 505907fee0..a7169b4460 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -9d418a7a491761eeb38a70898677a493e2631e5d62e75ee88431f52d3dfd2344 \ No newline at end of file +a8927d14f88c44828e794787bab080455ab62705c93f65ce7d8db83478aa5a8e \ No newline at end of file From 3f3f2c73575ea8ae9a46ea30b3af6dfc342cd6c9 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Sep 2019 13:23:13 +0000 Subject: [PATCH 104/112] Ensure that the idxStr for FTS5 is always zero-terminated. Fix for check-in [e6db945454a0dae2] FossilOrigin-Name: 090cd07d37904da4610d6a6787a3cc825c9a8bdcc5f051267d4608bba9b49d03 --- ext/fts5/fts5_main.c | 2 ++ manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/ext/fts5/fts5_main.c b/ext/fts5/fts5_main.c index 09041ba494..fc4ec0c482 100644 --- a/ext/fts5/fts5_main.c +++ b/ext/fts5/fts5_main.c @@ -567,6 +567,8 @@ static int fts5BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){ /* As there exists an unusable MATCH constraint this is an ** unusable plan. Set a prohibitively high cost. */ pInfo->estimatedCost = 1e50; + assert( iIdxStr < pInfo->nConstraint*6 + 1 ); + idxStr[iIdxStr] = 0; return SQLITE_OK; }else{ if( iCol==nCol+1 ){ diff --git a/manifest b/manifest index 6420f20d18..f7bb1bed41 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sharmless\scompiler\swarnings. -D 2019-09-13T12:24:58.472 +C Ensure\sthat\sthe\sidxStr\sfor\sFTS5\sis\salways\szero-terminated.\nFix\sfor\scheck-in\s[e6db945454a0dae2] +D 2019-09-13T13:23:13.490 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -117,7 +117,7 @@ F ext/fts5/fts5_config.c 606a29f2962a8f4508923e6ad833974b32a3ab4093f63fd6de0fb33 F ext/fts5/fts5_expr.c 5661fe64f4f5a499710df9561075de84b743f01e808af46df4130a9ec343a0fd F ext/fts5/fts5_hash.c 1cc0095646f5f3b46721aa112fb4f9bf29ae175cb5338f89dcec66ed97acfe75 F ext/fts5/fts5_index.c b062bdb836e195656aac8d6684e943585cff4bf7d7c593c80cb67c3b6cfef7ee -F ext/fts5/fts5_main.c c589c81760579fd5cc3ed6c5c31eb6059b4d61a89770b7003f749a30d10c36f2 +F ext/fts5/fts5_main.c bf637030722badf06667d28f7159e4c209dbafd7aa76c33f387104b78ad147e1 F ext/fts5/fts5_storage.c 801b4e3cd33786a60a07b6b01f86d0fbdf7e68325054e08d17176293a8081e99 F ext/fts5/fts5_tcl.c 39bcbae507f594aad778172fa914cad0f585bf92fd3b078c686e249282db0d95 F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee @@ -1842,7 +1842,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 9d418a7a491761eeb38a70898677a493e2631e5d62e75ee88431f52d3dfd2344 -R 081d79e579f06000a847b33f6c7ba7a5 +P a8927d14f88c44828e794787bab080455ab62705c93f65ce7d8db83478aa5a8e +R 1b0d381d385e92afee32191d4d702401 U drh -Z 573c86de16a248cef196a4da7e7449bd +Z bf931f65c31f45c41d3fdaadb23bca9e diff --git a/manifest.uuid b/manifest.uuid index a7169b4460..528dcf10a8 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a8927d14f88c44828e794787bab080455ab62705c93f65ce7d8db83478aa5a8e \ No newline at end of file +090cd07d37904da4610d6a6787a3cc825c9a8bdcc5f051267d4608bba9b49d03 \ No newline at end of file From 01a3b6b1b2dae46b1a54264ce78ff95fb7fc2d95 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 13 Sep 2019 17:05:48 +0000 Subject: [PATCH 105/112] Change the meaning of the SQLITE_SUBTYPE flag so that it indicates that the user-defined function cares about the subtypes of its arguments. FossilOrigin-Name: af1bc20f502816db460d2b2d353f715da5cf660e59095de5214c829c1cb20981 --- ext/misc/json1.c | 8 ++++---- manifest | 19 +++++++++++-------- manifest.uuid | 2 +- src/sqlite.h.in | 10 +++++++--- src/window.c | 28 +--------------------------- 5 files changed, 24 insertions(+), 43 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index 1c63c3e409..b3130eaf07 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -2504,14 +2504,14 @@ int sqlite3Json1Init(sqlite3 *db){ #endif for(i=0; idb; - int i; - for(i=0; inExpr; i++){ - Expr *p = pList->a[i].pExpr; - if( p->op==TK_FUNCTION ){ - FuncDef *pDef; - int nArg = 0; - if( !ExprHasProperty(p, EP_TokenOnly) && p->x.pList ){ - nArg = p->x.pList->nExpr; - } - pDef = sqlite3FindFunction(db, p->u.zToken, nArg, db->enc, 0); - if( pDef && (pDef->funcFlags & SQLITE_FUNC_SUBTYPE) ){ - return 1; - } - } - } - } - return 0; -} - /* ** Append a copy of each expression in expression-list pAppend to ** expression list pList. Return a pointer to the result list. @@ -992,7 +966,7 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){ ** results. */ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ ExprList *pArgs = pWin->pOwner->x.pList; - if( exprListContainsSubtype(pParse, pArgs) ){ + if( pWin->pFunc->funcFlags & SQLITE_FUNC_SUBTYPE ){ selectWindowRewriteEList(pParse, pMWin, pSrc, pArgs, pTab, &pSublist); pWin->iArgCol = (pSublist ? pSublist->nExpr : 0); pWin->bExprArgs = 1; From 477f1f12e2b9a13c663aab985d28ad589d37a1ea Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Sep 2019 17:30:24 +0000 Subject: [PATCH 106/112] Fix a typo in the carray extension header comment - the comment that serves as the documentation to this extension. FossilOrigin-Name: 658a42d3633b31fda260f2c5a1a2c7dd8eb4eb0114d322369017c56faf5ecd42 --- ext/misc/carray.c | 2 +- manifest | 12 ++++++------ manifest.uuid | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ext/misc/carray.c b/ext/misc/carray.c index b39904ae15..32fec3406e 100644 --- a/ext/misc/carray.c +++ b/ext/misc/carray.c @@ -24,7 +24,7 @@ ** ** static int aX[] = { 53, 9, 17, 2231, 4, 99 }; ** int i = sqlite3_bind_parameter_index(pStmt, "$ptr"); -** sqlite3_bind_value(pStmt, i, aX, "carray", 0); +** sqlite3_bind_pointer(pStmt, i, aX, "carray", 0); ** ** There is an optional third parameter to determine the datatype of ** the C-language array. Allowed values of the third parameter are diff --git a/manifest b/manifest index f7bb1bed41..c2333b555e 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Ensure\sthat\sthe\sidxStr\sfor\sFTS5\sis\salways\szero-terminated.\nFix\sfor\scheck-in\s[e6db945454a0dae2] -D 2019-09-13T13:23:13.490 +C Fix\sa\stypo\sin\sthe\scarray\sextension\sheader\scomment\s-\sthe\scomment\sthat\sserves\nas\sthe\sdocumentation\sto\sthis\sextension. +D 2019-09-13T17:30:24.452 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -282,7 +282,7 @@ F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a2 F ext/misc/appendvfs.c 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7 F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a F ext/misc/btreeinfo.c 4f0ebf278f46e68e6306c667917766cebc5550fd35d5de17847988e22892d4d2 -F ext/misc/carray.c ed96c218ea940b85c9a274c4d9c59fe9491c299147a38a8bba537687bd6c6005 +F ext/misc/carray.c 91e9a7f512fda934894bed30464552fffa7d3073b5be04189ae0bd0c59f26bfd F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 F ext/misc/completion.c cec672d40604075bb341a7f11ac48393efdcd90a979269b8fe7977ea62d0547f F ext/misc/compress.c dd4f8a6d0baccff3c694757db5b430f3bbd821d8686d1fc24df55cf9f035b189 @@ -1842,7 +1842,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 a8927d14f88c44828e794787bab080455ab62705c93f65ce7d8db83478aa5a8e -R 1b0d381d385e92afee32191d4d702401 +P 090cd07d37904da4610d6a6787a3cc825c9a8bdcc5f051267d4608bba9b49d03 +R a8c45dcd00465c1593cf4300db620ee6 U drh -Z bf931f65c31f45c41d3fdaadb23bca9e +Z 17496dbdca5aeac5a2f3f36b6a26cda7 diff --git a/manifest.uuid b/manifest.uuid index 528dcf10a8..3cdaf86f59 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -090cd07d37904da4610d6a6787a3cc825c9a8bdcc5f051267d4608bba9b49d03 \ No newline at end of file +658a42d3633b31fda260f2c5a1a2c7dd8eb4eb0114d322369017c56faf5ecd42 \ No newline at end of file From e087a7c35b1bedfb37c2b41baac77e794ed89f63 Mon Sep 17 00:00:00 2001 From: drh Date: Fri, 13 Sep 2019 18:59:04 +0000 Subject: [PATCH 107/112] Fix the windowB test module so that it works even if SQLite is built without JSON support. FossilOrigin-Name: 807975c76b36347f02aa0ce9661d608adbffe1f7e77c15f8da677e47e1187153 --- manifest | 15 +++++++-------- manifest.uuid | 2 +- test/windowB.test | 25 ++++++++++++------------- 3 files changed, 20 insertions(+), 22 deletions(-) diff --git a/manifest b/manifest index 100f9e3219..9aa66f4bda 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\sSQLITE_SUBTYPE\sflag,\swhich\smay\sbe\spassed\sto\ssqlite3_create_window_function()\sto\sindicate\sthat\sthe\swindow\sfunction\suses\ssqlite3_value_subtype()\sto\scheck\sthe\ssub-type\sof\sits\sarguments. -D 2019-09-13T18:27:17.192 +C Fix\sthe\swindowB\stest\smodule\sso\sthat\sit\sworks\seven\sif\sSQLite\sis\sbuilt\swithout\nJSON\ssupport. +D 2019-09-13T18:59:04.975 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -1719,7 +1719,7 @@ F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be -F test/windowB.test 24daa26628291b6e584064efd34b1914aa69058280ece8a512b2e59ba71b6f02 +F test/windowB.test 3f0ae24a7860abaae9f092589f275a87787804b6d98ad6f23a0bc87fb4491d43 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 @@ -1843,8 +1843,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 658a42d3633b31fda260f2c5a1a2c7dd8eb4eb0114d322369017c56faf5ecd42 af1bc20f502816db460d2b2d353f715da5cf660e59095de5214c829c1cb20981 -R 919177d10d46e9cfa222a1bf25a1d5fb -T +closed af1bc20f502816db460d2b2d353f715da5cf660e59095de5214c829c1cb20981 -U dan -Z 7f5ff2b3722751f14dcaaa30ef08814d +P ba2ebc3a348decc5cedaf14960e30e7ae26a26824cfa198727f2499162142ef3 +R bae0d8d6f0a49acfd1c53d207a1b5d08 +U drh +Z 2837255703db522fd15af08765e39ee9 diff --git a/manifest.uuid b/manifest.uuid index bf7e581e98..f1017be8a5 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ba2ebc3a348decc5cedaf14960e30e7ae26a26824cfa198727f2499162142ef3 \ No newline at end of file +807975c76b36347f02aa0ce9661d608adbffe1f7e77c15f8da677e47e1187153 \ No newline at end of file diff --git a/test/windowB.test b/test/windowB.test index 0c242acc70..0c3c56dec8 100644 --- a/test/windowB.test +++ b/test/windowB.test @@ -87,20 +87,19 @@ do_execsql_test 3.0 { INSERT INTO testjson VALUES(2, '{"b":2}'); } -do_execsql_test 3.1 { - SELECT json_group_array(json(j)) FROM testjson; -} { - {[{"a":1},{"b":2}]} -} +ifcapable json1 { + do_execsql_test 3.1 { + SELECT json_group_array(json(j)) FROM testjson; + } { + {[{"a":1},{"b":2}]} + } -breakpoint -do_execsql_test 3.2 { - SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson; -} { - {[{"a":1}]} - {[{"a":1},{"b":2}]} + do_execsql_test 3.2 { + SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson; + } { + {[{"a":1}]} + {[{"a":1},{"b":2}]} + } } - finish_test - From 51a75aaa76c300b3826e434013ddaf73c49e57c1 Mon Sep 17 00:00:00 2001 From: dan Date: Fri, 13 Sep 2019 20:42:46 +0000 Subject: [PATCH 108/112] Fix a problem with using json1 window functions with an EXCLUDE clause. FossilOrigin-Name: 4a1978814da41608a16f6953bd575c97d587a34bd80b7ac0e619d62bfdc903d2 --- manifest | 16 ++++----- manifest.uuid | 2 +- src/window.c | 14 ++++++-- test/windowB.test | 87 ++++++++++++++++++++++++++++++++++++++++++----- 4 files changed, 99 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 9aa66f4bda..02392e71b4 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\swindowB\stest\smodule\sso\sthat\sit\sworks\seven\sif\sSQLite\sis\sbuilt\swithout\nJSON\ssupport. -D 2019-09-13T18:59:04.975 +C Fix\sa\sproblem\swith\susing\sjson1\swindow\sfunctions\swith\san\sEXCLUDE\sclause. +D 2019-09-13T20:42:46.328 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -615,7 +615,7 @@ F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64 F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4 -F src/window.c a35ad309132c639d075344a7c12f3133a8a738da238a35d8338f5034bd94c0a0 +F src/window.c 2a10191a3ec7dd3422f8c77dac423d0e55019dee9efe319613ebd0f02b98991e F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1719,7 +1719,7 @@ F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be -F test/windowB.test 3f0ae24a7860abaae9f092589f275a87787804b6d98ad6f23a0bc87fb4491d43 +F test/windowB.test fae072a311cea62715007b482afd40b1124fef56dcc9988bffb85b29ccabb5dd F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 @@ -1843,7 +1843,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 ba2ebc3a348decc5cedaf14960e30e7ae26a26824cfa198727f2499162142ef3 -R bae0d8d6f0a49acfd1c53d207a1b5d08 -U drh -Z 2837255703db522fd15af08765e39ee9 +P 807975c76b36347f02aa0ce9661d608adbffe1f7e77c15f8da677e47e1187153 +R 19b6534ebeb3a6a9bfaaa41ce75a9354 +U dan +Z e45766b9d1c40d7379299659b41fb108 diff --git a/manifest.uuid b/manifest.uuid index f1017be8a5..4bf78a743d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -807975c76b36347f02aa0ce9661d608adbffe1f7e77c15f8da677e47e1187153 \ No newline at end of file +4a1978814da41608a16f6953bd575c97d587a34bd80b7ac0e619d62bfdc903d2 \ No newline at end of file diff --git a/src/window.c b/src/window.c index 43946dd55a..15f38ee006 100644 --- a/src/window.c +++ b/src/window.c @@ -1481,8 +1481,8 @@ static void windowAggStep( int addrIf = 0; if( pWin->pFilter ){ int regTmp; - assert( nArg==0 || nArg==pWin->pOwner->x.pList->nExpr ); - assert( nArg || pWin->pOwner->x.pList==0 ); + assert( pWin->bExprArgs || !nArg ||nArg==pWin->pOwner->x.pList->nExpr ); + assert( pWin->bExprArgs || nArg ||pWin->pOwner->x.pList==0 ); regTmp = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol+nArg,regTmp); addrIf = sqlite3VdbeAddOp3(v, OP_IfNot, regTmp, 0, 1); @@ -1490,9 +1490,19 @@ static void windowAggStep( sqlite3ReleaseTempReg(pParse, regTmp); } if( pWin->bExprArgs ){ + int iStart = sqlite3VdbeCurrentAddr(v); + VdbeOp *pOp, *pEnd; + nArg = pWin->pOwner->x.pList->nExpr; regArg = sqlite3GetTempRange(pParse, nArg); sqlite3ExprCodeExprList(pParse, pWin->pOwner->x.pList, regArg, 0, 0); + + pEnd = sqlite3VdbeGetOp(v, -1); + for(pOp=sqlite3VdbeGetOp(v, iStart); pOp<=pEnd; pOp++){ + if( pOp->opcode==OP_Column && pOp->p1==pWin->iEphCsr ){ + pOp->p1 = csr; + } + } } if( pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ CollSeq *pColl; diff --git a/test/windowB.test b/test/windowB.test index 0c3c56dec8..2fbbe2064a 100644 --- a/test/windowB.test +++ b/test/windowB.test @@ -80,25 +80,94 @@ foreach {tn win} { } #------------------------------------------------------------------------- -reset_db -do_execsql_test 3.0 { - CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT); - INSERT INTO testjson VALUES(1, '{"a":1}'); - INSERT INTO testjson VALUES(2, '{"b":2}'); -} - ifcapable json1 { + reset_db + do_execsql_test 3.0 { + CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT); + INSERT INTO testjson VALUES(1, '{"a":1}'); + INSERT INTO testjson VALUES(2, '{"b":2}'); + INSERT INTO testjson VALUES(3, '{"c":3}'); + INSERT INTO testjson VALUES(4, '{"d":4}'); + } + do_execsql_test 3.1 { SELECT json_group_array(json(j)) FROM testjson; } { - {[{"a":1},{"b":2}]} + {[{"a":1},{"b":2},{"c":3},{"d":4}]} } - + do_execsql_test 3.2 { SELECT json_group_array(json(j)) OVER (ORDER BY id) FROM testjson; } { {[{"a":1}]} {[{"a":1},{"b":2}]} + {[{"a":1},{"b":2},{"c":3}]} + {[{"a":1},{"b":2},{"c":3},{"d":4}]} + } + + do_execsql_test 3.3 { + SELECT json_group_array(json(j)) OVER ( + ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE TIES + ) FROM testjson; + } { + {[{"a":1}]} + {[{"a":1},{"b":2}]} + {[{"a":1},{"b":2},{"c":3}]} + {[{"a":1},{"b":2},{"c":3},{"d":4}]} + } + + do_execsql_test 3.4 { + SELECT json_group_array(json(j)) OVER ( + ORDER BY id ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING + ) FROM testjson; + } { + {[{"a":1},{"b":2}]} + {[{"a":1},{"b":2},{"c":3}]} + {[{"b":2},{"c":3},{"d":4}]} + {[{"c":3},{"d":4}]} + } + + do_execsql_test 3.5 { + SELECT json_group_array(json(j)) OVER ( + ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING + ) FROM testjson; + } { + {[]} + {[{"a":1}]} + {[{"a":1},{"b":2}]} + {[{"b":2},{"c":3}]} + } + + if 0 { + + do_execsql_test 3.5 { + SELECT json_group_array(json(j)) OVER ( + ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING + ) FROM testjson; + } { + {[]} + {[{"a":1}]} + {[{"a":1},{"b":2}]} + {[{"b":2},{"c":3}]} + } + + explain_i { + SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER ( + ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING + ) FROM testjson; + } + do_execsql_test 3.7 { + PRAGMA vdbe_trace = 1; + SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER ( + ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING + ) FROM testjson; + } { + {[]} + {[{"a":1}]} + {[{"a":1}]} + {[{"c":3}]} + } + } } From fab5b07395796f7761dbf3ba8604325889af9522 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 14 Sep 2019 00:21:34 +0000 Subject: [PATCH 109/112] Fix the windows inverse function on the JSON aggregates. FossilOrigin-Name: f464d847af490dd3ec45565dcc4c2e6ff4ed1ebb65036f30ca0b3ce2e73080e6 --- ext/misc/json1.c | 20 ++++++++---- manifest | 16 ++++----- manifest.uuid | 2 +- test/windowB.test | 83 ++++++++++++++++++++++++++++++++--------------- 4 files changed, 80 insertions(+), 41 deletions(-) diff --git a/ext/misc/json1.c b/ext/misc/json1.c index b3130eaf07..251fd14afc 100644 --- a/ext/misc/json1.c +++ b/ext/misc/json1.c @@ -1820,7 +1820,7 @@ static void jsonArrayStep( if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); jsonAppendChar(pStr, '['); - }else{ + }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); pStr->pCtx = ctx; } @@ -1870,7 +1870,9 @@ static void jsonGroupInverse( ){ int i; int inStr = 0; + int nNest = 0; char *z; + char c; JsonString *pStr; UNUSED_PARAM(argc); UNUSED_PARAM(argv); @@ -1881,12 +1883,18 @@ static void jsonGroupInverse( if( NEVER(!pStr) ) return; #endif z = pStr->zBuf; - for(i=1; z[i]!=',' || inStr; i++){ - assert( inUsed ); - if( z[i]=='"' ){ + for(i=1; (c = z[i])!=',' || inStr || nNest; i++){ + if( i>=pStr->nUsed ){ + pStr->nUsed = 1; + return; + } + if( c=='"' ){ inStr = !inStr; - }else if( z[i]=='\\' ){ + }else if( c=='\\' ){ i++; + }else if( !inStr ){ + if( c=='{' || c=='[' ) nNest++; + if( c=='}' || c==']' ) nNest--; } } pStr->nUsed -= i; @@ -1916,7 +1924,7 @@ static void jsonObjectStep( if( pStr->zBuf==0 ){ jsonInit(pStr, ctx); jsonAppendChar(pStr, '{'); - }else{ + }else if( pStr->nUsed>1 ){ jsonAppendChar(pStr, ','); pStr->pCtx = ctx; } diff --git a/manifest b/manifest index 02392e71b4..d398e3ef45 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sa\sproblem\swith\susing\sjson1\swindow\sfunctions\swith\san\sEXCLUDE\sclause. -D 2019-09-13T20:42:46.328 +C Fix\sthe\swindows\sinverse\sfunction\son\sthe\sJSON\saggregates. +D 2019-09-14T00:21:34.282 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -295,7 +295,7 @@ F ext/misc/fileio.c 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09 F ext/misc/fossildelta.c 7708651072eb5620ab21bbfb518d184f27b2c29c0131b09b9a2d8852a8016430 F ext/misc/fuzzer.c c4e27daf41433a64cad5265cd27dbcb891147e9994d0422200ce81ce9a54b625 F ext/misc/ieee754.c f190d0cc5182529acb15babd177781be1ac1718c -F ext/misc/json1.c 5e94e787ddce590585227ace85005bb7dd2a768def24bc77d7fc4a386989dd76 +F ext/misc/json1.c 061950860e6b8b7af6fc40029bf673fb97887ab04d6a33950c32a0ced6775577 F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b F ext/misc/memvfs.c ab36f49e02ebcdf85a1e08dc4d8599ea8f343e073ac9e0bca18a98b7e1ec9567 @@ -1719,7 +1719,7 @@ F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be -F test/windowB.test fae072a311cea62715007b482afd40b1124fef56dcc9988bffb85b29ccabb5dd +F test/windowB.test af8f3b0a24cc5e7f296e13ef4d312391427d95ace391e248120e1fb90226c3b2 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 @@ -1843,7 +1843,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 807975c76b36347f02aa0ce9661d608adbffe1f7e77c15f8da677e47e1187153 -R 19b6534ebeb3a6a9bfaaa41ce75a9354 -U dan -Z e45766b9d1c40d7379299659b41fb108 +P 4a1978814da41608a16f6953bd575c97d587a34bd80b7ac0e619d62bfdc903d2 +R 476ca0efeffea95d421b220f4123feec +U drh +Z 549cbff31496c774b10a02d54a853bdd diff --git a/manifest.uuid b/manifest.uuid index 4bf78a743d..5a92e55ff6 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -4a1978814da41608a16f6953bd575c97d587a34bd80b7ac0e619d62bfdc903d2 \ No newline at end of file +f464d847af490dd3ec45565dcc4c2e6ff4ed1ebb65036f30ca0b3ce2e73080e6 \ No newline at end of file diff --git a/test/windowB.test b/test/windowB.test index 2fbbe2064a..fcefbd4e85 100644 --- a/test/windowB.test +++ b/test/windowB.test @@ -83,11 +83,11 @@ foreach {tn win} { ifcapable json1 { reset_db do_execsql_test 3.0 { - CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT); - INSERT INTO testjson VALUES(1, '{"a":1}'); - INSERT INTO testjson VALUES(2, '{"b":2}'); - INSERT INTO testjson VALUES(3, '{"c":3}'); - INSERT INTO testjson VALUES(4, '{"d":4}'); + CREATE TABLE testjson(id INTEGER PRIMARY KEY, j TEXT, x TEXT); + INSERT INTO testjson VALUES(1, '{"a":1}', 'a'); + INSERT INTO testjson VALUES(2, '{"b":2}', 'b'); + INSERT INTO testjson VALUES(3, '{"c":3}', 'c'); + INSERT INTO testjson VALUES(4, '{"d":4}', 'd'); } do_execsql_test 3.1 { @@ -107,7 +107,8 @@ ifcapable json1 { do_execsql_test 3.3 { SELECT json_group_array(json(j)) OVER ( - ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW EXCLUDE TIES + ORDER BY id RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW + EXCLUDE TIES ) FROM testjson; } { {[{"a":1}]} @@ -138,36 +139,66 @@ ifcapable json1 { {[{"b":2},{"c":3}]} } - if 0 { - - do_execsql_test 3.5 { + do_execsql_test 3.5a { + UPDATE testjson SET j = replace(j,char(125),',"e":9'||char(125)); + SELECT j FROM testjson; + } { + {{"a":1,"e":9}} + {{"b":2,"e":9}} + {{"c":3,"e":9}} + {{"d":4,"e":9}} + } + do_execsql_test 3.5b { + SELECT group_concat(x,'') OVER ( + ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING + ) FROM testjson ORDER BY id; + } {bc cd d {}} + do_execsql_test 3.5c { SELECT json_group_array(json(j)) OVER ( ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING ) FROM testjson; } { + {[{"b":2,"e":9},{"c":3,"e":9}]} + {[{"c":3,"e":9},{"d":4,"e":9}]} + {[{"d":4,"e":9}]} {[]} - {[{"a":1}]} - {[{"a":1},{"b":2}]} - {[{"b":2},{"c":3}]} } - - explain_i { - SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER ( - ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING - ) FROM testjson; - } - do_execsql_test 3.7 { - PRAGMA vdbe_trace = 1; - SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER ( - ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING + do_execsql_test 3.5d { + SELECT json_group_object(x,json(j)) OVER ( + ORDER BY id ROWS BETWEEN 1 FOLLOWING AND 2 FOLLOWING ) FROM testjson; } { - {[]} - {[{"a":1}]} - {[{"a":1}]} - {[{"c":3}]} + {{"b":{"b":2,"e":9},"c":{"c":3,"e":9}}} + {{"c":{"c":3,"e":9},"d":{"d":4,"e":9}}} + {{"d":{"d":4,"e":9}}} + {{}} } + do_execsql_test 3.7b { + SELECT group_concat(x,'') FILTER (WHERE id!=2) OVER ( + ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING + ) FROM testjson; + } {{} a a c} + + do_execsql_test 3.7c { + SELECT json_group_array(json(j)) FILTER (WHERE id!=2) OVER ( + ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING + ) FROM testjson + } { + {[]} + {[{"a":1,"e":9}]} + {[{"a":1,"e":9}]} + {[{"c":3,"e":9}]} + } + do_execsql_test 3.7d { + SELECT json_group_object(x,json(j)) FILTER (WHERE id!=2) OVER ( + ORDER BY id ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING + ) FROM testjson + } { + {{}} + {{"a":{"a":1,"e":9}}} + {{"a":{"a":1,"e":9}}} + {{"c":{"c":3,"e":9}}} } } From d44c617ad444717fbf9f213c8a654d2661fc64e7 Mon Sep 17 00:00:00 2001 From: drh Date: Sat, 14 Sep 2019 16:21:02 +0000 Subject: [PATCH 110/112] Extra comments on fields of the Window object. FossilOrigin-Name: 3dbed162518a73213bbfb137c763064518fdc2daeae3952cfab39ce0e6813d3f --- manifest | 12 ++++++------ manifest.uuid | 2 +- src/sqliteInt.h | 7 ++++--- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/manifest b/manifest index d398e3ef45..b3ace16386 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\sthe\swindows\sinverse\sfunction\son\sthe\sJSON\saggregates. -D 2019-09-14T00:21:34.282 +C Extra\scomments\son\sfields\sof\sthe\sWindow\sobject. +D 2019-09-14T16:21:02.133 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -530,7 +530,7 @@ F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21 F src/sqlite.h.in 155fea14c0747f8842c4e592e04734f47ad8218d0f33c511849b15d410a7fb5c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 -F src/sqliteInt.h 34cc038470f74a961ce9c1155df4c3926c2c88d784631272943ae0b7e9bd2aa2 +F src/sqliteInt.h 4a478f7fa0937d7c3141393d8c30c49e242e5e696e6976e19281e4d933a8ab95 F src/sqliteLimit.h 1513bfb7b20378aa0041e7022d04acb73525de35b80b252f1b83fedb4de6a76b F src/status.c 46e7aec11f79dad50965a5ca5fa9de009f7d6bde08be2156f1538a0a296d4d0e F src/table.c b46ad567748f24a326d9de40e5b9659f96ffff34 @@ -1843,7 +1843,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 4a1978814da41608a16f6953bd575c97d587a34bd80b7ac0e619d62bfdc903d2 -R 476ca0efeffea95d421b220f4123feec +P f464d847af490dd3ec45565dcc4c2e6ff4ed1ebb65036f30ca0b3ce2e73080e6 +R ecd7799055991f616443bfa6b30bbda4 U drh -Z 549cbff31496c774b10a02d54a853bdd +Z 99d49b049fe9df8372384c89d49f686e diff --git a/manifest.uuid b/manifest.uuid index 5a92e55ff6..0b68def461 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -f464d847af490dd3ec45565dcc4c2e6ff4ed1ebb65036f30ca0b3ce2e73080e6 \ No newline at end of file +3dbed162518a73213bbfb137c763064518fdc2daeae3952cfab39ce0e6813d3f \ No newline at end of file diff --git a/src/sqliteInt.h b/src/sqliteInt.h index e7c1d9c1f2..0a3c432bf0 100644 --- a/src/sqliteInt.h +++ b/src/sqliteInt.h @@ -3601,8 +3601,8 @@ struct Window { Expr *pFilter; /* The FILTER expression */ FuncDef *pFunc; /* The function */ int iEphCsr; /* Partition buffer or Peer buffer */ - int regAccum; - int regResult; + int regAccum; /* Accumulator */ + int regResult; /* Interim result */ int csrApp; /* Function cursor (used by min/max) */ int regApp; /* Function register (also used by min/max) */ int regPart; /* Array of registers for PARTITION BY values */ @@ -3612,7 +3612,8 @@ struct Window { int regOne; /* Register containing constant value 1 */ int regStartRowid; int regEndRowid; - u8 bExprArgs; + u8 bExprArgs; /* Defer evaluation of window function arguments + ** due to the SQLITE_SUBTYPE flag */ }; #ifndef SQLITE_OMIT_WINDOWFUNC From 8cce6b8310da057f5c4ffce3ce117ac84264e2ab Mon Sep 17 00:00:00 2001 From: dan Date: Sat, 14 Sep 2019 16:44:51 +0000 Subject: [PATCH 111/112] Add the --no-rowids option to the ".recover" command. FossilOrigin-Name: 01d71b947a7422081d5c7d6ac2c91b9c936dc41926ab58c92f4a088a64e8c051 --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/shell.c.in | 20 +++++++++++++++++--- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/manifest b/manifest index b3ace16386..d1eb00a791 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Extra\scomments\son\sfields\sof\sthe\sWindow\sobject. -D 2019-09-14T16:21:02.133 +C Add\sthe\s--no-rowids\soption\sto\sthe\s".recover"\scommand. +D 2019-09-14T16:44:51.726 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -526,7 +526,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384 F src/resolve.c 9891cf5fd155bb199f8b1ff5d1429b9f70484487f4c455bba94348d4cb6f829f F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93 F src/select.c e2c870548541d33d090a066e89ab2e7943299006e2827c1abfae39561041fc0b -F src/shell.c.in e5fb91505f29ae9458cabf1a63bbd1faf6b4b34eabca33d0f75a06aacecca21b +F src/shell.c.in 68698630c21c5489fb3dc961a3ab3840e726c3c01e475dab96055788a7b6e5e6 F src/sqlite.h.in 155fea14c0747f8842c4e592e04734f47ad8218d0f33c511849b15d410a7fb5c F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h cef696ce3293242c67b2339763608427bf72ee66f1f3a05389ac2a7b46001c31 @@ -1843,7 +1843,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 f464d847af490dd3ec45565dcc4c2e6ff4ed1ebb65036f30ca0b3ce2e73080e6 -R ecd7799055991f616443bfa6b30bbda4 -U drh -Z 99d49b049fe9df8372384c89d49f686e +P 3dbed162518a73213bbfb137c763064518fdc2daeae3952cfab39ce0e6813d3f +R 893a8c502e7609a361861540de405b55 +U dan +Z 284f9491bb2c84cd052f56239d66ee3a diff --git a/manifest.uuid b/manifest.uuid index 0b68def461..ba52a328a7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -3dbed162518a73213bbfb137c763064518fdc2daeae3952cfab39ce0e6813d3f \ No newline at end of file +01d71b947a7422081d5c7d6ac2c91b9c936dc41926ab58c92f4a088a64e8c051 \ No newline at end of file diff --git a/src/shell.c.in b/src/shell.c.in index 9ae39a1d64..bde360b0eb 100644 --- a/src/shell.c.in +++ b/src/shell.c.in @@ -3588,6 +3588,8 @@ static const char *(azHelp[]) = { " --freelist-corrupt Assume the freelist is corrupt", " --recovery-db NAME Store recovery metadata in database file NAME", " --lost-and-found TABLE Alternative name for the lost-and-found table", + " --no-rowids Do not attempt to recover rowid values", + " that are not also INTEGER PRIMARY KEYs", #endif ".restore ?DB? FILE Restore content of DB (default \"main\") from FILE", ".save FILE Write in-memory database into FILE", @@ -6592,6 +6594,7 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ RecoverTable *pOrphan = 0; int bFreelist = 1; /* 0 if --freelist-corrupt is specified */ + int bRowids = 1; /* 0 if --no-rowids */ for(i=1; idb, &rc, "SELECT pgno FROM recovery.map WHERE root=?", &pPages ); + shellPrepare(pState->db, &rc, - "SELECT max(field), group_concat(shell_escape_crnl(quote(value)), ', ')" + "SELECT max(field), group_concat(shell_escape_crnl(quote" + "(case when (? AND field<0) then NULL else value end)" + "), ', ')" ", min(field) " "FROM sqlite_dbdata WHERE pgno = ? AND field != ?" "GROUP BY cell", &pCells @@ -6808,11 +6817,16 @@ static int recoverDatabaseCmd(ShellState *pState, int nArg, char **azArg){ raw_printf(pState->out, "DELETE FROM sqlite_sequence;\n"); } sqlite3_bind_int(pPages, 1, iRoot); - sqlite3_bind_int(pCells, 2, pTab->iPk); + if( bRowids==0 && pTab->iPk<0 ){ + sqlite3_bind_int(pCells, 1, 1); + }else{ + sqlite3_bind_int(pCells, 1, 0); + } + sqlite3_bind_int(pCells, 3, pTab->iPk); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pPages) ){ int iPgno = sqlite3_column_int(pPages, 0); - sqlite3_bind_int(pCells, 1, iPgno); + sqlite3_bind_int(pCells, 2, iPgno); while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pCells) ){ int nField = sqlite3_column_int(pCells, 0); int iMin = sqlite3_column_int(pCells, 2); From b42eb3571c35341ae2171fcd5dc63ca9a49784c0 Mon Sep 17 00:00:00 2001 From: dan Date: Mon, 16 Sep 2019 05:34:08 +0000 Subject: [PATCH 112/112] Fix a problem with processing CTEs that use a WINDOW clause. FossilOrigin-Name: ca564d4b5b19fe56842a04f31bb61352e6ae9d72a7e7634eb27ebcf5f670545a --- manifest | 14 +++++++------- manifest.uuid | 2 +- src/window.c | 2 ++ test/windowB.test | 28 ++++++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 8 deletions(-) diff --git a/manifest b/manifest index d1eb00a791..3e4365572a 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sthe\s--no-rowids\soption\sto\sthe\s".recover"\scommand. -D 2019-09-14T16:44:51.726 +C Fix\sa\sproblem\swith\sprocessing\sCTEs\sthat\suse\sa\sWINDOW\sclause. +D 2019-09-16T05:34:08.899 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -615,7 +615,7 @@ F src/where.c 9685d5988b79b93ebbe46941fbdb60d14861bb0fe3f9126117ef1753acc69b64 F src/whereInt.h 2c6bae136a7c0be6ff75dc36950d1968c67d005c8e51d7a9d77cb996bb4843d9 F src/wherecode.c 535c8e228478fd971b9a5b6cb6773995b0fbf7020d5989508a5094ce5b8cd95b F src/whereexpr.c b3bbae199e7acd8d0fa822c9a29cbb822ef2b3d84d68de55a3d60b013f5d5da4 -F src/window.c 2a10191a3ec7dd3422f8c77dac423d0e55019dee9efe319613ebd0f02b98991e +F src/window.c bf055d1baec203de508c9d7ed3ac20146d5551518f2f77009f781876b8d0fdd5 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test da465d3d490ab24ef64f7715b5953343a4967762b9350b29eb1462879ff3fb9e F test/affinity3.test 6a101af2fc945ce2912f6fe54dd646018551710d @@ -1719,7 +1719,7 @@ F test/window8.tcl f2711aa3571e4e6b0dad98db8d95fd6cb8d9db0c92bbdf535f153b07606a1 F test/window8.test c4331b27a6f66d69fa8f8bab10cc731db1a81d293ae108a68f7c3487fa94e65b F test/window9.test 20a6b590be718b6bc98a5356d4396d6cdf19329c547da084fa225b92d68e1693 F test/windowA.test 6d63dc1260daa17141a55007600581778523a8b420629f1282d2acfc36af23be -F test/windowB.test af8f3b0a24cc5e7f296e13ef4d312391427d95ace391e248120e1fb90226c3b2 +F test/windowB.test be2ecc1298021e87eef375af35906288cc929fc21f2651139f7dd50a5844b120 F test/windowerr.tcl f5acd6fbc210d7b5546c0e879d157888455cd4a17a1d3f28f07c1c8a387019e0 F test/windowerr.test a8b752402109c15aa1c5efe1b93ccb0ce1ef84fa964ae1cd6684dd0b3cc1819b F test/windowfault.test a90b397837209f15e54afa62e8be39b2759a0101fae04e05a08bcc50e243a452 @@ -1843,7 +1843,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 3dbed162518a73213bbfb137c763064518fdc2daeae3952cfab39ce0e6813d3f -R 893a8c502e7609a361861540de405b55 +P 01d71b947a7422081d5c7d6ac2c91b9c936dc41926ab58c92f4a088a64e8c051 +R c92814bccf2f0531ff265b831a716091 U dan -Z 284f9491bb2c84cd052f56239d66ee3a +Z cfe2dcdda6abe970278e2187a7ab525e diff --git a/manifest.uuid b/manifest.uuid index ba52a328a7..177b32dc78 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -01d71b947a7422081d5c7d6ac2c91b9c936dc41926ab58c92f4a088a64e8c051 \ No newline at end of file +ca564d4b5b19fe56842a04f31bb61352e6ae9d72a7e7634eb27ebcf5f670545a \ No newline at end of file diff --git a/src/window.c b/src/window.c index 15f38ee006..0fb8eb461d 100644 --- a/src/window.c +++ b/src/window.c @@ -2215,6 +2215,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ pNew = sqlite3DbMallocZero(db, sizeof(Window)); if( pNew ){ pNew->zName = sqlite3DbStrDup(db, p->zName); + pNew->zBase = sqlite3DbStrDup(db, p->zBase); pNew->pFilter = sqlite3ExprDup(db, p->pFilter, 0); pNew->pFunc = p->pFunc; pNew->pPartition = sqlite3ExprListDup(db, p->pPartition, 0); @@ -2227,6 +2228,7 @@ Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p){ pNew->pStart = sqlite3ExprDup(db, p->pStart, 0); pNew->pEnd = sqlite3ExprDup(db, p->pEnd, 0); pNew->pOwner = pOwner; + pNew->bImplicitFrame = p->bImplicitFrame; } } return pNew; diff --git a/test/windowB.test b/test/windowB.test index fcefbd4e85..d28ee0da19 100644 --- a/test/windowB.test +++ b/test/windowB.test @@ -202,4 +202,32 @@ ifcapable json1 { } } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE TABLE x(a); + INSERT INTO x VALUES(1); + INSERT INTO x VALUES(2); +} + +do_execsql_test 4.1 { + WITH y AS ( + SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION BY a) + ) + SELECT * FROM y; +} { + 1 1 +} + +do_catchsql_test 4.2 { + WITH y AS ( + SELECT Row_Number() OVER (win) FROM x WINDOW win AS (PARTITION + BY fake_column)) + SELECT * FROM y; +} {1 {no such column: fake_column}} + +do_catchsql_test 4.3 { + SELECT 1 WINDOW win AS (PARTITION BY fake_column); +} {0 1} + finish_test