]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix the sqlite3_normalized_sql() interface so that it renders
authordrh <drh@noemail.net>
Fri, 7 Dec 2018 16:32:11 +0000 (16:32 +0000)
committerdrh <drh@noemail.net>
Fri, 7 Dec 2018 16:32:11 +0000 (16:32 +0000)
double-quoted string literals as "?".

FossilOrigin-Name: 0d8e150434bbd179696f1ffe71d1e06cb3d43e6468496c7e481fca8486387bad

manifest
manifest.uuid
src/prepare.c
src/resolve.c
src/vdbe.h
src/vdbeInt.h
src/vdbeaux.c
test/normalize.test

index 4087d03b834a35fd3ea824045a85421699609911..f4fb1dff1bc85afc5aaa5bff1f6d4cd0b14c41d8 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sdbfuzz2.c\sso\sthat\sit\sworks\swith\s-DSQLITE_OMIT_INIT
-D 2018-12-07T03:01:07.990
+C Fix\sthe\ssqlite3_normalized_sql()\sinterface\sso\sthat\sit\srenders\ndouble-quoted\sstring\sliterals\sas\s"?".
+D 2018-12-07T16:32:11.362
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F Makefile.in 68d0ba0f0b533d5bc84c78c13a6ce84ee81183a67014caa47a969e67f028fa1c
@@ -502,10 +502,10 @@ F src/pcache.h 4f87acd914cef5016fae3030343540d75f5b85a1877eed1a2a19b9f284248586
 F src/pcache1.c ad0ffc5b35b0280d045ac569d34d4b842e3e6a4a118f6396b320987a0957afcc
 F src/pragma.c 96ce7dce4dc9cb2b7aa0e1b2ce7536870bdc00b10becc278245e775489447ea0
 F src/pragma.h fdd03d78a7497f74a3f652909f945328480089189526841ae829ce7313d98d13
-F src/prepare.c 5fe8eb586d0e9d4009609490866525f242a3d0df01e39d967bf2611dc8081088
+F src/prepare.c be449edb106a16f1ad95f9b798bdc2337f8c3f83b96c284f417c0a26d43f0c1b
 F src/printf.c 0f1177cf1dd4d7827bf64d840768514ec76409abecaca9e8b577dbd065150381
 F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
-F src/resolve.c e0408228bad5d13937a626521cba42c6f768643a6353712218d7e01fb201b202
+F src/resolve.c 095d1d41d7a981ee9db8bfeae25ed0d6a8a5e5e3d66b0f4efd71877ed7b56132
 F src/rowset.c d977b011993aaea002cab3e0bb2ce50cf346000dff94e944d547b989f4b1fe93
 F src/select.c 8c7317d5ee920516a56b8b4ca79fbfca70a1f8b52d67e884c808ea3a016c04e3
 F src/shell.c.in 1f0819e69fb1ebd2eb44695530dc43936608bf9b752981a0ffd4e2e4a9e3883d
@@ -579,10 +579,10 @@ F src/utf.c 810fbfebe12359f10bc2a011520a6e10879ab2a163bcb26c74768eab82ea62a5
 F src/util.c d9eb0a6c4aae1b00a7369eadd7ca0bbe946cb4c953b6751aa20d357c2f482157
 F src/vacuum.c c67085526fb51e141a85be3f7c9b91a2d38705bbb0ef911d8dec1e2d36cbdce1
 F src/vdbe.c c7312c909df5032b4ed27996c2ed8f5bf948f6a982458f85398520aaba0ccf81
-F src/vdbe.h 5081dcc497777efe5e9ebe7330d283a044a005e4bdda2e2e984f03bf89a0d907
-F src/vdbeInt.h 437e6c6af679fdf157867eb83a8adc6cf5145d6774453c2214cfd0bd01d92980
+F src/vdbe.h d82f323d581b36b8e147d650257ef34e0e93790039b6cbda45c321c275f7595e
+F src/vdbeInt.h 73f5051923f3f29779bfc374c0c68e23b8e5e3792def2e33e51b427edb890abd
 F src/vdbeapi.c 9709452bee82963e1f7f1f5d0c71db823d553f8dbb2c47a911c4983d537a1947
-F src/vdbeaux.c d71429f70e95e21aaf15ee287a78beefcda4bdc7d1b6d3c704dfeba820a792e0
+F src/vdbeaux.c 9a9617666124e18cbd6e936740f7469dcf0d82867b1abf9ed828694500930b64
 F src/vdbeblob.c f5c70f973ea3a9e915d1693278a5f890dc78594300cf4d54e64f2b0917c94191
 F src/vdbemem.c 7b3305bc4a5139f4536ac9b5f61da0f915e49d2e3fdfa87dfdfa9d7aba8bc1e9
 F src/vdbesort.c 90aad5a92608f2dd771c96749beabdb562c9d881131a860a7a5bccf66dc3be7f
@@ -1142,7 +1142,7 @@ F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660
 F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1
 F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a
 F test/nolock.test f196cf8b8fbea4e2ca345140a2b3f3b0da45c76e
