Fossil

Check-in [4d34e18c21]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Latest upstream sqlite3 shell.c, primarily to squelch warnings on cygwin.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 4d34e18c213827effeafd3c7f05aa0ac1ca8ddb90b49f8453e503c54dd47aca4
User & Date: stephan 2025-03-06 07:49:42.168
Context
2025-03-06
11:01
Work around issues with aggressive caching of pikchr.wasm that were making it difficult to upgrade. (1) On the /built-in page, allow filenames to have text of the form -vNNNNNNNN before the file suffix, where N is an arbitrary digit and there are at least 8 of them. The extra -vNNNNNNNN is removed before looking up the file. (2) When running "make wasm" modify the generated scripts to add random -vNNNNNNNN values to key filenames, so that browsers won't try to use the old names still in cache. check-in: dd20f34950 user: drh tags: trunk
07:49
Latest upstream sqlite3 shell.c, primarily to squelch warnings on cygwin. check-in: 4d34e18c21 user: stephan tags: trunk
2025-03-05
15:52
Update the Environment Variables and Global Options document and the Change Log to reflect current development. (Plus an unrelated formatting fix in the first document.) check-in: 007fd18d69 user: florian tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to extsrc/shell.c.
232
233
234
235
236
237
238


239
240
241
242
243
244
245
#define isatty(x) 1
#endif

/* ctype macros that work with signed characters */
#define IsSpace(X)  isspace((unsigned char)X)
#define IsDigit(X)  isdigit((unsigned char)X)
#define ToLower(X)  (char)tolower((unsigned char)X)



#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
#include <intrin.h>
#endif
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN







>
>







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
#define isatty(x) 1
#endif

/* ctype macros that work with signed characters */
#define IsSpace(X)  isspace((unsigned char)X)
#define IsDigit(X)  isdigit((unsigned char)X)
#define ToLower(X)  (char)tolower((unsigned char)X)
#define IsAlnum(X)  isalnum((unsigned char)X)
#define IsAlpha(X)  isalpha((unsigned char)X)

#if defined(_WIN32) || defined(WIN32)
#if SQLITE_OS_WINRT
#include <intrin.h>
#endif
#undef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
** that quoting is required.
**
** Return '"' if quoting is required.  Return 0 if no quoting is required.
*/
static char quoteChar(const char *zName){
  int i;
  if( zName==0 ) return '"';
  if( !isalpha((unsigned char)zName[0]) && zName[0]!='_' ) return '"';
  for(i=0; zName[i]; i++){
    if( !isalnum((unsigned char)zName[i]) && zName[i]!='_' ) return '"';
  }
  return sqlite3_keyword_check(zName, i) ? '"' : 0;
}

/*
** Construct a fake object name and column list to describe the structure
** of the view, virtual table, or table valued function zSchema.zName.







|

|







1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
** that quoting is required.
**
** Return '"' if quoting is required.  Return 0 if no quoting is required.
*/
static char quoteChar(const char *zName){
  int i;
  if( zName==0 ) return '"';
  if( !IsAlpha(zName[0]) && zName[0]!='_' ) return '"';
  for(i=0; zName[i]; i++){
    if( !IsAlnum(zName[i]) && zName[i]!='_' ) return '"';
  }
  return sqlite3_keyword_check(zName, i) ? '"' : 0;
}

