From: drh <> Date: Thu, 16 Dec 2021 00:36:48 +0000 (+0000) Subject: Change the query planner so that it excludes virtual table constraints that X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fvtab-collation-fix;p=thirdparty%2Fsqlite.git Change the query planner so that it excludes virtual table constraints that do not have the correct collation. This breaks the expert extension. FossilOrigin-Name: da3aae7bcf0743c39d2cdb462811df7a5ad2cc0b4231a8f736be17c61d93359a --- diff --git a/manifest b/manifest index 9ffb0be7d0..b4d42663ad 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Simplify\sthe\sgeneration\sof\sthe\ssqlite3_index_info\sobject\sduring\squery\splanning\nfor\svirtual\stables. -D 2021-12-15T20:48:15.594 +C Change\sthe\squery\splanner\sso\sthat\sit\sexcludes\svirtual\stable\sconstraints\sthat\s\ndo\snot\shave\sthe\scorrect\scollation.\s\sThis\sbreaks\sthe\sexpert\sextension. +D 2021-12-16T00:36:48.534 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 @@ -553,7 +553,7 @@ F src/resolve.c 4a1db4aadd802683db40ca2dbbb268187bd195f10cbdb7206dbd8ac988795571 F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 F src/select.c a7a3d9f54eb24821ec5f67f2e5589b68a5d42d46fc5849d7376886777d93a85a F src/shell.c.in 239bee1085d94964f02582b0714dc3fc85cfc16e27e95813e4dbc24bb215a7e0 -F src/sqlite.h.in 5999d6db0e65afbd686b76cddc385b310aa3815624edba43987913067f50e209 +F src/sqlite.h.in 1b8fd9beded71c886b8da8fc72cac7bf01b524850f0a0d594ef7c25fbdd22270 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 F src/sqlite3ext.h 8ff2fd2c166150b2e48639f5e506fb44e29f1a3f65031710b9e89d1c126ac839 F src/sqliteInt.h e7dd69a85c53461c937d50c97f8efd9761b14f9bcfb63450809e85c100c08538 @@ -638,8 +638,8 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 F src/wal.c ed0398a7adf02c31e34aada42cc86c58f413a7afe5f741a5d373ad087abde028 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c 8696f664dceaa7bab9c18212633b1d7d61063ee8c5066b49514b148946a4c467 -F src/whereInt.h 91865afa4a3540bb3bd643619acc56fbceff7defeb8f249b8e157fd5325d88be +F src/where.c 083b7e6455f16f340ce6d5577dc78693db771ebd67da0a7dab95db9b5d057dbb +F src/whereInt.h ce4fb951e433ab6b0f7d3af690207ff6c5957b059c7f89940d2e298a17dbbd35 F src/wherecode.c 6a594ed25bfbeb60d455868b7be62637575e4f1949152de4336e4825e0c54ba6 F src/whereexpr.c 9f64c39e53070584e99e4d20c1dd3397e125fabbae8fd414ffec574c410ac7d3 F src/window.c 5d3b397b0c026d0ff5890244ac41359e524c01ae31e78782e1ff418c3e271a9e @@ -1697,7 +1697,7 @@ F test/varint.test bbce22cda8fc4d135bcc2b589574be8410614e62 F test/veryquick.test 57ab846bacf7b90cf4e9a672721ea5c5b669b661 F test/view.test d654fbadae82f936c2a820bbc892592085467548ff59e88acef201416e9fe48a F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679 -F test/vtab1.test 09a72330d0f31eda2ffaa828b06a6b917fb86250ee72de0301570af725774c07 +F test/vtab1.test cd6aabc23a91419dc84ea9a61ee84d19d2c0de59cde54b561ba0f741ac273616 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e F test/vtab4.test 8e73ed268f3d596bc3590f45fc948fb40f28e9c3 @@ -1934,7 +1934,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 5c3d398d20b86a1558720e995eddf11403aec2d160590571fa9525fe8f6efff9 -R 508a1ec856c9c59ad14d9d50f3ec0f6a +P 241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19 +R 9c438336b8749645ef1e2bda859983f1 +T *branch * vtab-collation-fix +T *sym-vtab-collation-fix * +T -sym-trunk * U drh -Z 7cfa744adc9adca884cde06b49136ec0 +Z bf81fd5460e061a7966cd97fc31f3365 diff --git a/manifest.uuid b/manifest.uuid index b41eacb4bb..ed101ba093 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -241dc0428a6e0238c57e2449e98ea60047e777e29c83a4ebe6da16f7cba40e19 \ No newline at end of file +da3aae7bcf0743c39d2cdb462811df7a5ad2cc0b4231a8f736be17c61d93359a \ No newline at end of file diff --git a/src/sqlite.h.in b/src/sqlite.h.in index 63a6f37e9a..04ac81a9be 100644 --- a/src/sqlite.h.in +++ b/src/sqlite.h.in @@ -9472,8 +9472,17 @@ int sqlite3_vtab_nochange(sqlite3_context*); ** structure passed to xBestIndex. This function returns a pointer to a buffer ** containing the name of the collation sequence for the corresponding ** constraint. +** +** In older versions of SQLite, it was the responsibility of the [xBestIndex] +** method in the [virtual table] implementation to verify that constraints +** used the correct collating sequence. This method was required in order +** for the xBestIndex method to accomplish that. But, beginning with +** SQLite 3.38.0 ([dateof:3.38.0]), the query planner will only populate +** the sqlite3_index_info object with constraint for which the collating +** sequence has already been verified. This routine has become +** superfluous and is therefore deprecated. */ -SQLITE_EXPERIMENTAL const char *sqlite3_vtab_collation(sqlite3_index_info*,int); +SQLITE_DEPRECATED const char *sqlite3_vtab_collation(sqlite3_index_info*,int); /* ** CAPI3REF: Conflict resolution modes diff --git a/src/where.c b/src/where.c index c7a9b856aa..9c620c10c9 100644 --- a/src/where.c +++ b/src/where.c @@ -1125,6 +1125,8 @@ static sqlite3_index_info *allocateIndexInfo( ** terms found. */ for(i=nTerm=0, pTerm=pWC->a; inTerm; i++, pTerm++){ + const char *zColl; + const CollSeq *pColl; pTerm->wtFlags &= ~TERM_OK; if( pTerm->leftCursor != pSrc->iCursor ) continue; if( pTerm->prereqRight & mUnusable ) continue; @@ -1147,6 +1149,22 @@ static sqlite3_index_info *allocateIndexInfo( ){ continue; } + + if( pTerm->u.x.leftColumn>=0 && (pTerm->eOperator & WO_CMP)!=0 ){ + /* Verify compatible collating sequences on comparison operators */ + zColl = sqlite3ColumnColl(&pTab->aCol[pTerm->u.x.leftColumn]); + if( zColl==0 ){ + zColl = sqlite3StrBINARY; + } + pColl = sqlite3ExprCompareCollSeq(pParse, pTerm->pExpr); + if( pColl==0 ){ + pColl = pParse->db->pDfltColl; + } + if( sqlite3StrICmp(zColl, pColl->zName)!=0 ){ + continue; + } + } + nTerm++; pTerm->wtFlags |= TERM_OK; } @@ -1172,7 +1190,12 @@ static sqlite3_index_info *allocateIndexInfo( } /* 2nd case - a column reference with a COLLATE operator. Only match - ** of the COLLATE operator matches the collation of the column. */ + ** if the COLLATE operator matches the collation of the column. This + ** is different from WHERE clause constraints. WHERE clause constraints + ** are always passed in even if the collating sequence does not match, + ** and it is the responsibility of the underlying xBestIndex() method + ** to check for compatible constraints using sqlite3_vtab_collation() + */ if( pExpr->op==TK_COLLATE && (pE2 = pExpr->pLeft)->op==TK_COLUMN && pE2->iTable==pSrc->iCursor diff --git a/src/whereInt.h b/src/whereInt.h index a97b4afc69..1fb50a9530 100644 --- a/src/whereInt.h +++ b/src/whereInt.h @@ -578,6 +578,7 @@ void sqlite3WhereTabFuncArgs(Parse*, SrcItem*, WhereClause*); #define WO_ALL 0x1fff /* Mask of all possible WO_* values */ #define WO_SINGLE 0x01ff /* Mask of all non-compound WO_* values */ +#define WO_CMP 0x00bf /* Comparison ops: IN = < > <= >= IS */ /* ** These are definitions of bits in the WhereLoop.wsFlags field. diff --git a/test/vtab1.test b/test/vtab1.test index 4b8fb9c700..7a179fb752 100644 --- a/test/vtab1.test +++ b/test/vtab1.test @@ -1301,7 +1301,7 @@ do_test vtab1-17.2 { unset -nocomplain echo_module_begin_fail do_execsql_test 18.1.0 { - CREATE TABLE t6(a, b TEXT); + CREATE TABLE t6(a, b TEXT COLLATE nocase); CREATE INDEX i6 ON t6(b, a); INSERT INTO t6 VALUES(1, 'Peter'); INSERT INTO t6 VALUES(2, 'Andrew'); @@ -1335,7 +1335,20 @@ ifcapable !icu { } } -do_execsql_test 18.2.0 { PRAGMA case_sensitive_like = ON } +do_execsql_test 18.2.0 { + DROP TABLE t6; + DROP TABLE e6; + CREATE TABLE t6(a, b TEXT COLLATE binary); + CREATE INDEX i6 ON t6(b, a); + INSERT INTO t6 VALUES(1, 'Peter'); + INSERT INTO t6 VALUES(2, 'Andrew'); + INSERT INTO t6 VALUES(3, '8James'); + INSERT INTO t6 VALUES(4, '8John'); + INSERT INTO t6 VALUES(5, 'Phillip'); + INSERT INTO t6 VALUES(6, 'Bartholomew'); + CREATE VIRTUAL TABLE e6 USING echo(t6); + PRAGMA case_sensitive_like = ON; +} foreach {tn sql res filter} { 2.1 "SELECT a FROM e6 WHERE b LIKE '8%'" {3 4} {xFilter {SELECT rowid, a, b FROM 't6' WHERE b like ?} 8%}