-F test/normalize.test 7fe7674d83e37c635ea2e88a27b54a0fe1afddb192d636d5672b1639859800f1
+F test/normalize.test 17ff5c732bc16b100f4e479da3a59735ed24f4ed574fccf8e46279fad182f81e
 F test/notify1.test 669b2b743618efdc18ca4b02f45423d5d2304abf
 F test/notify2.test 2ecabaa1305083856b7c39cf32816b612740c161
 F test/notify3.test 10ff25cde502e72a92053a2f215d64bece4ef934
@@ -1782,7 +1782,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 db5ed2268eda2e6c1df15cd8df4176463d89103b8fda33ba9a0604f0d92bd4da
-R 2969a28b361c45f45888cf9a9ac52a9e
+P 9ad796a8822f1b7e1e99b73c2cc5be59dbfd85e9c27f3e795c29a2c002c611d1
+R 75d9d47dfde008764fbf9239d7b4fada
 U drh
-Z 1170e81cf6857f6b3144fe1a49be0ee2
+Z 20abf3696cef97c5bdf0b2ae41ceaaa6
index 55f1f4ff1efa8f720c120b8f4795a737d2af6a9c..30608cbb376d923d900a749d2d6581b679ec1fe8 100644 (file)
@@ -1 +1 @@
-9ad796a8822f1b7e1e99b73c2cc5be59dbfd85e9c27f3e795c29a2c002c611d1
\ No newline at end of file
+0d8e150434bbd179696f1ffe71d1e06cb3d43e6468496c7e481fca8486387bad
\ No newline at end of file
index ad07eca45ac1656af3ab1510a7d0a8d92a472a50..811ef95aeab0f117a2c92c9bde030f1f70b6daa3 100644 (file)
@@ -882,9 +882,13 @@ char *sqlite3Normalize(
           z[j++] = ' ';
         }
         if( tokenType==TK_ID ){
-          int i2 = i, n2 = n;
+          if( zSql[i]=='"'
+           && sqlite3VdbeUsesDoubleQuotedString(db,pVdbe,zSql+i,n)
+          ){
+            z[j++] = '?';
+            break;
+          }
           if( nParen==nParenAtIN ) iStartIN = 0;
-          if( flags&SQLITE_TOKEN_QUOTED ){ i2++; n2-=2; }
         }
         copyNormalizedToken(zSql, i, n, flags, z, &j);
         break;
index 39c2039f59c936b8942b9a69f425f13640169006..a9262a45adb6082e6ac9aa30e6b5ebd0e718ed8b 100644 (file)
@@ -490,6 +490,9 @@ static int lookupName(
       */
       sqlite3_log(SQLITE_WARNING,
         "double-quoted string literal: \"%w\"", zCol);
+#ifdef SQLITE_ENABLE_NORMALIZE
+      sqlite3VdbeAddDblquoteStr(db,pParse->pVdbe, zCol);
+#endif
       pExpr->op = TK_STRING;
       pExpr->y.pTab = 0;
       return WRC_Prune;
index d42acc0cca2b44fd1fa3c6a1874c397d31f88860..1712b8b2249b145dbe03c81acc7bb563b88225b4 100644 (file)
@@ -251,6 +251,10 @@ void sqlite3VdbeCountChanges(Vdbe*);
 sqlite3 *sqlite3VdbeDb(Vdbe*);
 u8 sqlite3VdbePrepareFlags(Vdbe*);
 void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, u8);
+#ifdef SQLITE_ENABLE_NORMALIZE
+void sqlite3VdbeAddDblquoteStr(sqlite3*,Vdbe*,const char*);
+int sqlite3VdbeUsesDoubleQuotedString(sqlite3*,Vdbe*,const char*,int);
+#endif
 void sqlite3VdbeSwap(Vdbe*,Vdbe*);
 VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*);
 sqlite3_value *sqlite3VdbeGetBoundValue(Vdbe*, int, u8);