/*
** Construct a fake object name and column list to describe the structure
** of the view, virtual table, or table valued function zSchema.zName.
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
**                             Notice the ":" at the end of the prefix, which
**                             is needed to separate the prefix from the
**                             content in cases where the content starts
**                             with a digit.
**
**    typeof(Y)='blob'         The hash is taken over prefix "Bnnn:" followed
**                             by the binary content of the blob.  The "nnn"
**                             in the prefix is the mimimum-length decimal
**                             representation of the byte-length of the blob.
**
** According to the rules above, all of the following SELECT statements
** should return TRUE:
**
**    SELECT sha3(1) = sha3('1');
**







|







2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
**                             Notice the ":" at the end of the prefix, which
**                             is needed to separate the prefix from the
**                             content in cases where the content starts
**                             with a digit.
**
**    typeof(Y)='blob'         The hash is taken over prefix "Bnnn:" followed
**                             by the binary content of the blob.  The "nnn"
**                             in the prefix is the minimum-length decimal
**                             representation of the byte-length of the blob.
**
** According to the rules above, all of the following SELECT statements
** should return TRUE:
**
**    SELECT sha3(1) = sha3('1');
**
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
**
** This SQLite extension implements the UINT collating sequence.
**
** UINT works like BINARY for text, except that embedded strings
** of digits compare in numeric order.
**
**     *   Leading zeros are handled properly, in the sense that
**         they do not mess of the maginitude comparison of embedded
**         strings of digits.  "x00123y" is equal to "x123y".
**
**     *   Only unsigned integers are recognized.  Plus and minus
**         signs are ignored.  Decimal points and exponential notation
**         are ignored.
**
**     *   Embedded integers can be of arbitrary length.  Comparison







|







3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
**
** This SQLite extension implements the UINT collating sequence.
**
** UINT works like BINARY for text, except that embedded strings
** of digits compare in numeric order.
**
**     *   Leading zeros are handled properly, in the sense that
**         they do not mess of the magnitude comparison of embedded
**         strings of digits.  "x00123y" is equal to "x123y".
**
**     *   Only unsigned integers are recognized.  Plus and minus
**         signs are ignored.  Decimal points and exponential notation
**         are ignored.
**
**     *   Embedded integers can be of arbitrary length.  Comparison
3750
3751
3752
3753
3754
3755
3756



3757
3758
3759
3760
3761
3762
3763

/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
#ifndef UNUSED_PARAMETER
# define UNUSED_PARAMETER(X)  (void)(X)
#endif





/* A decimal object */
typedef struct Decimal Decimal;
struct Decimal {
  char sign;        /* 0 for positive, 1 for negative */
  char oom;         /* True if an OOM is encountered */
  char isNull;      /* True if holds a NULL rather than a number */







>
>
>







3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
3765
3766
3767
3768

/* Mark a function parameter as unused, to suppress nuisance compiler
** warnings. */
#ifndef UNUSED_PARAMETER
# define UNUSED_PARAMETER(X)  (void)(X)
#endif

#ifndef IsSpace
#define IsSpace(X)  isspace((unsigned char)X)
#endif

/* A decimal object */
typedef struct Decimal Decimal;
struct Decimal {
  char sign;        /* 0 for positive, 1 for negative */
  char oom;         /* True if an OOM is encountered */
  char isNull;      /* True if holds a NULL rather than a number */
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
  p->oom = 0;
  p->isInit = 1;
  p->isNull = 0;
  p->nDigit = 0;
  p->nFrac = 0;
  p->a = sqlite3_malloc64( n+1 );
  if( p->a==0 ) goto new_from_text_failed;
  for(i=0; isspace(zIn[i]); i++){}
  if( zIn[i]=='-' ){
    p->sign = 1;
    i++;
  }else if( zIn[i]=='+' ){
    i++;
  }
  while( i<n && zIn[i]=='0' ) i++;







|







3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
  p->oom = 0;
  p->isInit = 1;
  p->isNull = 0;
  p->nDigit = 0;
  p->nFrac = 0;
  p->a = sqlite3_malloc64( n+1 );
  if( p->a==0 ) goto new_from_text_failed;
  for(i=0; IsSpace(zIn[i]); i++){}
  if( zIn[i]=='-' ){
    p->sign = 1;
    i++;
  }else if( zIn[i]=='+' ){
    i++;
  }
  while( i<n && zIn[i]=='0' ) i++;
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
    decimal_add(pA, pB);
    decimal_result(context, pA);
  }
  decimal_free(pA);
  decimal_free(pB);
}

/* Aggregate funcion:   decimal_sum(X)
**
** Works like sum() except that it uses decimal arithmetic for unlimited
** precision.
*/
static void decimalSumStep(
  sqlite3_context *context,
  int argc,







|







4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
    decimal_add(pA, pB);
    decimal_result(context, pA);
  }
  decimal_free(pA);
  decimal_free(pB);
}

/* Aggregate function:   decimal_sum(X)
**
** Works like sum() except that it uses decimal arithmetic for unlimited
** precision.
*/
static void decimalSumStep(
  sqlite3_context *context,
  int argc,
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
  if( bExact ) return -1;
  return iFirst;
}

/*
** Generate an error for a percentile function.
**
** The error format string must have exactly one occurrance of "%%s()"
** (with two '%' characters).  That substring will be replaced by the name
** of the function.
*/
static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){
  PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
  char *zMsg1;
  char *zMsg2;







|







4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
  if( bExact ) return -1;
  return iFirst;
}

