Fossil

Diff
Login

Differences From Artifact [a7c23a39fb]:

To Artifact [25fc3be68e]:


16
17
18
19
20
21
22
23

24
25
26
27
28
29
30
16
17
18
19
20
21
22

23
24
25
26
27
28
29
30







-
+







/* This needs to come before any includes for MSVC compiler */
#define _CRT_SECURE_NO_WARNINGS
#endif

/*
** Enable large-file support for fopen() and friends on unix.
*/
#ifndef SQLITE_DISABLE_LFS
#ifndef SQLITE4_DISABLE_LFS
# define _LARGE_FILE       1
# ifndef _FILE_OFFSET_BITS
#   define _FILE_OFFSET_BITS 64
# endif
# define _LARGEFILE_SOURCE 1
#endif

248
249
250
251
252
253
254
255

256
257
258
259
260
261
262
263
264
265

266
267
268
269
270
271
272
248
249
250
251
252
253
254

255
256
257
258
259
260
261
262
263
264

265
266
267
268
269
270
271
272







-
+









-
+







*/
static char mainPrompt[20];     /* First line prompt. default: "sqlite> "*/
static char continuePrompt[20]; /* Continuation prompt. default: "   ...> " */

/*
** Write I/O traces to the following stream.
*/
#ifdef SQLITE_ENABLE_IOTRACE
#ifdef SQLITE4_ENABLE_IOTRACE
static FILE *iotrace = 0;
#endif

/*
** This routine works like printf in that its first argument is a
** format string and subsequent arguments are values to be substituted
** in place of % fields.  The result of formatting this string
** is written to iotrace.
*/
#ifdef SQLITE_ENABLE_IOTRACE
#ifdef SQLITE4_ENABLE_IOTRACE
static void iotracePrintf(const char *zFormat, ...){
  va_list ap;
  char *z;
  if( iotrace==0 ) return;
  va_start(ap, zFormat);
  z = sqlite4_vmprintf(0, zFormat, ap);
  va_end(ap);
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331







-
+







  int argc,
  sqlite4_value **argv
){
  assert( 0==argc );
  assert( zShellStatic );
  UNUSED_PARAMETER(argc);
  UNUSED_PARAMETER(argv);
  sqlite4_result_text(context, zShellStatic, -1, SQLITE_STATIC);
  sqlite4_result_text(context, zShellStatic, -1, SQLITE4_STATIC);
}


/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
813
814
815
816
817
818
819
820

821
822

823
824
825

826
827

828
829
830
831
832
833
834
813
814
815
816
817
818
819

820
821

822
823
824

825
826

827
828
829
830
831
832
833
834







-
+

-
+


-
+

