]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
When a column must be a constant due to WHERE clause and the value of that
authordrh <drh@noemail.net>
Thu, 9 Aug 2018 18:36:54 +0000 (18:36 +0000)
committerdrh <drh@noemail.net>
Thu, 9 Aug 2018 18:36:54 +0000 (18:36 +0000)
column is being coded as a constant, make sure the affinity is correct.

FossilOrigin-Name: 7404ea83168e6c739ebe8fc5d65bbf0265432ccb35b3418bb0381d74362f7527

manifest
manifest.uuid
src/expr.c
test/whereL.test

index 4f7d41429e49c3f2b0319710d131c013bc19d8bc..2ebf291cb5aecce5e151565a1d6c564a79b77e68 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Minor\sstyle\simprovements.
-D 2018-08-08T20:46:35.755
+C When\sa\scolumn\smust\sbe\sa\sconstant\sdue\sto\sWHERE\sclause\sand\sthe\svalue\sof\sthat\ncolumn\sis\sbeing\scoded\sas\sa\sconstant,\smake\ssure\sthe\saffinity\sis\scorrect.
+D 2018-08-09T18:36:54.837
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 0a3a6c81e6fcb969ff9106e882f0a08547014ba463cb6beca4c4efaecc924ee6
@@ -450,7 +450,7 @@ F src/date.c ebe1dc7c8a347117bb02570f1a931c62dd78f4a2b1b516f4837d45b7d6426957
 F src/dbpage.c 4aa7f26198934dbd002e69418220eae3dbc71b010bbac32bd78faf86b52ce6c3
 F src/dbstat.c edabb82611143727511a45ca0859b8cd037851ebe756ae3db289859dd18b6f91
 F src/delete.c 107e28d3ef8bd72fd11953374ca9107cd74e8b09c3ded076a6048742d26ce7d2
-F src/expr.c aac1c33ef8899d0cfe32e4269810e10372f8fdbce6554b38034973d5e8c285d9
+F src/expr.c 4a555ff68084360c133c5b9d985ae05d2cf914125d4c8e5614496dc071d318dd
 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007
 F src/fkey.c f59253c0be4b1e9dfcb073b6d6d6ab83090ae50c08b5c113b76013c4b157cd6a
 F src/func.c 7c288b4ce309b5a8b8473514b88e1f8e69a80134509a8c0db8e39c858e367e7f
@@ -1618,7 +1618,7 @@ F test/whereH.test e4b07f7a3c2f5d31195cd33710054c78667573b2
 F test/whereI.test b7769ee8dbefd987fb266715fee887f05f9ff180016b06fca7fa402df739193b
 F test/whereJ.test 88287550f6ee604422403b053455b1ad894eeaa5c35d348532dfa1439286cb9a
 F test/whereK.test f8e3cf26a8513ecc7f514f54df9f0572c046c42b
-F test/whereL.test 786ae3e0b6d8f7c9b83a98bffcd9d458b0de47c6a9f9dcf872043f54a4752c68
+F test/whereL.test 84de61afe4b8e5a3ff7d741c990d85cb44b3ce798cd8412d5603930f3f75014f
 F test/wherefault.test 1374c3aa198388925246475f84ad4cd5f9528864
 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3
 F test/wherelimit.test 592081800806d297dd7449b1030c863d2883d6d42901837ccd2e5a9bd962edb0