/*
** Generate an error for a percentile function.
**
** The error format string must have exactly one occurrence of "%%s()"
** (with two '%' characters).  That substring will be replaced by the name
** of the function.
*/
static void percentError(sqlite3_context *pCtx, const char *zFormat, ...){
  PercentileFunc *pFunc = (PercentileFunc*)sqlite3_user_data(pCtx);
  char *zMsg1;
  char *zMsg2;
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
**
** Here is a query to show various boundry values for the binary64
** number format:
**
**    WITH c(name,bin) AS (VALUES
**       ('minimum positive value',        x'0000000000000001'),
**       ('maximum subnormal value',       x'000fffffffffffff'),
**       ('mininum positive nornal value', x'0010000000000000'),
**       ('maximum value',                 x'7fefffffffffffff'))
**    SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
**
*/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1







|







5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
**
** Here is a query to show various boundry values for the binary64
** number format:
**
**    WITH c(name,bin) AS (VALUES
**       ('minimum positive value',        x'0000000000000001'),
**       ('maximum subnormal value',       x'000fffffffffffff'),
**       ('minimum positive normal value', x'0010000000000000'),
**       ('maximum value',                 x'7fefffffffffffff'))
**    SELECT c.name, decimal_mul(ieee754_mantissa(c.bin),pow2.v)
**      FROM pow2, c WHERE pow2.x=ieee754_exponent(c.bin);
**
*/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
6342
6343
6344
6345
6346
6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
    ix -= mxI64;
    /* With 2's complement ALU, this next can be 1 step, but is split into
     * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */
    smBase += (mxI64/2) * smStep;
    smBase += (mxI64 - mxI64/2) * smStep;
  }
  /* Under UBSAN (or on 1's complement machines), must do this last term
   * in steps to avoid the dreaded (and harmless) signed multiply overlow. */
  if( ix>=2 ){
    sqlite3_int64 ix2 = (sqlite3_int64)ix/2;
    smBase += ix2*smStep;
    ix -= ix2;
  }
  return smBase + ((sqlite3_int64)ix)*smStep;
}







|







6347
6348
6349
6350
6351
6352
6353
6354
6355
6356
6357
6358
6359
6360
6361
    ix -= mxI64;
    /* With 2's complement ALU, this next can be 1 step, but is split into
     * 2 for UBSAN's satisfaction (and hypothetical 1's complement ALUs.) */
    smBase += (mxI64/2) * smStep;
    smBase += (mxI64 - mxI64/2) * smStep;
  }
  /* Under UBSAN (or on 1's complement machines), must do this last term
   * in steps to avoid the dreaded (and harmless) signed multiply overflow. */
  if( ix>=2 ){
    sqlite3_int64 ix2 = (sqlite3_int64)ix/2;
    smBase += ix2*smStep;
    ix -= ix2;
  }
  return smBase + ((sqlite3_int64)ix)*smStep;
}
9022
9023
9024
9025
9026
9027
9028





9029
9030
9031
9032
9033
9034
9035
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE






