]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Do not reuse factored constants that might have had their encodings changed.
authordrh <drh@noemail.net>
Thu, 21 Nov 2013 21:23:31 +0000 (21:23 +0000)
committerdrh <drh@noemail.net>
Thu, 21 Nov 2013 21:23:31 +0000 (21:23 +0000)
FossilOrigin-Name: 487f20366ce77f0c90865d10d5aaedd95af98694

manifest
manifest.uuid
src/expr.c
src/sqliteInt.h
test/func5.test [new file with mode: 0644]

index baab9046f77d41a59b37a6de7806efcffccaf549..bf817c4cacdc8393755bed7f2e816dfab55415e6 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sthe\scode\sgenerator\sto\shonor\sturning\soff\sconstant\sexpression\sfactoring.
-D 2013-11-21T20:48:42.154
+C Do\snot\sreuse\sfactored\sconstants\sthat\smight\shave\shad\stheir\sencodings\schanged.
+D 2013-11-21T21:23:31.703
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 8a07bebafbfda0eb67728f4bd15a36201662d1a1
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -175,7 +175,7 @@ F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
 F src/ctime.c ea4b7f3623a0fcb1146e7f245d7410033e86859c
 F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
 F src/delete.c 909936019ccb8d0f4a10d0d10ad607c38ee62cbe
-F src/expr.c afc039ecfe2b990572f813aee0cbd734c167c955
+F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf
 F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
 F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5
 F src/func.c ef30d26ae4d79bbc7300c74e77fd117a0ba30235
@@ -224,7 +224,7 @@ F src/shell.c 849ee96c952d20e504d417e42a06acc5ca94ef17
 F src/sqlite.h.in a5dc058a909d9f14470bad9329d9e9303020ea4e
 F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
 F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
-F src/sqliteInt.h 5cf2c563e8909cd21378b47ace439826f1407120
+F src/sqliteInt.h 9d586cb37572cd9e0a48242d449c6a69c2e74e72
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -577,6 +577,7 @@ F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8
 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
 F test/func3.test dbccee9133cfef1473c59ec07b5f0262b9d72f9a
 F test/func4.test 6beacdfcb0e18c358e6c2dcacf1b65d1fa80955f
+F test/func5.test 1435dd313c0bae70d6af089c97a2a997fc5d0e53
 F test/fuzz-oss1.test 4912e528ec9cf2f42134456933659d371c9e0d74
 F test/fuzz.test 77fd50afc12847af50fcf1941679d90adebadde6
 F test/fuzz2.test 207d0f9d06db3eaf47a6b7bfc835b8e2fc397167
@@ -1140,7 +1141,7 @@ F tool/vdbe-compress.tcl f12c884766bd14277f4fcedcae07078011717381
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
 F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
-P a89fdf87553f01c150729c570796b5078a9b069d
-R 71de4796954de06b931dd50d526bd744
+P 882622662dfadf49c65c7d80b7fd87533d079ce9
+R 919d251b93f214648dcb5abd041a55e3
 U drh