@@ -1754,7 +1754,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 20c995d3f0f4de5410962172cb59da0f25edf0c62e199420186cc59ea874e981
-R 014c774e40cbfa2bcee43c9763debd4b
-U mistachkin
-Z 600fd5c95427bbc0567125b367270e9a
+P 60bbca2b9a591800cd8e7b374e62d75b1df0e8fd2d2f71f9b4d5fd044da78be0
+R ef663a1df8c5f6cbefbb7dcd86b83b66
+U drh
+Z 68dbd529c4e95246b96ffd22fa0b508e
index e73ce883081e05bab422f1550e87c0943475e2db..e0abbb9304beeade86ea6c8c7c96a0cd681fff9a 100644 (file)
@@ -1 +1 @@
-60bbca2b9a591800cd8e7b374e62d75b1df0e8fd2d2f71f9b4d5fd044da78be0
\ No newline at end of file
+7404ea83168e6c739ebe8fc5d65bbf0265432ccb35b3418bb0381d74362f7527
\ No newline at end of file
index a590bc6a996dd371410403123d0fdaa3eab54f84..769d198c22f5f03a55fbf8f5a95e6628bc885a17 100644 (file)
@@ -3367,7 +3367,26 @@ expr_code_doover:
     case TK_COLUMN: {
       int iTab = pExpr->iTable;
       if( ExprHasProperty(pExpr, EP_FixedCol) ){
-        return sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
+        /* This COLUMN expression is really a constant due to WHERE clause
+        ** constraints, and that constant is coded by the pExpr->pLeft
+        ** expresssion.  However, make sure the constant has the correct
+        ** datatype by applying the Affinity of the table column to the
+        ** constant.
+        */
+        int iReg = sqlite3ExprCodeTarget(pParse, pExpr->pLeft,target);
+        int aff = sqlite3TableColumnAffinity(pExpr->pTab, pExpr->iColumn);
+        if( aff!=SQLITE_AFF_BLOB ){
+          static const char zAff[] = "B\000C\000D\000E";
+          assert( SQLITE_AFF_BLOB=='A' );
+          assert( SQLITE_AFF_TEXT=='B' );
+          if( iReg!=target ){
+            sqlite3VdbeAddOp2(v, OP_SCopy, iReg, target);
+            iReg = target;
+          }
+          sqlite3VdbeAddOp4(v, OP_Affinity, iReg, 1, 0,
+                            &zAff[(aff-'B')*2], P4_STATIC);
+        }
+        return iReg;
       }
       if( iTab<0 ){
         if( pParse->iSelfTab<0 ){
index 177efa1ddf22101433bd8639a4d3ab1922f6e3b2..3fe725b8774755c7e0b9a53e2cfd50f925863741 100644 (file)
@@ -67,4 +67,48 @@ do_execsql_test 201 {
   SELECT * FROM c3 WHERE x='abc' AND y='abc' AND z='abc';
 } {}
 
+# Constant propagation caused an incorrect answer in the following
+# query.  (Reported by Bentley system on 2018-08-09.)
+#
+do_execsql_test 300 {
+  CREATE TABLE A(id INTEGER PRIMARY KEY, label TEXT);
+  CREATE TABLE B(id INTEGER PRIMARY KEY, label TEXT, Aid INTEGER);
+  CREATE TABLE C(
+    id INTEGER PRIMARY KEY,
+    xx INTEGER NOT NULL,
+    yy INTEGER,
+    zz INTEGER
+  );
+  CREATE UNIQUE INDEX x2 ON C(yy);
+  CREATE UNIQUE INDEX x4 ON C(yy, zz);
+  INSERT INTO A(id) VALUES(1);
+  INSERT INTO B(id) VALUES(2);
+  INSERT INTO C(id,xx,yy,zz) VALUES(99,50,1,2);
+  SELECT 1
+    FROM A,
+         (SELECT id,xx,yy,zz FROM C) subq,
+         B
+   WHERE A.id='1'
+     AND A.id=subq.yy
+     AND B.id=subq.zz;
+} {1}  
+do_execsql_test 301 {
+  SELECT 1
+    FROM A,
+         (SELECT id,xx,yy,zz FROM C) subq,
+         B
+   WHERE A.id=1
+     AND A.id=subq.yy
+     AND B.id=subq.zz;
+} {1}  
+do_execsql_test 302 {
+  SELECT 1
+    FROM A,
+         (SELECT id,yy,zz FROM C) subq,
+         B
+   WHERE A.id='1'
+     AND A.id=subq.yy
+     AND B.id=subq.zz;
+} {1}  
+
 finish_test