From: drh Date: Thu, 9 Apr 2015 18:14:03 +0000 (+0000) Subject: Add the --primarykey option to the sqldiff tool, which causes it to use the X-Git-Tag: version-3.8.10~163 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a37591cdd10ead51ed87a43aeeb9f83312636fd1;p=thirdparty%2Fsqlite.git Add the --primarykey option to the sqldiff tool, which causes it to use the schema-defined PRIMARY KEY. FossilOrigin-Name: 5063f9070afde9374ea0f2bc338fee840d8b3dd4 --- diff --git a/manifest b/manifest index a4817bdb6c..d6f8442010 100644 --- 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 diff --git a/manifest.uuid b/manifest.uuid index 341851e55f..fda938f72a 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -83b342a44ffc9ea07dc4d59f2866cefc68ee4f13 \ No newline at end of file +5063f9070afde9374ea0f2bc338fee840d8b3dd4 \ No newline at end of file diff --git a/tool/sqldiff.c b/tool/sqldiff.c index 2b982e914a..28b66b2c37 100644 --- a/tool/sqldiff.c +++ b/tool/sqldiff.c @@ -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