/* completion_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a completion virtual table
*/
typedef struct completion_vtab completion_vtab;
struct completion_vtab {
  sqlite3_vtab base;  /* Base class - must be first */







>
>
>
>
>







9027
9028
9029
9030
9031
9032
9033
9034
9035
9036
9037
9038
9039
9040
9041
9042
9043
9044
9045
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <ctype.h>

#ifndef SQLITE_OMIT_VIRTUALTABLE

#ifndef IsAlnum
#define IsAlnum(X)  isalnum((unsigned char)X)
#endif


/* completion_vtab is a subclass of sqlite3_vtab which will
** serve as the underlying representation of a completion virtual table
*/
typedef struct completion_vtab completion_vtab;
struct completion_vtab {
  sqlite3_vtab base;  /* Base class - must be first */
9359
9360
9361
9362
9363
9364
9365
9366
9367
9368
9369
9370
9371
9372
9373
    if( pCur->nLine>0 ){
      pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
      if( pCur->zLine==0 ) return SQLITE_NOMEM;
    }
  }
  if( pCur->zLine!=0 && pCur->zPrefix==0 ){
    int i = pCur->nLine;
    while( i>0 && (isalnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
      i--;
    }
    pCur->nPrefix = pCur->nLine - i;
    if( pCur->nPrefix>0 ){
      pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
    }







|







9369
9370
9371
9372
9373
9374
9375
9376
9377
9378
9379
9380
9381
9382
9383
    if( pCur->nLine>0 ){
      pCur->zLine = sqlite3_mprintf("%s", sqlite3_value_text(argv[iArg]));
      if( pCur->zLine==0 ) return SQLITE_NOMEM;
    }
  }
  if( pCur->zLine!=0 && pCur->zPrefix==0 ){
    int i = pCur->nLine;
    while( i>0 && (IsAlnum(pCur->zLine[i-1]) || pCur->zLine[i-1]=='_') ){
      i--;
    }
    pCur->nPrefix = pCur->nLine - i;
    if( pCur->nPrefix>0 ){
      pCur->zPrefix = sqlite3_mprintf("%.*s", pCur->nPrefix, pCur->zLine + i);
      if( pCur->zPrefix==0 ) return SQLITE_NOMEM;
    }
14766
14767
14768
14769
14770
14771
14772
14773
14774
14775
14776
14777
14778
14779
14780
  }

  /* Register the auth callback with dbv */
  if( rc==SQLITE_OK ){
    sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
  }

  /* If an error has occurred, free the new object and reutrn NULL. Otherwise,
  ** return the new sqlite3expert handle.  */
  if( rc!=SQLITE_OK ){
    sqlite3_expert_destroy(pNew);
    pNew = 0;
  }
  return pNew;
}







|







14776
14777
14778
14779
14780
14781
14782
14783
14784
14785
14786
14787
14788
14789
14790
  }

  /* Register the auth callback with dbv */
  if( rc==SQLITE_OK ){
    sqlite3_set_authorizer(pNew->dbv, idxAuthCallback, (void*)pNew);
  }

  /* If an error has occurred, free the new object and return NULL. Otherwise,
  ** return the new sqlite3expert handle.  */
  if( rc!=SQLITE_OK ){
    sqlite3_expert_destroy(pNew);
    pNew = 0;
  }
  return pNew;
}
16288
16289
16290
16291
16292
16293
16294
16295
16296
16297
16298
16299
16300
16301
16302
**
** To enable all output (which is the default setting):
**
**    PRAGMA vfstrace('+all');
**
** Individual APIs can be enabled or disabled by name, with or without
** the initial "x" character.  For example, to set up for tracing lock
** primatives only:
**
**    PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock');
**
** The argument to the vfstrace pragma ignores capitalization and any
** characters other than alphabetics, '+', and '-'.
*/
#include <stdlib.h>







|







16298
16299
16300
16301
16302
16303
16304
16305
16306
16307
16308
16309
16310
16311
16312
**
** To enable all output (which is the default setting):
**
**    PRAGMA vfstrace('+all');
**
** Individual APIs can be enabled or disabled by name, with or without
** the initial "x" character.  For example, to set up for tracing lock
** primitives only:
**
**    PRAGMA vfstrace('-all, +Lock,Unlock,ShmLock');
**
** The argument to the vfstrace pragma ignores capitalization and any
** characters other than alphabetics, '+', and '-'.
*/
#include <stdlib.h>
21239
21240
21241
21242
21243
21244
21245
21246

21247
21248
21249
21250

21251
21252
21253
21254
21255
21256
21257
21258









21259

21260
21261
21262
21263
21264
21265
21266
21267
21268
21269



21270
21271
21272
21273


21274
21275
21276

