blob: 44f05e75f9e594cfb87fcd478e5afb2429858574 [file] [log] [blame]
drhd62c0f42015-04-09 13:34:29 +00001/*
2** 2015-04-06
3**
4** The author disclaims copyright to this source code. In place of
5** a legal notice, here is a blessing:
6**
7** May you do good and not evil.
8** May you find forgiveness for yourself and forgive others.
9** May you share freely, never taking more than you give.
10**
11*************************************************************************
12**
drh50be9c42015-04-17 12:16:09 +000013** This is a utility program that computes the differences in content
drhd62c0f42015-04-09 13:34:29 +000014** between two SQLite databases.
drh50be9c42015-04-17 12:16:09 +000015**
16** To compile, simply link against SQLite.
17**
18** See the showHelp() routine below for a brief description of how to
19** run the utility.
drhd62c0f42015-04-09 13:34:29 +000020*/
21#include <stdio.h>
22#include <stdlib.h>
23#include <stdarg.h>
24#include <ctype.h>
25#include <string.h>
dana9ca8af2015-07-31 19:52:03 +000026#include <assert.h>
drhd62c0f42015-04-09 13:34:29 +000027#include "sqlite3.h"
28
29/*
30** All global variables are gathered into the "g" singleton.
31*/
32struct GlobalVars {
33 const char *zArgv0; /* Name of program */
34 int bSchemaOnly; /* Only show schema differences */
drha37591c2015-04-09 18:14:03 +000035 int bSchemaPK; /* Use the schema-defined PK, not the true PK */
dan9c987a82016-06-21 10:34:41 +000036 int bHandleVtab; /* Handle fts3, fts4, fts5 and rtree vtabs */
drhd62c0f42015-04-09 13:34:29 +000037 unsigned fDebug; /* Debug flags */
38 sqlite3 *db; /* The database connection */
39} g;
40
41/*
42** Allowed values for g.fDebug
43*/
44#define DEBUG_COLUMN_NAMES 0x000001
45#define DEBUG_DIFF_SQL 0x000002
46
47/*
48** Dynamic string object
49*/
50typedef struct Str Str;
51struct Str {
52 char *z; /* Text of the string */
53 int nAlloc; /* Bytes allocated in z[] */
54 int nUsed; /* Bytes actually used in z[] */
55};
56
57/*
58** Initialize a Str object
59*/
60static void strInit(Str *p){
61 p->z = 0;
62 p->nAlloc = 0;
63 p->nUsed = 0;
64}
65
66/*
67** Print an error resulting from faulting command-line arguments and
68** abort the program.
69*/
70static void cmdlineError(const char *zFormat, ...){
71 va_list ap;
72 fprintf(stderr, "%s: ", g.zArgv0);
73 va_start(ap, zFormat);
74 vfprintf(stderr, zFormat, ap);
75 va_end(ap);
76 fprintf(stderr, "\n\"%s --help\" for more help\n", g.zArgv0);
77 exit(1);
78}
79
80/*
81** Print an error message for an error that occurs at runtime, then
82** abort the program.
83*/
84static void runtimeError(const char *zFormat, ...){
85 va_list ap;
86 fprintf(stderr, "%s: ", g.zArgv0);
87 va_start(ap, zFormat);
88 vfprintf(stderr, zFormat, ap);
89 va_end(ap);
90 fprintf(stderr, "\n");
91 exit(1);
92}
93
94/*
95** Free all memory held by a Str object
96*/
97static void strFree(Str *p){
98 sqlite3_free(p->z);
99 strInit(p);
100}
101
102/*
103** Add formatted text to the end of a Str object
104*/
105static void strPrintf(Str *p, const char *zFormat, ...){
106 int nNew;
107 for(;;){
108 if( p->z ){
109 va_list ap;
110 va_start(ap, zFormat);
111 sqlite3_vsnprintf(p->nAlloc-p->nUsed, p->z+p->nUsed, zFormat, ap);
112 va_end(ap);
113 nNew = (int)strlen(p->z + p->nUsed);
114 }else{
115 nNew = p->nAlloc;
116 }
117 if( p->nUsed+nNew < p->nAlloc-1 ){
118 p->nUsed += nNew;
119 break;
120 }
121 p->nAlloc = p->nAlloc*2 + 1000;
122 p->z = sqlite3_realloc(p->z, p->nAlloc);
123 if( p->z==0 ) runtimeError("out of memory");
124 }
125}
126
127
128
129/* Safely quote an SQL identifier. Use the minimum amount of transformation
130** necessary to allow the string to be used with %s.
131**
132** Space to hold the returned string is obtained from sqlite3_malloc(). The
133** caller is responsible for ensuring this space is freed when no longer
134** needed.
135*/
136static char *safeId(const char *zId){
137 /* All SQLite keywords, in alphabetical order */
138 static const char *azKeywords[] = {
139 "ABORT", "ACTION", "ADD", "AFTER", "ALL", "ALTER", "ANALYZE", "AND", "AS",
140 "ASC", "ATTACH", "AUTOINCREMENT", "BEFORE", "BEGIN", "BETWEEN", "BY",
141 "CASCADE", "CASE", "CAST", "CHECK", "COLLATE", "COLUMN", "COMMIT",
142 "CONFLICT", "CONSTRAINT", "CREATE", "CROSS", "CURRENT_DATE",
143 "CURRENT_TIME", "CURRENT_TIMESTAMP", "DATABASE", "DEFAULT", "DEFERRABLE",
drh7eabc442018-04-25 17:10:30 +0000144 "DEFERRED", "DELETE", "DESC", "DETACH", "DISTINCT", "DO", "DROP", "EACH",
drhd62c0f42015-04-09 13:34:29 +0000145 "ELSE", "END", "ESCAPE", "EXCEPT", "EXCLUSIVE", "EXISTS", "EXPLAIN",
146 "FAIL", "FOR", "FOREIGN", "FROM", "FULL", "GLOB", "GROUP", "HAVING", "IF",
147 "IGNORE", "IMMEDIATE", "IN", "INDEX", "INDEXED", "INITIALLY", "INNER",
148 "INSERT", "INSTEAD", "INTERSECT", "INTO", "IS", "ISNULL", "JOIN", "KEY",
drh7eabc442018-04-25 17:10:30 +0000149 "LEFT", "LIKE", "LIMIT",
150 "MATCH", "NATURAL", "NO", "NOT", "NOTHING", "NOTNULL",
drhd62c0f42015-04-09 13:34:29 +0000151 "NULL", "OF", "OFFSET", "ON", "OR", "ORDER", "OUTER", "PLAN", "PRAGMA",
152 "PRIMARY", "QUERY", "RAISE", "RECURSIVE", "REFERENCES", "REGEXP",
153 "REINDEX", "RELEASE", "RENAME", "REPLACE", "RESTRICT", "RIGHT",
154 "ROLLBACK", "ROW", "SAVEPOINT", "SELECT", "SET", "TABLE", "TEMP",
155 "TEMPORARY", "THEN", "TO", "TRANSACTION", "TRIGGER", "UNION", "UNIQUE",
156 "UPDATE", "USING", "VACUUM", "VALUES", "VIEW", "VIRTUAL", "WHEN", "WHERE",
157 "WITH", "WITHOUT",
158 };
159 int lwr, upr, mid, c, i, x;
drh06db66f2015-11-29 21:46:19 +0000160 if( zId[0]==0 ) return sqlite3_mprintf("\"\"");
drhd62c0f42015-04-09 13:34:29 +0000161 for(i=x=0; (c = zId[i])!=0; i++){
162 if( !isalpha(c) && c!='_' ){
163 if( i>0 && isdigit(c) ){
164 x++;
165 }else{
166 return sqlite3_mprintf("\"%w\"", zId);
167 }
168 }
169 }
170 if( x ) return sqlite3_mprintf("%s", zId);
171 lwr = 0;
172 upr = sizeof(azKeywords)/sizeof(azKeywords[0]) - 1;
173 while( lwr<=upr ){
174 mid = (lwr+upr)/2;
175 c = sqlite3_stricmp(azKeywords[mid], zId);
176 if( c==0 ) return sqlite3_mprintf("\"%w\"", zId);
177 if( c<0 ){
178 lwr = mid+1;
179 }else{
180 upr = mid-1;
181 }
182 }
183 return sqlite3_mprintf("%s", zId);
184}
185
186/*
187** Prepare a new SQL statement. Print an error and abort if anything
188** goes wrong.
189*/
190static sqlite3_stmt *db_vprepare(const char *zFormat, va_list ap){
191 char *zSql;
192 int rc;
193 sqlite3_stmt *pStmt;
194
195 zSql = sqlite3_vmprintf(zFormat, ap);
196 if( zSql==0 ) runtimeError("out of memory");
197 rc = sqlite3_prepare_v2(g.db, zSql, -1, &pStmt, 0);
198 if( rc ){
199 runtimeError("SQL statement error: %s\n\"%s\"", sqlite3_errmsg(g.db),
200 zSql);
201 }
202 sqlite3_free(zSql);
203 return pStmt;
204}
205static sqlite3_stmt *db_prepare(const char *zFormat, ...){
206 va_list ap;
207 sqlite3_stmt *pStmt;
208 va_start(ap, zFormat);
209 pStmt = db_vprepare(zFormat, ap);
210 va_end(ap);
211 return pStmt;
212}
213
214/*
215** Free a list of strings
216*/
217static void namelistFree(char **az){
218 if( az ){
219 int i;
220 for(i=0; az[i]; i++) sqlite3_free(az[i]);
221 sqlite3_free(az);
222 }
223}
224
225/*
226** Return a list of column names for the table zDb.zTab. Space to
drh39b355c2015-04-09 13:40:18 +0000227** hold the list is obtained from sqlite3_malloc() and should released
228** using namelistFree() when no longer needed.
drhd62c0f42015-04-09 13:34:29 +0000229**
drha37591c2015-04-09 18:14:03 +0000230** Primary key columns are listed first, followed by data columns.
231** The number of columns in the primary key is returned in *pnPkey.
drhd62c0f42015-04-09 13:34:29 +0000232**
drha37591c2015-04-09 18:14:03 +0000233** Normally, the "primary key" in the previous sentence is the true
234** primary key - the rowid or INTEGER PRIMARY KEY for ordinary tables
235** or the declared PRIMARY KEY for WITHOUT ROWID tables. However, if
236** the g.bSchemaPK flag is set, then the schema-defined PRIMARY KEY is
237** used in all cases. In that case, entries that have NULL values in
238** any of their primary key fields will be excluded from the analysis.
239**
240** If the primary key for a table is the rowid but rowid is inaccessible,
drhd62c0f42015-04-09 13:34:29 +0000241** then this routine returns a NULL pointer.
242**
243** Examples:
244** CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
245** *pnPKey = 1;
drha37591c2015-04-09 18:14:03 +0000246** az = { "rowid", "a", "b", "c", 0 } // Normal case
247** az = { "c", "a", "b", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000248**
249** CREATE TABLE t2(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(b));
250** *pnPKey = 1;
251** az = { "b", "a", "c", 0 }
252**
253** CREATE TABLE t3(x,y,z,PRIMARY KEY(y,z));
drha37591c2015-04-09 18:14:03 +0000254** *pnPKey = 1 // Normal case
255** az = { "rowid", "x", "y", "z", 0 } // Normal case
256** *pnPKey = 2 // g.bSchemaPK==1
257** az = { "y", "x", "z", 0 } // g.bSchemaPK==1
drhd62c0f42015-04-09 13:34:29 +0000258**
259** CREATE TABLE t4(x,y,z,PRIMARY KEY(y,z)) WITHOUT ROWID;
260** *pnPKey = 2
261** az = { "y", "z", "x", 0 }
262**
263** CREATE TABLE t5(rowid,_rowid_,oid);
264** az = 0 // The rowid is not accessible
265*/
dan99461852015-07-30 20:26:16 +0000266static char **columnNames(
267 const char *zDb, /* Database ("main" or "aux") to query */
268 const char *zTab, /* Name of table to return details of */
269 int *pnPKey, /* OUT: Number of PK columns */
270 int *pbRowid /* OUT: True if PK is an implicit rowid */
271){
drha37591c2015-04-09 18:14:03 +0000272 char **az = 0; /* List of column names to be returned */
273 int naz = 0; /* Number of entries in az[] */
274 sqlite3_stmt *pStmt; /* SQL statement being run */
drhd62c0f42015-04-09 13:34:29 +0000275 char *zPkIdxName = 0; /* Name of the PRIMARY KEY index */
drha37591c2015-04-09 18:14:03 +0000276 int truePk = 0; /* PRAGMA table_info indentifies the PK to use */
drhd62c0f42015-04-09 13:34:29 +0000277 int nPK = 0; /* Number of PRIMARY KEY columns */
drha37591c2015-04-09 18:14:03 +0000278 int i, j; /* Loop counters */
drhd62c0f42015-04-09 13:34:29 +0000279
drha37591c2015-04-09 18:14:03 +0000280 if( g.bSchemaPK==0 ){
281 /* Normal case: Figure out what the true primary key is for the table.
282 ** * For WITHOUT ROWID tables, the true primary key is the same as
283 ** the schema PRIMARY KEY, which is guaranteed to be present.
284 ** * For rowid tables with an INTEGER PRIMARY KEY, the true primary
285 ** key is the INTEGER PRIMARY KEY.
286 ** * For all other rowid tables, the rowid is the true primary key.
287 */
288 pStmt = db_prepare("PRAGMA %s.index_list=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000289 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drha37591c2015-04-09 18:14:03 +0000290 if( sqlite3_stricmp((const char*)sqlite3_column_text(pStmt,3),"pk")==0 ){
291 zPkIdxName = sqlite3_mprintf("%s", sqlite3_column_text(pStmt, 1));
292 break;
293 }
drhd62c0f42015-04-09 13:34:29 +0000294 }
295 sqlite3_finalize(pStmt);
drha37591c2015-04-09 18:14:03 +0000296 if( zPkIdxName ){
297 int nKey = 0;
298 int nCol = 0;
299 truePk = 0;
300 pStmt = db_prepare("PRAGMA %s.index_xinfo=%Q", zDb, zPkIdxName);
301 while( SQLITE_ROW==sqlite3_step(pStmt) ){
302 nCol++;
303 if( sqlite3_column_int(pStmt,5) ){ nKey++; continue; }
304 if( sqlite3_column_int(pStmt,1)>=0 ) truePk = 1;
305 }
306 if( nCol==nKey ) truePk = 1;
307 if( truePk ){
308 nPK = nKey;
309 }else{
310 nPK = 1;
311 }
312 sqlite3_finalize(pStmt);
313 sqlite3_free(zPkIdxName);
314 }else{
315 truePk = 1;
316 nPK = 1;
317 }
318 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
drhd62c0f42015-04-09 13:34:29 +0000319 }else{
drha37591c2015-04-09 18:14:03 +0000320 /* The g.bSchemaPK==1 case: Use whatever primary key is declared
321 ** in the schema. The "rowid" will still be used as the primary key
322 ** if the table definition does not contain a PRIMARY KEY.
323 */
324 nPK = 0;
325 pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
326 while( SQLITE_ROW==sqlite3_step(pStmt) ){
327 if( sqlite3_column_int(pStmt,5)>0 ) nPK++;
328 }
329 sqlite3_reset(pStmt);
330 if( nPK==0 ) nPK = 1;
drhd62c0f42015-04-09 13:34:29 +0000331 truePk = 1;
drhd62c0f42015-04-09 13:34:29 +0000332 }
333 *pnPKey = nPK;
334 naz = nPK;
335 az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
336 if( az==0 ) runtimeError("out of memory");
337 memset(az, 0, sizeof(char*)*(nPK+1));
drhd62c0f42015-04-09 13:34:29 +0000338 while( SQLITE_ROW==sqlite3_step(pStmt) ){
339 int iPKey;
340 if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
341 az[iPKey-1] = safeId((char*)sqlite3_column_text(pStmt,1));
342 }else{
343 az = sqlite3_realloc(az, sizeof(char*)*(naz+2) );
344 if( az==0 ) runtimeError("out of memory");
345 az[naz++] = safeId((char*)sqlite3_column_text(pStmt,1));
346 }
347 }
348 sqlite3_finalize(pStmt);
349 if( az ) az[naz] = 0;
dan99461852015-07-30 20:26:16 +0000350
351 /* If it is non-NULL, set *pbRowid to indicate whether or not the PK of
352 ** this table is an implicit rowid (*pbRowid==1) or not (*pbRowid==0). */
353 if( pbRowid ) *pbRowid = (az[0]==0);
354
355 /* If this table has an implicit rowid for a PK, figure out how to refer
356 ** to it. There are three options - "rowid", "_rowid_" and "oid". Any
357 ** of these will work, unless the table has an explicit column of the
358 ** same name. */
drhd62c0f42015-04-09 13:34:29 +0000359 if( az[0]==0 ){
360 const char *azRowid[] = { "rowid", "_rowid_", "oid" };
361 for(i=0; i<sizeof(azRowid)/sizeof(azRowid[0]); i++){
362 for(j=1; j<naz; j++){
363 if( sqlite3_stricmp(az[j], azRowid[i])==0 ) break;
364 }
365 if( j>=naz ){
366 az[0] = sqlite3_mprintf("%s", azRowid[i]);
367 break;
368 }
369 }
370 if( az[0]==0 ){
371 for(i=1; i<naz; i++) sqlite3_free(az[i]);
372 sqlite3_free(az);
373 az = 0;
374 }
375 }
376 return az;
377}
378
379/*
380** Print the sqlite3_value X as an SQL literal.
381*/
drh8a1cd762015-04-14 19:01:08 +0000382static void printQuoted(FILE *out, sqlite3_value *X){
drhd62c0f42015-04-09 13:34:29 +0000383 switch( sqlite3_value_type(X) ){
384 case SQLITE_FLOAT: {
385 double r1;
386 char zBuf[50];
387 r1 = sqlite3_value_double(X);
388 sqlite3_snprintf(sizeof(zBuf), zBuf, "%!.15g", r1);
drh8a1cd762015-04-14 19:01:08 +0000389 fprintf(out, "%s", zBuf);
drhd62c0f42015-04-09 13:34:29 +0000390 break;
391 }
392 case SQLITE_INTEGER: {
drh8a1cd762015-04-14 19:01:08 +0000393 fprintf(out, "%lld", sqlite3_value_int64(X));
drhd62c0f42015-04-09 13:34:29 +0000394 break;
395 }
396 case SQLITE_BLOB: {
397 const unsigned char *zBlob = sqlite3_value_blob(X);
398 int nBlob = sqlite3_value_bytes(X);
399 if( zBlob ){
400 int i;
drh8a1cd762015-04-14 19:01:08 +0000401 fprintf(out, "x'");
drhd62c0f42015-04-09 13:34:29 +0000402 for(i=0; i<nBlob; i++){
drh8a1cd762015-04-14 19:01:08 +0000403 fprintf(out, "%02x", zBlob[i]);
drhd62c0f42015-04-09 13:34:29 +0000404 }
drh8a1cd762015-04-14 19:01:08 +0000405 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000406 }else{
dan12c56aa2016-09-12 14:23:51 +0000407 /* Could be an OOM, could be a zero-byte blob */
408 fprintf(out, "X''");
drhd62c0f42015-04-09 13:34:29 +0000409 }
410 break;
411 }
412 case SQLITE_TEXT: {
413 const unsigned char *zArg = sqlite3_value_text(X);
414 int i, j;
415
416 if( zArg==0 ){
drh8a1cd762015-04-14 19:01:08 +0000417 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000418 }else{
drh8a1cd762015-04-14 19:01:08 +0000419 fprintf(out, "'");
drhd62c0f42015-04-09 13:34:29 +0000420 for(i=j=0; zArg[i]; i++){
421 if( zArg[i]=='\'' ){
drh8a1cd762015-04-14 19:01:08 +0000422 fprintf(out, "%.*s'", i-j+1, &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000423 j = i+1;
424 }
425 }
drh8a1cd762015-04-14 19:01:08 +0000426 fprintf(out, "%s'", &zArg[j]);
drhd62c0f42015-04-09 13:34:29 +0000427 }
428 break;
429 }
430 case SQLITE_NULL: {
drh8a1cd762015-04-14 19:01:08 +0000431 fprintf(out, "NULL");
drhd62c0f42015-04-09 13:34:29 +0000432 break;
433 }
434 }
435}
436
437/*
438** Output SQL that will recreate the aux.zTab table.
439*/
drh8a1cd762015-04-14 19:01:08 +0000440static void dump_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000441 char *zId = safeId(zTab); /* Name of the table */
442 char **az = 0; /* List of columns */
443 int nPk; /* Number of true primary key columns */
444 int nCol; /* Number of data columns */
445 int i; /* Loop counter */
446 sqlite3_stmt *pStmt; /* SQL statement */
447 const char *zSep; /* Separator string */
448 Str ins; /* Beginning of the INSERT statement */
449
450 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master WHERE name=%Q", zTab);
451 if( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000452 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000453 }
454 sqlite3_finalize(pStmt);
455 if( !g.bSchemaOnly ){
dan99461852015-07-30 20:26:16 +0000456 az = columnNames("aux", zTab, &nPk, 0);
drhd62c0f42015-04-09 13:34:29 +0000457 strInit(&ins);
458 if( az==0 ){
459 pStmt = db_prepare("SELECT * FROM aux.%s", zId);
460 strPrintf(&ins,"INSERT INTO %s VALUES", zId);
461 }else{
462 Str sql;
463 strInit(&sql);
464 zSep = "SELECT";
465 for(i=0; az[i]; i++){
466 strPrintf(&sql, "%s %s", zSep, az[i]);
467 zSep = ",";
468 }
469 strPrintf(&sql," FROM aux.%s", zId);
470 zSep = " ORDER BY";
471 for(i=1; i<=nPk; i++){
472 strPrintf(&sql, "%s %d", zSep, i);
473 zSep = ",";
474 }
475 pStmt = db_prepare("%s", sql.z);
476 strFree(&sql);
477 strPrintf(&ins, "INSERT INTO %s", zId);
478 zSep = "(";
479 for(i=0; az[i]; i++){
480 strPrintf(&ins, "%s%s", zSep, az[i]);
481 zSep = ",";
482 }
483 strPrintf(&ins,") VALUES");
484 namelistFree(az);
485 }
486 nCol = sqlite3_column_count(pStmt);
487 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000488 fprintf(out, "%s",ins.z);
drhd62c0f42015-04-09 13:34:29 +0000489 zSep = "(";
490 for(i=0; i<nCol; i++){
drh8a1cd762015-04-14 19:01:08 +0000491 fprintf(out, "%s",zSep);
492 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000493 zSep = ",";
494 }
drh8a1cd762015-04-14 19:01:08 +0000495 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000496 }
497 sqlite3_finalize(pStmt);
498 strFree(&ins);
499 } /* endif !g.bSchemaOnly */
500 pStmt = db_prepare("SELECT sql FROM aux.sqlite_master"
501 " WHERE type='index' AND tbl_name=%Q AND sql IS NOT NULL",
502 zTab);
503 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000504 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000505 }
506 sqlite3_finalize(pStmt);
507}
508
509
510/*
511** Compute all differences for a single table.
512*/
drh8a1cd762015-04-14 19:01:08 +0000513static void diff_one_table(const char *zTab, FILE *out){
drhd62c0f42015-04-09 13:34:29 +0000514 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
515 char **az = 0; /* Columns in main */
516 char **az2 = 0; /* Columns in aux */
517 int nPk; /* Primary key columns in main */
518 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +0000519 int n = 0; /* Number of columns in main */
drhd62c0f42015-04-09 13:34:29 +0000520 int n2; /* Number of columns in aux */
521 int nQ; /* Number of output columns in the diff query */
522 int i; /* Loop counter */
523 const char *zSep; /* Separator string */
524 Str sql; /* Comparison query */
525 sqlite3_stmt *pStmt; /* Query statement to do the diff */
526
527 strInit(&sql);
528 if( g.fDebug==DEBUG_COLUMN_NAMES ){
529 /* Simply run columnNames() on all tables of the origin
530 ** database and show the results. This is used for testing
531 ** and debugging of the columnNames() function.
532 */
dan99461852015-07-30 20:26:16 +0000533 az = columnNames("aux",zTab, &nPk, 0);
drhd62c0f42015-04-09 13:34:29 +0000534 if( az==0 ){
535 printf("Rowid not accessible for %s\n", zId);
536 }else{
537 printf("%s:", zId);
538 for(i=0; az[i]; i++){
539 printf(" %s", az[i]);
540 if( i+1==nPk ) printf(" *");
541 }
542 printf("\n");
543 }
544 goto end_diff_one_table;
545 }
546
547
548 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
549 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
550 /* Table missing from second database. */
drh8a1cd762015-04-14 19:01:08 +0000551 fprintf(out, "DROP TABLE %s;\n", zId);
drhd62c0f42015-04-09 13:34:29 +0000552 }
553 goto end_diff_one_table;
554 }
555
556 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
557 /* Table missing from source */
drh8a1cd762015-04-14 19:01:08 +0000558 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000559 goto end_diff_one_table;
560 }
561
dan99461852015-07-30 20:26:16 +0000562 az = columnNames("main", zTab, &nPk, 0);
563 az2 = columnNames("aux", zTab, &nPk2, 0);
drhd62c0f42015-04-09 13:34:29 +0000564 if( az && az2 ){
drhedd22602015-11-07 18:32:17 +0000565 for(n=0; az[n] && az2[n]; n++){
drhd62c0f42015-04-09 13:34:29 +0000566 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
567 }
568 }
569 if( az==0
570 || az2==0
571 || nPk!=nPk2
572 || az[n]
573 ){
574 /* Schema mismatch */
drhedd22602015-11-07 18:32:17 +0000575 fprintf(out, "DROP TABLE %s; -- due to schema mismatch\n", zId);
drh8a1cd762015-04-14 19:01:08 +0000576 dump_table(zTab, out);
drhd62c0f42015-04-09 13:34:29 +0000577 goto end_diff_one_table;
578 }
579
580 /* Build the comparison query */
drhedd22602015-11-07 18:32:17 +0000581 for(n2=n; az2[n2]; n2++){
582 fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, safeId(az2[n2]));
583 }
drhd62c0f42015-04-09 13:34:29 +0000584 nQ = nPk2+1+2*(n2-nPk2);
585 if( n2>nPk2 ){
586 zSep = "SELECT ";
587 for(i=0; i<nPk; i++){
588 strPrintf(&sql, "%sB.%s", zSep, az[i]);
589 zSep = ", ";
590 }
591 strPrintf(&sql, ", 1%s -- changed row\n", nPk==n ? "" : ",");
592 while( az[i] ){
593 strPrintf(&sql, " A.%s IS NOT B.%s, B.%s%s\n",
drhedd22602015-11-07 18:32:17 +0000594 az[i], az2[i], az2[i], az2[i+1]==0 ? "" : ",");
595 i++;
596 }
597 while( az2[i] ){
598 strPrintf(&sql, " B.%s IS NOT NULL, B.%s%s\n",
599 az2[i], az2[i], az2[i+1]==0 ? "" : ",");
drhd62c0f42015-04-09 13:34:29 +0000600 i++;
601 }
602 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
603 zSep = " WHERE";
604 for(i=0; i<nPk; i++){
605 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
606 zSep = " AND";
607 }
608 zSep = "\n AND (";
609 while( az[i] ){
610 strPrintf(&sql, "%sA.%s IS NOT B.%s%s\n",
drhedd22602015-11-07 18:32:17 +0000611 zSep, az[i], az2[i], az2[i+1]==0 ? ")" : "");
612 zSep = " OR ";
613 i++;
614 }
615 while( az2[i] ){
616 strPrintf(&sql, "%sB.%s IS NOT NULL%s\n",
617 zSep, az2[i], az2[i+1]==0 ? ")" : "");
drhd62c0f42015-04-09 13:34:29 +0000618 zSep = " OR ";
619 i++;
620 }
621 strPrintf(&sql, " UNION ALL\n");
622 }
623 zSep = "SELECT ";
624 for(i=0; i<nPk; i++){
625 strPrintf(&sql, "%sA.%s", zSep, az[i]);
626 zSep = ", ";
627 }
628 strPrintf(&sql, ", 2%s -- deleted row\n", nPk==n ? "" : ",");
drhedd22602015-11-07 18:32:17 +0000629 while( az2[i] ){
drhd62c0f42015-04-09 13:34:29 +0000630 strPrintf(&sql, " NULL, NULL%s\n", i==n2-1 ? "" : ",");
631 i++;
632 }
633 strPrintf(&sql, " FROM main.%s A\n", zId);
634 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
635 zSep = " WHERE";
636 for(i=0; i<nPk; i++){
637 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
638 zSep = " AND";
639 }
640 strPrintf(&sql, ")\n");
641 zSep = " UNION ALL\nSELECT ";
642 for(i=0; i<nPk; i++){
643 strPrintf(&sql, "%sB.%s", zSep, az[i]);
644 zSep = ", ";
645 }
646 strPrintf(&sql, ", 3%s -- inserted row\n", nPk==n ? "" : ",");
647 while( az2[i] ){
drhedd22602015-11-07 18:32:17 +0000648 strPrintf(&sql, " 1, B.%s%s\n", az2[i], az2[i+1]==0 ? "" : ",");
drhd62c0f42015-04-09 13:34:29 +0000649 i++;
650 }
651 strPrintf(&sql, " FROM aux.%s B\n", zId);
652 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
653 zSep = " WHERE";
654 for(i=0; i<nPk; i++){
655 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
656 zSep = " AND";
657 }
658 strPrintf(&sql, ")\n ORDER BY");
659 zSep = " ";
660 for(i=1; i<=nPk; i++){
661 strPrintf(&sql, "%s%d", zSep, i);
662 zSep = ", ";
663 }
664 strPrintf(&sql, ";\n");
665
666 if( g.fDebug & DEBUG_DIFF_SQL ){
667 printf("SQL for %s:\n%s\n", zId, sql.z);
668 goto end_diff_one_table;
669 }
670
671 /* Drop indexes that are missing in the destination */
672 pStmt = db_prepare(
673 "SELECT name FROM main.sqlite_master"
674 " WHERE type='index' AND tbl_name=%Q"
675 " AND sql IS NOT NULL"
676 " AND sql NOT IN (SELECT sql FROM aux.sqlite_master"
677 " WHERE type='index' AND tbl_name=%Q"
678 " AND sql IS NOT NULL)",
679 zTab, zTab);
680 while( SQLITE_ROW==sqlite3_step(pStmt) ){
681 char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
drh8a1cd762015-04-14 19:01:08 +0000682 fprintf(out, "DROP INDEX %s;\n", z);
drhd62c0f42015-04-09 13:34:29 +0000683 sqlite3_free(z);
684 }
685 sqlite3_finalize(pStmt);
686
687 /* Run the query and output differences */
688 if( !g.bSchemaOnly ){
drh52254492016-07-08 02:14:24 +0000689 pStmt = db_prepare("%s", sql.z);
drhd62c0f42015-04-09 13:34:29 +0000690 while( SQLITE_ROW==sqlite3_step(pStmt) ){
691 int iType = sqlite3_column_int(pStmt, nPk);
692 if( iType==1 || iType==2 ){
693 if( iType==1 ){ /* Change the content of a row */
drh8a1cd762015-04-14 19:01:08 +0000694 fprintf(out, "UPDATE %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000695 zSep = " SET";
696 for(i=nPk+1; i<nQ; i+=2){
697 if( sqlite3_column_int(pStmt,i)==0 ) continue;
drh8a1cd762015-04-14 19:01:08 +0000698 fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
drhd62c0f42015-04-09 13:34:29 +0000699 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000700 printQuoted(out, sqlite3_column_value(pStmt,i+1));
drhd62c0f42015-04-09 13:34:29 +0000701 }
702 }else{ /* Delete a row */
drh8a1cd762015-04-14 19:01:08 +0000703 fprintf(out, "DELETE FROM %s", zId);
drhd62c0f42015-04-09 13:34:29 +0000704 }
705 zSep = " WHERE";
706 for(i=0; i<nPk; i++){
drh8a1cd762015-04-14 19:01:08 +0000707 fprintf(out, "%s %s=", zSep, az2[i]);
708 printQuoted(out, sqlite3_column_value(pStmt,i));
drh74504942015-11-09 12:47:04 +0000709 zSep = " AND";
drhd62c0f42015-04-09 13:34:29 +0000710 }
drh8a1cd762015-04-14 19:01:08 +0000711 fprintf(out, ";\n");
drhd62c0f42015-04-09 13:34:29 +0000712 }else{ /* Insert a row */
drh8a1cd762015-04-14 19:01:08 +0000713 fprintf(out, "INSERT INTO %s(%s", zId, az2[0]);
714 for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
715 fprintf(out, ") VALUES");
drhd62c0f42015-04-09 13:34:29 +0000716 zSep = "(";
717 for(i=0; i<nPk2; i++){
drh8a1cd762015-04-14 19:01:08 +0000718 fprintf(out, "%s", zSep);
drhd62c0f42015-04-09 13:34:29 +0000719 zSep = ",";
drh8a1cd762015-04-14 19:01:08 +0000720 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000721 }
722 for(i=nPk2+2; i<nQ; i+=2){
drh8a1cd762015-04-14 19:01:08 +0000723 fprintf(out, ",");
724 printQuoted(out, sqlite3_column_value(pStmt,i));
drhd62c0f42015-04-09 13:34:29 +0000725 }
drh8a1cd762015-04-14 19:01:08 +0000726 fprintf(out, ");\n");
drhd62c0f42015-04-09 13:34:29 +0000727 }
728 }
729 sqlite3_finalize(pStmt);
730 } /* endif !g.bSchemaOnly */
731
732 /* Create indexes that are missing in the source */
733 pStmt = db_prepare(
734 "SELECT sql FROM aux.sqlite_master"
735 " WHERE type='index' AND tbl_name=%Q"
736 " AND sql IS NOT NULL"
737 " AND sql NOT IN (SELECT sql FROM main.sqlite_master"
738 " WHERE type='index' AND tbl_name=%Q"
739 " AND sql IS NOT NULL)",
740 zTab, zTab);
741 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +0000742 fprintf(out, "%s;\n", sqlite3_column_text(pStmt,0));
drhd62c0f42015-04-09 13:34:29 +0000743 }
744 sqlite3_finalize(pStmt);
745
746end_diff_one_table:
747 strFree(&sql);
748 sqlite3_free(zId);
749 namelistFree(az);
750 namelistFree(az2);
751 return;
752}
753
754/*
dan99461852015-07-30 20:26:16 +0000755** Check that table zTab exists and has the same schema in both the "main"
756** and "aux" databases currently opened by the global db handle. If they
757** do not, output an error message on stderr and exit(1). Otherwise, if
758** the schemas do match, return control to the caller.
759*/
760static void checkSchemasMatch(const char *zTab){
761 sqlite3_stmt *pStmt = db_prepare(
762 "SELECT A.sql=B.sql FROM main.sqlite_master A, aux.sqlite_master B"
763 " WHERE A.name=%Q AND B.name=%Q", zTab, zTab
764 );
765 if( SQLITE_ROW==sqlite3_step(pStmt) ){
766 if( sqlite3_column_int(pStmt,0)==0 ){
767 runtimeError("schema changes for table %s", safeId(zTab));
768 }
769 }else{
770 runtimeError("table %s missing from one or both databases", safeId(zTab));
771 }
772 sqlite3_finalize(pStmt);
773}
774
dana9ca8af2015-07-31 19:52:03 +0000775/**************************************************************************
776** The following code is copied from fossil. It is used to generate the
777** fossil delta blobs sometimes used in RBU update records.
778*/
779
780typedef unsigned short u16;
781typedef unsigned int u32;
782typedef unsigned char u8;
783
784/*
785** The width of a hash window in bytes. The algorithm only works if this
786** is a power of 2.
787*/
788#define NHASH 16
789
790/*
791** The current state of the rolling hash.
792**
793** z[] holds the values that have been hashed. z[] is a circular buffer.
794** z[i] is the first entry and z[(i+NHASH-1)%NHASH] is the last entry of
795** the window.
796**
797** Hash.a is the sum of all elements of hash.z[]. Hash.b is a weighted
798** sum. Hash.b is z[i]*NHASH + z[i+1]*(NHASH-1) + ... + z[i+NHASH-1]*1.
799** (Each index for z[] should be module NHASH, of course. The %NHASH operator
800** is omitted in the prior expression for brevity.)
801*/
802typedef struct hash hash;
803struct hash {
804 u16 a, b; /* Hash values */
805 u16 i; /* Start of the hash window */
806 char z[NHASH]; /* The values that have been hashed */
807};
808
809/*
810** Initialize the rolling hash using the first NHASH characters of z[]
811*/
812static void hash_init(hash *pHash, const char *z){
813 u16 a, b, i;
814 a = b = 0;
815 for(i=0; i<NHASH; i++){
816 a += z[i];
817 b += (NHASH-i)*z[i];
818 pHash->z[i] = z[i];
819 }
820 pHash->a = a & 0xffff;
821 pHash->b = b & 0xffff;
822 pHash->i = 0;
823}
824
825/*
826** Advance the rolling hash by a single character "c"
827*/
828static void hash_next(hash *pHash, int c){
829 u16 old = pHash->z[pHash->i];
mistachkin1abbe282015-08-20 21:09:32 +0000830 pHash->z[pHash->i] = (char)c;
dana9ca8af2015-07-31 19:52:03 +0000831 pHash->i = (pHash->i+1)&(NHASH-1);
mistachkin1abbe282015-08-20 21:09:32 +0000832 pHash->a = pHash->a - old + (char)c;
dana9ca8af2015-07-31 19:52:03 +0000833 pHash->b = pHash->b - NHASH*old + pHash->a;
834}
835
836/*
837** Return a 32-bit hash value
838*/
839static u32 hash_32bit(hash *pHash){
840 return (pHash->a & 0xffff) | (((u32)(pHash->b & 0xffff))<<16);
841}
842
843/*
844** Write an base-64 integer into the given buffer.
845*/
846static void putInt(unsigned int v, char **pz){
847 static const char zDigits[] =
848 "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~";
849 /* 123456789 123456789 123456789 123456789 123456789 123456789 123 */
850 int i, j;
851 char zBuf[20];
852 if( v==0 ){
853 *(*pz)++ = '0';
854 return;
855 }
856 for(i=0; v>0; i++, v>>=6){
857 zBuf[i] = zDigits[v&0x3f];
858 }
859 for(j=i-1; j>=0; j--){
860 *(*pz)++ = zBuf[j];
861 }
862}
863
864/*
dana9ca8af2015-07-31 19:52:03 +0000865** Return the number digits in the base-64 representation of a positive integer
866*/
867static int digit_count(int v){
868 unsigned int i, x;
mistachkin1abbe282015-08-20 21:09:32 +0000869 for(i=1, x=64; (unsigned int)v>=x; i++, x <<= 6){}
dana9ca8af2015-07-31 19:52:03 +0000870 return i;
871}
872
873/*
874** Compute a 32-bit checksum on the N-byte buffer. Return the result.
875*/
876static unsigned int checksum(const char *zIn, size_t N){
877 const unsigned char *z = (const unsigned char *)zIn;
878 unsigned sum0 = 0;
879 unsigned sum1 = 0;
880 unsigned sum2 = 0;
881 unsigned sum3 = 0;
882 while(N >= 16){
883 sum0 += ((unsigned)z[0] + z[4] + z[8] + z[12]);
884 sum1 += ((unsigned)z[1] + z[5] + z[9] + z[13]);
885 sum2 += ((unsigned)z[2] + z[6] + z[10]+ z[14]);
886 sum3 += ((unsigned)z[3] + z[7] + z[11]+ z[15]);
887 z += 16;
888 N -= 16;
889 }
890 while(N >= 4){
891 sum0 += z[0];
892 sum1 += z[1];
893 sum2 += z[2];
894 sum3 += z[3];
895 z += 4;
896 N -= 4;
897 }
898 sum3 += (sum2 << 8) + (sum1 << 16) + (sum0 << 24);
899 switch(N){
900 case 3: sum3 += (z[2] << 8);
901 case 2: sum3 += (z[1] << 16);
902 case 1: sum3 += (z[0] << 24);
903 default: ;
904 }
905 return sum3;
906}
907
908/*
909** Create a new delta.
910**
911** The delta is written into a preallocated buffer, zDelta, which
912** should be at least 60 bytes longer than the target file, zOut.
913** The delta string will be NUL-terminated, but it might also contain
914** embedded NUL characters if either the zSrc or zOut files are
915** binary. This function returns the length of the delta string
916** in bytes, excluding the final NUL terminator character.
917**
918** Output Format:
919**
920** The delta begins with a base64 number followed by a newline. This
921** number is the number of bytes in the TARGET file. Thus, given a
922** delta file z, a program can compute the size of the output file
923** simply by reading the first line and decoding the base-64 number
924** found there. The delta_output_size() routine does exactly this.
925**
926** After the initial size number, the delta consists of a series of
927** literal text segments and commands to copy from the SOURCE file.
928** A copy command looks like this:
929**
930** NNN@MMM,
931**
932** where NNN is the number of bytes to be copied and MMM is the offset
933** into the source file of the first byte (both base-64). If NNN is 0
934** it means copy the rest of the input file. Literal text is like this:
935**
936** NNN:TTTTT
937**
938** where NNN is the number of bytes of text (base-64) and TTTTT is the text.
939**
940** The last term is of the form
941**
942** NNN;
943**
944** In this case, NNN is a 32-bit bigendian checksum of the output file
945** that can be used to verify that the delta applied correctly. All
946** numbers are in base-64.
947**
948** Pure text files generate a pure text delta. Binary files generate a
949** delta that may contain some binary data.
950**
951** Algorithm:
952**
953** The encoder first builds a hash table to help it find matching
954** patterns in the source file. 16-byte chunks of the source file
955** sampled at evenly spaced intervals are used to populate the hash
956** table.
957**
958** Next we begin scanning the target file using a sliding 16-byte
959** window. The hash of the 16-byte window in the target is used to
960** search for a matching section in the source file. When a match
961** is found, a copy command is added to the delta. An effort is
962** made to extend the matching section to regions that come before
963** and after the 16-byte hash window. A copy command is only issued
964** if the result would use less space that just quoting the text
965** literally. Literal text is added to the delta for sections that
966** do not match or which can not be encoded efficiently using copy
967** commands.
968*/
969static int rbuDeltaCreate(
970 const char *zSrc, /* The source or pattern file */
971 unsigned int lenSrc, /* Length of the source file */
972 const char *zOut, /* The target file */
973 unsigned int lenOut, /* Length of the target file */
974 char *zDelta /* Write the delta into this buffer */
975){
mistachkin1abbe282015-08-20 21:09:32 +0000976 unsigned int i, base;
dana9ca8af2015-07-31 19:52:03 +0000977 char *zOrigDelta = zDelta;
978 hash h;
979 int nHash; /* Number of hash table entries */
980 int *landmark; /* Primary hash table */
981 int *collide; /* Collision chain */
982 int lastRead = -1; /* Last byte of zSrc read by a COPY command */
983
984 /* Add the target file size to the beginning of the delta
985 */
986 putInt(lenOut, &zDelta);
987 *(zDelta++) = '\n';
988
989 /* If the source file is very small, it means that we have no
990 ** chance of ever doing a copy command. Just output a single
991 ** literal segment for the entire target and exit.
992 */
993 if( lenSrc<=NHASH ){
994 putInt(lenOut, &zDelta);
995 *(zDelta++) = ':';
996 memcpy(zDelta, zOut, lenOut);
997 zDelta += lenOut;
998 putInt(checksum(zOut, lenOut), &zDelta);
999 *(zDelta++) = ';';
drh62e63bb2016-01-14 12:23:16 +00001000 return (int)(zDelta - zOrigDelta);
dana9ca8af2015-07-31 19:52:03 +00001001 }
1002
1003 /* Compute the hash table used to locate matching sections in the
1004 ** source file.
1005 */
1006 nHash = lenSrc/NHASH;
1007 collide = sqlite3_malloc( nHash*2*sizeof(int) );
1008 landmark = &collide[nHash];
1009 memset(landmark, -1, nHash*sizeof(int));
1010 memset(collide, -1, nHash*sizeof(int));
1011 for(i=0; i<lenSrc-NHASH; i+=NHASH){
1012 int hv;
1013 hash_init(&h, &zSrc[i]);
1014 hv = hash_32bit(&h) % nHash;
1015 collide[i/NHASH] = landmark[hv];
1016 landmark[hv] = i/NHASH;
1017 }
1018
1019 /* Begin scanning the target file and generating copy commands and
1020 ** literal sections of the delta.
1021 */
1022 base = 0; /* We have already generated everything before zOut[base] */
1023 while( base+NHASH<lenOut ){
1024 int iSrc, iBlock;
mistachkin1abbe282015-08-20 21:09:32 +00001025 int bestCnt, bestOfst=0, bestLitsz=0;
dana9ca8af2015-07-31 19:52:03 +00001026 hash_init(&h, &zOut[base]);
1027 i = 0; /* Trying to match a landmark against zOut[base+i] */
1028 bestCnt = 0;
1029 while( 1 ){
1030 int hv;
1031 int limit = 250;
1032
1033 hv = hash_32bit(&h) % nHash;
1034 iBlock = landmark[hv];
1035 while( iBlock>=0 && (limit--)>0 ){
1036 /*
1037 ** The hash window has identified a potential match against
1038 ** landmark block iBlock. But we need to investigate further.
1039 **
1040 ** Look for a region in zOut that matches zSrc. Anchor the search
1041 ** at zSrc[iSrc] and zOut[base+i]. Do not include anything prior to
1042 ** zOut[base] or after zOut[outLen] nor anything after zSrc[srcLen].
1043 **
1044 ** Set cnt equal to the length of the match and set ofst so that
1045 ** zSrc[ofst] is the first element of the match. litsz is the number
1046 ** of characters between zOut[base] and the beginning of the match.
1047 ** sz will be the overhead (in bytes) needed to encode the copy
1048 ** command. Only generate copy command if the overhead of the
1049 ** copy command is less than the amount of literal text to be copied.
1050 */
1051 int cnt, ofst, litsz;
1052 int j, k, x, y;
1053 int sz;
1054
1055 /* Beginning at iSrc, match forwards as far as we can. j counts
1056 ** the number of characters that match */
1057 iSrc = iBlock*NHASH;
mistachkin1abbe282015-08-20 21:09:32 +00001058 for(
1059 j=0, x=iSrc, y=base+i;
1060 (unsigned int)x<lenSrc && (unsigned int)y<lenOut;
1061 j++, x++, y++
1062 ){
dana9ca8af2015-07-31 19:52:03 +00001063 if( zSrc[x]!=zOut[y] ) break;
1064 }
1065 j--;
1066
1067 /* Beginning at iSrc-1, match backwards as far as we can. k counts
1068 ** the number of characters that match */
mistachkin1abbe282015-08-20 21:09:32 +00001069 for(k=1; k<iSrc && (unsigned int)k<=i; k++){
dana9ca8af2015-07-31 19:52:03 +00001070 if( zSrc[iSrc-k]!=zOut[base+i-k] ) break;
1071 }
1072 k--;
1073
1074 /* Compute the offset and size of the matching region */
1075 ofst = iSrc-k;
1076 cnt = j+k+1;
1077 litsz = i-k; /* Number of bytes of literal text before the copy */
1078 /* sz will hold the number of bytes needed to encode the "insert"
1079 ** command and the copy command, not counting the "insert" text */
1080 sz = digit_count(i-k)+digit_count(cnt)+digit_count(ofst)+3;
1081 if( cnt>=sz && cnt>bestCnt ){
1082 /* Remember this match only if it is the best so far and it
1083 ** does not increase the file size */
1084 bestCnt = cnt;
1085 bestOfst = iSrc-k;
1086 bestLitsz = litsz;
1087 }
1088
1089 /* Check the next matching block */
1090 iBlock = collide[iBlock];
1091 }
1092
1093 /* We have a copy command that does not cause the delta to be larger
1094 ** than a literal insert. So add the copy command to the delta.
1095 */
1096 if( bestCnt>0 ){
1097 if( bestLitsz>0 ){
1098 /* Add an insert command before the copy */
1099 putInt(bestLitsz,&zDelta);
1100 *(zDelta++) = ':';
1101 memcpy(zDelta, &zOut[base], bestLitsz);
1102 zDelta += bestLitsz;
1103 base += bestLitsz;
1104 }
1105 base += bestCnt;
1106 putInt(bestCnt, &zDelta);
1107 *(zDelta++) = '@';
1108 putInt(bestOfst, &zDelta);
1109 *(zDelta++) = ',';
1110 if( bestOfst + bestCnt -1 > lastRead ){
1111 lastRead = bestOfst + bestCnt - 1;
1112 }
1113 bestCnt = 0;
1114 break;
1115 }
1116
1117 /* If we reach this point, it means no match is found so far */
1118 if( base+i+NHASH>=lenOut ){
1119 /* We have reached the end of the file and have not found any
1120 ** matches. Do an "insert" for everything that does not match */
1121 putInt(lenOut-base, &zDelta);
1122 *(zDelta++) = ':';
1123 memcpy(zDelta, &zOut[base], lenOut-base);
1124 zDelta += lenOut-base;
1125 base = lenOut;
1126 break;
1127 }
1128
1129 /* Advance the hash by one character. Keep looking for a match */
1130 hash_next(&h, zOut[base+i+NHASH]);
1131 i++;
1132 }
1133 }
1134 /* Output a final "insert" record to get all the text at the end of
1135 ** the file that does not match anything in the source file.
1136 */
1137 if( base<lenOut ){
1138 putInt(lenOut-base, &zDelta);
1139 *(zDelta++) = ':';
1140 memcpy(zDelta, &zOut[base], lenOut-base);
1141 zDelta += lenOut-base;
1142 }
1143 /* Output the final checksum record. */
1144 putInt(checksum(zOut, lenOut), &zDelta);
1145 *(zDelta++) = ';';
1146 sqlite3_free(collide);
drh62e63bb2016-01-14 12:23:16 +00001147 return (int)(zDelta - zOrigDelta);
dana9ca8af2015-07-31 19:52:03 +00001148}
1149
1150/*
1151** End of code copied from fossil.
1152**************************************************************************/
1153
dan99461852015-07-30 20:26:16 +00001154static void strPrintfArray(
1155 Str *pStr, /* String object to append to */
1156 const char *zSep, /* Separator string */
1157 const char *zFmt, /* Format for each entry */
1158 char **az, int n /* Array of strings & its size (or -1) */
1159){
1160 int i;
1161 for(i=0; az[i] && (i<n || n<0); i++){
1162 if( i!=0 ) strPrintf(pStr, "%s", zSep);
1163 strPrintf(pStr, zFmt, az[i], az[i], az[i]);
1164 }
1165}
1166
1167static void getRbudiffQuery(
1168 const char *zTab,
1169 char **azCol,
1170 int nPK,
1171 int bOtaRowid,
1172 Str *pSql
1173){
1174 int i;
1175
1176 /* First the newly inserted rows: **/
1177 strPrintf(pSql, "SELECT ");
1178 strPrintfArray(pSql, ", ", "%s", azCol, -1);
dana9ca8af2015-07-31 19:52:03 +00001179 strPrintf(pSql, ", 0, "); /* Set ota_control to 0 for an insert */
1180 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
dan99461852015-07-30 20:26:16 +00001181 strPrintf(pSql, " FROM aux.%Q AS n WHERE NOT EXISTS (\n", zTab);
1182 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1183 strPrintf(pSql, " main.%Q AS o WHERE ", zTab);
dane5a0cfa2016-09-01 14:03:28 +00001184 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1185 strPrintf(pSql, "\n) AND ");
1186 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001187
1188 /* Deleted rows: */
1189 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1190 strPrintfArray(pSql, ", ", "%s", azCol, nPK);
dandd688e72015-07-31 15:13:29 +00001191 if( azCol[nPK] ){
1192 strPrintf(pSql, ", ");
1193 strPrintfArray(pSql, ", ", "NULL", &azCol[nPK], -1);
1194 }
dana9ca8af2015-07-31 19:52:03 +00001195 strPrintf(pSql, ", 1, "); /* Set ota_control to 1 for a delete */
1196 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
dan99461852015-07-30 20:26:16 +00001197 strPrintf(pSql, " FROM main.%Q AS n WHERE NOT EXISTS (\n", zTab);
1198 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1199 strPrintf(pSql, " aux.%Q AS o WHERE ", zTab);
dane5a0cfa2016-09-01 14:03:28 +00001200 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1201 strPrintf(pSql, "\n) AND ");
1202 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001203
dandd688e72015-07-31 15:13:29 +00001204 /* Updated rows. If all table columns are part of the primary key, there
1205 ** can be no updates. In this case this part of the compound SELECT can
1206 ** be omitted altogether. */
1207 if( azCol[nPK] ){
1208 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1209 strPrintfArray(pSql, ", ", "n.%s", azCol, nPK);
dan99461852015-07-30 20:26:16 +00001210 strPrintf(pSql, ",\n");
dandd688e72015-07-31 15:13:29 +00001211 strPrintfArray(pSql, " ,\n",
1212 " CASE WHEN n.%s IS o.%s THEN NULL ELSE n.%s END", &azCol[nPK], -1
1213 );
dan99461852015-07-30 20:26:16 +00001214
dandd688e72015-07-31 15:13:29 +00001215 if( bOtaRowid==0 ){
1216 strPrintf(pSql, ", '");
1217 strPrintfArray(pSql, "", ".", azCol, nPK);
1218 strPrintf(pSql, "' ||\n");
1219 }else{
1220 strPrintf(pSql, ",\n");
1221 }
1222 strPrintfArray(pSql, " ||\n",
1223 " CASE WHEN n.%s IS o.%s THEN '.' ELSE 'x' END", &azCol[nPK], -1
1224 );
dana9ca8af2015-07-31 19:52:03 +00001225 strPrintf(pSql, "\nAS ota_control, ");
1226 strPrintfArray(pSql, ", ", "NULL", azCol, nPK);
1227 strPrintf(pSql, ",\n");
1228 strPrintfArray(pSql, " ,\n",
1229 " CASE WHEN n.%s IS o.%s THEN NULL ELSE o.%s END", &azCol[nPK], -1
1230 );
dandd688e72015-07-31 15:13:29 +00001231
1232 strPrintf(pSql, "\nFROM main.%Q AS o, aux.%Q AS n\nWHERE ", zTab, zTab);
dane5a0cfa2016-09-01 14:03:28 +00001233 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
dandd688e72015-07-31 15:13:29 +00001234 strPrintf(pSql, " AND ota_control LIKE '%%x%%'");
1235 }
dan99461852015-07-30 20:26:16 +00001236
1237 /* Now add an ORDER BY clause to sort everything by PK. */
1238 strPrintf(pSql, "\nORDER BY ");
1239 for(i=1; i<=nPK; i++) strPrintf(pSql, "%s%d", ((i>1)?", ":""), i);
1240}
1241
1242static void rbudiff_one_table(const char *zTab, FILE *out){
1243 int bOtaRowid; /* True to use an ota_rowid column */
1244 int nPK; /* Number of primary key columns in table */
1245 char **azCol; /* NULL terminated array of col names */
1246 int i;
1247 int nCol;
1248 Str ct = {0, 0, 0}; /* The "CREATE TABLE data_xxx" statement */
1249 Str sql = {0, 0, 0}; /* Query to find differences */
1250 Str insert = {0, 0, 0}; /* First part of output INSERT statement */
1251 sqlite3_stmt *pStmt = 0;
danfebfe022016-03-19 16:21:26 +00001252 int nRow = 0; /* Total rows in data_xxx table */
dan99461852015-07-30 20:26:16 +00001253
1254 /* --rbu mode must use real primary keys. */
1255 g.bSchemaPK = 1;
1256
1257 /* Check that the schemas of the two tables match. Exit early otherwise. */
1258 checkSchemasMatch(zTab);
1259
1260 /* Grab the column names and PK details for the table(s). If no usable PK
1261 ** columns are found, bail out early. */
1262 azCol = columnNames("main", zTab, &nPK, &bOtaRowid);
1263 if( azCol==0 ){
1264 runtimeError("table %s has no usable PK columns", zTab);
1265 }
dana9ca8af2015-07-31 19:52:03 +00001266 for(nCol=0; azCol[nCol]; nCol++);
dan99461852015-07-30 20:26:16 +00001267
1268 /* Build and output the CREATE TABLE statement for the data_xxx table */
1269 strPrintf(&ct, "CREATE TABLE IF NOT EXISTS 'data_%q'(", zTab);
1270 if( bOtaRowid ) strPrintf(&ct, "rbu_rowid, ");
1271 strPrintfArray(&ct, ", ", "%s", &azCol[bOtaRowid], -1);
1272 strPrintf(&ct, ", rbu_control);");
1273
dan99461852015-07-30 20:26:16 +00001274 /* Get the SQL for the query to retrieve data from the two databases */
1275 getRbudiffQuery(zTab, azCol, nPK, bOtaRowid, &sql);
1276
1277 /* Build the first part of the INSERT statement output for each row
1278 ** in the data_xxx table. */
1279 strPrintf(&insert, "INSERT INTO 'data_%q' (", zTab);
1280 if( bOtaRowid ) strPrintf(&insert, "rbu_rowid, ");
1281 strPrintfArray(&insert, ", ", "%s", &azCol[bOtaRowid], -1);
1282 strPrintf(&insert, ", rbu_control) VALUES(");
1283
1284 pStmt = db_prepare("%s", sql.z);
dana9ca8af2015-07-31 19:52:03 +00001285
dan99461852015-07-30 20:26:16 +00001286 while( sqlite3_step(pStmt)==SQLITE_ROW ){
dana9ca8af2015-07-31 19:52:03 +00001287
1288 /* If this is the first row output, print out the CREATE TABLE
1289 ** statement first. And then set ct.z to NULL so that it is not
1290 ** printed again. */
dan99461852015-07-30 20:26:16 +00001291 if( ct.z ){
1292 fprintf(out, "%s\n", ct.z);
1293 strFree(&ct);
1294 }
1295
dana9ca8af2015-07-31 19:52:03 +00001296 /* Output the first part of the INSERT statement */
dan99461852015-07-30 20:26:16 +00001297 fprintf(out, "%s", insert.z);
danfebfe022016-03-19 16:21:26 +00001298 nRow++;
dana9ca8af2015-07-31 19:52:03 +00001299
1300 if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){
1301 for(i=0; i<=nCol; i++){
1302 if( i>0 ) fprintf(out, ", ");
1303 printQuoted(out, sqlite3_column_value(pStmt, i));
1304 }
1305 }else{
1306 char *zOtaControl;
1307 int nOtaControl = sqlite3_column_bytes(pStmt, nCol);
1308
dan6ff46272016-08-11 09:55:55 +00001309 zOtaControl = (char*)sqlite3_malloc(nOtaControl+1);
dana9ca8af2015-07-31 19:52:03 +00001310 memcpy(zOtaControl, sqlite3_column_text(pStmt, nCol), nOtaControl+1);
1311
1312 for(i=0; i<nCol; i++){
1313 int bDone = 0;
1314 if( i>=nPK
1315 && sqlite3_column_type(pStmt, i)==SQLITE_BLOB
1316 && sqlite3_column_type(pStmt, nCol+1+i)==SQLITE_BLOB
1317 ){
1318 const char *aSrc = sqlite3_column_blob(pStmt, nCol+1+i);
1319 int nSrc = sqlite3_column_bytes(pStmt, nCol+1+i);
1320 const char *aFinal = sqlite3_column_blob(pStmt, i);
1321 int nFinal = sqlite3_column_bytes(pStmt, i);
1322 char *aDelta;
1323 int nDelta;
1324
1325 aDelta = sqlite3_malloc(nFinal + 60);
1326 nDelta = rbuDeltaCreate(aSrc, nSrc, aFinal, nFinal, aDelta);
1327 if( nDelta<nFinal ){
1328 int j;
1329 fprintf(out, "x'");
1330 for(j=0; j<nDelta; j++) fprintf(out, "%02x", (u8)aDelta[j]);
1331 fprintf(out, "'");
1332 zOtaControl[i-bOtaRowid] = 'f';
1333 bDone = 1;
1334 }
1335 sqlite3_free(aDelta);
1336 }
1337
1338 if( bDone==0 ){
1339 printQuoted(out, sqlite3_column_value(pStmt, i));
1340 }
1341 fprintf(out, ", ");
1342 }
1343 fprintf(out, "'%s'", zOtaControl);
1344 sqlite3_free(zOtaControl);
dan99461852015-07-30 20:26:16 +00001345 }
dana9ca8af2015-07-31 19:52:03 +00001346
1347 /* And the closing bracket of the insert statement */
dan99461852015-07-30 20:26:16 +00001348 fprintf(out, ");\n");
1349 }
1350
1351 sqlite3_finalize(pStmt);
danfebfe022016-03-19 16:21:26 +00001352 if( nRow>0 ){
1353 Str cnt = {0, 0, 0};
1354 strPrintf(&cnt, "INSERT INTO rbu_count VALUES('data_%q', %d);", zTab, nRow);
1355 fprintf(out, "%s\n", cnt.z);
1356 strFree(&cnt);
1357 }
dan99461852015-07-30 20:26:16 +00001358
1359 strFree(&ct);
1360 strFree(&sql);
1361 strFree(&insert);
1362}
1363
1364/*
drh8a1cd762015-04-14 19:01:08 +00001365** Display a summary of differences between two versions of the same
1366** table table.
1367**
1368** * Number of rows changed
1369** * Number of rows added
1370** * Number of rows deleted
1371** * Number of identical rows
1372*/
1373static void summarize_one_table(const char *zTab, FILE *out){
1374 char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
1375 char **az = 0; /* Columns in main */
1376 char **az2 = 0; /* Columns in aux */
1377 int nPk; /* Primary key columns in main */
1378 int nPk2; /* Primary key columns in aux */
drhb3f3d642015-04-25 18:39:21 +00001379 int n = 0; /* Number of columns in main */
drh8a1cd762015-04-14 19:01:08 +00001380 int n2; /* Number of columns in aux */
1381 int i; /* Loop counter */
1382 const char *zSep; /* Separator string */
1383 Str sql; /* Comparison query */
1384 sqlite3_stmt *pStmt; /* Query statement to do the diff */
1385 sqlite3_int64 nUpdate; /* Number of updated rows */
1386 sqlite3_int64 nUnchanged; /* Number of unmodified rows */
1387 sqlite3_int64 nDelete; /* Number of deleted rows */
1388 sqlite3_int64 nInsert; /* Number of inserted rows */
1389
1390 strInit(&sql);
1391 if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
1392 if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
1393 /* Table missing from second database. */
1394 fprintf(out, "%s: missing from second database\n", zTab);
1395 }
1396 goto end_summarize_one_table;
1397 }
1398
1399 if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
1400 /* Table missing from source */
1401 fprintf(out, "%s: missing from first database\n", zTab);
1402 goto end_summarize_one_table;
1403 }
1404
dan99461852015-07-30 20:26:16 +00001405 az = columnNames("main", zTab, &nPk, 0);
1406 az2 = columnNames("aux", zTab, &nPk2, 0);
drh8a1cd762015-04-14 19:01:08 +00001407 if( az && az2 ){
1408 for(n=0; az[n]; n++){
1409 if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
1410 }
1411 }
1412 if( az==0
1413 || az2==0
1414 || nPk!=nPk2
1415 || az[n]
1416 ){
1417 /* Schema mismatch */
1418 fprintf(out, "%s: incompatible schema\n", zTab);
1419 goto end_summarize_one_table;
1420 }
1421
1422 /* Build the comparison query */
1423 for(n2=n; az[n2]; n2++){}
1424 strPrintf(&sql, "SELECT 1, count(*)");
1425 if( n2==nPk2 ){
1426 strPrintf(&sql, ", 0\n");
1427 }else{
1428 zSep = ", sum(";
1429 for(i=nPk; az[i]; i++){
1430 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, az[i], az[i]);
1431 zSep = " OR ";
1432 }
1433 strPrintf(&sql, ")\n");
1434 }
1435 strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId);
1436 zSep = " WHERE";
1437 for(i=0; i<nPk; i++){
1438 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1439 zSep = " AND";
1440 }
1441 strPrintf(&sql, " UNION ALL\n");
1442 strPrintf(&sql, "SELECT 2, count(*), 0\n");
1443 strPrintf(&sql, " FROM main.%s A\n", zId);
1444 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B ", zId);
1445 zSep = "WHERE";
1446 for(i=0; i<nPk; i++){
1447 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1448 zSep = " AND";
1449 }
1450 strPrintf(&sql, ")\n");
1451 strPrintf(&sql, " UNION ALL\n");
1452 strPrintf(&sql, "SELECT 3, count(*), 0\n");
1453 strPrintf(&sql, " FROM aux.%s B\n", zId);
1454 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A ", zId);
1455 zSep = "WHERE";
1456 for(i=0; i<nPk; i++){
1457 strPrintf(&sql, "%s A.%s=B.%s", zSep, az[i], az[i]);
1458 zSep = " AND";
1459 }
1460 strPrintf(&sql, ")\n ORDER BY 1;\n");
1461
1462 if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
1463 printf("SQL for %s:\n%s\n", zId, sql.z);
1464 goto end_summarize_one_table;
1465 }
1466
1467 /* Run the query and output difference summary */
drh52254492016-07-08 02:14:24 +00001468 pStmt = db_prepare("%s", sql.z);
drh8a1cd762015-04-14 19:01:08 +00001469 nUpdate = 0;
1470 nInsert = 0;
1471 nDelete = 0;
1472 nUnchanged = 0;
1473 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1474 switch( sqlite3_column_int(pStmt,0) ){
1475 case 1:
1476 nUpdate = sqlite3_column_int64(pStmt,2);
1477 nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate;
1478 break;
1479 case 2:
1480 nDelete = sqlite3_column_int64(pStmt,1);
1481 break;
1482 case 3:
1483 nInsert = sqlite3_column_int64(pStmt,1);
1484 break;
1485 }
1486 }
1487 sqlite3_finalize(pStmt);
1488 fprintf(out, "%s: %lld changes, %lld inserts, %lld deletes, %lld unchanged\n",
1489 zTab, nUpdate, nInsert, nDelete, nUnchanged);
1490
1491end_summarize_one_table:
1492 strFree(&sql);
1493 sqlite3_free(zId);
1494 namelistFree(az);
1495 namelistFree(az2);
1496 return;
1497}
1498
1499/*
drh697e5db2015-04-11 12:07:40 +00001500** Write a 64-bit signed integer as a varint onto out
1501*/
1502static void putsVarint(FILE *out, sqlite3_uint64 v){
1503 int i, n;
drh6e42ce42015-04-11 13:48:01 +00001504 unsigned char p[12];
drh697e5db2015-04-11 12:07:40 +00001505 if( v & (((sqlite3_uint64)0xff000000)<<32) ){
1506 p[8] = (unsigned char)v;
1507 v >>= 8;
1508 for(i=7; i>=0; i--){
1509 p[i] = (unsigned char)((v & 0x7f) | 0x80);
1510 v >>= 7;
1511 }
1512 fwrite(p, 8, 1, out);
1513 }else{
1514 n = 9;
1515 do{
1516 p[n--] = (unsigned char)((v & 0x7f) | 0x80);
1517 v >>= 7;
1518 }while( v!=0 );
drh6e42ce42015-04-11 13:48:01 +00001519 p[9] &= 0x7f;
1520 fwrite(p+n+1, 9-n, 1, out);
1521 }
1522}
1523
1524/*
1525** Write an SQLite value onto out.
1526*/
1527static void putValue(FILE *out, sqlite3_value *pVal){
1528 int iDType = sqlite3_value_type(pVal);
1529 sqlite3_int64 iX;
1530 double rX;
1531 sqlite3_uint64 uX;
1532 int j;
1533
1534 putc(iDType, out);
1535 switch( iDType ){
1536 case SQLITE_INTEGER:
1537 iX = sqlite3_value_int64(pVal);
1538 memcpy(&uX, &iX, 8);
1539 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
1540 break;
1541 case SQLITE_FLOAT:
drh33aa4db2015-05-04 15:04:47 +00001542 rX = sqlite3_value_double(pVal);
drh6e42ce42015-04-11 13:48:01 +00001543 memcpy(&uX, &rX, 8);
1544 for(j=56; j>=0; j-=8) putc((uX>>j)&0xff, out);
1545 break;
1546 case SQLITE_TEXT:
1547 iX = sqlite3_value_bytes(pVal);
1548 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +00001549 fwrite(sqlite3_value_text(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +00001550 break;
1551 case SQLITE_BLOB:
1552 iX = sqlite3_value_bytes(pVal);
1553 putsVarint(out, (sqlite3_uint64)iX);
drh33aa4db2015-05-04 15:04:47 +00001554 fwrite(sqlite3_value_blob(pVal),1,(size_t)iX,out);
drh6e42ce42015-04-11 13:48:01 +00001555 break;
1556 case SQLITE_NULL:
1557 break;
drh697e5db2015-04-11 12:07:40 +00001558 }
1559}
1560
1561/*
drh83e63dc2015-04-10 19:41:18 +00001562** Generate a CHANGESET for all differences from main.zTab to aux.zTab.
1563*/
1564static void changeset_one_table(const char *zTab, FILE *out){
1565 sqlite3_stmt *pStmt; /* SQL statment */
1566 char *zId = safeId(zTab); /* Escaped name of the table */
1567 char **azCol = 0; /* List of escaped column names */
1568 int nCol = 0; /* Number of columns */
1569 int *aiFlg = 0; /* 0 if column is not part of PK */
1570 int *aiPk = 0; /* Column numbers for each PK column */
1571 int nPk = 0; /* Number of PRIMARY KEY columns */
1572 Str sql; /* SQL for the diff query */
drh6e42ce42015-04-11 13:48:01 +00001573 int i, k; /* Loop counters */
drh83e63dc2015-04-10 19:41:18 +00001574 const char *zSep; /* List separator */
1575
dan99461852015-07-30 20:26:16 +00001576 /* Check that the schemas of the two tables match. Exit early otherwise. */
1577 checkSchemasMatch(zTab);
1578
drh83e63dc2015-04-10 19:41:18 +00001579 pStmt = db_prepare("PRAGMA main.table_info=%Q", zTab);
1580 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1581 nCol++;
1582 azCol = sqlite3_realloc(azCol, sizeof(char*)*nCol);
1583 if( azCol==0 ) runtimeError("out of memory");
1584 aiFlg = sqlite3_realloc(aiFlg, sizeof(int)*nCol);
1585 if( aiFlg==0 ) runtimeError("out of memory");
1586 azCol[nCol-1] = safeId((const char*)sqlite3_column_text(pStmt,1));
1587 aiFlg[nCol-1] = i = sqlite3_column_int(pStmt,5);
1588 if( i>0 ){
1589 if( i>nPk ){
1590 nPk = i;
1591 aiPk = sqlite3_realloc(aiPk, sizeof(int)*nPk);
1592 if( aiPk==0 ) runtimeError("out of memory");
1593 }
1594 aiPk[i-1] = nCol-1;
1595 }
1596 }
1597 sqlite3_finalize(pStmt);
1598 if( nPk==0 ) goto end_changeset_one_table;
1599 strInit(&sql);
1600 if( nCol>nPk ){
drh697e5db2015-04-11 12:07:40 +00001601 strPrintf(&sql, "SELECT %d", SQLITE_UPDATE);
drh6e42ce42015-04-11 13:48:01 +00001602 for(i=0; i<nCol; i++){
1603 if( aiFlg[i] ){
1604 strPrintf(&sql, ",\n A.%s", azCol[i]);
1605 }else{
1606 strPrintf(&sql, ",\n A.%s IS NOT B.%s, A.%s, B.%s",
1607 azCol[i], azCol[i], azCol[i], azCol[i]);
1608 }
1609 }
drh83e63dc2015-04-10 19:41:18 +00001610 strPrintf(&sql,"\n FROM main.%s A, aux.%s B\n", zId, zId);
1611 zSep = " WHERE";
1612 for(i=0; i<nPk; i++){
1613 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1614 zSep = " AND";
1615 }
1616 zSep = "\n AND (";
1617 for(i=0; i<nCol; i++){
1618 if( aiFlg[i] ) continue;
1619 strPrintf(&sql, "%sA.%s IS NOT B.%s", zSep, azCol[i], azCol[i]);
1620 zSep = " OR\n ";
1621 }
1622 strPrintf(&sql,")\n UNION ALL\n");
1623 }
drh697e5db2015-04-11 12:07:40 +00001624 strPrintf(&sql, "SELECT %d", SQLITE_DELETE);
drh6e42ce42015-04-11 13:48:01 +00001625 for(i=0; i<nCol; i++){
1626 if( aiFlg[i] ){
1627 strPrintf(&sql, ",\n A.%s", azCol[i]);
1628 }else{
1629 strPrintf(&sql, ",\n 1, A.%s, NULL", azCol[i]);
1630 }
1631 }
1632 strPrintf(&sql, "\n FROM main.%s A\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001633 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM aux.%s B\n", zId);
1634 zSep = " WHERE";
1635 for(i=0; i<nPk; i++){
1636 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1637 zSep = " AND";
1638 }
1639 strPrintf(&sql, ")\n UNION ALL\n");
drh697e5db2015-04-11 12:07:40 +00001640 strPrintf(&sql, "SELECT %d", SQLITE_INSERT);
drh6e42ce42015-04-11 13:48:01 +00001641 for(i=0; i<nCol; i++){
1642 if( aiFlg[i] ){
1643 strPrintf(&sql, ",\n B.%s", azCol[i]);
1644 }else{
1645 strPrintf(&sql, ",\n 1, NULL, B.%s", azCol[i]);
1646 }
1647 }
1648 strPrintf(&sql, "\n FROM aux.%s B\n", zId);
drh83e63dc2015-04-10 19:41:18 +00001649 strPrintf(&sql, " WHERE NOT EXISTS(SELECT 1 FROM main.%s A\n", zId);
1650 zSep = " WHERE";
1651 for(i=0; i<nPk; i++){
1652 strPrintf(&sql, "%s A.%s=B.%s", zSep, azCol[aiPk[i]], azCol[aiPk[i]]);
1653 zSep = " AND";
1654 }
1655 strPrintf(&sql, ")\n");
1656 strPrintf(&sql, " ORDER BY");
1657 zSep = " ";
1658 for(i=0; i<nPk; i++){
drh6e42ce42015-04-11 13:48:01 +00001659 strPrintf(&sql, "%s %d", zSep, aiPk[i]+2);
drh83e63dc2015-04-10 19:41:18 +00001660 zSep = ",";
1661 }
1662 strPrintf(&sql, ";\n");
1663
drh697e5db2015-04-11 12:07:40 +00001664 if( g.fDebug & DEBUG_DIFF_SQL ){
1665 printf("SQL for %s:\n%s\n", zId, sql.z);
1666 goto end_changeset_one_table;
1667 }
1668
1669 putc('T', out);
1670 putsVarint(out, (sqlite3_uint64)nCol);
dan07d0f152017-05-22 18:09:00 +00001671 for(i=0; i<nCol; i++) putc(aiFlg[i], out);
drh697e5db2015-04-11 12:07:40 +00001672 fwrite(zTab, 1, strlen(zTab), out);
1673 putc(0, out);
1674
1675 pStmt = db_prepare("%s", sql.z);
1676 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1677 int iType = sqlite3_column_int(pStmt,0);
drh697e5db2015-04-11 12:07:40 +00001678 putc(iType, out);
1679 putc(0, out);
drh6e42ce42015-04-11 13:48:01 +00001680 switch( sqlite3_column_int(pStmt,0) ){
1681 case SQLITE_UPDATE: {
1682 for(k=1, i=0; i<nCol; i++){
1683 if( aiFlg[i] ){
1684 putValue(out, sqlite3_column_value(pStmt,k));
1685 k++;
1686 }else if( sqlite3_column_int(pStmt,k) ){
1687 putValue(out, sqlite3_column_value(pStmt,k+1));
1688 k += 3;
1689 }else{
1690 putc(0, out);
1691 k += 3;
1692 }
1693 }
1694 for(k=1, i=0; i<nCol; i++){
1695 if( aiFlg[i] ){
1696 putc(0, out);
1697 k++;
1698 }else if( sqlite3_column_int(pStmt,k) ){
1699 putValue(out, sqlite3_column_value(pStmt,k+2));
1700 k += 3;
1701 }else{
1702 putc(0, out);
1703 k += 3;
1704 }
1705 }
1706 break;
1707 }
1708 case SQLITE_INSERT: {
1709 for(k=1, i=0; i<nCol; i++){
1710 if( aiFlg[i] ){
1711 putValue(out, sqlite3_column_value(pStmt,k));
1712 k++;
1713 }else{
1714 putValue(out, sqlite3_column_value(pStmt,k+2));
1715 k += 3;
1716 }
1717 }
1718 break;
1719 }
1720 case SQLITE_DELETE: {
1721 for(k=1, i=0; i<nCol; i++){
1722 if( aiFlg[i] ){
1723 putValue(out, sqlite3_column_value(pStmt,k));
1724 k++;
1725 }else{
1726 putValue(out, sqlite3_column_value(pStmt,k+1));
1727 k += 3;
1728 }
1729 }
1730 break;
drh697e5db2015-04-11 12:07:40 +00001731 }
1732 }
1733 }
1734 sqlite3_finalize(pStmt);
drh83e63dc2015-04-10 19:41:18 +00001735
1736end_changeset_one_table:
1737 while( nCol>0 ) sqlite3_free(azCol[--nCol]);
1738 sqlite3_free(azCol);
1739 sqlite3_free(aiPk);
1740 sqlite3_free(zId);
1741}
1742
1743/*
dan9c987a82016-06-21 10:34:41 +00001744** Extract the next SQL keyword or quoted string from buffer zIn and copy it
1745** (or a prefix of it if it will not fit) into buffer zBuf, size nBuf bytes.
1746** Return a pointer to the character within zIn immediately following
1747** the token or quoted string just extracted.
1748*/
1749const char *gobble_token(const char *zIn, char *zBuf, int nBuf){
1750 const char *p = zIn;
1751 char *pOut = zBuf;
1752 char *pEnd = &pOut[nBuf-1];
1753 char q = 0; /* quote character, if any */
1754
1755 if( p==0 ) return 0;
1756 while( *p==' ' ) p++;
1757 switch( *p ){
1758 case '"': q = '"'; break;
1759 case '\'': q = '\''; break;
1760 case '`': q = '`'; break;
1761 case '[': q = ']'; break;
1762 }
1763
1764 if( q ){
1765 p++;
1766 while( *p && pOut<pEnd ){
1767 if( *p==q ){
1768 p++;
1769 if( *p!=q ) break;
1770 }
1771 if( pOut<pEnd ) *pOut++ = *p;
1772 p++;
1773 }
1774 }else{
1775 while( *p && *p!=' ' && *p!='(' ){
1776 if( pOut<pEnd ) *pOut++ = *p;
1777 p++;
1778 }
1779 }
1780
1781 *pOut = '\0';
1782 return p;
1783}
1784
1785/*
1786** This function is the implementation of SQL scalar function "module_name":
1787**
1788** module_name(SQL)
1789**
1790** The only argument should be an SQL statement of the type that may appear
1791** in the sqlite_master table. If the statement is a "CREATE VIRTUAL TABLE"
1792** statement, then the value returned is the name of the module that it
1793** uses. Otherwise, if the statement is not a CVT, NULL is returned.
1794*/
1795static void module_name_func(
1796 sqlite3_context *pCtx,
1797 int nVal, sqlite3_value **apVal
1798){
1799 const char *zSql;
1800 char zToken[32];
1801
1802 assert( nVal==1 );
1803 zSql = (const char*)sqlite3_value_text(apVal[0]);
1804
1805 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1806 if( zSql==0 || sqlite3_stricmp(zToken, "create") ) return;
1807 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1808 if( zSql==0 || sqlite3_stricmp(zToken, "virtual") ) return;
1809 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1810 if( zSql==0 || sqlite3_stricmp(zToken, "table") ) return;
1811 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1812 if( zSql==0 ) return;
1813 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1814 if( zSql==0 || sqlite3_stricmp(zToken, "using") ) return;
1815 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1816
1817 sqlite3_result_text(pCtx, zToken, -1, SQLITE_TRANSIENT);
1818}
1819
1820/*
1821** Return the text of an SQL statement that itself returns the list of
1822** tables to process within the database.
1823*/
1824const char *all_tables_sql(){
1825 if( g.bHandleVtab ){
1826 int rc;
1827
1828 rc = sqlite3_exec(g.db,
dan12ca5ac2016-07-22 10:09:26 +00001829 "CREATE TEMP TABLE tblmap(module COLLATE nocase, postfix);"
dan9c987a82016-06-21 10:34:41 +00001830 "INSERT INTO temp.tblmap VALUES"
1831 "('fts3', '_content'), ('fts3', '_segments'), ('fts3', '_segdir'),"
1832
1833 "('fts4', '_content'), ('fts4', '_segments'), ('fts4', '_segdir'),"
1834 "('fts4', '_docsize'), ('fts4', '_stat'),"
1835
1836 "('fts5', '_data'), ('fts5', '_idx'), ('fts5', '_content'),"
1837 "('fts5', '_docsize'), ('fts5', '_config'),"
1838
1839 "('rtree', '_node'), ('rtree', '_rowid'), ('rtree', '_parent');"
1840 , 0, 0, 0
1841 );
1842 assert( rc==SQLITE_OK );
1843
1844 rc = sqlite3_create_function(
1845 g.db, "module_name", 1, SQLITE_UTF8, 0, module_name_func, 0, 0
1846 );
1847 assert( rc==SQLITE_OK );
1848
1849 return
1850 "SELECT name FROM main.sqlite_master\n"
1851 " WHERE type='table' AND (\n"
1852 " module_name(sql) IS NULL OR \n"
1853 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1854 " ) AND name NOT IN (\n"
1855 " SELECT a.name || b.postfix \n"
1856 "FROM main.sqlite_master AS a, temp.tblmap AS b \n"
1857 "WHERE module_name(a.sql) = b.module\n"
1858 " )\n"
1859 "UNION \n"
1860 "SELECT name FROM aux.sqlite_master\n"
1861 " WHERE type='table' AND (\n"
1862 " module_name(sql) IS NULL OR \n"
1863 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1864 " ) AND name NOT IN (\n"
1865 " SELECT a.name || b.postfix \n"
1866 "FROM aux.sqlite_master AS a, temp.tblmap AS b \n"
1867 "WHERE module_name(a.sql) = b.module\n"
1868 " )\n"
1869 " ORDER BY name";
1870 }else{
1871 return
1872 "SELECT name FROM main.sqlite_master\n"
1873 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1874 " UNION\n"
1875 "SELECT name FROM aux.sqlite_master\n"
1876 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1877 " ORDER BY name";
1878 }
1879}
1880
1881/*
drhd62c0f42015-04-09 13:34:29 +00001882** Print sketchy documentation for this utility program
1883*/
1884static void showHelp(void){
1885 printf("Usage: %s [options] DB1 DB2\n", g.zArgv0);
1886 printf(
1887"Output SQL text that would transform DB1 into DB2.\n"
1888"Options:\n"
drh83e63dc2015-04-10 19:41:18 +00001889" --changeset FILE Write a CHANGESET into FILE\n"
drh9a9219f2015-05-04 13:25:56 +00001890" -L|--lib LIBRARY Load an SQLite extension library\n"
drha37591c2015-04-09 18:14:03 +00001891" --primarykey Use schema-defined PRIMARY KEYs\n"
dan99461852015-07-30 20:26:16 +00001892" --rbu Output SQL to create/populate RBU table(s)\n"
drhd62c0f42015-04-09 13:34:29 +00001893" --schema Show only differences in the schema\n"
drh8a1cd762015-04-14 19:01:08 +00001894" --summary Show only a summary of the differences\n"
drhd62c0f42015-04-09 13:34:29 +00001895" --table TAB Show only differences in table TAB\n"
drh05d4ebf2015-11-13 13:15:42 +00001896" --transaction Show SQL output inside a transaction\n"
dan9c987a82016-06-21 10:34:41 +00001897" --vtab Handle fts3, fts4, fts5 and rtree tables\n"
drhd62c0f42015-04-09 13:34:29 +00001898 );
1899}
1900
1901int main(int argc, char **argv){
1902 const char *zDb1 = 0;
1903 const char *zDb2 = 0;
1904 int i;
1905 int rc;
1906 char *zErrMsg = 0;
1907 char *zSql;
1908 sqlite3_stmt *pStmt;
1909 char *zTab = 0;
drh8a1cd762015-04-14 19:01:08 +00001910 FILE *out = stdout;
1911 void (*xDiff)(const char*,FILE*) = diff_one_table;
drh9493caf2016-03-17 23:16:37 +00001912#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001913 int nExt = 0;
drh33aa4db2015-05-04 15:04:47 +00001914 char **azExt = 0;
drh9493caf2016-03-17 23:16:37 +00001915#endif
drh05d4ebf2015-11-13 13:15:42 +00001916 int useTransaction = 0;
1917 int neverUseTransaction = 0;
drhd62c0f42015-04-09 13:34:29 +00001918
1919 g.zArgv0 = argv[0];
drhaa62e482015-05-12 00:46:40 +00001920 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
drhd62c0f42015-04-09 13:34:29 +00001921 for(i=1; i<argc; i++){
1922 const char *z = argv[i];
1923 if( z[0]=='-' ){
1924 z++;
1925 if( z[0]=='-' ) z++;
drh83e63dc2015-04-10 19:41:18 +00001926 if( strcmp(z,"changeset")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001927 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drh83e63dc2015-04-10 19:41:18 +00001928 out = fopen(argv[++i], "wb");
1929 if( out==0 ) cmdlineError("cannot open: %s", argv[i]);
drh8a1cd762015-04-14 19:01:08 +00001930 xDiff = changeset_one_table;
drh05d4ebf2015-11-13 13:15:42 +00001931 neverUseTransaction = 1;
drh83e63dc2015-04-10 19:41:18 +00001932 }else
drhd62c0f42015-04-09 13:34:29 +00001933 if( strcmp(z,"debug")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001934 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001935 g.fDebug = strtol(argv[++i], 0, 0);
1936 }else
1937 if( strcmp(z,"help")==0 ){
1938 showHelp();
1939 return 0;
1940 }else
drh6582ae52015-05-12 12:24:50 +00001941#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001942 if( strcmp(z,"lib")==0 || strcmp(z,"L")==0 ){
1943 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
1944 azExt = realloc(azExt, sizeof(azExt[0])*(nExt+1));
1945 if( azExt==0 ) cmdlineError("out of memory");
1946 azExt[nExt++] = argv[++i];
1947 }else
drh6582ae52015-05-12 12:24:50 +00001948#endif
drha37591c2015-04-09 18:14:03 +00001949 if( strcmp(z,"primarykey")==0 ){
1950 g.bSchemaPK = 1;
1951 }else
dan99461852015-07-30 20:26:16 +00001952 if( strcmp(z,"rbu")==0 ){
1953 xDiff = rbudiff_one_table;
1954 }else
drhd62c0f42015-04-09 13:34:29 +00001955 if( strcmp(z,"schema")==0 ){
1956 g.bSchemaOnly = 1;
1957 }else
drh8a1cd762015-04-14 19:01:08 +00001958 if( strcmp(z,"summary")==0 ){
1959 xDiff = summarize_one_table;
1960 }else
drhd62c0f42015-04-09 13:34:29 +00001961 if( strcmp(z,"table")==0 ){
drh9a9219f2015-05-04 13:25:56 +00001962 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
drhd62c0f42015-04-09 13:34:29 +00001963 zTab = argv[++i];
1964 }else
drh05d4ebf2015-11-13 13:15:42 +00001965 if( strcmp(z,"transaction")==0 ){
1966 useTransaction = 1;
1967 }else
dan9c987a82016-06-21 10:34:41 +00001968 if( strcmp(z,"vtab")==0 ){
1969 g.bHandleVtab = 1;
1970 }else
drhd62c0f42015-04-09 13:34:29 +00001971 {
1972 cmdlineError("unknown option: %s", argv[i]);
1973 }
1974 }else if( zDb1==0 ){
1975 zDb1 = argv[i];
1976 }else if( zDb2==0 ){
1977 zDb2 = argv[i];
1978 }else{
1979 cmdlineError("unknown argument: %s", argv[i]);
1980 }
1981 }
1982 if( zDb2==0 ){
1983 cmdlineError("two database arguments required");
1984 }
1985 rc = sqlite3_open(zDb1, &g.db);
1986 if( rc ){
1987 cmdlineError("cannot open database file \"%s\"", zDb1);
1988 }
1989 rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_master", 0, 0, &zErrMsg);
1990 if( rc || zErrMsg ){
1991 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
1992 }
drh6582ae52015-05-12 12:24:50 +00001993#ifndef SQLITE_OMIT_LOAD_EXTENSION
drh9a9219f2015-05-04 13:25:56 +00001994 sqlite3_enable_load_extension(g.db, 1);
1995 for(i=0; i<nExt; i++){
1996 rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
1997 if( rc || zErrMsg ){
1998 cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
1999 }
2000 }
2001 free(azExt);
drh9493caf2016-03-17 23:16:37 +00002002#endif
drhd62c0f42015-04-09 13:34:29 +00002003 zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
2004 rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
2005 if( rc || zErrMsg ){
2006 cmdlineError("cannot attach database \"%s\"", zDb2);
2007 }
2008 rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg);
2009 if( rc || zErrMsg ){
2010 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2);
2011 }
2012
drh05d4ebf2015-11-13 13:15:42 +00002013 if( neverUseTransaction ) useTransaction = 0;
danfebfe022016-03-19 16:21:26 +00002014 if( useTransaction ) fprintf(out, "BEGIN TRANSACTION;\n");
2015 if( xDiff==rbudiff_one_table ){
2016 fprintf(out, "CREATE TABLE IF NOT EXISTS rbu_count"
2017 "(tbl TEXT PRIMARY KEY COLLATE NOCASE, cnt INTEGER) "
2018 "WITHOUT ROWID;\n"
2019 );
2020 }
drhd62c0f42015-04-09 13:34:29 +00002021 if( zTab ){
drh8a1cd762015-04-14 19:01:08 +00002022 xDiff(zTab, out);
drhd62c0f42015-04-09 13:34:29 +00002023 }else{
2024 /* Handle tables one by one */
drh52254492016-07-08 02:14:24 +00002025 pStmt = db_prepare("%s", all_tables_sql() );
drhd62c0f42015-04-09 13:34:29 +00002026 while( SQLITE_ROW==sqlite3_step(pStmt) ){
drh8a1cd762015-04-14 19:01:08 +00002027 xDiff((const char*)sqlite3_column_text(pStmt,0), out);
drhd62c0f42015-04-09 13:34:29 +00002028 }
2029 sqlite3_finalize(pStmt);
2030 }
drh05d4ebf2015-11-13 13:15:42 +00002031 if( useTransaction ) printf("COMMIT;\n");
drhd62c0f42015-04-09 13:34:29 +00002032
2033 /* TBD: Handle trigger differences */
2034 /* TBD: Handle view differences */
2035 sqlite3_close(g.db);
2036 return 0;
2037}