]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix some problems surrounding WITHOUT ROWID tables with DESC primary key indexes
authordan <dan@noemail.net>
Tue, 3 Feb 2015 18:43:42 +0000 (18:43 +0000)
committerdan <dan@noemail.net>
Tue, 3 Feb 2015 18:43:42 +0000 (18:43 +0000)
.

FossilOrigin-Name: a21fefb79a161e6bb057ae4f6ba554f659706ac1

ext/ota/ota1.test
ext/ota/sqlite3ota.c
manifest
manifest.uuid
src/pragma.c

index 0b2da1a60e74bd7bf1da47885702b9256ee15567..afb5fd5865a36d93eb6dcd33aabdf56b78eb9241 100644 (file)
@@ -148,6 +148,39 @@ foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_uri} {
       CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c));
       CREATE INDEX i1 ON t1(b);
     }
+
+    10 { 
+      CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
+      CREATE INDEX i1 ON t1(b DESC);
+    }
+
+    11 { 
+      CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
+      CREATE INDEX i1 ON t1(b DESC, a ASC, c DESC);
+    }
+
+    12 { 
+      CREATE TABLE t1(a INT PRIMARY KEY DESC, b, c) WITHOUT ROWID; 
+    }
+
+    13 { 
+      CREATE TABLE t1(a INT, b, c, PRIMARY KEY(a DESC)) WITHOUT ROWID; 
+    }
+
+    14 { 
+      CREATE TABLE t1(a, b, c, PRIMARY KEY(a DESC, c)) WITHOUT ROWID;
+      CREATE INDEX i1 ON t1(b);
+    }
+
+    15 { 
+      CREATE TABLE t1(a, b, c, PRIMARY KEY(a, c DESC)) WITHOUT ROWID;
+      CREATE INDEX i1 ON t1(b);
+    }
+
+    16 { 
+      CREATE TABLE t1(a, b, c, PRIMARY KEY(c DESC, a)) WITHOUT ROWID;
+      CREATE INDEX i1 ON t1(b DESC, c, a);
+    }
   } {
     reset_db
     execsql $schema
@@ -157,15 +190,23 @@ foreach {tn2 cmd} {1 run_ota 2 step_ota 3 step_ota_uri} {
       $cmd test.db ota.db
     } {SQLITE_DONE}
 
-    do_execsql_test 1.$tn2.$tn.2 {
-      SELECT * FROM t1 ORDER BY a ASC;
-    } {
+    do_execsql_test 1.$tn2.$tn.2 { SELECT * FROM t1 ORDER BY a ASC } {
       1 2 3 
       2 two three 
       3 {} 8.2
     }
+    do_execsql_test 1.$tn2.$tn.3 { SELECT * FROM t1 ORDER BY b ASC } {
+      3 {} 8.2
+      1 2 3 
+      2 two three 
+    }
+    do_execsql_test 1.$tn2.$tn.4 { SELECT * FROM t1 ORDER BY c ASC } {
+      1 2 3 
+      3 {} 8.2
+      2 two three 
+    }
  
-    do_execsql_test 1.$tn2.$tn.3 { PRAGMA integrity_check } ok
+    do_execsql_test 1.$tn2.$tn.5 { PRAGMA integrity_check } ok
   }
 }
 
@@ -277,6 +318,19 @@ foreach {tn2 cmd} {1 run_ota 2 step_ota} {
       CREATE INDEX i2 ON t1(c, b);
       CREATE INDEX i3 ON t1(c, b, c);
     }
