]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not use an expression index on a generated column if generated column has the...
authordrh <>
Fri, 3 Mar 2023 19:47:09 +0000 (19:47 +0000)
committerdrh <>
Fri, 3 Mar 2023 19:47:09 +0000 (19:47 +0000)
FossilOrigin-Name: 65ffee234787213ca3b12afde1b5ed7ae536366c30e984b14c0975da0c57917d

manifest
manifest.uuid
src/build.c
src/expr.c
src/sqliteInt.h
src/where.c
test/gencol1.test

index 146e80c97dcbe9411de4d8ad63c5d949490e3f73..a7326def9cfa8154b266d160bfefdbe80e4fa30b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Enhance\sPRAGMA\sintegrity_check\sso\sthat\sit\scan\sdetect\swhen\sthere\sare\sextra\nbytes\sat\sthe\send\sof\san\sindex\srecord,\swhich\smight\scause\sOP_IdxRowid\sto\nmalfunction.
-D 2023-03-03T18:47:29.693
+C Do\snot\suse\san\sexpression\sindex\son\sa\sgenerated\scolumn\sif\sgenerated\scolumn\shas\sthe\swrong\saffinity.
+D 2023-03-03T19:47:09.146
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -563,7 +563,7 @@ F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca
 F src/btree.c 2f012aea074de6319c191cbf5c45034de79bf1c762826e381b1cf75421d8d831
 F src/btree.h aa354b9bad4120af71e214666b35132712b8f2ec11869cb2315c52c81fad45cc
 F src/btreeInt.h 06bb2c1a07172d5a1cd27a2a5d617b93b1e976c5873709c31964786f86365a6e
-F src/build.c c55ab6d1b089ceef57160e840f05f692955ac90944c3d04fcf01d97fd7bfd08d
+F src/build.c 542a04532ae810a58366c47453de4fc1ca9fa6e6b2d920b6d639cdd1a1831309
 F src/callback.c 4cd7225b26a97f7de5fee5ae10464bed5a78f2adefe19534cc2095b3a8ca484a
 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e
 F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d
@@ -571,7 +571,7 @@ F src/date.c f21815ca7172ce073db3163ac54c8d9f2841077165c1a6123b4d1c376a0c7ec7
 F src/dbpage.c d47549716549311f79dc39fe5c8fb19390a6eb2c960f8e37c89a9c4de0c1052e
 F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef
 F src/delete.c 86573edae75e3d3e9a8b590d87db8e47222103029df4f3e11fa56044459b514e
-F src/expr.c 8f9d5c20cf412d231b485bae592c78ff1906ce4b8e6b0f185f07441bd4070e72
+F src/expr.c 399c10566b94ded9b565c01382026bfa0a7350782d4e9aa4194af1ac05f8af31
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c 722f20779f5342a787922deded3628d8c74b5249cab04098cf17ee2f2aaff002
 F src/func.c d187be57a886ddf4e6b7ef584a494361899be3df5eee6d4a747b68ff4aff4122
@@ -626,7 +626,7 @@ F src/shell.c.in 6f36f5ca05f1bebf74935a7fcf2dce983016e807a09cbd752a673583ad7da08
 F src/sqlite.h.in 662a2fa083d093896b92560c871dea6d86792b49dc4bf7b4e8dbeca8e7171488
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
 F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4
-F src/sqliteInt.h 4dcc36b21dd0c77efeb0bb38b0d31916bc63fb429c8a89d186c945eba0816447
+F src/sqliteInt.h 107157709ddfb05583343b69f14b0fa159f3ff8899ae2115415977a64815b364
 F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657
 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749
 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1
@@ -706,7 +706,7 @@ F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
 F src/wal.c b9df133a705093da8977da5eb202eaadb844839f1c7297c08d33471f5491843d
 F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a
 F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b
