mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Add the --primarykey option to the sqldiff tool, which causes it to use the
schema-defined PRIMARY KEY. FossilOrigin-Name: 5063f9070afde9374ea0f2bc338fee840d8b3dd4
This commit is contained in:
12
manifest
12
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]
|
C Add\sthe\s--primarykey\soption\sto\sthe\ssqldiff\stool,\swhich\scauses\sit\sto\suse\sthe\nschema-defined\sPRIMARY\sKEY.
|
||||||
D 2015-04-09T16:30:56.502
|
D 2015-04-09T18:14:03.130
|
||||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||||
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
|
F Makefile.in 5f78b1ab81b64e7c57a75d170832443e66c0880a
|
||||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||||
@ -1239,7 +1239,7 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
|||||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||||
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
|
||||||
F tool/sqldiff.c a28d17d824bc80940c2d67b2cf85a387c461dc97
|
F tool/sqldiff.c 9334ebc767dda9e02b904d4cbbd31cf8aaba3ca5
|
||||||
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43
|
||||||
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d
|
||||||
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
|
F tool/symbols.sh fec58532668296d7c7dc48be9c87f75ccdb5814f
|
||||||
@ -1250,7 +1250,7 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
|||||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||||
P 32ab2bb990746a84f5944e3cf428fb2dff3628da
|
P 83b342a44ffc9ea07dc4d59f2866cefc68ee4f13
|
||||||
R 37f01a89c55b4805b0a5cf101a377c7c
|
R 80b4d61d5d12e62d07bcaa502c23a21f
|
||||||
U drh
|
U drh
|
||||||
Z 80169060600c5dd4d547a3dab7f7d969
|
Z 965913d93d231505652de01e91883fad
|
||||||
|
@ -1 +1 @@
|
|||||||
83b342a44ffc9ea07dc4d59f2866cefc68ee4f13
|
5063f9070afde9374ea0f2bc338fee840d8b3dd4
|
112
tool/sqldiff.c
112
tool/sqldiff.c
@ -26,6 +26,7 @@
|
|||||||
struct GlobalVars {
|
struct GlobalVars {
|
||||||
const char *zArgv0; /* Name of program */
|
const char *zArgv0; /* Name of program */
|
||||||
int bSchemaOnly; /* Only show schema differences */
|
int bSchemaOnly; /* Only show schema differences */
|
||||||
|
int bSchemaPK; /* Use the schema-defined PK, not the true PK */
|
||||||
unsigned fDebug; /* Debug flags */
|
unsigned fDebug; /* Debug flags */
|
||||||
sqlite3 *db; /* The database connection */
|
sqlite3 *db; /* The database connection */
|
||||||
} g;
|
} g;
|
||||||
@ -217,27 +218,34 @@ static void namelistFree(char **az){
|
|||||||
** hold the list is obtained from sqlite3_malloc() and should released
|
** hold the list is obtained from sqlite3_malloc() and should released
|
||||||
** using namelistFree() when no longer needed.
|
** using namelistFree() when no longer needed.
|
||||||
**
|
**
|
||||||
** Primary key columns are listed first, followed by data columns. The
|
** Primary key columns are listed first, followed by data columns.
|
||||||
** "primary key" in the previous sentence is the true primary key - the
|
** The number of columns in the primary key is returned in *pnPkey.
|
||||||
** 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.
|
|
||||||
**
|
**
|
||||||
** 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.
|
** then this routine returns a NULL pointer.
|
||||||
**
|
**
|
||||||
** Examples:
|
** Examples:
|
||||||
** CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
|
** CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
|
||||||
** *pnPKey = 1;
|
** *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));
|
** CREATE TABLE t2(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(b));
|
||||||
** *pnPKey = 1;
|
** *pnPKey = 1;
|
||||||
** az = { "b", "a", "c", 0 }
|
** az = { "b", "a", "c", 0 }
|
||||||
**
|
**
|
||||||
** CREATE TABLE t3(x,y,z,PRIMARY KEY(y,z));
|
** CREATE TABLE t3(x,y,z,PRIMARY KEY(y,z));
|
||||||
** *pnPKey = 1
|
** *pnPKey = 1 // Normal case
|
||||||
** az = { "rowid", "x", "y", "z", 0 }
|
** 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;
|
** CREATE TABLE t4(x,y,z,PRIMARY KEY(y,z)) WITHOUT ROWID;
|
||||||
** *pnPKey = 2
|
** *pnPKey = 2
|
||||||
@ -247,50 +255,72 @@ static void namelistFree(char **az){
|
|||||||
** az = 0 // The rowid is not accessible
|
** az = 0 // The rowid is not accessible
|
||||||
*/
|
*/
|
||||||
static char **columnNames(const char *zDb, const char *zTab, int *pnPKey){
|
static char **columnNames(const char *zDb, const char *zTab, int *pnPKey){
|
||||||
char **az = 0;
|
char **az = 0; /* List of column names to be returned */
|
||||||
int naz = 0;
|
int naz = 0; /* Number of entries in az[] */
|
||||||
sqlite3_stmt *pStmt;
|
sqlite3_stmt *pStmt; /* SQL statement being run */
|
||||||
char *zPkIdxName = 0; /* Name of the PRIMARY KEY index */
|
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 nPK = 0; /* Number of PRIMARY KEY columns */
|
||||||
int i, j;
|
int i, j; /* Loop counters */
|
||||||
|
|
||||||
pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
|
if( g.bSchemaPK==0 ){
|
||||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
/* Normal case: Figure out what the true primary key is for the table.
|
||||||
if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
|
** * For WITHOUT ROWID tables, the true primary key is the same as
|
||||||
zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
|
** the schema PRIMARY KEY, which is guaranteed to be present.
|
||||||
break;
|
** * 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.
|
||||||
sqlite3_finalize(pStmt);
|
*/
|
||||||
if( zPkIdxName ){
|
pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
|
||||||
int nKey = 0;
|
|
||||||
int nCol = 0;
|
|
||||||
truePk = 0;
|
|
||||||
pStmt = db_prepare("PRAGMA %s.index_xinfo=%Q", zDb, zPkIdxName);
|
|
||||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||||
nCol++;
|
if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
|
||||||
if( sqlite3_column_int(pStmt,5) ){ nKey++; continue; }
|
zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
|
||||||
if( sqlite3_column_int(pStmt,1)>=0 ) truePk = 1;
|
break;
|
||||||
}
|
}
|
||||||
if( nCol==nKey ) truePk = 1;
|
|
||||||
if( truePk ){
|
|
||||||
nPK = nKey;
|
|
||||||
}else{
|
|
||||||
nPK = 1;
|
|
||||||
}
|
}
|
||||||
sqlite3_finalize(pStmt);
|
sqlite3_finalize(pStmt);
|
||||||
sqlite3_free(zPkIdxName);
|
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;
|
||||||
|
}
|
||||||
|
pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
|
||||||
}else{
|
}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;
|
truePk = 1;
|
||||||
nPK = 1;
|
|
||||||
}
|
}
|
||||||
*pnPKey = nPK;
|
*pnPKey = nPK;
|
||||||
naz = nPK;
|
naz = nPK;
|
||||||
az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
|
az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
|
||||||
if( az==0 ) runtimeError("out of memory");
|
if( az==0 ) runtimeError("out of memory");
|
||||||
memset(az, 0, sizeof(char*)*(nPK+1));
|
memset(az, 0, sizeof(char*)*(nPK+1));
|
||||||
pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
|
|
||||||
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
while( SQLITE_ROW==sqlite3_step(pStmt) ){
|
||||||
int iPKey;
|
int iPKey;
|
||||||
if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
|
if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
|
||||||
@ -692,6 +722,7 @@ static void showHelp(void){
|
|||||||
printf(
|
printf(
|
||||||
"Output SQL text that would transform DB1 into DB2.\n"
|
"Output SQL text that would transform DB1 into DB2.\n"
|
||||||
"Options:\n"
|
"Options:\n"
|
||||||
|
" --primarykey Use schema-defined PRIMARY KEYs\n"
|
||||||
" --schema Show only differences in the schema\n"
|
" --schema Show only differences in the schema\n"
|
||||||
" --table TAB Show only differences in table TAB\n"
|
" --table TAB Show only differences in table TAB\n"
|
||||||
);
|
);
|
||||||
@ -720,6 +751,9 @@ int main(int argc, char **argv){
|
|||||||
showHelp();
|
showHelp();
|
||||||
return 0;
|
return 0;
|
||||||
}else
|
}else
|
||||||
|
if( strcmp(z,"primarykey")==0 ){
|
||||||
|
g.bSchemaPK = 1;
|
||||||
|
}else
|
||||||
if( strcmp(z,"schema")==0 ){
|
if( strcmp(z,"schema")==0 ){
|
||||||
g.bSchemaOnly = 1;
|
g.bSchemaOnly = 1;
|
||||||
}else
|
}else
|
||||||
|
Reference in New Issue
Block a user