-
+







    }
    case MODE_Insert: {
      p->cnt++;
      if( azArg==0 ) break;
      fprintf(p->out,"INSERT INTO %s VALUES(",p->zDestTable);
      for(i=0; i<nArg; i++){
        char *zSep = i>0 ? ",": "";
        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE_NULL) ){
        if( (azArg[i]==0) || (aiType && aiType[i]==SQLITE4_NULL) ){
          fprintf(p->out,"%sNULL",zSep);
        }else if( aiType && aiType[i]==SQLITE_TEXT ){
        }else if( aiType && aiType[i]==SQLITE4_TEXT ){
          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          output_quoted_string(p->out, azArg[i]);
        }else if( aiType && (aiType[i]==SQLITE_INTEGER || aiType[i]==SQLITE_FLOAT) ){
        }else if( aiType && (aiType[i]==SQLITE4_INTEGER || aiType[i]==SQLITE4_FLOAT) ){
          fprintf(p->out,"%s%s",zSep, azArg[i]);
        }else if( aiType && aiType[i]==SQLITE_BLOB && p->pStmt ){
        }else if( aiType && aiType[i]==SQLITE4_BLOB && p->pStmt ){
          const void *pBlob = sqlite4_column_blob(p->pStmt, i);
          int nBlob = sqlite4_column_bytes(p->pStmt, i);
          if( zSep[0] ) fprintf(p->out,"%s",zSep);
          output_hex_blob(p->out, pBlob, nBlob);
        }else if( isNumber(azArg[i], 0) ){
          fprintf(p->out,"%s%s",zSep, azArg[i]);
        }else{
937
938
939
940
941
942
943
944

945
946
947
948
949
950
951
952
953
954

955
956
957
958
959
960

961
962
963
964
965
966
967
968
969

970
971
972
973
974
975
976
937
938
939
940
941
942
943

944
945
946
947
948
949
950
951
952
953

954
955
956
957
958
959

960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
976







-
+









-
+





-
+








-
+









/*
** Execute a query statement that has a single result column.  Print
** that result column on a line by itself with a semicolon terminator.
**
** This is used, for example, to show the schema of the database by
** querying the SQLITE_MASTER table.
** querying the SQLITE4_MASTER table.
*/
static int run_table_dump_query(
  struct callback_data *p, /* Query context */
  const char *zSelect,     /* SELECT statement to extract content */
  const char *zFirstRow    /* Print before first row, if not NULL */
){
  sqlite4_stmt *pSelect;
  int rc;
  rc = sqlite4_prepare(p->db, zSelect, -1, &pSelect, 0);
  if( rc!=SQLITE_OK || !pSelect ){
  if( rc!=SQLITE4_OK || !pSelect ){
    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite4_errmsg(p->db));
    p->nErr++;
    return rc;
  }
  rc = sqlite4_step(pSelect);
  while( rc==SQLITE_ROW ){
  while( rc==SQLITE4_ROW ){
    if( zFirstRow ){
      fprintf(p->out, "%s", zFirstRow);
      zFirstRow = 0;
    }
    fprintf(p->out, "%s;\n", sqlite4_column_text(pSelect, 0));
    rc = sqlite4_step(pSelect);
  }
  rc = sqlite4_finalize(pSelect);
  if( rc!=SQLITE_OK ){
  if( rc!=SQLITE4_OK ){
    fprintf(p->out, "/**** ERROR: (%d) %s *****/\n", rc, sqlite4_errmsg(p->db));
    p->nErr++;
  }
  return rc;
}

/*
996
997
998
999
1000
1001
1002
1003

1004
1005

1006
1007

1008
1009

1010
1011
1012

1013
1014
1015

1016
1017
1018
1019
1020

1021
1022

1023
1024

1025
1026
1027
1028
1029
1030
1031
996
997
998
999
1000
1001
1002

1003
1004

1005
1006

1007
1008

1009
1010
1011

1012
1013
1014

1015
1016
1017
1018
1019

1020
1021

1022
1023

1024
1025
1026
1027
1028
1029
1030
1031







-
+

-
+

-
+

-
+


-
+


-
+




-
+

-
+

-
+







  int bReset                  /* True to reset the stats */
){
  int iCur;
  int iHiwtr;

  if( pArg && pArg->out && db ){
    iHiwtr = iCur = -1;
    sqlite4_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
    sqlite4_db_status(db, SQLITE4_DBSTATUS_LOOKASIDE_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Lookaside Slots Used:                %d (max %d)\n", iCur, iHiwtr);
    sqlite4_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
    sqlite4_db_status(db, SQLITE4_DBSTATUS_LOOKASIDE_HIT, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Successful lookaside attempts:       %d\n", iHiwtr);
    sqlite4_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
    sqlite4_db_status(db, SQLITE4_DBSTATUS_LOOKASIDE_MISS_SIZE, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Lookaside failures due to size:      %d\n", iHiwtr);
    sqlite4_db_status(db, SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
    sqlite4_db_status(db, SQLITE4_DBSTATUS_LOOKASIDE_MISS_FULL, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Lookaside failures due to OOM:       %d\n", iHiwtr);
    iHiwtr = iCur = -1;
    sqlite4_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
    sqlite4_db_status(db, SQLITE4_DBSTATUS_SCHEMA_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Schema Heap Usage:                   %d bytes\n", iCur); 
    iHiwtr = iCur = -1;
    sqlite4_db_status(db, SQLITE_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
    sqlite4_db_status(db, SQLITE4_DBSTATUS_STMT_USED, &iCur, &iHiwtr, bReset);
    fprintf(pArg->out, "Statement Heap/Lookaside Usage:      %d bytes\n", iCur); 
  }

  if( pArg && pArg->out && db && pArg->pStmt ){
    iCur = sqlite4_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_FULLSCAN_STEP, bReset);
    iCur = sqlite4_stmt_status(pArg->pStmt, SQLITE4_STMTSTATUS_FULLSCAN_STEP, bReset);
    fprintf(pArg->out, "Fullscan Steps:                      %d\n", iCur);
    iCur = sqlite4_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_SORT, bReset);
    iCur = sqlite4_stmt_status(pArg->pStmt, SQLITE4_STMTSTATUS_SORT, bReset);
    fprintf(pArg->out, "Sort Operations:                     %d\n", iCur);
    iCur = sqlite4_stmt_status(pArg->pStmt, SQLITE_STMTSTATUS_AUTOINDEX, bReset);
    iCur = sqlite4_stmt_status(pArg->pStmt, SQLITE4_STMTSTATUS_AUTOINDEX, bReset);
    fprintf(pArg->out, "Autoindex Inserts:                   %d\n", iCur);
  }

  return 0;
}

/*
1042
1043
1044
1045
1046
1047
1048
1049

1050
1051
1052
1053
1054
1055
1056
1057

1058
1059

1060
1061
1062
1063
1064
1065
1066
1042
1043
1044
1045
1046
1047
1048

1049
1050
1051
1052
1053
1054
1055
1056

1057
1058

1059
1060
1061
1062
1063
1064
1065
1066







-
+







-
+

-
+







  const char *zSql,                           /* SQL to be evaluated */
  int (*xCallback)(void*,int,char**,char**,int*),   /* Callback function */
                                              /* (not the same as sqlite4_exec) */
  struct callback_data *pArg,                 /* Pointer to struct callback_data */
  char **pzErrMsg                             /* Error msg written here */
){
  sqlite4_stmt *pStmt = NULL;     /* Statement to execute. */
  int rc = SQLITE_OK;             /* Return Code */
  int rc = SQLITE4_OK;             /* Return Code */
  int rc2;
  const char *zLeftover;          /* Tail of unprocessed SQL */

  if( pzErrMsg ){
    *pzErrMsg = NULL;
  }

  while( zSql[0] && (SQLITE_OK == rc) ){
  while( zSql[0] && (SQLITE4_OK == rc) ){
    rc = sqlite4_prepare(db, zSql, -1, &pStmt, &zLeftover);
    if( SQLITE_OK != rc ){
    if( SQLITE4_OK != rc ){
      if( pzErrMsg ){
        *pzErrMsg = save_err_msg(db);
      }
    }else{
      if( !pStmt ){
        /* this happens for a comment or white-space */
        zSql = zLeftover;
1079
1080
1081
1082
1083
1084
1085
1086

1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097

1098
1099
1100
1101
1102
1103
1104

1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121


1122
1123
1124
1125
1126
1127

1128
1129
1130

1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155


1156
1157
1158
1159
1160
1161
1162
1079
1080
1081
1082
1083
1084
1085

1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096

1097
1098
1099
1100
1101
1102
1103

1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119


1120
1121
1122
1123
1124
1125
1126

1127
1128
1129

1130
1131
1132
1133
1134

1135
1136
1137
1138
1139
1140

1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153


1154
1155
1156
1157
1158
1159
1160
1161
1162







-
+










-
+






-
+















-
-
+
+





-
+


-
+




-
+





-
+












-
-
+
+







        const char *zStmtSql = sqlite4_sql(pStmt);
        fprintf(pArg->out, "%s\n", zStmtSql ? zStmtSql : zSql);
      }

      /* Output TESTCTRL_EXPLAIN text of requested */
      if( pArg && pArg->mode==MODE_Explain ){
        const char *zExplain = 0;
        sqlite4_test_control(SQLITE_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
        sqlite4_test_control(SQLITE4_TESTCTRL_EXPLAIN_STMT, pStmt, &zExplain);
        if( zExplain && zExplain[0] ){
          fprintf(pArg->out, "%s", zExplain);
        }
      }

      /* perform the first step.  this will tell us if we
      ** have a result set or not and how wide it is.
      */
      rc = sqlite4_step(pStmt);
      /* if we have a result set... */
      if( SQLITE_ROW == rc ){
      if( SQLITE4_ROW == rc ){
        /* if we have a callback... */
        if( xCallback ){
          /* allocate space for col name ptr, value ptr, and type */
          int nCol = sqlite4_column_count(pStmt);
          void *pData = sqlite4_malloc(0, 3*nCol*sizeof(const char*) + 1);
          if( !pData ){
            rc = SQLITE_NOMEM;
            rc = SQLITE4_NOMEM;
          }else{
            char **azCols = (char **)pData;      /* Names of result columns */
            char **azVals = &azCols[nCol];       /* Results */
            int *aiTypes = (int *)&azVals[nCol]; /* Result types */
            int i;
            assert(sizeof(int) <= sizeof(char *)); 
            /* save off ptrs to column names */
            for(i=0; i<nCol; i++){
              azCols[i] = (char *)sqlite4_column_name(pStmt, i);
            }
            do{
              /* extract the data and data types */
              for(i=0; i<nCol; i++){
                azVals[i] = (char *)sqlite4_column_text(pStmt, i);
                aiTypes[i] = sqlite4_column_type(pStmt, i);
                if( !azVals[i] && (aiTypes[i]!=SQLITE_NULL) ){
                  rc = SQLITE_NOMEM;
                if( !azVals[i] && (aiTypes[i]!=SQLITE4_NULL) ){
                  rc = SQLITE4_NOMEM;
                  break; /* from for */
                }
              } /* end for */

              /* if data and types extracted successfully... */
              if( SQLITE_ROW == rc ){ 
              if( SQLITE4_ROW == rc ){ 
                /* call the supplied callback with the result row data */
                if( xCallback(pArg, nCol, azVals, azCols, aiTypes) ){
                  rc = SQLITE_ABORT;
                  rc = SQLITE4_ABORT;
                }else{
                  rc = sqlite4_step(pStmt);
                }
              }
            } while( SQLITE_ROW == rc );
            } while( SQLITE4_ROW == rc );
            sqlite4_free(0, pData);
          }
        }else{
          do{
            rc = sqlite4_step(pStmt);
          } while( rc == SQLITE_ROW );
          } while( rc == SQLITE4_ROW );
        }
      }

      /* print usage stats if stats on */
      if( pArg && pArg->statsOn ){
        display_stats(db, pArg, 0);
      }

      /* Finalize the statement just executed. If this fails, save a 
      ** copy of the error message. Otherwise, set zSql to point to the
      ** next statement to execute. */
      rc2 = sqlite4_finalize(pStmt);
      if( rc!=SQLITE_NOMEM ) rc = rc2;
      if( rc==SQLITE_OK ){
      if( rc!=SQLITE4_NOMEM ) rc = rc2;
      if( rc==SQLITE4_OK ){
        zSql = zLeftover;
        while( IsSpace(zSql[0]) ) zSql++;
      }else if( pzErrMsg ){
        *pzErrMsg = save_err_msg(db);
      }

      /* clear saved stmt handle */
1222
1223
1224
1225
1226
1227
1228
1229

1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240

1241
1242
1243
1244
1245

1246
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
1261

1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274

1275
1276
1277
1278
1279
1280
1281
1282
1283
1284

1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300

1301
1302
1303
1304
1305
1306
1307
1222
1223
1224
1225
1226
1227
1228

1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239

1240
1241
1242
1243
1244

1245
1246
1247
1248
1249
1250
1251
1252

1253
1254
1255
1256
1257
1258
1259
1260

1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273

1274
1275
1276
1277
1278
1279
1280
1281
1282
1283

1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299

1300
1301
1302
1303
1304
1305
1306
1307







-
+










-
+




-
+







-
+







-
+












-
+









-
+















-
+







   
    zTableInfo = appendText(zTableInfo, "PRAGMA table_info(", 0);
    zTableInfo = appendText(zTableInfo, zTable, '"');
    zTableInfo = appendText(zTableInfo, ");", 0);

    rc = sqlite4_prepare(p->db, zTableInfo, -1, &pTableInfo, 0);
    free(zTableInfo);
    if( rc!=SQLITE_OK || !pTableInfo ){
    if( rc!=SQLITE4_OK || !pTableInfo ){
      return 1;
    }

    zSelect = appendText(zSelect, "SELECT 'INSERT INTO ' || ", 0);
    zTmp = appendText(zTmp, zTable, '"');
    if( zTmp ){
      zSelect = appendText(zSelect, zTmp, '\'');
    }
    zSelect = appendText(zSelect, " || ' VALUES(' || ", 0);
    rc = sqlite4_step(pTableInfo);
    while( rc==SQLITE_ROW ){
    while( rc==SQLITE4_ROW ){
      const char *zText = (const char *)sqlite4_column_text(pTableInfo, 1);
      zSelect = appendText(zSelect, "quote(", 0);
      zSelect = appendText(zSelect, zText, '"');
      rc = sqlite4_step(pTableInfo);
      if( rc==SQLITE_ROW ){
      if( rc==SQLITE4_ROW ){
        zSelect = appendText(zSelect, ") || ',' || ", 0);
      }else{
        zSelect = appendText(zSelect, ") ", 0);
      }
      nRow++;
    }
    rc = sqlite4_finalize(pTableInfo);
    if( rc!=SQLITE_OK || nRow==0 ){
    if( rc!=SQLITE4_OK || nRow==0 ){
      free(zSelect);
      return 1;
    }
    zSelect = appendText(zSelect, "|| ')' FROM  ", 0);
    zSelect = appendText(zSelect, zTable, '"');

    rc = run_table_dump_query(p, zSelect, zPrepStmt);
    if( rc==SQLITE_CORRUPT ){
    if( rc==SQLITE4_CORRUPT ){
      zSelect = appendText(zSelect, " ORDER BY rowid DESC", 0);
      run_table_dump_query(p, zSelect, 0);
    }
    if( zSelect ) free(zSelect);
  }
  return 0;
}

/*
** Run zQuery.  Use dump_callback() as the callback routine so that
** the contents of the query are output as SQL statements.
**
** If we get a SQLITE_CORRUPT error, rerun the query after appending
** If we get a SQLITE4_CORRUPT error, rerun the query after appending
** "ORDER BY rowid DESC" to the end.
*/
static int run_schema_dump_query(
  struct callback_data *p, 
  const char *zQuery
){
  int rc;
  char *zErr = 0;
  rc = sqlite4_exec(p->db, zQuery, dump_callback, p, &zErr);
  if( rc==SQLITE_CORRUPT ){
  if( rc==SQLITE4_CORRUPT ){
    char *zQ2;
    int len = strlen30(zQuery);
    fprintf(p->out, "/****** CORRUPTION ERROR *******/\n");
    if( zErr ){
      fprintf(p->out, "/****** %s ******/\n", zErr);
      sqlite4_free(0, zErr);
      zErr = 0;
    }
    zQ2 = malloc( len+100 );
    if( zQ2==0 ) return rc;
    sqlite4_snprintf(zQ2,sizeof(zQ2), "%s ORDER BY rowid DESC", zQuery);
    rc = sqlite4_exec(p->db, zQ2, dump_callback, p, &zErr);
    if( rc ){
      fprintf(p->out, "/****** ERROR: %s ******/\n", zErr);
    }else{
      rc = SQLITE_CORRUPT;
      rc = SQLITE4_CORRUPT;
    }
    sqlite4_free(0, zErr);
    free(zQ2);
  }
  return rc;
}

1320
1321
1322
1323
1324
1325
1326
1327

1328
1329
1330

1331
1332
1333
1334
1335
1336
1337
1320
1321
1322
1323
1324
1325
1326

1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
1337







-
+


-
+







  "                         With no args, it turns EXPLAIN on.\n"
  ".header(s) ON|OFF      Turn display of headers on or off\n"
  ".help                  Show this message\n"
  ".import FILE TABLE     Import data from FILE into TABLE\n"
  ".indices ?TABLE?       Show names of all indices\n"
  "                         If TABLE specified, only show indices for tables\n"
  "                         matching LIKE pattern TABLE.\n"
#ifdef SQLITE_ENABLE_IOTRACE
#ifdef SQLITE4_ENABLE_IOTRACE
  ".iotrace FILE          Enable I/O diagnostic logging to FILE\n"
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
#ifndef SQLITE4_OMIT_LOAD_EXTENSION
  ".load FILE ?ENTRY?     Load an extension library\n"
#endif
  ".log FILE|off          Turn logging on or off.  FILE can be stderr/stdout\n"
  ".mode MODE ?TABLE?     Set output mode where MODE is one of:\n"
  "                         csv      Comma-separated values\n"
  "                         column   Left-aligned columns.  (See .width)\n"
  "                         html     HTML <table> code\n"
1369
1370
1371
1372
1373
1374
1375
1376
1377


1378
1379
1380

1381
1382
1383
1384
1385

1386
1387
1388
1389
1390
1391
1392
1369
1370
1371
1372
1373
1374
1375


1376
1377
1378
1379

1380
1381
1382
1383
1384

1385
1386
1387
1388
1389
1390
1391
1392







-
-
+
+


-
+




-
+







** Make sure the database is open.  If it is not, then open it.  If
** the database fails to open, print an error message and exit.
*/
static void open_db(struct callback_data *p){
  if( p->db==0 ){
    sqlite4_open(0, p->zDbFilename, &p->db, 0);
    db = p->db;
    if( db && sqlite4_errcode(db)==SQLITE_OK ){
      sqlite4_create_function(db, "shellstatic", 0, SQLITE_UTF8, 0,
    if( db && sqlite4_errcode(db)==SQLITE4_OK ){
      sqlite4_create_function(db, "shellstatic", 0, SQLITE4_UTF8, 0,
          shellstaticFunc, 0, 0);
    }
    if( db==0 || SQLITE_OK!=sqlite4_errcode(db) ){
    if( db==0 || SQLITE4_OK!=sqlite4_errcode(db) ){
      fprintf(stderr,"Error: unable to open database \"%s\": %s\n", 
          p->zDbFilename, sqlite4_errmsg(db));
      exit(1);
    }
#if 0 /*ndef SQLITE_OMIT_LOAD_EXTENSION*/
#if 0 /*ndef SQLITE4_OMIT_LOAD_EXTENSION*/
    sqlite4_enable_load_extension(p->db, 1);
#endif
  }
}

/*
** Do C-language style dequoting.
1713
1714
1715
1716
1717
1718
1719
1720

1721
1722
1723
1724
1725

1726
1727
1728
1729
1730
1731
1732
1713
1714
1715
1716
1717
1718
1719

1720
1721
1722
1723
1724

1725
1726
1727
1728
1729
1730
1731
1732







-
+




-
+







          int k;
          for(z=azCol[i], j=1, k=0; z[j]; j++){
            if( z[j]=='"' ){ j++; if( z[j]==0 ) break; }
            z[k++] = z[j];
          }
          z[k] = 0;
        }
        sqlite4_bind_text(pStmt, i+1, azCol[i], -1, SQLITE_STATIC);
        sqlite4_bind_text(pStmt, i+1, azCol[i], -1, SQLITE4_STATIC);
      }
      sqlite4_step(pStmt);
      rc = sqlite4_reset(pStmt);
      free(zLine);
      if( rc!=SQLITE_OK ){
      if( rc!=SQLITE4_OK ){
        fprintf(stderr,"Error: %s\n", sqlite4_errmsg(db));
        zCommit = "ROLLBACK";
        rc = 1;
        break; /* from while */
      }
    } /* end while */
    free(azCol);
1765
1766
1767
1768
1769
1770
1771
1772

1773
1774
1775
1776
1777
1778

1779
1780
1781
1782
1783
1784
1785
1765
1766
1767
1768
1769
1770
1771

1772
1773
1774
1775
1776
1777

1778
1779
1780
1781
1782
1783
1784
1785







-
+





-
+







      );
      zShellStatic = 0;
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite4_free(0, zErrMsg);
      rc = 1;
    }else if( rc != SQLITE_OK ){
    }else if( rc != SQLITE4_OK ){
      fprintf(stderr,"Error: querying sqlite_master and sqlite_temp_master\n");
      rc = 1;
    }
  }else

#ifdef SQLITE_ENABLE_IOTRACE
#ifdef SQLITE4_ENABLE_IOTRACE
  if( c=='i' && strncmp(azArg[0], "iotrace", n)==0 ){
    extern void (*sqlite4IoTrace)(const char*, ...);
    if( iotrace && iotrace!=stdout ) fclose(iotrace);
    iotrace = 0;
    if( nArg<2 ){
      sqlite4IoTrace = 0;
    }else if( strcmp(azArg[1], "-")==0 ){
1794
1795
1796
1797
1798
1799
1800
1801

1802
1803
1804
1805
1806
1807
1808
1809

1810
1811
1812
1813
1814
1815
1816
1794
1795
1796
1797
1798
1799
1800

1801
1802
1803
1804
1805
1806
1807
1808

1809
1810
1811
1812
1813
1814
1815
1816







-
+







-
+







      }else{
        sqlite4IoTrace = iotracePrintf;
      }
    }
  }else
#endif

#if 0 /*ndef SQLITE_OMIT_LOAD_EXTENSION*/
#if 0 /*ndef SQLITE4_OMIT_LOAD_EXTENSION*/
  if( c=='l' && strncmp(azArg[0], "load", n)==0 && nArg>=2 ){
    const char *zFile, *zProc;
    char *zErrMsg = 0;
    zFile = azArg[1];
    zProc = nArg>=3 ? azArg[2] : 0;
    open_db(p);
    rc = sqlite4_load_extension(p->db, zFile, zProc, &zErrMsg);
    if( rc!=SQLITE_OK ){
    if( rc!=SQLITE4_OK ){
      fprintf(stderr, "Error: %s\n", zErrMsg);
      sqlite4_free(0, zErrMsg);
      rc = 1;
    }
  }else
#endif

1946
1947
1948
1949
1950
1951
1952
1953

1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967

1968
1969
1970
1971
1972
1973
1974
1946
1947
1948
1949
1950
1951
1952

1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966

1967
1968
1969
1970
1971
1972
1973
1974







-
+













-
+







                      "  rootpage integer,\n"
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
        rc = SQLITE_OK;
        rc = SQLITE4_OK;
      }else if( strcmp(azArg[1],"sqlite_temp_master")==0 ){
        char *new_argv[2], *new_colv[2];
        new_argv[0] = "CREATE TEMP TABLE sqlite_temp_master (\n"
                      "  type text,\n"
                      "  name text,\n"
                      "  tbl_name text,\n"
                      "  rootpage integer,\n"
                      "  sql text\n"
                      ")";
        new_argv[1] = 0;
        new_colv[0] = "sql";
        new_colv[1] = 0;
        callback(&data, 1, new_argv, new_colv);
        rc = SQLITE_OK;
        rc = SQLITE4_OK;
      }else{
        zShellStatic = azArg[1];
        rc = sqlite4_exec(p->db,
          "SELECT sql FROM "
          "  (SELECT sql sql, type type, tbl_name tbl_name, name name"
          "     FROM sqlite_master UNION ALL"
          "   SELECT sql, type, tbl_name, name FROM sqlite_temp_master) "
1989
1990
1991
1992
1993
1994
1995
1996

1997
1998
1999
2000
2001
2002
2003
1989
1990
1991
1992
1993
1994
1995

1996
1997
1998
1999
2000
2001
2002
2003







-
+







         callback, &data, &zErrMsg
      );
    }
    if( zErrMsg ){
      fprintf(stderr,"Error: %s\n", zErrMsg);
      sqlite4_free(0, zErrMsg);
      rc = 1;
    }else if( rc != SQLITE_OK ){
    }else if( rc != SQLITE4_OK ){
      fprintf(stderr,"Error: querying schema information\n");
      rc = 1;
    }else{
      rc = 0;
    }
  }else

2042
2043
2044
2045
2046
2047
2048
2049

2050
2051
2052
2053
2054
2055
2056
2042
2043
2044
2045
2046
2047
2048

2049
2050
2051
2052
2053
2054
2055
2056







-
+







    rc = sqlite4_prepare(p->db, "PRAGMA database_list", -1, &pStmt, 0);
    if( rc ) return rc;
    zSql = sqlite4_mprintf(0, 
        "SELECT name FROM sqlite_master"
        " WHERE type IN ('table','view')"
        "   AND name NOT LIKE 'sqlite_%%'"
        "   AND name LIKE ?1");
    while( sqlite4_step(pStmt)==SQLITE_ROW ){
    while( sqlite4_step(pStmt)==SQLITE4_ROW ){
      const char *zDbName = (const char*)sqlite4_column_text(pStmt, 1);
      if( zDbName==0 || strcmp(zDbName,"main")==0 ) continue;
      if( strcmp(zDbName,"temp")==0 ){
        zSql = sqlite4_mprintf(0, 
                 "%z UNION ALL "
                 "SELECT 'temp.' || name FROM sqlite_temp_master"
                 " WHERE type IN ('table','view')"
2069
2070
2071
2072
2073
2074
2075
2076

2077
2078

2079
2080

2081
2082
2083
2084
2085
2086
2087
2069
2070
2071
2072
2073
2074
2075

2076
2077

2078
2079

2080
2081
2082
2083
2084
2085
2086
2087







-
+

-
+

-
+







    zSql = sqlite4_mprintf(0, "%z ORDER BY 1", zSql);
    rc = sqlite4_prepare(p->db, zSql, -1, &pStmt, 0);
    sqlite4_free(0, zSql);
    if( rc ) return rc;
    nRow = nAlloc = 0;
    azResult = 0;
    if( nArg>1 ){
      sqlite4_bind_text(pStmt, 1, azArg[1], -1, SQLITE_TRANSIENT);
      sqlite4_bind_text(pStmt, 1, azArg[1], -1, SQLITE4_TRANSIENT);
    }else{
      sqlite4_bind_text(pStmt, 1, "%", -1, SQLITE_STATIC);
      sqlite4_bind_text(pStmt, 1, "%", -1, SQLITE4_STATIC);
    }
    while( sqlite4_step(pStmt)==SQLITE_ROW ){
    while( sqlite4_step(pStmt)==SQLITE4_ROW ){
      if( nRow>=nAlloc ){
        char **azNew;
        int n = nAlloc*2 + 10;
        azNew = sqlite4_realloc(0, azResult, sizeof(azResult[0])*n);
        if( azNew==0 ){
          fprintf(stderr, "Error: out of memory\n");
          break;
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128





2129
2130
2131
2132
2133
2134
2135
2117
2118
2119
2120
2121
2122
2123





2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135







-
-
-
-
-
+
+
+
+
+







  }else

  if( c=='t' && n>=8 && strncmp(azArg[0], "testctrl", n)==0 && nArg>=2 ){
    static const struct {
       const char *zCtrlName;   /* Name of a test-control option */
       int ctrlCode;            /* Integer code for that option */
    } aCtrl[] = {
      { "fault_install",         SQLITE_TESTCTRL_FAULT_INSTALL          },
      { "assert",                SQLITE_TESTCTRL_ASSERT                 },
      { "always",                SQLITE_TESTCTRL_ALWAYS                 },
      { "optimizations",         SQLITE_TESTCTRL_OPTIMIZATIONS          },
      { "iskeyword",             SQLITE_TESTCTRL_ISKEYWORD              },
      { "fault_install",         SQLITE4_TESTCTRL_FAULT_INSTALL          },
      { "assert",                SQLITE4_TESTCTRL_ASSERT                 },
      { "always",                SQLITE4_TESTCTRL_ALWAYS                 },
      { "optimizations",         SQLITE4_TESTCTRL_OPTIMIZATIONS          },
      { "iskeyword",             SQLITE4_TESTCTRL_ISKEYWORD              },
    };
    int testctrl = -1;
    int rc = 0;
    int i, n;
    open_db(p);

    /* convert testctrl text option to value. allow any unique prefix
2143
2144
2145
2146
2147
2148
2149
2150

2151
2152
2153
2154
2155
2156
2157


2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170


2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183


2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195

2196
2197
2198
2199
2200
2201
2202
2143
2144
2145
2146
2147
2148
2149

2150
2151
2152
2153
2154
2155


2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168


2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181


2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194

2195
2196
2197
2198
2199
2200
2201
2202







-
+





-
-
+
+











-
-
+
+











-
-
+
+











-
+







          fprintf(stderr, "ambiguous option name: \"%s\"\n", azArg[1]);
          testctrl = -1;
          break;
        }
      }
    }
    if( testctrl<0 ) testctrl = atoi(azArg[1]);
    if( (testctrl<SQLITE_TESTCTRL_FIRST) || (testctrl>SQLITE_TESTCTRL_LAST) ){
    if( (testctrl<SQLITE4_TESTCTRL_FIRST) || (testctrl>SQLITE4_TESTCTRL_LAST) ){
      fprintf(stderr,"Error: invalid testctrl option: %s\n", azArg[1]);
    }else{
      switch(testctrl){

        /* sqlite4_test_control(int, db, int) */
        case SQLITE_TESTCTRL_OPTIMIZATIONS:
        case SQLITE_TESTCTRL_RESERVE:             
        case SQLITE4_TESTCTRL_OPTIMIZATIONS:
        case SQLITE4_TESTCTRL_RESERVE:             
          if( nArg==3 ){
            int opt = (int)strtol(azArg[2], 0, 0);        
            rc = sqlite4_test_control(testctrl, p->db, opt);
            printf("%d (0x%08x)\n", rc, rc);
          } else {
            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
                    azArg[1]);
          }
          break;

        /* sqlite4_test_control(int, int) */
        case SQLITE_TESTCTRL_ASSERT:              
        case SQLITE_TESTCTRL_ALWAYS:              
        case SQLITE4_TESTCTRL_ASSERT:              
        case SQLITE4_TESTCTRL_ALWAYS:              
          if( nArg==3 ){
            int opt = atoi(azArg[2]);        
            rc = sqlite4_test_control(testctrl, opt);
            printf("%d (0x%08x)\n", rc, rc);
          } else {
            fprintf(stderr,"Error: testctrl %s takes a single int option\n",
                            azArg[1]);
          }
          break;

        /* sqlite4_test_control(int, char *) */
#ifdef SQLITE_N_KEYWORD
        case SQLITE_TESTCTRL_ISKEYWORD:           
#ifdef SQLITE4_N_KEYWORD
        case SQLITE4_TESTCTRL_ISKEYWORD:           
          if( nArg==3 ){
            const char *opt = azArg[2];        
            rc = sqlite4_test_control(testctrl, opt);
            printf("%d (0x%08x)\n", rc, rc);
          } else {
            fprintf(stderr,"Error: testctrl %s takes a single char * option\n",
                            azArg[1]);
          }
          break;
#endif

        case SQLITE_TESTCTRL_FAULT_INSTALL:       
        case SQLITE4_TESTCTRL_FAULT_INSTALL:       
        default:
          fprintf(stderr,"Error: CLI support for testctrl %s not implemented\n",
                  azArg[1]);
          break;
      }
    }
  }else
2529
2530
2531
2532
2533
2534
2535
2536

2537
2538
2539
2540
2541
2542
2543
2529
2530
2531
2532
2533
2534
2535

2536
2537
2538
2539
2540
2541
2542
2543







-
+







  "   -html                set output mode to HTML\n"
  "   -line                set output mode to 'line'\n"
  "   -list                set output mode to 'list'\n"
  "   -separator 'x'       set output field separator (|)\n"
  "   -stats               print memory stats before each finalize\n"
  "   -nullvalue 'text'    set text string for NULL values\n"
  "   -version             show SQLite version\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
#ifdef SQLITE4_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
;
static void usage(int showDetail){
  fprintf(stderr,
      "Usage: %s [OPTIONS] FILENAME [SQL]\n"  
      "FILENAME is the name of an SQLite database. A new database is created\n"
2554
2555
2556
2557
2558
2559
2560
2561

2562
2563
2564

2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575

2576
2577

2578
2579
2580
2581
2582
2583
2584
2554
2555
2556
2557
2558
2559
2560

2561
2562
2563

2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574

2575
2576

2577
2578
2579
2580
2581
2582
2583
2584







-
+


-
+










-
+

-
+







** Initialize the state information in data
*/
static void main_init(struct callback_data *data) {
  memset(data, 0, sizeof(*data));
  data->mode = MODE_List;
  memcpy(data->separator,"|", 2);
  data->showHeader = 0;
  sqlite4_env_config(0, SQLITE_ENVCONFIG_LOG, shellLog, data);
  sqlite4_env_config(0, SQLITE4_ENVCONFIG_LOG, shellLog, data);
  sqlite4_snprintf(mainPrompt,sizeof(mainPrompt),        "sqlite> ");
  sqlite4_snprintf(continuePrompt,sizeof(continuePrompt),"   ...> ");
  sqlite4_env_config(0, SQLITE_ENVCONFIG_SINGLETHREAD);
  sqlite4_env_config(0, SQLITE4_ENVCONFIG_SINGLETHREAD);
}

int main(int argc, char **argv){
  char *zErrMsg = 0;
  struct callback_data data;
  const char *zInitFile = 0;
  char *zFirstCmd = 0;
  int i;
  int rc = 0;

  if( strcmp(sqlite4_sourceid(),SQLITE_SOURCE_ID)!=0 ){
  if( strcmp(sqlite4_sourceid(),SQLITE4_SOURCE_ID)!=0 ){
    fprintf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
            sqlite4_sourceid(), SQLITE_SOURCE_ID);
            sqlite4_sourceid(), SQLITE4_SOURCE_ID);
    exit(1);
  }
  Argv0 = argv[0];
  main_init(&data);
  stdin_is_interactive = isatty(0);

  /* Make sure we have a valid signal handler early, before anything
2606
2607
2608
2609
2610
2611
2612
2613

2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626

2627
2628

2629
2630
2631
2632
2633
2634
2635
2636

2637
2638
2639
2640
2641
2642

2643
2644
2645
2646
2647
2648
2649
2606
2607
2608
2609
2610
2611
2612

2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625

2626
2627

2628
2629
2630
2631
2632
2633
2634
2635

2636
2637
2638
2639
2640
2641

2642
2643
2644
2645
2646
2647
2648
2649







-
+












-
+

-
+







-
+





-
+







    /* Need to check for batch mode here to so we can avoid printing
    ** informational messages (like from process_sqliterc) before 
    ** we do the actual processing of arguments later in a second pass.
    */
    }else if( strcmp(argv[i],"-batch")==0 ){
      stdin_is_interactive = 0;
    }else if( strcmp(argv[i],"-heap")==0 ){
#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
#if defined(SQLITE4_ENABLE_MEMSYS3) || defined(SQLITE4_ENABLE_MEMSYS5)
      int j, c;
      const char *zSize;
      sqlite4_int64 szHeap;

      zSize = argv[++i];
      szHeap = atoi(zSize);
      for(j=0; (c = zSize[j])!=0; j++){
        if( c=='M' ){ szHeap *= 1000000; break; }
        if( c=='K' ){ szHeap *= 1000; break; }
        if( c=='G' ){ szHeap *= 1000000000; break; }
      }
      if( szHeap>0x7fff0000 ) szHeap = 0x7fff0000;
      sqlite4_config(0,SQLITE_CONFIG_HEAP, malloc((int)szHeap),(int)szHeap,64);
      sqlite4_config(0,SQLITE4_CONFIG_HEAP, malloc((int)szHeap),(int)szHeap,64);
#endif
#ifdef SQLITE_ENABLE_MULTIPLEX
#ifdef SQLITE4_ENABLE_MULTIPLEX
    }else if( strcmp(argv[i],"-multiplex")==0 ){
      extern int sqlite4_multiple_initialize(const char*,int);
      sqlite4_multiplex_initialize(0, 1);
#endif
    }
  }
  if( i<argc ){
#if defined(SQLITE_OS_OS2) && SQLITE_OS_OS2
#if defined(SQLITE4_OS_OS2) && SQLITE4_OS_OS2
    data.zDbFilename = (const char *)convertCpPathToUtf8( argv[i++] );
#else
    data.zDbFilename = argv[i++];
#endif
  }else{
#ifndef SQLITE_OMIT_MEMORYDB
#ifndef SQLITE4_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
#else
    data.zDbFilename = 0;
#endif
    /***** Begin Fossil Patch *****/
    {
      extern void fossil_open(const char **);
2657
2658
2659
2660
2661
2662
2663
2664

2665
2666
2667
2668
2669
2670
2671
2657
2658
2659
2660
2661
2662
2663

2664
2665
2666
2667
2668
2669
2670
2671







-
+







  if( i<argc ){
    fprintf(stderr,"%s: Error: too many options: \"%s\"\n", Argv0, argv[i]);
    fprintf(stderr,"Use -help for a list of options.\n");
    return 1;
  }
  data.out = stdout;

#ifdef SQLITE_OMIT_MEMORYDB
#ifdef SQLITE4_OMIT_MEMORYDB
  if( data.zDbFilename==0 ){
    fprintf(stderr,"%s: Error: no database filename specified\n", Argv0);
    return 1;
  }
#endif

  /* Go ahead and open the database file if it already exists.  If the
2740
2741
2742
2743
2744
2745
2746
2747

2748
2749
2750
2751
2752
2753
2754
2740
2741
2742
2743
2744
2745
2746

2747
2748
2749
2750
2751
2752
2753
2754







-
+







      return 0;
    }else if( strcmp(z,"-interactive")==0 ){
      stdin_is_interactive = 1;
    }else if( strcmp(z,"-batch")==0 ){
      stdin_is_interactive = 0;
    }else if( strcmp(z,"-heap")==0 ){
      i++;
#ifdef SQLITE_ENABLE_MULTIPLEX
#ifdef SQLITE4_ENABLE_MULTIPLEX
    }else if( strcmp(z,"-multiplex")==0 ){
      i++;
#endif
    }else if( strcmp(z,"-help")==0 || strcmp(z, "--help")==0 ){
      usage(1);
    }else{
      fprintf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);