-F src/where.c 38c36bb654b4172148aef3b295bbbc1342b52078cf20174f771c746caa98f69a
+F src/where.c 7e048157dd645223feba2198553325718b8f76a1bfc136219c9f93612f5c13c7
 F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c
 F src/wherecode.c b82d0d33315e1526904b95155e55e61149c4462147668e1cc4567c812735eff1
 F src/whereexpr.c 16d1eefd95f69843b45aba6d04fe2b63fc4f51584dff85ae380f5c20718f3c75
@@ -1152,7 +1152,7 @@ F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14
 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc
 F test/fuzzinvariants.c a153253600b2b33a7d5710d40e89b2ac1373a1912517867fb995a45b2d67dcb8
 F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c
-F test/gencol1.test cc0dbb0ee116e5602e18ea7d47f2a0f76b26e09a823b7c36ef254370c2b0f3c1
+F test/gencol1.test e40c94c0d3485c37c23ec8ff42dbb4464cef3f3e41d96ef1abf9c4f2b97936c9
 F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98
 F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9
 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751
@@ -2045,9 +2045,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 0fc7f7c2a90ce9bc3462478441b4e628c90e5adff0d461e6cc3521371b7f1f08
-Q +f418bdd627e84e7d494f730d7124d8f4846ebcde031f5b2498685c9aceebb3c8
-R 39b150a043148b367745d13321c7b473
+P c143f08713ec5dcc7609804f1fa0d795005c7ebd265b73e42342584d759eae01
+Q +2535bc8c256a7642a6ac00ebfd3393beb93da94394c13b886c3ddd20d114aa3c
+Q +e95439119ac200cb47d0e277622f41ee7986b364487cd252b485ce5fa030d70f
+R 0d4fa04bd11ed2cae24189b7146a3c93
 U drh
-Z 3cbccaacdd478e53d713111e17ce94b9
+Z db3203019d98a74cf1f281a73ec4a1bb
 # Remove this line to create a well-formed Fossil manifest.
index 75390b11279164fad4e27257e71ae0abb26f59df..f8d4854599e5f23db1f2bc44a738969b16f2a98c 100644 (file)
@@ -1 +1 @@
-c143f08713ec5dcc7609804f1fa0d795005c7ebd265b73e42342584d759eae01
\ No newline at end of file
+65ffee234787213ca3b12afde1b5ed7ae536366c30e984b14c0975da0c57917d
\ No newline at end of file
index 0390e321f281a64771395885f82e91d316dd25ba..c91e7bdd6a19d459a6631346cc3cc2e382bf0c0d 100644 (file)
@@ -2012,6 +2012,7 @@ void sqlite3AddGenerated(Parse *pParse, Expr *pExpr, Token *pType){
     ** turn it into one by adding a unary "+" operator. */
     pExpr = sqlite3PExpr(pParse, TK_UPLUS, pExpr, 0);
   }
+  if( pExpr ) pExpr->affExpr = pCol->affinity;
   sqlite3ColumnSetExpr(pParse, pTab, pCol, pExpr);
   pExpr = 0;
   goto generated_done;