+
+    6 {
+      CREATE TABLE t1(a INT PRIMARY KEY DESC, b, c);
+      CREATE INDEX i1 ON t1(b DESC);
+      CREATE INDEX i2 ON t1(c, b);
+      CREATE INDEX i3 ON t1(c DESC, b, c);
+    }
+    7 {
+      CREATE TABLE t1(a INT PRIMARY KEY DESC, b, c) WITHOUT ROWID;
+      CREATE INDEX i1 ON t1(b);
+      CREATE INDEX i2 ON t1(c, b);
+      CREATE INDEX i3 ON t1(c, b, c);
+    }
   } {
     reset_db
     execsql $schema
index ae45db032b0b4acc8a4271c5ba75bbab8af49c09..c7f3afec12752cbc812bc1c915feb29da812675d 100644 (file)
@@ -645,8 +645,9 @@ static char *otaObjIterGetIndexCols(
   }
 
   while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
-    const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
     int iCid = sqlite3_column_int(pXInfo, 1);
+    int bDesc = sqlite3_column_int(pXInfo, 3);
+    const char *zCollate = (const char*)sqlite3_column_text(pXInfo, 4);
     const char *zCol;
     const char *zType;
 
@@ -669,7 +670,8 @@ static char *otaObjIterGetIndexCols(
 
     zRet = sqlite3_mprintf("%z%s\"%w\" COLLATE %Q", zRet, zCom, zCol, zCollate);
     if( pIter->bUnique==0 || sqlite3_column_int(pXInfo, 5) ){
-      zImpPK = sqlite3_mprintf("%z%sc%d", zImpPK, zCom, nBind);
+      const char *zOrder = (bDesc ? " DESC" : "");
+      zImpPK = sqlite3_mprintf("%z%sc%d%s", zImpPK, zCom, nBind, zOrder);
     }
     zImpCols = sqlite3_mprintf(
         "%z%sc%d %s COLLATE %Q", zImpCols, zCom, nBind, zType, zCollate
@@ -839,6 +841,46 @@ static char *otaObjIterGetBindlist(sqlite3ota *p, int nBind){
   return zRet;
 }
 
+/*
+** The iterator currently points to a table (not index) of type 
+** OTA_PK_WITHOUT_ROWID. This function creates the PRIMARY KEY 
+** declaration for the corresponding imposter table. For example,
+** if the iterator points to a table created as:
+**
+**   CREATE TABLE t1(a, b, c, PRIMARY KEY(b, a DESC)) WITHOUT ROWID
+**
+** this function returns:
+**
+**   PRIMARY KEY("b", "a" DESC)
+*/
+static char *otaWithoutRowidPK(sqlite3ota *p, OtaObjIter *pIter){
+  char *z = 0;
+  assert( pIter->zIdx==0 );
+  if( p->rc==SQLITE_OK ){
+    const char *zSep = "PRIMARY KEY(";
+    sqlite3_stmt *pXInfo = 0;     /* PRAGMA index_xinfo = (pIter->zTbl) */
+    int rc;                       /* sqlite3_finalize() return code */
+
+    p->rc = prepareFreeAndCollectError(p->db, &pXInfo, &p->zErrmsg,
+        sqlite3_mprintf("PRAGMA main.index_xinfo = %Q", pIter->zTbl)
+    );
+    while( p->rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pXInfo) ){
+      if( sqlite3_column_int(pXInfo, 5) ){
+        /* int iCid = sqlite3_column_int(pXInfo, 0); */
+        const char *zCol = (const char*)sqlite3_column_text(pXInfo, 2);
+        const char *zDesc = sqlite3_column_int(pXInfo, 3) ? " DESC" : "";
+        z = otaMPrintfAndCollectError(p, "%z%s\"%w\"%s", z, zSep, zCol, zDesc);
+        zSep = ", ";
+      }
+    }
+    z = otaMPrintfAndCollectError(p, "%z)", z);
+
+    rc = sqlite3_finalize(pXInfo);
+    if( p->rc==SQLITE_OK ) p->rc = rc;
+  }
+  return z;
+}
+
 /*
 ** If an error has already occurred when this function is called, it 
 ** immediately returns zero (without doing any work). Or, if an error
@@ -876,30 +918,31 @@ static void otaCreateImposterTable(sqlite3ota *p, OtaObjIter *pIter){
     sqlite3_test_control(SQLITE_TESTCTRL_IMPOSTER, p->db, "main", 0, 1);
 
     for(iCol=0; p->rc==SQLITE_OK && iCol<pIter->nTblCol; iCol++){
+      const char *zPk = "";
       int iDataCol = pIter->aiTblOrder[iCol];
       const char *zCol = pIter->azTblCol[iDataCol];
       const char *zColl = 0;
+
       p->rc = sqlite3_table_column_metadata(
           p->db, "main", pIter->zTbl, zCol, 0, &zColl, 0, 0, 0
       );
-      zSql = otaMPrintfAndCollectError(p, "%z%s\"%w\" %s COLLATE %s", 
-          zSql, zComma, zCol, pIter->azTblType[iDataCol], zColl
+
+      if( pIter->eType==OTA_PK_IPK && pIter->abTblPk[iCol] ){
+        /* If the target table column is an "INTEGER PRIMARY KEY", add
+        ** "PRIMARY KEY" to the imposter table column declaration. */
+        zPk = "PRIMARY KEY ";
+      }
+      zSql = otaMPrintfAndCollectError(p, "%z%s\"%w\" %s %sCOLLATE %s", 
+          zSql, zComma, zCol, pIter->azTblType[iDataCol], zPk, zColl
       );
       zComma = ", ";
     }
 