-Z 94a313bef91e05454ee1a8fb62156d74
+Z 333bbe2ad90c7a14f3cc2f1f3886517e
index 441a088dc5255b30db1286d3f44706786ade622c..4a7a4a96ed6605fc1dc3ed0e82e60f439e50761b 100644 (file)
@@ -1 +1 @@
-882622662dfadf49c65c7d80b7fd87533d079ce9
\ No newline at end of file
+487f20366ce77f0c90865d10d5aaedd95af98694
\ No newline at end of file
index 2fb26b20fd8e7787eea15014cc5bf9813a5e9c04..6c8a8cce775ec531d0be8573af1d3e24a926ec7e 100644 (file)
@@ -2989,13 +2989,22 @@ int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target){
 /*
 ** Factor out the code of the given expression to initialization time.
 */
-void sqlite3ExprCodeAtInit(Parse *pParse, Expr *pExpr, int regDest){
+void sqlite3ExprCodeAtInit(
+  Parse *pParse,    /* Parsing context */
+  Expr *pExpr,      /* The expression to code when the VDBE initializes */
+  int regDest,      /* Store the value in this register */
+  u8 reusable       /* True if this expression is reusable */
+){
   ExprList *p;
   assert( ConstFactorOk(pParse) );
   p = pParse->pConstExpr;
   pExpr = sqlite3ExprDup(pParse->db, pExpr, 0);
   p = sqlite3ExprListAppend(pParse, p, pExpr);
-  if( p ) p->a[p->nExpr-1].u.iConstExprReg = regDest;
+  if( p ){
+     struct ExprList_item *pItem = &p->a[p->nExpr-1];
+     pItem->u.iConstExprReg = regDest;
+     pItem->reusable = reusable;
+  }
   pParse->pConstExpr = p;
 }
 
@@ -3023,14 +3032,15 @@ int sqlite3ExprCodeTemp(Parse *pParse, Expr *pExpr, int *pReg){
     int i;
     *pReg  = 0;
     if( p ){
-      for(i=0; i<p->nExpr; i++){
-        if( sqlite3ExprCompare(p->a[i].pExpr, pExpr, -1)==0 ){
-          return p->a[i].u.iConstExprReg;
+      struct ExprList_item *pItem;
+      for(pItem=p->a, i=p->nExpr; i>0; pItem++, i--){
+        if( pItem->reusable && sqlite3ExprCompare(pItem->pExpr,pExpr,-1)==0 ){
+          return pItem->u.iConstExprReg;
         }
       }
     }
     r2 = ++pParse->nMem;
-    sqlite3ExprCodeAtInit(pParse, pExpr, r2);
+    sqlite3ExprCodeAtInit(pParse, pExpr, r2, 1);
   }else{
     int r1 = sqlite3GetTempReg(pParse);
     r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1);
@@ -3399,7 +3409,7 @@ int sqlite3ExprCodeExprList(
   for(pItem=pList->a, i=0; i<n; i++, pItem++){
     Expr *pExpr = pItem->pExpr;
     if( (flags & SQLITE_ECEL_FACTOR)!=0 && sqlite3ExprIsConstant(pExpr) ){
-      sqlite3ExprCodeAtInit(pParse, pExpr, target+i);
+      sqlite3ExprCodeAtInit(pParse, pExpr, target+i, 0);
     }else{
       int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
       if( inReg!=target+i ){
index 932b29c5de49323a223d0b8894ab4bf295af19bb..6373bb75d7fd7882d3d96829340a5d58d1dc53df 100644 (file)
@@ -1916,6 +1916,7 @@ struct ExprList {
     u8 sortOrder;           /* 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 */
     union {
       struct {
         u16 iOrderByCol;      /* For ORDER BY, column number in result set */
@@ -2910,7 +2911,7 @@ void sqlite3ExprCacheRemove(Parse*, int, int);
 void sqlite3ExprCacheClear(Parse*);
 void sqlite3ExprCacheAffinityChange(Parse*, int, int);
 int sqlite3ExprCode(Parse*, Expr*, int);
-void sqlite3ExprCodeAtInit(Parse*, Expr*, int);
+void sqlite3ExprCodeAtInit(Parse*, Expr*, int, u8);
 int sqlite3ExprCodeTemp(Parse*, Expr*, int*);
 int sqlite3ExprCodeTarget(Parse*, Expr*, int);
 int sqlite3ExprCodeAndCache(Parse*, Expr*, int);
diff --git a/test/func5.test b/test/func5.test
new file mode 100644 (file)
index 0000000..83ecb78
--- /dev/null
@@ -0,0 +1,33 @@
+# 2013-11-21
+#
+# 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.
+#
+#*************************************************************************
+#
+# Verify that constant string expressions that get factored into initializing
+# code are not reused between function parameters and other values in the
+# VDBE program, as the function might have changed the encoding.
+#
+set testdir [file dirname $argv0]
+source $testdir/tester.tcl
+
+do_execsql_test func5-1.1 {
+  PRAGMA encoding=UTF16le;
+  CREATE TABLE t1(x,a,b,c);
+  INSERT INTO t1 VALUES(1,'ab','cd',1);
+  INSERT INTO t1 VALUES(2,'gh','ef',5);
+  INSERT INTO t1 VALUES(3,'pqr','fuzzy',99);
+  INSERT INTO t1 VALUES(4,'abcdefg','xy',22);
+  INSERT INTO t1 VALUES(5,'shoe','mayer',2953);
+  SELECT x FROM t1 WHERE c=instr('abcdefg',b) OR a='abcdefg' ORDER BY +x;
+} {2 4}
+do_execsql_test func5-1.2 {
+  SELECT x FROM t1 WHERE a='abcdefg' OR c=instr('abcdefg',b) ORDER BY +x;
+} {2 4}
+
+finish_test