index 5c719923d78bc93a20c8584e853d6d25c8c6138f..70543526c1bc4342c1d9ed9e7c5ae6765ab8b582 100644 (file)
@@ -335,6 +335,9 @@ struct sqlite3_context {
 */
 typedef unsigned bft;  /* Bit Field Type */
 
+/* The ScanStatus object holds a single value for the
+** sqlite3_stmt_scanstatus() interface.
+*/
 typedef struct ScanStatus ScanStatus;
 struct ScanStatus {
   int addrExplain;                /* OP_Explain for loop */
@@ -345,6 +348,19 @@ struct ScanStatus {
   char *zName;                    /* Name of table or index */
 };
 
+/* The DblquoteStr object holds the text of a double-quoted
+** string for a prepared statement.  A linked list of these objects
+** is constructed during statement parsing and is held on Vdbe.pDblStr.
+** When computing a normalized SQL statement for an SQL statement, that
+** list is consulted for each double-quoted identifier to see if the
+** identifier should really be a string literal.
+*/
+typedef struct DblquoteStr DblquoteStr;
+struct DblquoteStr {
+  DblquoteStr *pNextStr;   /* Next string literal in the list */
+  char z[8];               /* Dequoted value for the string */
+};
+
 /*
 ** An instance of the virtual machine.  This structure contains the complete
 ** state of the virtual machine.
@@ -364,7 +380,7 @@ struct Vdbe {
   int pc;                 /* The program counter */
   int rc;                 /* Value to return */
   int nChange;            /* Number of db changes made since last reset */
-  int iStatement;         /* Statement number (or 0 if has not opened stmt) */
+  int iStatement;         /* Statement number (or 0 if has no opened stmt) */
   i64 iCurrentTime;       /* Value of julianday('now') for this statement */
   i64 nFkConstraint;      /* Number of imm. FK constraints this VM */
   i64 nStmtDefCons;       /* Number of def. constraints when stmt started */
@@ -408,6 +424,7 @@ struct Vdbe {
   char *zSql;             /* Text of the SQL statement that generated this */
 #ifdef SQLITE_ENABLE_NORMALIZE
   char *zNormSql;         /* Normalization of the associated SQL statement */
+  DblquoteStr *pDblStr;   /* List of double-quoted string literals */
 #endif
   void *pFree;            /* Free this when deleting the vdbe */
   VdbeFrame *pFrame;      /* Parent frame */
index 40a63319db11078d1bb89f20803df603304cf0ed..2f45c217f14b4f7f8c809823cf8dde0e503c267f 100644 (file)
@@ -73,6 +73,53 @@ void sqlite3VdbeSetSql(Vdbe *p, const char *z, int n, u8 prepFlags){
 #endif
 }
 
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** Add a new element to the Vdbe->pDblStr list.
+*/
+void sqlite3VdbeAddDblquoteStr(sqlite3 *db, Vdbe *p, const char *z){
+  if( p ){
+    int n = sqlite3Strlen30(z);
+    DblquoteStr *pStr = sqlite3DbMallocRawNN(db,
+                            sizeof(*pStr)+n+1-sizeof(pStr->z));
+    if( pStr ){
+      pStr->pNextStr = p->pDblStr;
+      p->pDblStr = pStr;
+      memcpy(pStr->z, z, n+1);
+    }
+  }
+}
+#endif
+
+#ifdef SQLITE_ENABLE_NORMALIZE
+/*
+** zId of length nId is a double-quoted identifier.  Check to see if
+** that identifier is really used as a string literal.
+*/
+int sqlite3VdbeUsesDoubleQuotedString(
+  sqlite3 *db,            /* Used for transient malloc */
+  Vdbe *pVdbe,            /* The prepared statement */
+  const char *zId,        /* The double-quoted identifier */
+  int nId                 /* Bytes in zId, which is not zero-terminated */
+){
+  char *z;
+  DblquoteStr *pStr;
+  assert( zId!=0 );
+  assert( zId[0]=='"' );
+  assert( nId>=2 );
+  assert( zId[nId-1]=='"' );
+  if( pVdbe->pDblStr==0 ) return 0;
+  z = sqlite3DbStrNDup(db, zId, nId);
+  if( z==0 ) return 0;
+  sqlite3Dequote(z);
+  for(pStr=pVdbe->pDblStr; pStr; pStr=pStr->pNextStr){
+    if( strcmp(z, pStr->z)==0 ) break;
+  }
+  sqlite3DbFree(db, z);
+  return pStr!=0;
+}
+#endif
+
 /*
 ** Swap all content between two VDBE structures.
 */
@@ -92,7 +139,7 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
   zTmp = pA->zSql;
   pA->zSql = pB->zSql;
   pB->zSql = zTmp;
-#ifdef SQLITE_ENABLE_NORMALIZE
+#if 0
   zTmp = pA->zNormSql;
   pA->zNormSql = pB->zNormSql;
   pB->zNormSql = zTmp;
@@ -3170,6 +3217,13 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
   sqlite3DbFree(db, p->zSql);
 #ifdef SQLITE_ENABLE_NORMALIZE
   sqlite3DbFree(db, p->zNormSql);
+  {
+    DblquoteStr *pThis, *pNext;
+    for(pThis=p->pDblStr; pThis; pThis=pNext){
+      pNext = pThis->pNextStr;
+      sqlite3DbFree(db, pThis);
+    }
+  }
 #endif
 #ifdef SQLITE_ENABLE_STMT_SCANSTATUS
   {
index c5b69336e933f7d486522429019913187d36a4bb..35c995fe758efb9f493e6702cfdc8cab5f9af374 100644 (file)
@@ -207,7 +207,7 @@ foreach {tnum sql flags norm} {
   430
   {SELECT "a" FROM t1 WHERE "x" IN ("1","2",'3');}
   0x2
-  {0 {SELECT"a"FROM t1 WHERE"x"IN("1","2",?);}}
+  {0 {SELECT"a"FROM t1 WHERE"x"IN(?,?,?);}}
 
   440
   {SELECT 'a' FROM t1 WHERE 'x';}