]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Add the --primarykey option to the sqldiff tool, which causes it to use the
authordrh <drh@noemail.net>
Thu, 9 Apr 2015 18:14:03 +0000 (18:14 +0000)
committerdrh <drh@noemail.net>
Thu, 9 Apr 2015 18:14:03 +0000 (18:14 +0000)
schema-defined PRIMARY KEY.

FossilOrigin-Name: 5063f9070afde9374ea0f2bc338fee840d8b3dd4

manifest
manifest.uuid
tool/sqldiff.c

index a4817bdb6cf81b912ed3a21b83036e05dac1ebd9..d6f8442010670922f076a623a91d175ef0a5b302 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Remove\stwo\spointless\sassert()\sstatements.\s\sThis\sshould\ssilence\sharmless\ncompiler\swarnings\sreported\sat\s\n[https://bugzilla.mozilla.org/show_bug.cgi?id=1152845]
-D 2015-04-09T16:30:56.502
+C Add\sthe\s--primarykey\soption\sto\sthe\ssqldiff\stool,\swhich\scauses\sit\sto\suse\sthe\nschema-defined\sPRIMARY\sKEY.
+D 2015-04-09T18:14:03.130
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -1239,7 +1239,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
-F tool/sqldiff.c a28d17d824bc80940c2d67b2cf85a387c461dc97
+F tool/sqldiff.c 9334ebc767dda9e02b904d4cbbd31cf8aaba3ca5
 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
 F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
@@ -1250,7 +1250,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 32ab2bb990746a84f5944e3cf428fb2dff3628da
-R 37f01a89c55b4805b0a5cf101a377c7c
+P 83b342a44ffc9ea07dc4d59f2866cefc68ee4f13
+R 80b4d61d5d12e62d07bcaa502c23a21f
 U drh
-Z 80169060600c5dd4d547a3dab7f7d969
+Z 965913d93d231505652de01e91883fad
index 341851e55fe0219653981ec28dd9bcfa13746fde..fda938f72a3dfd882d2ae180e196d2eb8623fb9c 100644 (file)
@@ -1 +1 @@
-83b342a44ffc9ea07dc4d59f2866cefc68ee4f13
\ No newline at end of file
+5063f9070afde9374ea0f2bc338fee840d8b3dd4
\ No newline at end of file
index 2b982e914aefad34100465f74f9de3551ef510d8..28b66b2c374945a31f56a43b2c92d2fd032a8326 100644 (file)
@@ -26,6 +26,7 @@
 struct GlobalVars {
   const char *zArgv0;       /* Name of program */
   int bSchemaOnly;          /* Only show schema differences */
+  int bSchemaPK;            /* Use the schema-defined PK, not the true PK */
   unsigned fDebug;          /* Debug flags */
   sqlite3 *db;              /* The database connection */
 } g;
@@ -217,27 +218,34 @@ static void namelistFree(char **az){
 ** hold the list is obtained from sqlite3_malloc() and should released
 ** using namelistFree() when no longer needed.
 **
-** Primary key columns are listed first, followed by data columns.  The
-** "primary key" in the previous sentence is the true primary key - the
-** rowid or INTEGER PRIMARY KEY for ordinary tables or the declared
-** PRIMARY KEY for WITHOUT ROWID tables.  The number of columns in the
-** primary key is returned in *pnPkey.
+** Primary key columns are listed first, followed by data columns.
+** The number of columns in the primary key is returned in *pnPkey.
 **
-** If the table is a rowid table for which the rowid is inaccessible,
+** Normally, the "primary key" in the previous sentence is the true
+** primary key - the rowid or INTEGER PRIMARY KEY for ordinary tables
+** or the declared PRIMARY KEY for WITHOUT ROWID tables.  However, if
+** the g.bSchemaPK flag is set, then the schema-defined PRIMARY KEY is
+** used in all cases.  In that case, entries that have NULL values in
+** any of their primary key fields will be excluded from the analysis.
+**
+** If the primary key for a table is the rowid but rowid is inaccessible,
 ** then this routine returns a NULL pointer.
 **
 ** Examples:
 **    CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
 **    *pnPKey = 1;
-**    az = { "rowid", "a", "b", "c", 0 }
+**    az = { "rowid", "a", "b", "c", 0 }  // Normal case
+**    az = { "c", "a", "b", 0 }           // g.bSchemaPK==1
 **
 **    CREATE TABLE t2(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(b));
 **    *pnPKey = 1;
 **    az = { "b", "a", "c", 0 }
 **
 **    CREATE TABLE t3(x,y,z,PRIMARY KEY(y,z));
-**    *pnPKey = 1
-**    az = { "rowid", "x", "y", "z", 0 }
+**    *pnPKey = 1                         // Normal case
+**    az = { "rowid", "x", "y", "z", 0 }  // Normal case
+**    *pnPKey = 2                         // g.bSchemaPK==1
+**    az = { "y", "x", "z", 0 }           // g.bSchemaPK==1
 **
 **    CREATE TABLE t4(x,y,z,PRIMARY KEY(y,z)) WITHOUT ROWID;
 **    *pnPKey = 2
@@ -247,50 +255,72 @@ static void namelistFree(char **az){
 **    az = 0     // The rowid is not accessible
 */
 static char **columnNames(const char *zDb, const char *zTab, int *pnPKey){
-  char **az = 0;
-  int naz = 0;
-  sqlite3_stmt *pStmt;
+  char **az = 0;           /* List of column names to be returned */
+  int naz = 0;             /* Number of entries in az[] */
+  sqlite3_stmt *pStmt;     /* SQL statement being run */
   char *zPkIdxName = 0;    /* Name of the PRIMARY KEY index */
-  int truePk = 0;          /* PRAGMA table_info indentifies the true PK */
+  int truePk = 0;          /* PRAGMA table_info indentifies the PK to use */
   int nPK = 0;             /* Number of PRIMARY KEY columns */
-  int i, j;
-
-  pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
-  while( SQLITE_ROW==sqlite3_step(pStmt) ){
-    if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
-      zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
-      break;
-    }
-  }
-  sqlite3_finalize(pStmt);
-  if( zPkIdxName ){
-    int nKey = 0;
-    int nCol = 0;
-    truePk = 0;
-    pStmt = db_prepare("PRAGMA %s.index_xinfo=%Q", zDb, zPkIdxName);
+  int i, j;                /* Loop counters */
+
+  if( g.bSchemaPK==0 ){
+    /* Normal case:  Figure out what the true primary key is for the table.
+    **   *  For WITHOUT ROWID tables, the true primary key is the same as
+    **      the schema PRIMARY KEY, which is guaranteed to be present.
+    **   *  For rowid tables with an INTEGER PRIMARY KEY, the true primary
+    **      key is the INTEGER PRIMARY KEY.
+    **   *  For all other rowid tables, the rowid is the true primary key.
+    */
+    pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
     while( SQLITE_ROW==sqlite3_step(pStmt) ){
-      nCol++;
-      if( sqlite3_column_int(pStmt,5) ){ nKey++; continue; }
-      if( sqlite3_column_int(pStmt,1)>=0 ) truePk = 1;
+      if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
+        zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
+        break;
+      }
     }
-    if( nCol==nKey ) truePk = 1;
-    if( truePk ){
-      nPK = nKey;
+    sqlite3_finalize(pStmt);
+    if( zPkIdxName ){
+      int nKey = 0;
+      int nCol = 0;
+      truePk = 0;
+      pStmt = db_prepare("PRAGMA %s.index_xinfo=%Q", zDb, zPkIdxName);
+      while( SQLITE_ROW==sqlite3_step(pStmt) ){
+        nCol++;
+        if( sqlite3_column_int(pStmt,5) ){ nKey++; continue; }
+        if( sqlite3_column_int(pStmt,1)>=0 ) truePk = 1;
+      }
+      if( nCol==nKey ) truePk = 1;
+      if( truePk ){
+        nPK = nKey;
+      }else{
+        nPK = 1;
+      }
+      sqlite3_finalize(pStmt);
+      sqlite3_free(zPkIdxName);
     }else{
+      truePk = 1;
       nPK = 1;
     }
-    sqlite3_finalize(pStmt);
-    sqlite3_free(zPkIdxName);
+    pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
   }else{
+    /* The g.bSchemaPK==1 case:  Use whatever primary key is declared
+    ** in the schema.  The "rowid" will still be used as the primary key
+    ** if the table definition does not contain a PRIMARY KEY.
+    */
+    nPK = 0;
+    pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
+    while( SQLITE_ROW==sqlite3_step(pStmt) ){
+      if( sqlite3_column_int(pStmt,5)>0 ) nPK++;
+    }
+    sqlite3_reset(pStmt);
+    if( nPK==0 ) nPK = 1;
     truePk = 1;
-    nPK = 1;
   }
   *pnPKey = nPK;
   naz = nPK;
   az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
   if( az==0 ) runtimeError("out of memory");
   memset(az, 0, sizeof(char*)*(nPK+1));
-  pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
   while( SQLITE_ROW==sqlite3_step(pStmt) ){
     int iPKey;
     if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
@@ -692,6 +722,7 @@ static void showHelp(void){
   printf(
 "Output SQL text that would transform DB1 into DB2.\n"
 "Options:\n"
+"  --primarykey          Use schema-defined PRIMARY KEYs\n"
 "  --schema              Show only differences in the schema\n"
 "  --table TAB           Show only differences in table TAB\n"
   );
@@ -720,6 +751,9 @@ int main(int argc, char **argv){
         showHelp();
         return 0;
       }else
+      if( strcmp(z,"primarykey")==0 ){
+        g.bSchemaPK = 1;
+      }else
       if( strcmp(z,"schema")==0 ){
         g.bSchemaOnly = 1;
       }else