21277
21278
21279
21280
21281
21282
21283
** This function does the work of a single sqlite3_recover_step() call. It
** is guaranteed that the handle is not in an error state when this
** function is called.
*/
static void recoverStep(sqlite3_recover *p){
  assert( p && p->errCode==SQLITE_OK );
  switch( p->eState ){
    case RECOVER_STATE_INIT:

      /* This is the very first call to sqlite3_recover_step() on this object.
      */
      recoverSqlCallback(p, "BEGIN");
      recoverSqlCallback(p, "PRAGMA writable_schema = on");


      recoverEnterMutex();
      recoverInstallWrapper(p);

      /* Open the output database. And register required virtual tables and 
      ** user functions with the new handle. */
      recoverOpenOutput(p);










      /* Open transactions on both the input and output databases. */

      sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
      recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
      recoverExec(p, p->dbIn, "BEGIN");
      if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
      recoverExec(p, p->dbIn, "SELECT 1 FROM sqlite_schema");
      recoverTransferSettings(p);
      recoverOpenRecovery(p);
      recoverCacheSchema(p);

      recoverUninstallWrapper(p);



      recoverLeaveMutex();

      recoverExec(p, p->dbOut, "BEGIN");



      recoverWriteSchema1(p);
      p->eState = RECOVER_STATE_WRITING;
      break;

      
    case RECOVER_STATE_WRITING: {
      if( p->w1.pTbls==0 ){
        recoverWriteDataInit(p);
      }
      if( SQLITE_DONE==recoverWriteDataStep(p) ){
        recoverWriteDataCleanup(p);







|
>




>


<





>
>
>
>
>
>
>
>
>
|
>
|
|
|
|
|
|
|
|

|
>
>
>
|
|
<

>
>



>







21249
21250
21251
21252
21253
21254
21255
21256
21257
21258
21259
21260
21261
21262
21263
21264

21265
21266
21267
21268
21269
21270
21271
21272
21273
21274
21275
21276
21277
21278
21279
21280
21281
21282
21283
21284
21285
21286
21287
21288
21289
21290
21291
21292
21293
21294
21295

21296
21297
21298
21299
21300
21301
21302
21303
21304
21305
21306
21307
21308
21309
** This function does the work of a single sqlite3_recover_step() call. It
** is guaranteed that the handle is not in an error state when this
** function is called.
*/
static void recoverStep(sqlite3_recover *p){
  assert( p && p->errCode==SQLITE_OK );
  switch( p->eState ){
    case RECOVER_STATE_INIT: {
      int bUseWrapper = 1;
      /* This is the very first call to sqlite3_recover_step() on this object.
      */
      recoverSqlCallback(p, "BEGIN");
      recoverSqlCallback(p, "PRAGMA writable_schema = on");
      recoverSqlCallback(p, "PRAGMA foreign_keys = off");

      recoverEnterMutex();


      /* Open the output database. And register required virtual tables and 
      ** user functions with the new handle. */
      recoverOpenOutput(p);

      /* Attempt to open a transaction and read page 1 of the input database.
      ** Two attempts may be made - one with a wrapper installed to ensure
      ** that the database header is sane, and then if that attempt returns
      ** SQLITE_NOTADB, then again with no wrapper. The second attempt is
      ** required for encrypted databases.  */
      if( p->errCode==SQLITE_OK ){
        do{
          p->errCode = SQLITE_OK;
          if( bUseWrapper ) recoverInstallWrapper(p);

          /* Open a transaction on the input database. */
          sqlite3_file_control(p->dbIn, p->zDb, SQLITE_FCNTL_RESET_CACHE, 0);
          recoverExec(p, p->dbIn, "PRAGMA writable_schema = on");
          recoverExec(p, p->dbIn, "BEGIN");
          if( p->errCode==SQLITE_OK ) p->bCloseTransaction = 1;
          recoverExec(p, p->dbIn, "SELECT 1 FROM sqlite_schema");
          recoverTransferSettings(p);
          recoverOpenRecovery(p);
          recoverCacheSchema(p);

          if( bUseWrapper ) recoverUninstallWrapper(p);
        }while( p->errCode==SQLITE_NOTADB 
             && (bUseWrapper--) 
             && SQLITE_OK==sqlite3_exec(p->dbIn, "ROLLBACK", 0, 0, 0)
        );
      }


      recoverLeaveMutex();
      recoverExec(p, p->dbOut, "BEGIN");
      recoverWriteSchema1(p);
      p->eState = RECOVER_STATE_WRITING;
      break;
    }
      
    case RECOVER_STATE_WRITING: {
      if( p->w1.pTbls==0 ){
        recoverWriteDataInit(p);
      }
      if( SQLITE_DONE==recoverWriteDataStep(p) ){
        recoverWriteDataCleanup(p);
21709
21710
21711
21712
21713
21714
21715
21716

21717
21718
21719
21720
21721
21722
21723
21724
21725
21726
21727
21728
21729
/* Bits in the ShellState.flgProgress variable */
#define SHELL_PROGRESS_QUIET 0x01  /* Omit announcing every progress callback */
#define SHELL_PROGRESS_RESET 0x02  /* Reset the count when the progress
                                   ** callback limit is reached, and for each
                                   ** top-level SQL statement */
#define SHELL_PROGRESS_ONCE  0x04  /* Cancel the --limit after firing once */

/* Allowed values for ShellState.eEscMode

*/
#define SHELL_ESC_SYMBOL       0      /* Substitute U+2400 graphics */
#define SHELL_ESC_ASCII        1      /* Substitute ^Y for X where Y=X+0x40 */
#define SHELL_ESC_OFF          2      /* Send characters verbatim */

static const char *shell_EscModeNames[] = { "symbol", "ascii", "off" };

/*
** These are the allowed shellFlgs values
*/
#define SHFLG_Pagecache      0x00000001 /* The --pagecache option is used */
#define SHFLG_Lookaside      0x00000002 /* Lookaside memory is used */
#define SHFLG_Backslash      0x00000004 /* The --backslash option is used */







|
>

|
|


|







21735
21736
21737
21738
21739
21740
21741
21742
21743
21744
21745
21746
21747
21748
21749
21750
21751
21752
21753
21754
21755
21756
/* Bits in the ShellState.flgProgress variable */
#define SHELL_PROGRESS_QUIET 0x01  /* Omit announcing every progress callback */
#define SHELL_PROGRESS_RESET 0x02  /* Reset the count when the progress
                                   ** callback limit is reached, and for each
                                   ** top-level SQL statement */
#define SHELL_PROGRESS_ONCE  0x04  /* Cancel the --limit after firing once */

/* Allowed values for ShellState.eEscMode.  The default value should
** be 0, so to change the default, reorder the names.
*/
#define SHELL_ESC_ASCII        0      /* Substitute ^Y for X where Y=X+0x40 */
#define SHELL_ESC_SYMBOL       1      /* Substitute U+2400 graphics */
#define SHELL_ESC_OFF          2      /* Send characters verbatim */

static const char *shell_EscModeNames[] = { "ascii", "symbol", "off" };

/*
** These are the allowed shellFlgs values
*/
#define SHFLG_Pagecache      0x00000001 /* The --pagecache option is used */
#define SHFLG_Lookaside      0x00000002 /* Lookaside memory is used */
#define SHFLG_Backslash      0x00000004 /* The --backslash option is used */
22900
22901
22902
22903
22904
22905
22906


22907
22908
22909
22910
22911
22912
22913
22914


22915
22916
22917
22918
22919
22920
22921
    case MODE_Pretty: {  /* .schema and .fullschema with --indent */
      char *z;
      int j;
      int nParen = 0;
      char cEnd = 0;
      char c;
      int nLine = 0;


      assert( nArg==1 );
      if( azArg[0]==0 ) break;
      if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
       || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
      ){
        sqlite3_fprintf(p->out, "%s;\n", azArg[0]);
        break;
      }


      z = sqlite3_mprintf("%s", azArg[0]);
      shell_check_oom(z);
      j = 0;
      for(i=0; IsSpace(z[i]); i++){}
      for(; (c = z[i])!=0; i++){
        if( IsSpace(c) ){
          if( z[j-1]=='\r' ) z[j-1] = '\n';







>
>








>
>







22927
22928
22929
22930
22931
22932
22933
22934
22935
22936
22937
22938
22939
22940
22941
22942
22943
22944
22945
22946
22947
22948
22949
22950
22951
22952
    case MODE_Pretty: {  /* .schema and .fullschema with --indent */
      char *z;
      int j;
      int nParen = 0;
      char cEnd = 0;
      char c;
      int nLine = 0;
      int isIndex;
      int isWhere = 0;
      assert( nArg==1 );
      if( azArg[0]==0 ) break;
      if( sqlite3_strlike("CREATE VIEW%", azArg[0], 0)==0
       || sqlite3_strlike("CREATE TRIG%", azArg[0], 0)==0
      ){
        sqlite3_fprintf(p->out, "%s;\n", azArg[0]);
        break;
      }
      isIndex = sqlite3_strlike("CREATE INDEX%", azArg[0], 0)==0
             || sqlite3_strlike("CREATE UNIQUE INDEX%", azArg[0], 0)==0;
      z = sqlite3_mprintf("%s", azArg[0]);
      shell_check_oom(z);
      j = 0;
      for(i=0; IsSpace(z[i]); i++){}
      for(; (c = z[i])!=0; i++){
        if( IsSpace(c) ){
          if( z[j-1]=='\r' ) z[j-1] = '\n';
22937
22938
22939
22940
22941
22942
22943
22944
22945
22946
22947











22948
22949
22950
22951

22952
22953
22954
22955
22956
22957
22958
            cEnd = ']';
          }else if( c=='-' && z[i+1]=='-' ){
            cEnd = '\n';
          }else if( c=='(' ){
            nParen++;
          }else if( c==')' ){
            nParen--;
            if( nLine>0 && nParen==0 && j>0 ){
              printSchemaLineN(p->out, z, j, "\n");
              j = 0;
            }











          }
          z[j++] = c;
          if( nParen==1 && cEnd==0
           && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))

          ){
            if( c=='\n' ) j--;
            printSchemaLineN(p->out, z, j, "\n  ");
            j = 0;
            nLine++;
            while( IsSpace(z[i+1]) ){ i++; }
          }







|



>
>
>
>
>
>
>
>
>
>
>




>







22968
22969
22970
22971
22972
22973
22974
22975
22976
22977
22978
22979
22980
22981
22982
22983
22984
22985
22986
22987
22988
22989
22990
22991
22992
22993
22994
22995
22996
22997
22998
22999
23000
23001
            cEnd = ']';
          }else if( c=='-' && z[i+1]=='-' ){
            cEnd = '\n';
          }else if( c=='(' ){
            nParen++;
          }else if( c==')' ){
            nParen--;
            if( nLine>0 && nParen==0 && j>0 && !isWhere ){
              printSchemaLineN(p->out, z, j, "\n");
              j = 0;
            }
          }else if( (c=='w' || c=='W')
                 && nParen==0 && isIndex
                 && sqlite3_strnicmp("WHERE",&z[i],5)==0
                 && !IsAlnum(z[i+5]) && z[i+5]!='_' ){
            isWhere = 1;
          }else if( isWhere && (c=='A' || c=='a')
                 && nParen==0
                 && sqlite3_strnicmp("AND",&z[i],3)==0
                 && !IsAlnum(z[i+3]) && z[i+3]!='_' ){
            printSchemaLineN(p->out, z, j, "\n    ");
            j = 0;
          }
          z[j++] = c;
          if( nParen==1 && cEnd==0
           && (c=='(' || c=='\n' || (c==',' && !wsToEol(z+i+1)))
           && !isWhere
          ){
            if( c=='\n' ) j--;
            printSchemaLineN(p->out, z, j, "\n  ");
            j = 0;
            nLine++;
            while( IsSpace(z[i+1]) ){ i++; }
          }
24148
24149
24150
24151
24152
24153
24154
24155
24156
24157
24158
24159
24160
24161
24162
24163
24164
24165
24166
    n++;
    j += 3;
    i++;
  }
  if( n>=mxWidth && bWordWrap  ){
    /* Perhaps try to back up to a better place to break the line */
    for(k=i; k>i/2; k--){
      if( isspace(z[k-1]) ) break;
    }
    if( k<=i/2 ){
      for(k=i; k>i/2; k--){
        if( isalnum(z[k-1])!=isalnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
      }
    }
    if( k<=i/2 ){
      k = i;
    }else{
      i = k;
      while( z[i]==' ' ) i++;







|



|







24191
24192
24193
24194
24195
24196
24197
24198
24199
24200
24201
24202
24203
24204
24205
24206
24207
24208
24209
    n++;
    j += 3;
    i++;
  }
  if( n>=mxWidth && bWordWrap  ){
    /* Perhaps try to back up to a better place to break the line */
    for(k=i; k>i/2; k--){
      if( IsSpace(z[k-1]) ) break;
    }
    if( k<=i/2 ){
      for(k=i; k>i/2; k--){
        if( IsAlnum(z[k-1])!=IsAlnum(z[k]) && (z[k]&0xc0)!=0x80 ) break;
      }
    }
    if( k<=i/2 ){
      k = i;
    }else{
      i = k;
      while( z[i]==' ' ) i++;
26086
26087
26088
26089
26090
26091
26092
26093
26094
26095
26096
26097
26098
26099
26100
  char zBuf[1000];

#if HAVE_LINENOISE==2
  UNUSED_PARAMETER(pUserData);
#endif
  if( nLine>(i64)sizeof(zBuf)-30 ) return;
  if( zLine[0]=='.' || zLine[0]=='#') return;
  for(i=nLine-1; i>=0 && (isalnum(zLine[i]) || zLine[i]=='_'); i--){}
  if( i==nLine-1 ) return;
  iStart = i+1;
  memcpy(zBuf, zLine, iStart);
  zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
                         "  FROM completion(%Q,%Q) ORDER BY 1",
                         &zLine[iStart], zLine);
  shell_check_oom(zSql);







|







26129
26130
26131
26132
26133
26134
26135
26136
26137
26138
26139
26140
26141
26142
26143
  char zBuf[1000];

#if HAVE_LINENOISE==2
  UNUSED_PARAMETER(pUserData);
#endif
  if( nLine>(i64)sizeof(zBuf)-30 ) return;
  if( zLine[0]=='.' || zLine[0]=='#') return;
  for(i=nLine-1; i>=0 && (IsAlnum(zLine[i]) || zLine[i]=='_'); i--){}
  if( i==nLine-1 ) return;
  iStart = i+1;
  memcpy(zBuf, zLine, iStart);
  zSql = sqlite3_mprintf("SELECT DISTINCT candidate COLLATE nocase"
                         "  FROM completion(%Q,%Q) ORDER BY 1",
                         &zLine[iStart], zLine);
  shell_check_oom(zSql);
28326
28327
28328
28329
28330
28331
28332

28333
28334
28335
28336
28337
28338
28339
  );

  sqlite3_recover_config(p, 789, (void*)zRecoveryDb);  /* Debug use only */
  sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
  sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
  sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);


  sqlite3_recover_run(p);
  if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
    const char *zErr = sqlite3_recover_errmsg(p);
    int errCode = sqlite3_recover_errcode(p);
    sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode);
  }
  rc = sqlite3_recover_finish(p);







>







28369
28370
28371
28372
28373
28374
28375
28376
28377
28378
28379
28380
28381
28382
28383
  );

  sqlite3_recover_config(p, 789, (void*)zRecoveryDb);  /* Debug use only */
  sqlite3_recover_config(p, SQLITE_RECOVER_LOST_AND_FOUND, (void*)zLAF);
  sqlite3_recover_config(p, SQLITE_RECOVER_ROWIDS, (void*)&bRowids);
  sqlite3_recover_config(p, SQLITE_RECOVER_FREELIST_CORRUPT,(void*)&bFreelist);

  sqlite3_fprintf(pState->out, ".dbconfig defensive off\n");
  sqlite3_recover_run(p);
  if( sqlite3_recover_errcode(p)!=SQLITE_OK ){
    const char *zErr = sqlite3_recover_errmsg(p);
    int errCode = sqlite3_recover_errcode(p);
    sqlite3_fprintf(stderr,"sql error: %s (%d)\n", zErr, errCode);
  }
  rc = sqlite3_recover_finish(p);
32417
32418
32419
32420
32421
32422
32423
32424
32425
32426
32427
32428
32429
32430
32431
}

/*
** The CLI needs a working sqlite3_complete() to work properly.  So error
** out of the build if compiling with SQLITE_OMIT_COMPLETE.
*/
#ifdef SQLITE_OMIT_COMPLETE
# error the CLI application is imcompatable with SQLITE_OMIT_COMPLETE.
#endif

/*
** Return true if zSql is a complete SQL statement.  Return false if it
** ends in the middle of a string literal or C-style comment.
*/
static int line_is_complete(char *zSql, int nSql){







|







32461
32462
32463
32464
32465
32466
32467
32468
32469
32470
32471
32472
32473
32474
32475
}

/*
** The CLI needs a working sqlite3_complete() to work properly.  So error
** out of the build if compiling with SQLITE_OMIT_COMPLETE.
*/
#ifdef SQLITE_OMIT_COMPLETE
# error the CLI application is incompatable with SQLITE_OMIT_COMPLETE.
#endif

/*
** Return true if zSql is a complete SQL statement.  Return false if it
** ends in the middle of a string literal or C-style comment.
*/
static int line_is_complete(char *zSql, int nSql){
32596
32597
32598
32599
32600
32601
32602
32603
32604
32605
32606
32607
32608
32609
32610
  i64 nZ = 0;

  UNUSED_PARAMETER(in);
  UNUSED_PARAMETER(isContinuation);
  if(!z || !*z){
    return 0;
  }
  while(*z && isspace(*z)) ++z;
  zBegin = z;
  for(; *z && '\n'!=*z; ++nZ, ++z){}
  if(nZ>0 && '\r'==zBegin[nZ-1]){
    --nZ;
  }
  shellState.wasm.zPos = z;
  zLine = realloc(zPrior, nZ+1);







|







32640
32641
32642
32643
32644
32645
32646
32647
32648
32649
32650
32651
32652
32653
32654
  i64 nZ = 0;

  UNUSED_PARAMETER(in);
  UNUSED_PARAMETER(isContinuation);
  if(!z || !*z){
    return 0;
  }
  while(*z && IsSpace(*z)) ++z;
  zBegin = z;
  for(; *z && '\n'!=*z; ++nZ, ++z){}
  if(nZ>0 && '\r'==zBegin[nZ-1]){
    --nZ;
  }
  shellState.wasm.zPos = z;
  zLine = realloc(zPrior, nZ+1);