Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1063)

Side by Side Diff: third_party/sqlite/src/tool/sqldiff.c

Issue 2751253002: [sql] Import SQLite 3.17.0. (Closed)
Patch Set: also clang on Linux i386 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/sqlite/src/tool/speed-check.sh ('k') | third_party/sqlite/src/tool/srcck1.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 ** 2015-04-06 2 ** 2015-04-06
3 ** 3 **
4 ** The author disclaims copyright to this source code. In place of 4 ** The author disclaims copyright to this source code. In place of
5 ** a legal notice, here is a blessing: 5 ** a legal notice, here is a blessing:
6 ** 6 **
7 ** May you do good and not evil. 7 ** May you do good and not evil.
8 ** May you find forgiveness for yourself and forgive others. 8 ** May you find forgiveness for yourself and forgive others.
9 ** May you share freely, never taking more than you give. 9 ** May you share freely, never taking more than you give.
10 ** 10 **
(...skipping 15 matching lines...) Expand all
26 #include <assert.h> 26 #include <assert.h>
27 #include "sqlite3.h" 27 #include "sqlite3.h"
28 28
29 /* 29 /*
30 ** All global variables are gathered into the "g" singleton. 30 ** All global variables are gathered into the "g" singleton.
31 */ 31 */
32 struct GlobalVars { 32 struct GlobalVars {
33 const char *zArgv0; /* Name of program */ 33 const char *zArgv0; /* Name of program */
34 int bSchemaOnly; /* Only show schema differences */ 34 int bSchemaOnly; /* Only show schema differences */
35 int bSchemaPK; /* Use the schema-defined PK, not the true PK */ 35 int bSchemaPK; /* Use the schema-defined PK, not the true PK */
36 int bHandleVtab; /* Handle fts3, fts4, fts5 and rtree vtabs */
36 unsigned fDebug; /* Debug flags */ 37 unsigned fDebug; /* Debug flags */
37 sqlite3 *db; /* The database connection */ 38 sqlite3 *db; /* The database connection */
38 } g; 39 } g;
39 40
40 /* 41 /*
41 ** Allowed values for g.fDebug 42 ** Allowed values for g.fDebug
42 */ 43 */
43 #define DEBUG_COLUMN_NAMES 0x000001 44 #define DEBUG_COLUMN_NAMES 0x000001
44 #define DEBUG_DIFF_SQL 0x000002 45 #define DEBUG_DIFF_SQL 0x000002
45 46
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 const unsigned char *zBlob = sqlite3_value_blob(X); 396 const unsigned char *zBlob = sqlite3_value_blob(X);
396 int nBlob = sqlite3_value_bytes(X); 397 int nBlob = sqlite3_value_bytes(X);
397 if( zBlob ){ 398 if( zBlob ){
398 int i; 399 int i;
399 fprintf(out, "x'"); 400 fprintf(out, "x'");
400 for(i=0; i<nBlob; i++){ 401 for(i=0; i<nBlob; i++){
401 fprintf(out, "%02x", zBlob[i]); 402 fprintf(out, "%02x", zBlob[i]);
402 } 403 }
403 fprintf(out, "'"); 404 fprintf(out, "'");
404 }else{ 405 }else{
405 fprintf(out, "NULL"); 406 /* Could be an OOM, could be a zero-byte blob */
407 fprintf(out, "X''");
406 } 408 }
407 break; 409 break;
408 } 410 }
409 case SQLITE_TEXT: { 411 case SQLITE_TEXT: {
410 const unsigned char *zArg = sqlite3_value_text(X); 412 const unsigned char *zArg = sqlite3_value_text(X);
411 int i, j; 413 int i, j;
412 414
413 if( zArg==0 ){ 415 if( zArg==0 ){
414 fprintf(out, "NULL"); 416 fprintf(out, "NULL");
415 }else{ 417 }else{
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
676 zTab, zTab); 678 zTab, zTab);
677 while( SQLITE_ROW==sqlite3_step(pStmt) ){ 679 while( SQLITE_ROW==sqlite3_step(pStmt) ){
678 char *z = safeId((const char*)sqlite3_column_text(pStmt,0)); 680 char *z = safeId((const char*)sqlite3_column_text(pStmt,0));
679 fprintf(out, "DROP INDEX %s;\n", z); 681 fprintf(out, "DROP INDEX %s;\n", z);
680 sqlite3_free(z); 682 sqlite3_free(z);
681 } 683 }
682 sqlite3_finalize(pStmt); 684 sqlite3_finalize(pStmt);
683 685
684 /* Run the query and output differences */ 686 /* Run the query and output differences */
685 if( !g.bSchemaOnly ){ 687 if( !g.bSchemaOnly ){
686 pStmt = db_prepare(sql.z); 688 pStmt = db_prepare("%s", sql.z);
687 while( SQLITE_ROW==sqlite3_step(pStmt) ){ 689 while( SQLITE_ROW==sqlite3_step(pStmt) ){
688 int iType = sqlite3_column_int(pStmt, nPk); 690 int iType = sqlite3_column_int(pStmt, nPk);
689 if( iType==1 || iType==2 ){ 691 if( iType==1 || iType==2 ){
690 if( iType==1 ){ /* Change the content of a row */ 692 if( iType==1 ){ /* Change the content of a row */
691 fprintf(out, "UPDATE %s", zId); 693 fprintf(out, "UPDATE %s", zId);
692 zSep = " SET"; 694 zSep = " SET";
693 for(i=nPk+1; i<nQ; i+=2){ 695 for(i=nPk+1; i<nQ; i+=2){
694 if( sqlite3_column_int(pStmt,i)==0 ) continue; 696 if( sqlite3_column_int(pStmt,i)==0 ) continue;
695 fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]); 697 fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
696 zSep = ","; 698 zSep = ",";
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
987 ** chance of ever doing a copy command. Just output a single 989 ** chance of ever doing a copy command. Just output a single
988 ** literal segment for the entire target and exit. 990 ** literal segment for the entire target and exit.
989 */ 991 */
990 if( lenSrc<=NHASH ){ 992 if( lenSrc<=NHASH ){
991 putInt(lenOut, &zDelta); 993 putInt(lenOut, &zDelta);
992 *(zDelta++) = ':'; 994 *(zDelta++) = ':';
993 memcpy(zDelta, zOut, lenOut); 995 memcpy(zDelta, zOut, lenOut);
994 zDelta += lenOut; 996 zDelta += lenOut;
995 putInt(checksum(zOut, lenOut), &zDelta); 997 putInt(checksum(zOut, lenOut), &zDelta);
996 *(zDelta++) = ';'; 998 *(zDelta++) = ';';
997 return zDelta - zOrigDelta; 999 return (int)(zDelta - zOrigDelta);
998 } 1000 }
999 1001
1000 /* Compute the hash table used to locate matching sections in the 1002 /* Compute the hash table used to locate matching sections in the
1001 ** source file. 1003 ** source file.
1002 */ 1004 */
1003 nHash = lenSrc/NHASH; 1005 nHash = lenSrc/NHASH;
1004 collide = sqlite3_malloc( nHash*2*sizeof(int) ); 1006 collide = sqlite3_malloc( nHash*2*sizeof(int) );
1005 landmark = &collide[nHash]; 1007 landmark = &collide[nHash];
1006 memset(landmark, -1, nHash*sizeof(int)); 1008 memset(landmark, -1, nHash*sizeof(int));
1007 memset(collide, -1, nHash*sizeof(int)); 1009 memset(collide, -1, nHash*sizeof(int));
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 if( base<lenOut ){ 1136 if( base<lenOut ){
1135 putInt(lenOut-base, &zDelta); 1137 putInt(lenOut-base, &zDelta);
1136 *(zDelta++) = ':'; 1138 *(zDelta++) = ':';
1137 memcpy(zDelta, &zOut[base], lenOut-base); 1139 memcpy(zDelta, &zOut[base], lenOut-base);
1138 zDelta += lenOut-base; 1140 zDelta += lenOut-base;
1139 } 1141 }
1140 /* Output the final checksum record. */ 1142 /* Output the final checksum record. */
1141 putInt(checksum(zOut, lenOut), &zDelta); 1143 putInt(checksum(zOut, lenOut), &zDelta);
1142 *(zDelta++) = ';'; 1144 *(zDelta++) = ';';
1143 sqlite3_free(collide); 1145 sqlite3_free(collide);
1144 return zDelta - zOrigDelta; 1146 return (int)(zDelta - zOrigDelta);
1145 } 1147 }
1146 1148
1147 /* 1149 /*
1148 ** End of code copied from fossil. 1150 ** End of code copied from fossil.
1149 **************************************************************************/ 1151 **************************************************************************/
1150 1152
1151 static void strPrintfArray( 1153 static void strPrintfArray(
1152 Str *pStr, /* String object to append to */ 1154 Str *pStr, /* String object to append to */
1153 const char *zSep, /* Separator string */ 1155 const char *zSep, /* Separator string */
1154 const char *zFmt, /* Format for each entry */ 1156 const char *zFmt, /* Format for each entry */
(...skipping 16 matching lines...) Expand all
1171 int i; 1173 int i;
1172 1174
1173 /* First the newly inserted rows: **/ 1175 /* First the newly inserted rows: **/
1174 strPrintf(pSql, "SELECT "); 1176 strPrintf(pSql, "SELECT ");
1175 strPrintfArray(pSql, ", ", "%s", azCol, -1); 1177 strPrintfArray(pSql, ", ", "%s", azCol, -1);
1176 strPrintf(pSql, ", 0, "); /* Set ota_control to 0 for an insert */ 1178 strPrintf(pSql, ", 0, "); /* Set ota_control to 0 for an insert */
1177 strPrintfArray(pSql, ", ", "NULL", azCol, -1); 1179 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
1178 strPrintf(pSql, " FROM aux.%Q AS n WHERE NOT EXISTS (\n", zTab); 1180 strPrintf(pSql, " FROM aux.%Q AS n WHERE NOT EXISTS (\n", zTab);
1179 strPrintf(pSql, " SELECT 1 FROM ", zTab); 1181 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1180 strPrintf(pSql, " main.%Q AS o WHERE ", zTab); 1182 strPrintf(pSql, " main.%Q AS o WHERE ", zTab);
1181 strPrintfArray(pSql, " AND ", "(n.%Q IS o.%Q)", azCol, nPK); 1183 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1182 strPrintf(pSql, "\n)"); 1184 strPrintf(pSql, "\n) AND ");
1185 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
1183 1186
1184 /* Deleted rows: */ 1187 /* Deleted rows: */
1185 strPrintf(pSql, "\nUNION ALL\nSELECT "); 1188 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1186 strPrintfArray(pSql, ", ", "%s", azCol, nPK); 1189 strPrintfArray(pSql, ", ", "%s", azCol, nPK);
1187 if( azCol[nPK] ){ 1190 if( azCol[nPK] ){
1188 strPrintf(pSql, ", "); 1191 strPrintf(pSql, ", ");
1189 strPrintfArray(pSql, ", ", "NULL", &azCol[nPK], -1); 1192 strPrintfArray(pSql, ", ", "NULL", &azCol[nPK], -1);
1190 } 1193 }
1191 strPrintf(pSql, ", 1, "); /* Set ota_control to 1 for a delete */ 1194 strPrintf(pSql, ", 1, "); /* Set ota_control to 1 for a delete */
1192 strPrintfArray(pSql, ", ", "NULL", azCol, -1); 1195 strPrintfArray(pSql, ", ", "NULL", azCol, -1);
1193 strPrintf(pSql, " FROM main.%Q AS n WHERE NOT EXISTS (\n", zTab); 1196 strPrintf(pSql, " FROM main.%Q AS n WHERE NOT EXISTS (\n", zTab);
1194 strPrintf(pSql, " SELECT 1 FROM ", zTab); 1197 strPrintf(pSql, " SELECT 1 FROM ", zTab);
1195 strPrintf(pSql, " aux.%Q AS o WHERE ", zTab); 1198 strPrintf(pSql, " aux.%Q AS o WHERE ", zTab);
1196 strPrintfArray(pSql, " AND ", "(n.%Q IS o.%Q)", azCol, nPK); 1199 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1197 strPrintf(pSql, "\n) "); 1200 strPrintf(pSql, "\n) AND ");
1201 strPrintfArray(pSql, " AND ", "(n.%Q IS NOT NULL)", azCol, nPK);
1198 1202
1199 /* Updated rows. If all table columns are part of the primary key, there 1203 /* Updated rows. If all table columns are part of the primary key, there
1200 ** can be no updates. In this case this part of the compound SELECT can 1204 ** can be no updates. In this case this part of the compound SELECT can
1201 ** be omitted altogether. */ 1205 ** be omitted altogether. */
1202 if( azCol[nPK] ){ 1206 if( azCol[nPK] ){
1203 strPrintf(pSql, "\nUNION ALL\nSELECT "); 1207 strPrintf(pSql, "\nUNION ALL\nSELECT ");
1204 strPrintfArray(pSql, ", ", "n.%s", azCol, nPK); 1208 strPrintfArray(pSql, ", ", "n.%s", azCol, nPK);
1205 strPrintf(pSql, ",\n"); 1209 strPrintf(pSql, ",\n");
1206 strPrintfArray(pSql, " ,\n", 1210 strPrintfArray(pSql, " ,\n",
1207 " CASE WHEN n.%s IS o.%s THEN NULL ELSE n.%s END", &azCol[nPK], -1 1211 " CASE WHEN n.%s IS o.%s THEN NULL ELSE n.%s END", &azCol[nPK], -1
(...skipping 10 matching lines...) Expand all
1218 " CASE WHEN n.%s IS o.%s THEN '.' ELSE 'x' END", &azCol[nPK], -1 1222 " CASE WHEN n.%s IS o.%s THEN '.' ELSE 'x' END", &azCol[nPK], -1
1219 ); 1223 );
1220 strPrintf(pSql, "\nAS ota_control, "); 1224 strPrintf(pSql, "\nAS ota_control, ");
1221 strPrintfArray(pSql, ", ", "NULL", azCol, nPK); 1225 strPrintfArray(pSql, ", ", "NULL", azCol, nPK);
1222 strPrintf(pSql, ",\n"); 1226 strPrintf(pSql, ",\n");
1223 strPrintfArray(pSql, " ,\n", 1227 strPrintfArray(pSql, " ,\n",
1224 " CASE WHEN n.%s IS o.%s THEN NULL ELSE o.%s END", &azCol[nPK], -1 1228 " CASE WHEN n.%s IS o.%s THEN NULL ELSE o.%s END", &azCol[nPK], -1
1225 ); 1229 );
1226 1230
1227 strPrintf(pSql, "\nFROM main.%Q AS o, aux.%Q AS n\nWHERE ", zTab, zTab); 1231 strPrintf(pSql, "\nFROM main.%Q AS o, aux.%Q AS n\nWHERE ", zTab, zTab);
1228 strPrintfArray(pSql, " AND ", "(n.%Q IS o.%Q)", azCol, nPK); 1232 strPrintfArray(pSql, " AND ", "(n.%Q = o.%Q)", azCol, nPK);
1229 strPrintf(pSql, " AND ota_control LIKE '%%x%%'"); 1233 strPrintf(pSql, " AND ota_control LIKE '%%x%%'");
1230 } 1234 }
1231 1235
1232 /* Now add an ORDER BY clause to sort everything by PK. */ 1236 /* Now add an ORDER BY clause to sort everything by PK. */
1233 strPrintf(pSql, "\nORDER BY "); 1237 strPrintf(pSql, "\nORDER BY ");
1234 for(i=1; i<=nPK; i++) strPrintf(pSql, "%s%d", ((i>1)?", ":""), i); 1238 for(i=1; i<=nPK; i++) strPrintf(pSql, "%s%d", ((i>1)?", ":""), i);
1235 } 1239 }
1236 1240
1237 static void rbudiff_one_table(const char *zTab, FILE *out){ 1241 static void rbudiff_one_table(const char *zTab, FILE *out){
1238 int bOtaRowid; /* True to use an ota_rowid column */ 1242 int bOtaRowid; /* True to use an ota_rowid column */
1239 int nPK; /* Number of primary key columns in table */ 1243 int nPK; /* Number of primary key columns in table */
1240 char **azCol; /* NULL terminated array of col names */ 1244 char **azCol; /* NULL terminated array of col names */
1241 int i; 1245 int i;
1242 int nCol; 1246 int nCol;
1243 Str ct = {0, 0, 0}; /* The "CREATE TABLE data_xxx" statement */ 1247 Str ct = {0, 0, 0}; /* The "CREATE TABLE data_xxx" statement */
1244 Str sql = {0, 0, 0}; /* Query to find differences */ 1248 Str sql = {0, 0, 0}; /* Query to find differences */
1245 Str insert = {0, 0, 0}; /* First part of output INSERT statement */ 1249 Str insert = {0, 0, 0}; /* First part of output INSERT statement */
1246 sqlite3_stmt *pStmt = 0; 1250 sqlite3_stmt *pStmt = 0;
1251 int nRow = 0; /* Total rows in data_xxx table */
1247 1252
1248 /* --rbu mode must use real primary keys. */ 1253 /* --rbu mode must use real primary keys. */
1249 g.bSchemaPK = 1; 1254 g.bSchemaPK = 1;
1250 1255
1251 /* Check that the schemas of the two tables match. Exit early otherwise. */ 1256 /* Check that the schemas of the two tables match. Exit early otherwise. */
1252 checkSchemasMatch(zTab); 1257 checkSchemasMatch(zTab);
1253 1258
1254 /* Grab the column names and PK details for the table(s). If no usable PK 1259 /* Grab the column names and PK details for the table(s). If no usable PK
1255 ** columns are found, bail out early. */ 1260 ** columns are found, bail out early. */
1256 azCol = columnNames("main", zTab, &nPK, &bOtaRowid); 1261 azCol = columnNames("main", zTab, &nPK, &bOtaRowid);
(...skipping 25 matching lines...) Expand all
1282 /* If this is the first row output, print out the CREATE TABLE 1287 /* If this is the first row output, print out the CREATE TABLE
1283 ** statement first. And then set ct.z to NULL so that it is not 1288 ** statement first. And then set ct.z to NULL so that it is not
1284 ** printed again. */ 1289 ** printed again. */
1285 if( ct.z ){ 1290 if( ct.z ){
1286 fprintf(out, "%s\n", ct.z); 1291 fprintf(out, "%s\n", ct.z);
1287 strFree(&ct); 1292 strFree(&ct);
1288 } 1293 }
1289 1294
1290 /* Output the first part of the INSERT statement */ 1295 /* Output the first part of the INSERT statement */
1291 fprintf(out, "%s", insert.z); 1296 fprintf(out, "%s", insert.z);
1297 nRow++;
1292 1298
1293 if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){ 1299 if( sqlite3_column_type(pStmt, nCol)==SQLITE_INTEGER ){
1294 for(i=0; i<=nCol; i++){ 1300 for(i=0; i<=nCol; i++){
1295 if( i>0 ) fprintf(out, ", "); 1301 if( i>0 ) fprintf(out, ", ");
1296 printQuoted(out, sqlite3_column_value(pStmt, i)); 1302 printQuoted(out, sqlite3_column_value(pStmt, i));
1297 } 1303 }
1298 }else{ 1304 }else{
1299 char *zOtaControl; 1305 char *zOtaControl;
1300 int nOtaControl = sqlite3_column_bytes(pStmt, nCol); 1306 int nOtaControl = sqlite3_column_bytes(pStmt, nCol);
1301 1307
1302 zOtaControl = (char*)sqlite3_malloc(nOtaControl); 1308 zOtaControl = (char*)sqlite3_malloc(nOtaControl+1);
1303 memcpy(zOtaControl, sqlite3_column_text(pStmt, nCol), nOtaControl+1); 1309 memcpy(zOtaControl, sqlite3_column_text(pStmt, nCol), nOtaControl+1);
1304 1310
1305 for(i=0; i<nCol; i++){ 1311 for(i=0; i<nCol; i++){
1306 int bDone = 0; 1312 int bDone = 0;
1307 if( i>=nPK 1313 if( i>=nPK
1308 && sqlite3_column_type(pStmt, i)==SQLITE_BLOB 1314 && sqlite3_column_type(pStmt, i)==SQLITE_BLOB
1309 && sqlite3_column_type(pStmt, nCol+1+i)==SQLITE_BLOB 1315 && sqlite3_column_type(pStmt, nCol+1+i)==SQLITE_BLOB
1310 ){ 1316 ){
1311 const char *aSrc = sqlite3_column_blob(pStmt, nCol+1+i); 1317 const char *aSrc = sqlite3_column_blob(pStmt, nCol+1+i);
1312 int nSrc = sqlite3_column_bytes(pStmt, nCol+1+i); 1318 int nSrc = sqlite3_column_bytes(pStmt, nCol+1+i);
(...skipping 22 matching lines...) Expand all
1335 } 1341 }
1336 fprintf(out, "'%s'", zOtaControl); 1342 fprintf(out, "'%s'", zOtaControl);
1337 sqlite3_free(zOtaControl); 1343 sqlite3_free(zOtaControl);
1338 } 1344 }
1339 1345
1340 /* And the closing bracket of the insert statement */ 1346 /* And the closing bracket of the insert statement */
1341 fprintf(out, ");\n"); 1347 fprintf(out, ");\n");
1342 } 1348 }
1343 1349
1344 sqlite3_finalize(pStmt); 1350 sqlite3_finalize(pStmt);
1351 if( nRow>0 ){
1352 Str cnt = {0, 0, 0};
1353 strPrintf(&cnt, "INSERT INTO rbu_count VALUES('data_%q', %d);", zTab, nRow);
1354 fprintf(out, "%s\n", cnt.z);
1355 strFree(&cnt);
1356 }
1345 1357
1346 strFree(&ct); 1358 strFree(&ct);
1347 strFree(&sql); 1359 strFree(&sql);
1348 strFree(&insert); 1360 strFree(&insert);
1349 } 1361 }
1350 1362
1351 /* 1363 /*
1352 ** Display a summary of differences between two versions of the same 1364 ** Display a summary of differences between two versions of the same
1353 ** table table. 1365 ** table table.
1354 ** 1366 **
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
1445 zSep = " AND"; 1457 zSep = " AND";
1446 } 1458 }
1447 strPrintf(&sql, ")\n ORDER BY 1;\n"); 1459 strPrintf(&sql, ")\n ORDER BY 1;\n");
1448 1460
1449 if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){ 1461 if( (g.fDebug & DEBUG_DIFF_SQL)!=0 ){
1450 printf("SQL for %s:\n%s\n", zId, sql.z); 1462 printf("SQL for %s:\n%s\n", zId, sql.z);
1451 goto end_summarize_one_table; 1463 goto end_summarize_one_table;
1452 } 1464 }
1453 1465
1454 /* Run the query and output difference summary */ 1466 /* Run the query and output difference summary */
1455 pStmt = db_prepare(sql.z); 1467 pStmt = db_prepare("%s", sql.z);
1456 nUpdate = 0; 1468 nUpdate = 0;
1457 nInsert = 0; 1469 nInsert = 0;
1458 nDelete = 0; 1470 nDelete = 0;
1459 nUnchanged = 0; 1471 nUnchanged = 0;
1460 while( SQLITE_ROW==sqlite3_step(pStmt) ){ 1472 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1461 switch( sqlite3_column_int(pStmt,0) ){ 1473 switch( sqlite3_column_int(pStmt,0) ){
1462 case 1: 1474 case 1:
1463 nUpdate = sqlite3_column_int64(pStmt,2); 1475 nUpdate = sqlite3_column_int64(pStmt,2);
1464 nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate; 1476 nUnchanged = sqlite3_column_int64(pStmt,1) - nUpdate;
1465 break; 1477 break;
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1721 sqlite3_finalize(pStmt); 1733 sqlite3_finalize(pStmt);
1722 1734
1723 end_changeset_one_table: 1735 end_changeset_one_table:
1724 while( nCol>0 ) sqlite3_free(azCol[--nCol]); 1736 while( nCol>0 ) sqlite3_free(azCol[--nCol]);
1725 sqlite3_free(azCol); 1737 sqlite3_free(azCol);
1726 sqlite3_free(aiPk); 1738 sqlite3_free(aiPk);
1727 sqlite3_free(zId); 1739 sqlite3_free(zId);
1728 } 1740 }
1729 1741
1730 /* 1742 /*
1743 ** Extract the next SQL keyword or quoted string from buffer zIn and copy it
1744 ** (or a prefix of it if it will not fit) into buffer zBuf, size nBuf bytes.
1745 ** Return a pointer to the character within zIn immediately following
1746 ** the token or quoted string just extracted.
1747 */
1748 const char *gobble_token(const char *zIn, char *zBuf, int nBuf){
1749 const char *p = zIn;
1750 char *pOut = zBuf;
1751 char *pEnd = &pOut[nBuf-1];
1752 char q = 0; /* quote character, if any */
1753
1754 if( p==0 ) return 0;
1755 while( *p==' ' ) p++;
1756 switch( *p ){
1757 case '"': q = '"'; break;
1758 case '\'': q = '\''; break;
1759 case '`': q = '`'; break;
1760 case '[': q = ']'; break;
1761 }
1762
1763 if( q ){
1764 p++;
1765 while( *p && pOut<pEnd ){
1766 if( *p==q ){
1767 p++;
1768 if( *p!=q ) break;
1769 }
1770 if( pOut<pEnd ) *pOut++ = *p;
1771 p++;
1772 }
1773 }else{
1774 while( *p && *p!=' ' && *p!='(' ){
1775 if( pOut<pEnd ) *pOut++ = *p;
1776 p++;
1777 }
1778 }
1779
1780 *pOut = '\0';
1781 return p;
1782 }
1783
1784 /*
1785 ** This function is the implementation of SQL scalar function "module_name":
1786 **
1787 ** module_name(SQL)
1788 **
1789 ** The only argument should be an SQL statement of the type that may appear
1790 ** in the sqlite_master table. If the statement is a "CREATE VIRTUAL TABLE"
1791 ** statement, then the value returned is the name of the module that it
1792 ** uses. Otherwise, if the statement is not a CVT, NULL is returned.
1793 */
1794 static void module_name_func(
1795 sqlite3_context *pCtx,
1796 int nVal, sqlite3_value **apVal
1797 ){
1798 const char *zSql;
1799 char zToken[32];
1800
1801 assert( nVal==1 );
1802 zSql = (const char*)sqlite3_value_text(apVal[0]);
1803
1804 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1805 if( zSql==0 || sqlite3_stricmp(zToken, "create") ) return;
1806 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1807 if( zSql==0 || sqlite3_stricmp(zToken, "virtual") ) return;
1808 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1809 if( zSql==0 || sqlite3_stricmp(zToken, "table") ) return;
1810 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1811 if( zSql==0 ) return;
1812 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1813 if( zSql==0 || sqlite3_stricmp(zToken, "using") ) return;
1814 zSql = gobble_token(zSql, zToken, sizeof(zToken));
1815
1816 sqlite3_result_text(pCtx, zToken, -1, SQLITE_TRANSIENT);
1817 }
1818
1819 /*
1820 ** Return the text of an SQL statement that itself returns the list of
1821 ** tables to process within the database.
1822 */
1823 const char *all_tables_sql(){
1824 if( g.bHandleVtab ){
1825 int rc;
1826
1827 rc = sqlite3_exec(g.db,
1828 "CREATE TEMP TABLE tblmap(module COLLATE nocase, postfix);"
1829 "INSERT INTO temp.tblmap VALUES"
1830 "('fts3', '_content'), ('fts3', '_segments'), ('fts3', '_segdir'),"
1831
1832 "('fts4', '_content'), ('fts4', '_segments'), ('fts4', '_segdir'),"
1833 "('fts4', '_docsize'), ('fts4', '_stat'),"
1834
1835 "('fts5', '_data'), ('fts5', '_idx'), ('fts5', '_content'),"
1836 "('fts5', '_docsize'), ('fts5', '_config'),"
1837
1838 "('rtree', '_node'), ('rtree', '_rowid'), ('rtree', '_parent');"
1839 , 0, 0, 0
1840 );
1841 assert( rc==SQLITE_OK );
1842
1843 rc = sqlite3_create_function(
1844 g.db, "module_name", 1, SQLITE_UTF8, 0, module_name_func, 0, 0
1845 );
1846 assert( rc==SQLITE_OK );
1847
1848 return
1849 "SELECT name FROM main.sqlite_master\n"
1850 " WHERE type='table' AND (\n"
1851 " module_name(sql) IS NULL OR \n"
1852 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1853 " ) AND name NOT IN (\n"
1854 " SELECT a.name || b.postfix \n"
1855 "FROM main.sqlite_master AS a, temp.tblmap AS b \n"
1856 "WHERE module_name(a.sql) = b.module\n"
1857 " )\n"
1858 "UNION \n"
1859 "SELECT name FROM aux.sqlite_master\n"
1860 " WHERE type='table' AND (\n"
1861 " module_name(sql) IS NULL OR \n"
1862 " module_name(sql) IN (SELECT module FROM temp.tblmap)\n"
1863 " ) AND name NOT IN (\n"
1864 " SELECT a.name || b.postfix \n"
1865 "FROM aux.sqlite_master AS a, temp.tblmap AS b \n"
1866 "WHERE module_name(a.sql) = b.module\n"
1867 " )\n"
1868 " ORDER BY name";
1869 }else{
1870 return
1871 "SELECT name FROM main.sqlite_master\n"
1872 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1873 " UNION\n"
1874 "SELECT name FROM aux.sqlite_master\n"
1875 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1876 " ORDER BY name";
1877 }
1878 }
1879
1880 /*
1731 ** Print sketchy documentation for this utility program 1881 ** Print sketchy documentation for this utility program
1732 */ 1882 */
1733 static void showHelp(void){ 1883 static void showHelp(void){
1734 printf("Usage: %s [options] DB1 DB2\n", g.zArgv0); 1884 printf("Usage: %s [options] DB1 DB2\n", g.zArgv0);
1735 printf( 1885 printf(
1736 "Output SQL text that would transform DB1 into DB2.\n" 1886 "Output SQL text that would transform DB1 into DB2.\n"
1737 "Options:\n" 1887 "Options:\n"
1738 " --changeset FILE Write a CHANGESET into FILE\n" 1888 " --changeset FILE Write a CHANGESET into FILE\n"
1739 " -L|--lib LIBRARY Load an SQLite extension library\n" 1889 " -L|--lib LIBRARY Load an SQLite extension library\n"
1740 " --primarykey Use schema-defined PRIMARY KEYs\n" 1890 " --primarykey Use schema-defined PRIMARY KEYs\n"
1741 " --rbu Output SQL to create/populate RBU table(s)\n" 1891 " --rbu Output SQL to create/populate RBU table(s)\n"
1742 " --schema Show only differences in the schema\n" 1892 " --schema Show only differences in the schema\n"
1743 " --summary Show only a summary of the differences\n" 1893 " --summary Show only a summary of the differences\n"
1744 " --table TAB Show only differences in table TAB\n" 1894 " --table TAB Show only differences in table TAB\n"
1745 " --transaction Show SQL output inside a transaction\n" 1895 " --transaction Show SQL output inside a transaction\n"
1896 " --vtab Handle fts3, fts4, fts5 and rtree tables\n"
1746 ); 1897 );
1747 } 1898 }
1748 1899
1749 int main(int argc, char **argv){ 1900 int main(int argc, char **argv){
1750 const char *zDb1 = 0; 1901 const char *zDb1 = 0;
1751 const char *zDb2 = 0; 1902 const char *zDb2 = 0;
1752 int i; 1903 int i;
1753 int rc; 1904 int rc;
1754 char *zErrMsg = 0; 1905 char *zErrMsg = 0;
1755 char *zSql; 1906 char *zSql;
1756 sqlite3_stmt *pStmt; 1907 sqlite3_stmt *pStmt;
1757 char *zTab = 0; 1908 char *zTab = 0;
1758 FILE *out = stdout; 1909 FILE *out = stdout;
1759 void (*xDiff)(const char*,FILE*) = diff_one_table; 1910 void (*xDiff)(const char*,FILE*) = diff_one_table;
1911 #ifndef SQLITE_OMIT_LOAD_EXTENSION
1760 int nExt = 0; 1912 int nExt = 0;
1761 char **azExt = 0; 1913 char **azExt = 0;
1914 #endif
1762 int useTransaction = 0; 1915 int useTransaction = 0;
1763 int neverUseTransaction = 0; 1916 int neverUseTransaction = 0;
1764 1917
1765 g.zArgv0 = argv[0]; 1918 g.zArgv0 = argv[0];
1766 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD); 1919 sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
1767 for(i=1; i<argc; i++){ 1920 for(i=1; i<argc; i++){
1768 const char *z = argv[i]; 1921 const char *z = argv[i];
1769 if( z[0]=='-' ){ 1922 if( z[0]=='-' ){
1770 z++; 1923 z++;
1771 if( z[0]=='-' ) z++; 1924 if( z[0]=='-' ) z++;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 if( strcmp(z,"summary")==0 ){ 1957 if( strcmp(z,"summary")==0 ){
1805 xDiff = summarize_one_table; 1958 xDiff = summarize_one_table;
1806 }else 1959 }else
1807 if( strcmp(z,"table")==0 ){ 1960 if( strcmp(z,"table")==0 ){
1808 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]); 1961 if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
1809 zTab = argv[++i]; 1962 zTab = argv[++i];
1810 }else 1963 }else
1811 if( strcmp(z,"transaction")==0 ){ 1964 if( strcmp(z,"transaction")==0 ){
1812 useTransaction = 1; 1965 useTransaction = 1;
1813 }else 1966 }else
1967 if( strcmp(z,"vtab")==0 ){
1968 g.bHandleVtab = 1;
1969 }else
1814 { 1970 {
1815 cmdlineError("unknown option: %s", argv[i]); 1971 cmdlineError("unknown option: %s", argv[i]);
1816 } 1972 }
1817 }else if( zDb1==0 ){ 1973 }else if( zDb1==0 ){
1818 zDb1 = argv[i]; 1974 zDb1 = argv[i];
1819 }else if( zDb2==0 ){ 1975 }else if( zDb2==0 ){
1820 zDb2 = argv[i]; 1976 zDb2 = argv[i];
1821 }else{ 1977 }else{
1822 cmdlineError("unknown argument: %s", argv[i]); 1978 cmdlineError("unknown argument: %s", argv[i]);
1823 } 1979 }
(...skipping 10 matching lines...) Expand all
1834 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1); 1990 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);
1835 } 1991 }
1836 #ifndef SQLITE_OMIT_LOAD_EXTENSION 1992 #ifndef SQLITE_OMIT_LOAD_EXTENSION
1837 sqlite3_enable_load_extension(g.db, 1); 1993 sqlite3_enable_load_extension(g.db, 1);
1838 for(i=0; i<nExt; i++){ 1994 for(i=0; i<nExt; i++){
1839 rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg); 1995 rc = sqlite3_load_extension(g.db, azExt[i], 0, &zErrMsg);
1840 if( rc || zErrMsg ){ 1996 if( rc || zErrMsg ){
1841 cmdlineError("error loading %s: %s", azExt[i], zErrMsg); 1997 cmdlineError("error loading %s: %s", azExt[i], zErrMsg);
1842 } 1998 }
1843 } 1999 }
2000 free(azExt);
1844 #endif 2001 #endif
1845 free(azExt);
1846 zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2); 2002 zSql = sqlite3_mprintf("ATTACH %Q as aux;", zDb2);
1847 rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg); 2003 rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
1848 if( rc || zErrMsg ){ 2004 if( rc || zErrMsg ){
1849 cmdlineError("cannot attach database \"%s\"", zDb2); 2005 cmdlineError("cannot attach database \"%s\"", zDb2);
1850 } 2006 }
1851 rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg); 2007 rc = sqlite3_exec(g.db, "SELECT * FROM aux.sqlite_master", 0, 0, &zErrMsg);
1852 if( rc || zErrMsg ){ 2008 if( rc || zErrMsg ){
1853 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2); 2009 cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb2);
1854 } 2010 }
1855 2011
1856 if( neverUseTransaction ) useTransaction = 0; 2012 if( neverUseTransaction ) useTransaction = 0;
1857 if( useTransaction ) printf("BEGIN TRANSACTION;\n"); 2013 if( useTransaction ) fprintf(out, "BEGIN TRANSACTION;\n");
2014 if( xDiff==rbudiff_one_table ){
2015 fprintf(out, "CREATE TABLE IF NOT EXISTS rbu_count"
2016 "(tbl TEXT PRIMARY KEY COLLATE NOCASE, cnt INTEGER) "
2017 "WITHOUT ROWID;\n"
2018 );
2019 }
1858 if( zTab ){ 2020 if( zTab ){
1859 xDiff(zTab, out); 2021 xDiff(zTab, out);
1860 }else{ 2022 }else{
1861 /* Handle tables one by one */ 2023 /* Handle tables one by one */
1862 pStmt = db_prepare( 2024 pStmt = db_prepare("%s", all_tables_sql() );
1863 "SELECT name FROM main.sqlite_master\n"
1864 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1865 " UNION\n"
1866 "SELECT name FROM aux.sqlite_master\n"
1867 " WHERE type='table' AND sql NOT LIKE 'CREATE VIRTUAL%%'\n"
1868 " ORDER BY name"
1869 );
1870 while( SQLITE_ROW==sqlite3_step(pStmt) ){ 2025 while( SQLITE_ROW==sqlite3_step(pStmt) ){
1871 xDiff((const char*)sqlite3_column_text(pStmt,0), out); 2026 xDiff((const char*)sqlite3_column_text(pStmt,0), out);
1872 } 2027 }
1873 sqlite3_finalize(pStmt); 2028 sqlite3_finalize(pStmt);
1874 } 2029 }
1875 if( useTransaction ) printf("COMMIT;\n"); 2030 if( useTransaction ) printf("COMMIT;\n");
1876 2031
1877 /* TBD: Handle trigger differences */ 2032 /* TBD: Handle trigger differences */
1878 /* TBD: Handle view differences */ 2033 /* TBD: Handle view differences */
1879 sqlite3_close(g.db); 2034 sqlite3_close(g.db);
1880 return 0; 2035 return 0;
1881 } 2036 }
OLDNEW
« no previous file with comments | « third_party/sqlite/src/tool/speed-check.sh ('k') | third_party/sqlite/src/tool/srcck1.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698