-    if( pIter->eType==OTA_PK_IPK || pIter->eType==OTA_PK_WITHOUT_ROWID ){
-      zSql = otaMPrintfAndCollectError(p, "%z, PRIMARY KEY(", zSql);
-      zComma = "";
-      for(iCol=0; iCol<pIter->nTblCol; iCol++){
-        if( pIter->abTblPk[iCol] ){
-          zSql = otaMPrintfAndCollectError(p, "%z%s\"%w\"", 
-              zSql, zComma, pIter->azTblCol[iCol]
-          );
-          zComma = ", ";
-        }
+    if( pIter->eType==OTA_PK_WITHOUT_ROWID ){
+      char *zPk = otaWithoutRowidPK(p, pIter);
+      if( zPk ){
+        zSql = otaMPrintfAndCollectError(p, "%z, %z", zSql, zPk);
       }
-      zSql = otaMPrintfAndCollectError(p, "%z)", zSql);
     }
 
     zSql = otaMPrintfAndCollectError(p, "CREATE TABLE ota_imposter(%z)%s", 
index 0a49c2b2a10f7833d404aeedfc346c76a0c432e5..39ded5aeaa46b9f8a4cf62fe1abadf61aa01167f 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\s"PRAGMA\sota_mode".
-D 2015-02-03T15:56:08.271
+C Fix\ssome\sproblems\ssurrounding\sWITHOUT\sROWID\stables\swith\sDESC\sprimary\skey\sindexes\n.
+D 2015-02-03T18:43:42.428
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5407a688f4d77a05c18a8142be8ae5a2829dd610
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -125,7 +125,7 @@ F ext/misc/vtshim.c babb0dc2bf116029e3e7c9a618b8a1377045303e
 F ext/misc/wholenumber.c 784b12543d60702ebdd47da936e278aa03076212
 F ext/ota/README.txt 78d4a9f78f567d4bf826cf0f02df6254902562ca
 F ext/ota/ota.c c11a85af71dccc45976622fe7a51169a481caa91
-F ext/ota/ota1.test d76b9ec77437759e9da0ff4abe9c070bb9f4eae1
+F ext/ota/ota1.test 719854e444dff2ead58ff6b62d8315954bd7762a
 F ext/ota/ota10.test ab815dff9cef7248c504f06b888627d236f25e9c
 F ext/ota/ota2.test 2829bc08ffbb71b605392a68fedfd554763356a7
 F ext/ota/ota3.test a77efbce7723332eb688d2b28bf18204fc9614d7
@@ -136,7 +136,7 @@ F ext/ota/ota7.test 1fe2c5761705374530e29f70c39693076028221a
 F ext/ota/ota8.test cd70e63a0c29c45c0906692827deafa34638feda
 F ext/ota/ota9.test d3eee95dd836824d07a22e5efcdb7bf6e869358b
 F ext/ota/otafault.test 508ba87c83d632670ac0f94371a465d4bb4d49dd
-F ext/ota/sqlite3ota.c 52c91eec41b8fbb5ed12a8f0a2159bc5ec16498f
+F ext/ota/sqlite3ota.c de2e605697871de02fd9ea717a57c00bf022a27e
 F ext/ota/sqlite3ota.h ce378c0c503f625611713133f9c79704ea4ee7a4
 F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761
 F ext/rtree/rtree.c 14e6239434d4e3f65d3e90320713f26aa24e167f
@@ -238,7 +238,7 @@ F src/parse.y c5d0d964f9ac023e8154cad512e54b0b6058e086
 F src/pcache.c d210cf90d04365a74f85d21374dded65af67b0cb
 F src/pcache.h b44658c9c932d203510279439d891a2a83e12ba8
 F src/pcache1.c 1e77432b40b7d3288327d9cdf399dcdfd2b6d3bf
-F src/pragma.c 26fc55619109828c9b7add4cfa8a961b6f4c456d
+F src/pragma.c e39954ff47e287f88bdf9e9adb123da029e83d9f
 F src/prepare.c 173a5a499138451b2561614ecb87d78f9f4644b9
 F src/printf.c 05edc41450d0eb2c05ef7db113bf32742ae65325
 F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
@@ -1254,7 +1254,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
 F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
 F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P cdaeab467f6aa3217be161377a9b78a4eec37093
-R 2703aba199c695992db82956950982ca
+P 1c111447a07687c30ed4ad5a6c27a169c85b7ea6
+R 544935f49f95af3db3c849fcc1fc392c
 U dan
-Z fae9dc4e5e5c1a2d2a162b422a05ccf9
+Z 5f7217c8a4b7a144888c5aa7b5260598
index 0e07d68cdf7b62a43a90934a03e83489334e1667..66e6bbaaef165b59c29c5d9cf903d801ab82d509 100644 (file)
@@ -1 +1 @@
-1c111447a07687c30ed4ad5a6c27a169c85b7ea6
\ No newline at end of file
+a21fefb79a161e6bb057ae4f6ba554f659706ac1
\ No newline at end of file
index 61c721f4d219728786631e760465aaf7b191ecae..fc39a5476c41e1697f6ffda2be19bd3834efca0e 100644 (file)
@@ -1581,6 +1581,10 @@ void sqlite3Pragma(
     Index *pIdx;
     Table *pTab;
     pIdx = sqlite3FindIndex(db, zRight, zDb);
+    if( pIdx==0 ){
+      pTab = sqlite3FindTable(db, zRight, zDb);
+      if( pTab && !HasRowid(pTab) ) pIdx = sqlite3PrimaryKeyIndex(pTab);
+    }
     if( pIdx ){
       int i;
       int mx = pPragma->iArg ? pIdx->nColumn : pIdx->nKeyCol;