index b688e5b40138675be7c995412c49f8baaaba33aa..6135da786c2dd222bd0dd68a543ae4eedd70ed10 100644 (file)
@@ -4133,6 +4133,7 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
   IndexedExpr *p;
   Vdbe *v;
   for(p=pParse->pIdxEpr; p; p=p->pIENext){
+    u8 exprAff;
     int iDataCur = p->iDataCur;
     if( iDataCur<0 ) continue;
     if( pParse->iSelfTab ){
@@ -4140,6 +4141,16 @@ static SQLITE_NOINLINE int sqlite3IndexedExprLookup(
       iDataCur = -1;
     }
     if( sqlite3ExprCompare(0, pExpr, p->pExpr, iDataCur)!=0 ) continue;
+    assert( p->aff>=SQLITE_AFF_BLOB && p->aff<=SQLITE_AFF_NUMERIC );
+    exprAff = sqlite3ExprAffinity(pExpr);
+    if( (exprAff<=SQLITE_AFF_BLOB && p->aff!=SQLITE_AFF_BLOB)
+     || (exprAff==SQLITE_AFF_TEXT && p->aff!=SQLITE_AFF_TEXT)
+     || (exprAff>=SQLITE_AFF_NUMERIC && p->aff!=SQLITE_AFF_NUMERIC)
+    ){
+      /* Affinity mismatch on a generated column */
+      continue;
+    }
+
     v = pParse->pVdbe;
     assert( v!=0 );
     if( p->bMaybeNullRow ){
index 9af38e8df4b152923afee5e8143d53357928cf6d..59637eb9e4bbf4f9475d1ab4e8b7a12666acdc5d 100644 (file)
@@ -3660,6 +3660,7 @@ struct IndexedExpr {
   int iIdxCur;            /* The index cursor */
   int iIdxCol;            /* The index column that contains value of pExpr */
   u8 bMaybeNullRow;       /* True if we need an OP_IfNullRow check */
+  u8 aff;                 /* Affinity of the pExpr expression */
   IndexedExpr *pIENext;   /* Next in a list of all indexed expressions */
 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
   const char *zIdxName;   /* Name of index, used only for bytecode comments */
index 08dd21824c34cd6f76b8f244cb24bb42acf43305..5d1f0dcb33d40c87f30e882d6c75524b16a0419a 100644 (file)
@@ -5694,6 +5694,9 @@ static SQLITE_NOINLINE void whereAddIndexedExpr(
     p->iIdxCur = iIdxCur;
     p->iIdxCol = i;
     p->bMaybeNullRow = bMaybeNullRow;
+    if( sqlite3IndexAffinityStr(pParse->db, pIdx) ){
+      p->aff = pIdx->zColAff[i];
+    }
 #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
     p->zIdxName = pIdx->zName;
 #endif
index ee0ebc53f52785715b1bc86bb13691ceaadcb4f8..266eee18b43874b75d5ea3e40256b996b1712a4e 100644 (file)
@@ -615,4 +615,49 @@ do_execsql_test gencol1-22.1 {
      AND (y.a=2 OR (x.b LIKE '2*' AND y.a=x.b));
 } {2 2 2 2}
 
+
+# 2023-03-02 dbsqlfuzz 65f5eb57f8859344d5f1f33e08c77ee12960ed83
+#
+set typelist {ANY INT REAL BLOB TEXT {}}
+set cnt 0
+foreach t1 $typelist {
+  foreach t2 $typelist {
+    incr cnt
+    db eval "
+      DROP TABLE IF EXISTS t1;
+      CREATE TABLE t1(
+        x $t1,
+        a $t2 AS (x) VIRTUAL,
+        b BLOB AS (x) VIRTUAL
+      );
+      CREATE INDEX x2 ON t1(a);
+      INSERT INTO t1(x) VALUES(NULL),('1'),(2),(3.5),('xyz');
+    "
+    set x1 [lsort [db eval {SELECT typeof(b) FROM t1}]]
+    do_test gencol1-23.1.$cnt {
+      lsort [db eval {SELECT typeof(b) FROM t1 INDEXED BY x2}]
+    } $x1
+  }
+}
+do_execsql_test gencol1-23.2 {
+  DROP TABLE t1;
+  CREATE TABLE t1(
+    x,
+    a INT AS (x) VIRTUAL,
+    b BLOB AS (x) VIRTUAL
+  );
+  CREATE INDEX x2 ON t1(a);
+  INSERT INTO t1(x) VALUES(NULL),('1'),('xyz'),(2),(3.5);
+  SELECT quote(a) FROM t1 INDEXED BY x2;
+} {NULL 1 2 3.5 'xyz'}
+do_execsql_test gencol1-23.3 {
+  EXPLAIN SELECT a FROM t1 INDEXED BY x2;
+} {~/Column 0/}
+#    ^^^^^^^^---- verfies that x2 acts like a covering index
+do_execsql_test gencol1-23.4 {
+  EXPLAIN SELECT b FROM t1 INDEXED BY x2;
+} {/Column 0/}
+#  ^^^^^^^^^^--- Must reference the original table in this case because
+# of the different datatype on column b.
+
 finish_test