Index: src/expr.c ================================================================== --- src/expr.c +++ src/expr.c @@ -3365,11 +3365,30 @@ /* Otherwise, fall thru into the TK_COLUMN case */ } 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 ){ /* Generating CHECK constraints or inserting into partial index */ return pExpr->iColumn - pParse->iSelfTab; Index: test/whereL.test ================================================================== --- test/whereL.test +++ test/whereL.test @@ -64,7 +64,51 @@ # query, the wrong answer results: # 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