Fossil

Check-in [9642cde384]
Login

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

Overview
Comment:Bring the built-in SQLite and the regexp implementation into alignment with upstream.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 9642cde38468682b797d1138102c23bd3d25d259303f322e7502c9cd53956a94
User & Date: drh 2025-09-26 13:36:14.507
Context
2025-09-26
14:12
Update the change log. check-in: 3a0dfc8920 user: drh tags: trunk
13:36
Bring the built-in SQLite and the regexp implementation into alignment with upstream. check-in: 9642cde384 user: drh tags: trunk
12:48
Prevent the cell background colors from extending beyond the outer rounded borders of the diff table in WebKit-based browsers. check-in: b666bbc54d user: florian tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to extsrc/shell.c.
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
      v *= aMult[i].iMult;
      break;
    }
  }
  if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow;
  return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v;
integer_overflow:
  return isNeg ? 0x8000000000000000LL : 0x7fffffffffffffffLL;
}

/*
** A variable length string to which one can append text.
*/
typedef struct ShellText ShellText;
struct ShellText {
  char *z;
  int n;
  int nAlloc;
};

/*
** Initialize and destroy a ShellText object
*/
static void initText(ShellText *p){
  memset(p, 0, sizeof(*p));
}
static void freeText(ShellText *p){
  free(p->z);
  initText(p);
}

/* zIn is either a pointer to a NULL-terminated string in memory obtained
** from malloc(), or a NULL pointer. The string pointed to by zAppend is
** added to zIn, and the result returned in memory obtained from malloc().
** zIn, if it was not NULL, is freed.







|







|
|
|









|







1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
      v *= aMult[i].iMult;
      break;
    }
  }
  if( isNeg && v>0x7fffffffffffffffULL ) goto integer_overflow;
  return isNeg? -(sqlite3_int64)v : (sqlite3_int64)v;
integer_overflow:
  return isNeg ? (i64)0x8000000000000000LL : 0x7fffffffffffffffLL;
}

/*
** A variable length string to which one can append text.
*/
typedef struct ShellText ShellText;
struct ShellText {
  char *zTxt;       /* The text */
  i64 n;            /* Number of bytes of zTxt[] actually used */
  i64 nAlloc;       /* Number of bytes allocated for zTxt[] */
};

/*
** Initialize and destroy a ShellText object
*/
static void initText(ShellText *p){
  memset(p, 0, sizeof(*p));
}
static void freeText(ShellText *p){
  sqlite3_free(p->zTxt);
  initText(p);
}

/* zIn is either a pointer to a NULL-terminated string in memory obtained
** from malloc(), or a NULL pointer. The string pointed to by zAppend is
** added to zIn, and the result returned in memory obtained from malloc().
** zIn, if it was not NULL, is freed.
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
  if( quote ){
    len += 2;
    for(i=0; i<nAppend; i++){
      if( zAppend[i]==quote ) len++;
    }
  }

  if( p->z==0 || p->n+len>=p->nAlloc ){
    p->nAlloc = p->nAlloc*2 + len + 20;
    p->z = realloc(p->z, p->nAlloc);
    shell_check_oom(p->z);
  }

  if( quote ){
    char *zCsr = p->z+p->n;
    *zCsr++ = quote;
    for(i=0; i<nAppend; i++){
      *zCsr++ = zAppend[i];
      if( zAppend[i]==quote ) *zCsr++ = quote;
    }
    *zCsr++ = quote;
    p->n = (int)(zCsr - p->z);
    *zCsr = '\0';
  }else{
    memcpy(p->z+p->n, zAppend, nAppend);
    p->n += nAppend;
    p->z[p->n] = '\0';
  }
}

/*
** Attempt to determine if identifier zName needs to be quoted, either
** because it contains non-alphanumeric characters, or because it is an
** SQLite keyword.  Be conservative in this estimate:  When in doubt assume







|

|
|



|






|


|

|







1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
  if( quote ){
    len += 2;
    for(i=0; i<nAppend; i++){
      if( zAppend[i]==quote ) len++;
    }
  }

  if( p->zTxt==0 || p->n+len>=p->nAlloc ){
    p->nAlloc = p->nAlloc*2 + len + 20;
    p->zTxt = sqlite3_realloc64(p->zTxt, p->nAlloc);
    shell_check_oom(p->zTxt);
  }

  if( quote ){
    char *zCsr = p->zTxt+p->n;
    *zCsr++ = quote;
    for(i=0; i<nAppend; i++){
      *zCsr++ = zAppend[i];
      if( zAppend[i]==quote ) *zCsr++ = quote;
    }
    *zCsr++ = quote;
    p->n = (i64)(zCsr - p->zTxt);
    *zCsr = '\0';
  }else{
    memcpy(p->zTxt+p->n, zAppend, nAppend);
    p->n += nAppend;
    p->zTxt[p->n] = '\0';
  }
}

/*
** Attempt to determine if identifier zName needs to be quoted, either
** because it contains non-alphanumeric characters, or because it is an
** SQLite keyword.  Be conservative in this estimate:  When in doubt assume
1599
1600
1601
1602
1603
1604
1605



1606
1607
1608
1609
1610
1611
1612
  }
  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.



*/
static char *shellFakeSchema(
  sqlite3 *db,            /* The database connection containing the vtab */
  const char *zSchema,    /* Schema of the database holding the vtab */
  const char *zName       /* The name of the virtual table */
){
  sqlite3_stmt *pStmt = 0;







>
>
>







1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
  }
  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.
**
** The returned string comes from sqlite3_mprintf() and should be freed
** by the caller using sqlite3_free().
*/
static char *shellFakeSchema(
  sqlite3 *db,            /* The database connection containing the vtab */
  const char *zSchema,    /* Schema of the database holding the vtab */
  const char *zName       /* The name of the virtual table */
){
  sqlite3_stmt *pStmt = 0;
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
    cQuote = quoteChar(zCol);
    appendText(&s, zCol, cQuote);
  }
  appendText(&s, ")", 0);
  sqlite3_finalize(pStmt);
  if( nRow==0 ){
    freeText(&s);
    s.z = 0;
  }
  return s.z;
}

/*
** SQL function:  strtod(X)
**
** Use the C-library strtod() function to convert string X into a double.
** Used for comparing the accuracy of SQLite's internal text-to-float conversion







|

|







1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
    cQuote = quoteChar(zCol);
    appendText(&s, zCol, cQuote);
  }
  appendText(&s, ")", 0);
  sqlite3_finalize(pStmt);
  if( nRow==0 ){
    freeText(&s);
    s.zTxt = 0;
  }
  return s.zTxt;
}

/*
** SQL function:  strtod(X)
**
** Use the C-library strtod() function to convert string X into a double.
** Used for comparing the accuracy of SQLite's internal text-to-float conversion
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
         && (zFake = shellFakeSchema(db, zSchema, zName))!=0
        ){
          if( z==0 ){
            z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
          }else{
            z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
          }
          free(zFake);
        }
        if( z ){
          sqlite3_result_text(pCtx, z, -1, sqlite3_free);
          return;
        }
      }
    }







|







1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
         && (zFake = shellFakeSchema(db, zSchema, zName))!=0
        ){
          if( z==0 ){
            z = sqlite3_mprintf("%s\n/* %s */", zIn, zFake);
          }else{
            z = sqlite3_mprintf("%z\n/* %s */", z, zFake);
          }
          sqlite3_free(zFake);
        }
        if( z ){
          sqlite3_result_text(pCtx, z, -1, sqlite3_free);
          return;
        }
      }
    }
6991
6992
6993
6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
** second.
**
**  The following regular expression syntax is supported:
**
**     X*      zero or more occurrences of X
**     X+      one or more occurrences of X
**     X?      zero or one occurrences of X
**     X{p,q}  between p and q occurrences of X
**     (X)     match X
**     X|Y     X or Y
**     ^X      X occurring at the beginning of the string
**     X$      X occurring at the end of the string
**     .       Match any single character
**     \c      Character c where c is one of \{}()[]|*+?.
**     \c      C-language escapes for c in afnrtv.  ex: \t or \n







|







6994
6995
6996
6997
6998
6999
7000
7001
7002
7003
7004
7005
7006
7007
7008
** second.
**
**  The following regular expression syntax is supported:
**
**     X*      zero or more occurrences of X
**     X+      one or more occurrences of X
**     X?      zero or one occurrences of X
**     X{p,q}  between p and q occurrences of X,   0 <= p,q <= 999
**     (X)     match X
**     X|Y     X or Y
**     ^X      X occurring at the beginning of the string
**     X$      X occurring at the end of the string
**     .       Match any single character
**     \c      Character c where c is one of \{}()[]|*+?.
**     \c      C-language escapes for c in afnrtv.  ex: \t or \n
7020
7021
7022
7023
7024
7025
7026



7027
7028
7029
7030
7031




7032
7033
7034
7035
7036
7037
7038
** A nondeterministic finite automaton (NFA) is used for matching, so the
** performance is bounded by O(N*M) where N is the size of the regular
** expression and M is the size of the input string.  The matcher never
** exhibits exponential behavior.  Note that the X{p,q} operator expands
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.



*/
#include <string.h>
#include <stdlib.h>
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1





/*
** The following #defines change the names of some functions implemented in
** this file to prevent name collisions with C-library functions of the
** same name.
*/
#define re_match   sqlite3re_match







>
>
>





>
>
>
>







7023
7024
7025
7026
7027
7028
7029
7030
7031
7032
7033
7034
7035
7036
7037
7038
7039
7040
7041
7042
7043
7044
7045
7046
7047
7048
** A nondeterministic finite automaton (NFA) is used for matching, so the
** performance is bounded by O(N*M) where N is the size of the regular
** expression and M is the size of the input string.  The matcher never
** exhibits exponential behavior.  Note that the X{p,q} operator expands
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.
**
** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999.
*/
#include <string.h>
#include <stdlib.h>
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1

#ifndef SQLITE_MAX_REGEXP_REPEAT
# define SQLITE_MAX_REGEXP_REPEAT 999
#endif

/*
** The following #defines change the names of some functions implemented in
** this file to prevent name collisions with C-library functions of the
** same name.
*/
#define re_match   sqlite3re_match
7528
7529
7530
7531
7532
7533
7534
7535
7536
7537
7538




7539
7540
7541
7542
7543



7544

7545
7546
7547
7548
7549
7550
7551
7552
7553
        break;
      }
      case '^': {
        re_append(p, RE_OP_ATSTART, 0);
        break;
      }
      case '{': {
        int m = 0, n = 0;
        int sz, j;
        if( iPrev<0 ) return "'{m,n}' without operand";
        while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }




        n = m;
        if( c==',' ){
          p->sIn.i++;
          n = 0;
          while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }



        }

        if( c!='}' ) return "unmatched '{'";
        if( n>0 && n<m ) return "n less than m in '{m,n}'";
        p->sIn.i++;
        sz = p->nState - iPrev;
        if( m==0 ){
          if( n==0 ) return "both m and n are zero in '{m,n}'";
          re_insert(p, iPrev, RE_OP_FORK, sz+1);
          iPrev++;
          n--;







|
|

|
>
>
>
>




|
>
>
>
|
>

|







7538
7539
7540
7541
7542
7543
7544
7545
7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
        break;
      }
      case '^': {
        re_append(p, RE_OP_ATSTART, 0);
        break;
      }
      case '{': {
        unsigned int m = 0, n = 0;
        unsigned int sz, j;
        if( iPrev<0 ) return "'{m,n}' without operand";
        while( (c=rePeek(p))>='0' && c<='9' ){
          m = m*10 + c - '0';
          if( m>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
          p->sIn.i++;
        }
        n = m;
        if( c==',' ){
          p->sIn.i++;
          n = 0;
          while( (c=rePeek(p))>='0' && c<='9' ){
            n = n*10 + c-'0';
            if( n>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
            p->sIn.i++;
          }
        }
        if( c!='}' ) return "unmatched '{'";
        if( n<m ) return "n less than m in '{m,n}'";
        p->sIn.i++;
        sz = p->nState - iPrev;
        if( m==0 ){
          if( n==0 ) return "both m and n are zero in '{m,n}'";
          re_insert(p, iPrev, RE_OP_FORK, sz+1);
          iPrev++;
          n--;
22096
22097
22098
22099
22100
22101
22102
22103
22104
22105
22106
22107
22108
22109
22110
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
  int i;
  unsigned char *aBlob = (unsigned char*)pBlob;

  char *zStr = sqlite3_malloc(nBlob*2 + 1);
  shell_check_oom(zStr);

  for(i=0; i<nBlob; i++){
    static const char aHex[] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };







|







22114
22115
22116
22117
22118
22119
22120
22121
22122
22123
22124
22125
22126
22127
22128
/*
** Output the given string as a hex-encoded blob (eg. X'1234' )
*/
static void output_hex_blob(FILE *out, const void *pBlob, int nBlob){
  int i;
  unsigned char *aBlob = (unsigned char*)pBlob;

  char *zStr = sqlite3_malloc64((i64)nBlob*2 + 1);
  shell_check_oom(zStr);

  for(i=0; i<nBlob; i++){
    static const char aHex[] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };
23373
23374
23375
23376
23377
23378
23379

23380




23381
23382
23383
23384
23385
23386
23387
*/
static void set_table_name(ShellState *p, const char *zName){
  if( p->zDestTable ){
    sqlite3_free(p->zDestTable);
    p->zDestTable = 0;
  }
  if( zName==0 ) return;

  p->zDestTable = sqlite3_mprintf("\"%w\"", zName);




}

/*
** Maybe construct two lines of text that point out the position of a
** syntax error.  Return a pointer to the text, in memory obtained from
** sqlite3_malloc().  Or, if the most recent error does not involve a
** specific token that we can point to, return an empty string.







>
|
>
>
>
>







23391
23392
23393
23394
23395
23396
23397
23398
23399
23400
23401
23402
23403
23404
23405
23406
23407
23408
23409
23410
*/
static void set_table_name(ShellState *p, const char *zName){
  if( p->zDestTable ){
    sqlite3_free(p->zDestTable);
    p->zDestTable = 0;
  }
  if( zName==0 ) return;
  if( quoteChar(zName) ){
    p->zDestTable = sqlite3_mprintf("\"%w\"", zName);
  }else{
    p->zDestTable = sqlite3_mprintf("%s", zName);
  }
  shell_check_oom(p->zDestTable);
}

/*
** Maybe construct two lines of text that point out the position of a
** syntax error.  Return a pointer to the text, in memory obtained from
** sqlite3_malloc().  Or, if the most recent error does not involve a
** specific token that we can point to, return an empty string.
25180
25181
25182
25183
25184
25185
25186
25187
25188
25189
25190
25191
25192
25193
25194
25195
25196
25197
25198
25199
25200
    }
    freeColumnList(azCol);
    appendText(&sSelect, " FROM ", 0);
    appendText(&sSelect, zTable, quoteChar(zTable));

    savedDestTable = p->zDestTable;
    savedMode = p->mode;
    p->zDestTable = sTable.z;
    p->mode = p->cMode = MODE_Insert;
    rc = shell_exec(p, sSelect.z, 0);
    if( (rc&0xff)==SQLITE_CORRUPT ){
      sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
      toggleSelectOrder(p->db);
      shell_exec(p, sSelect.z, 0);
      toggleSelectOrder(p->db);
    }
    p->zDestTable = savedDestTable;
    p->mode = savedMode;
    freeText(&sTable);
    freeText(&sSelect);
    if( rc ) p->nErr++;







|

|



|







25203
25204
25205
25206
25207
25208
25209
25210
25211
25212
25213
25214
25215
25216
25217
25218
25219
25220
25221
25222
25223
    }
    freeColumnList(azCol);
    appendText(&sSelect, " FROM ", 0);
    appendText(&sSelect, zTable, quoteChar(zTable));

    savedDestTable = p->zDestTable;
    savedMode = p->mode;
    p->zDestTable = sTable.zTxt;
    p->mode = p->cMode = MODE_Insert;
    rc = shell_exec(p, sSelect.zTxt, 0);
    if( (rc&0xff)==SQLITE_CORRUPT ){
      sqlite3_fputs("/****** CORRUPTION ERROR *******/\n", p->out);
      toggleSelectOrder(p->db);
      shell_exec(p, sSelect.zTxt, 0);
      toggleSelectOrder(p->db);
    }
    p->zDestTable = savedDestTable;
    p->mode = savedMode;
    freeText(&sTable);
    freeText(&sSelect);
    if( rc ) p->nErr++;
25800
25801
25802
25803
25804
25805
25806
25807

25808
25809
25810
25811
25812
25813
25814
25815
25816
25817
** Reconstruct an in-memory database using the output from the "dbtotxt"
** program.  Read content from the file in p->aAuxDb[].zDbFilename.
** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
*/
static unsigned char *readHexDb(ShellState *p, int *pnData){
  unsigned char *a = 0;
  int nLine;
  int n = 0;

  int pgsz = 0;
  int iOffset = 0;
  int j, k;
  int rc;
  FILE *in;
  const char *zDbFilename = p->pAuxDb->zDbFilename;
  unsigned int x[16];
  char zLine[1000];
  if( zDbFilename ){
    in = sqlite3_fopen(zDbFilename, "r");







|
>

|
<







25823
25824
25825
25826
25827
25828
25829
25830
25831
25832
25833

25834
25835
25836
25837
25838
25839
25840
** Reconstruct an in-memory database using the output from the "dbtotxt"
** program.  Read content from the file in p->aAuxDb[].zDbFilename.
** If p->aAuxDb[].zDbFilename is 0, then read from standard input.
*/
static unsigned char *readHexDb(ShellState *p, int *pnData){
  unsigned char *a = 0;
  int nLine;
  int n = 0;                      /* Size of db per first line of hex dump */
  i64 sz = 0;                     /* n rounded up to nearest page boundary */
  int pgsz = 0;
  i64 iOffset = 0;

  int rc;
  FILE *in;
  const char *zDbFilename = p->pAuxDb->zDbFilename;
  unsigned int x[16];
  char zLine[1000];
  if( zDbFilename ){
    in = sqlite3_fopen(zDbFilename, "r");
25827
25828
25829
25830
25831
25832
25833
25834
25835
25836
25837
25838
25839
25840
25841
25842




25843


25844
25845
25846
25847
25848
25849
25850
25851
25852
25853
25854
25855
25856
25857
25858
25859
25860
25861
25862
25863
25864
25865
25866
25867
25868
25869
25870
  }
  *pnData = 0;
  nLine++;
  if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
  rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
  if( rc!=2 ) goto readHexDb_error;
  if( n<0 ) goto readHexDb_error;
  if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto readHexDb_error;
  n = (n+pgsz-1)&~(pgsz-1);  /* Round n up to the next multiple of pgsz */
  a = sqlite3_malloc( n ? n : 1 );
  shell_check_oom(a);
  memset(a, 0, n);
  if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
    sqlite3_fputs("invalid pagesize\n", stderr);
    goto readHexDb_error;
  }




  for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){


    rc = sscanf(zLine, "| page %d offset %d", &j, &k);
    if( rc==2 ){
      iOffset = k;
      continue;
    }
    if( cli_strncmp(zLine, "| end ", 6)==0 ){
      break;
    }
    rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
    if( rc==17 ){
      k = iOffset+j;
      if( k+16<=n && k>=0 ){
        int ii;
        for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
      }
    }
  }
  *pnData = n;
  if( in!=p->in ){
    fclose(in);
  }else{
    p->lineno = nLine;
  }
  return a;








<
<
<
<
<




>
>
>
>

>
>












|
|

|



|







25850
25851
25852
25853
25854
25855
25856





25857
25858
25859
25860
25861
25862
25863
25864
25865
25866
25867
25868
25869
25870
25871
25872
25873
25874
25875
25876
25877
25878
25879
25880
25881
25882
25883
25884
25885
25886
25887
25888
25889
25890
25891
25892
25893
25894
  }
  *pnData = 0;
  nLine++;
  if( sqlite3_fgets(zLine, sizeof(zLine), in)==0 ) goto readHexDb_error;
  rc = sscanf(zLine, "| size %d pagesize %d", &n, &pgsz);
  if( rc!=2 ) goto readHexDb_error;
  if( n<0 ) goto readHexDb_error;





  if( pgsz<512 || pgsz>65536 || (pgsz & (pgsz-1))!=0 ){
    sqlite3_fputs("invalid pagesize\n", stderr);
    goto readHexDb_error;
  }
  sz = ((i64)n+pgsz-1)&~(pgsz-1); /* Round up to nearest multiple of pgsz */
  a = sqlite3_malloc( sz ? sz : 1 );
  shell_check_oom(a);
  memset(a, 0, sz);
  for(nLine++; sqlite3_fgets(zLine, sizeof(zLine), in)!=0; nLine++){
    int j = 0;                    /* Page number from "| page" line */
    int k = 0;                    /* Offset from "| page" line */
    rc = sscanf(zLine, "| page %d offset %d", &j, &k);
    if( rc==2 ){
      iOffset = k;
      continue;
    }
    if( cli_strncmp(zLine, "| end ", 6)==0 ){
      break;
    }
    rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
    if( rc==17 ){
      i64 iOff = iOffset+j;
      if( iOff+16<=sz && iOff>=0 ){
        int ii;
        for(ii=0; ii<16; ii++) a[iOff+ii] = x[ii]&0xff;
      }
    }
  }
  *pnData = sz;
  if( in!=p->in ){
    fclose(in);
  }else{
    p->lineno = nLine;
  }
  return a;

25923
25924
25925
25926
25927
25928
25929
25930
25931
25932
25933
25934
25935
25936
25937
  p->pLog = 0;
  zFake = zName? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0;
  p->pLog = pSavedLog;

  if( zFake ){
    sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
                        -1, sqlite3_free);
    free(zFake);
  }
}

/* Flags for open_db().
**
** The default behavior of open_db() is to exit(1) if the database fails to
** open.  The OPEN_DB_KEEPALIVE flag changes that so that it prints an error







|







25947
25948
25949
25950
25951
25952
25953
25954
25955
25956
25957
25958
25959
25960
25961
  p->pLog = 0;
  zFake = zName? shellFakeSchema(sqlite3_context_db_handle(pCtx), 0, zName) : 0;
  p->pLog = pSavedLog;

  if( zFake ){
    sqlite3_result_text(pCtx, sqlite3_mprintf("/* %s */", zFake),
                        -1, sqlite3_free);
    sqlite3_free(zFake);
  }
}

/* Flags for open_db().
**
** The default behavior of open_db() is to exit(1) if the database fails to
** open.  The OPEN_DB_KEEPALIVE flag changes that so that it prints an error
31007
31008
31009
31010
31011
31012
31013
31014
31015
31016
31017
31018
31019
31020
31021
31022
31023
      }
      if( bNoSystemTabs ){
        appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
      }
      appendText(&sSelect, "sql IS NOT NULL"
                           " ORDER BY snum, rowid", 0);
      if( bDebug ){
        sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.z);
      }else{
        rc = sqlite3_exec(p->db, sSelect.z, callback, &data, &zErrMsg);
      }
      freeText(&sSelect);
    }
    if( zErrMsg ){
      shellEmitError(zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;







|

|







31031
31032
31033
31034
31035
31036
31037
31038
31039
31040
31041
31042
31043
31044
31045
31046
31047
      }
      if( bNoSystemTabs ){
        appendText(&sSelect, "name NOT LIKE 'sqlite__%%' ESCAPE '_' AND ", 0);
      }
      appendText(&sSelect, "sql IS NOT NULL"
                           " ORDER BY snum, rowid", 0);
      if( bDebug ){
        sqlite3_fprintf(p->out, "SQL: %s;\n", sSelect.zTxt);
      }else{
        rc = sqlite3_exec(p->db, sSelect.zTxt, callback, &data, &zErrMsg);
      }
      freeText(&sSelect);
    }
    if( zErrMsg ){
      shellEmitError(zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
31333
31334
31335
31336
31337
31338
31339
31340
31341
31342
31343
31344
31345
31346
31347
31348
31349
31350
31351
31352
31353
31354
31355
31356
31357
31358
31359
31360
31361
31362
        }
        if( cli_strcmp(zOp,"memo")==0 ){
          sqlite3_fprintf(p->out, "%s\n", zSql);
        }else
        if( cli_strcmp(zOp,"run")==0 ){
          char *zErrMsg = 0;
          str.n = 0;
          str.z[0] = 0;
          rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
          nTest++;
          if( bVerbose ){
            sqlite3_fprintf(p->out, "Result: %s\n", str.z);
          }
          if( rc || zErrMsg ){
            nErr++;
            rc = 1;
            sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
            sqlite3_free(zErrMsg);
          }else if( cli_strcmp(zAns,str.z)!=0 ){
            nErr++;
            rc = 1;
            sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns);
            sqlite3_fprintf(p->out, "%d:      Got: [%s]\n", tno, str.z);
          }
        }
        else{
          sqlite3_fprintf(stderr,
                "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
          rc = 1;
          break;







|



|






|



|







31357
31358
31359
31360
31361
31362
31363
31364
31365
31366
31367
31368
31369
31370
31371
31372
31373
31374
31375
31376
31377
31378
31379
31380
31381
31382
31383
31384
31385
31386
        }
        if( cli_strcmp(zOp,"memo")==0 ){
          sqlite3_fprintf(p->out, "%s\n", zSql);
        }else
        if( cli_strcmp(zOp,"run")==0 ){
          char *zErrMsg = 0;
          str.n = 0;
          str.zTxt[0] = 0;
          rc = sqlite3_exec(p->db, zSql, captureOutputCallback, &str, &zErrMsg);
          nTest++;
          if( bVerbose ){
            sqlite3_fprintf(p->out, "Result: %s\n", str.zTxt);
          }
          if( rc || zErrMsg ){
            nErr++;
            rc = 1;
            sqlite3_fprintf(p->out, "%d: error-code-%d: %s\n", tno, rc,zErrMsg);
            sqlite3_free(zErrMsg);
          }else if( cli_strcmp(zAns,str.zTxt)!=0 ){
            nErr++;
            rc = 1;
            sqlite3_fprintf(p->out, "%d: Expected: [%s]\n", tno, zAns);
            sqlite3_fprintf(p->out, "%d:      Got: [%s]\n", tno, str.zTxt);
          }
        }
        else{
          sqlite3_fprintf(stderr,
                "Unknown operation \"%s\" on selftest line %d\n", zOp, tno);
          rc = 1;
          break;
31464
31465
31466
31467
31468
31469
31470
31471
31472
31473
31474
31475
31476
31477
31478
31479
31480
31481
31482
31483
31484
31485
31486
31487
31488
31489
31490
31491
31492
31493
31494
31495
31496
                           " ORDER BY tbl,idx;", 0);
      }else if( cli_strcmp(zTab, "sqlite_stat4")==0 ){
        appendText(&sQuery, "SELECT * FROM ", 0);
        appendText(&sQuery, zTab, 0);
        appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
      }
      appendText(&sSql, zSep, 0);
      appendText(&sSql, sQuery.z, '\'');
      sQuery.n = 0;
      appendText(&sSql, ",", 0);
      appendText(&sSql, zTab, '\'');
      zSep = "),(";
    }
    sqlite3_finalize(pStmt);
    if( bSeparate ){
      zSql = sqlite3_mprintf(
          "%s))"
          " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
          "   FROM [sha3sum$query]",
          sSql.z, iSize);
    }else{
      zSql = sqlite3_mprintf(
          "%s))"
          " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
          "   FROM [sha3sum$query]",
          sSql.z, iSize);
    }
    shell_check_oom(zSql);
    freeText(&sQuery);
    freeText(&sSql);
    if( bDebug ){
      sqlite3_fprintf(p->out, "%s\n", zSql);
    }else{







|











|





|







31488
31489
31490
31491
31492
31493
31494
31495
31496
31497
31498
31499
31500
31501
31502
31503
31504
31505
31506
31507
31508
31509
31510
31511
31512
31513
31514
31515
31516
31517
31518
31519
31520
                           " ORDER BY tbl,idx;", 0);
      }else if( cli_strcmp(zTab, "sqlite_stat4")==0 ){
        appendText(&sQuery, "SELECT * FROM ", 0);
        appendText(&sQuery, zTab, 0);
        appendText(&sQuery, " ORDER BY tbl, idx, rowid;\n", 0);
      }
      appendText(&sSql, zSep, 0);
      appendText(&sSql, sQuery.zTxt, '\'');
      sQuery.n = 0;
      appendText(&sSql, ",", 0);
      appendText(&sSql, zTab, '\'');
      zSep = "),(";
    }
    sqlite3_finalize(pStmt);
    if( bSeparate ){
      zSql = sqlite3_mprintf(
          "%s))"
          " SELECT lower(hex(sha3_query(a,%d))) AS hash, b AS label"
          "   FROM [sha3sum$query]",
          sSql.zTxt, iSize);
    }else{
      zSql = sqlite3_mprintf(
          "%s))"
          " SELECT lower(hex(sha3_query(group_concat(a,''),%d))) AS hash"
          "   FROM [sha3sum$query]",
          sSql.zTxt, iSize);
    }
    shell_check_oom(zSql);
    freeText(&sQuery);
    freeText(&sSql);
    if( bDebug ){
      sqlite3_fprintf(p->out, "%s\n", zSql);
    }else{
31682
31683
31684
31685
31686
31687
31688
31689
31690
31691
31692
31693
31694
31695
31696
      rc = 1;
      sqlite3_finalize(pStmt);
      goto meta_command_exit;
    }
    for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
      const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
      if( zDbName==0 ) continue;
      if( s.z && s.z[0] ) appendText(&s, " UNION ALL ", 0);
      if( sqlite3_stricmp(zDbName, "main")==0 ){
        appendText(&s, "SELECT name FROM ", 0);
      }else{
        appendText(&s, "SELECT ", 0);
        appendText(&s, zDbName, '\'');
        appendText(&s, "||'.'||name FROM ", 0);
      }







|







31706
31707
31708
31709
31710
31711
31712
31713
31714
31715
31716
31717
31718
31719
31720
      rc = 1;
      sqlite3_finalize(pStmt);
      goto meta_command_exit;
    }
    for(ii=0; sqlite3_step(pStmt)==SQLITE_ROW; ii++){
      const char *zDbName = (const char*)sqlite3_column_text(pStmt, 1);
      if( zDbName==0 ) continue;
      if( s.zTxt && s.zTxt[0] ) appendText(&s, " UNION ALL ", 0);
      if( sqlite3_stricmp(zDbName, "main")==0 ){
        appendText(&s, "SELECT name FROM ", 0);
      }else{
        appendText(&s, "SELECT ", 0);
        appendText(&s, zDbName, '\'');
        appendText(&s, "||'.'||name FROM ", 0);
      }
31704
31705
31706
31707
31708
31709
31710
31711
31712
31713
31714
31715
31716
31717
31718
        appendText(&s," WHERE type='index'"
                      "   AND tbl_name LIKE ?1", 0);
      }
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ){
      appendText(&s, " ORDER BY 1", 0);
      rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
    }
    freeText(&s);
    if( rc ) return shellDatabaseError(p->db);

    /* Run the SQL statement prepared by the above block. Store the results
    ** as an array of nul-terminated strings in azResult[].  */
    nRow = nAlloc = 0;







|







31728
31729
31730
31731
31732
31733
31734
31735
31736
31737
31738
31739
31740
31741
31742
        appendText(&s," WHERE type='index'"
                      "   AND tbl_name LIKE ?1", 0);
      }
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ){
      appendText(&s, " ORDER BY 1", 0);
      rc = sqlite3_prepare_v2(p->db, s.zTxt, -1, &pStmt, 0);
    }
    freeText(&s);
    if( rc ) return shellDatabaseError(p->db);

    /* Run the SQL statement prepared by the above block. Store the results
    ** as an array of nul-terminated strings in azResult[].  */
    nRow = nAlloc = 0;
Changes to extsrc/sqlite3.c.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** the text of this file.  Search for "Begin file sqlite3.h" to find the start
** of the embedded sqlite3.h header file.) Additional code files may be needed
** if you want a wrapper to interface SQLite with your choice of programming
** language. The code for the "sqlite3" command-line shell is also in a
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
** 821cc0e421bc14a68ebaee507e38a900e0c8 with changes in files:
**
**    
*/
#ifndef SQLITE_AMALGAMATION
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE







|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
** the text of this file.  Search for "Begin file sqlite3.h" to find the start
** of the embedded sqlite3.h header file.) Additional code files may be needed
** if you want a wrapper to interface SQLite with your choice of programming
** language. The code for the "sqlite3" command-line shell is also in a
** separate file. This file contains only code for the core SQLite library.
**
** The content in this amalgamation comes from Fossil check-in
** 911c745f88c0ee8569e67bbcbbab034264f8 with changes in files:
**
**    
*/
#ifndef SQLITE_AMALGAMATION
#define SQLITE_CORE 1
#define SQLITE_AMALGAMATION 1
#ifndef SQLITE_PRIVATE
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.51.0"
#define SQLITE_VERSION_NUMBER 3051000
#define SQLITE_SOURCE_ID      "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
#define SQLITE_SCM_BRANCH     "trunk"
#define SQLITE_SCM_TAGS       ""
#define SQLITE_SCM_DATETIME   "2025-09-24T19:10:58.215Z"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|


|







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.51.0"
#define SQLITE_VERSION_NUMBER 3051000
#define SQLITE_SOURCE_ID      "2025-09-26 13:14:20 911c745f88c0ee8569e67bbcbbab034264f8c981b505aadac3ce7289486a1a68"
#define SQLITE_SCM_BRANCH     "trunk"
#define SQLITE_SCM_TAGS       ""
#define SQLITE_SCM_DATETIME   "2025-09-26T13:14:20.156Z"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
21705
21706
21707
21708
21709
21710
21711
21712
21713
21714
21715
21716
21717
21718
21719
SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int);
SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
SQLITE_PRIVATE   int sqlite3JsonTableFunctions(sqlite3*);
#endif
SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p);

#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)







|







21705
21706
21707
21708
21709
21710
21711
21712
21713
21714
21715
21716
21717
21718
21719
SQLITE_PRIVATE void sqlite3QuoteValue(StrAccum*,sqlite3_value*,int);
SQLITE_PRIVATE int sqlite3AppendOneUtf8Character(char*, u32);
SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterJsonFunctions(void);
SQLITE_PRIVATE void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
SQLITE_PRIVATE   Module *sqlite3JsonVtabRegister(sqlite3*,const char*);
#endif
SQLITE_PRIVATE int sqlite3SafetyCheckOk(sqlite3*);
SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3*);
SQLITE_PRIVATE void sqlite3ChangeCookie(Parse*, int);
SQLITE_PRIVATE With *sqlite3WithDup(sqlite3 *db, With *p);

#if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER)
124260
124261
124262
124263
124264
124265
124266





124267
124268
124269
124270
124271
124272
124273
    ** CREATE, then check to see if it is the name of an virtual table that
    ** can be an eponymous virtual table. */
    if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){
      Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
      if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
        pMod = sqlite3PragmaVtabRegister(db, zName);
      }





      if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
        testcase( pMod->pEpoTab==0 );
        return pMod->pEpoTab;
      }
    }
#endif
    if( flags & LOCATE_NOERR ) return 0;







>
>
>
>
>







124260
124261
124262
124263
124264
124265
124266
124267
124268
124269
124270
124271
124272
124273
124274
124275
124276
124277
124278
    ** CREATE, then check to see if it is the name of an virtual table that
    ** can be an eponymous virtual table. */
    if( (pParse->prepFlags & SQLITE_PREPARE_NO_VTAB)==0 && db->init.busy==0 ){
      Module *pMod = (Module*)sqlite3HashFind(&db->aModule, zName);
      if( pMod==0 && sqlite3_strnicmp(zName, "pragma_", 7)==0 ){
        pMod = sqlite3PragmaVtabRegister(db, zName);
      }
#ifndef SQLITE_OMIT_JSON
      if( pMod==0 && sqlite3_strnicmp(zName, "json", 4)==0 ){
        pMod = sqlite3JsonVtabRegister(db, zName);
      }
#endif
      if( pMod && sqlite3VtabEponymousTableInit(pParse, pMod) ){
        testcase( pMod->pEpoTab==0 );
        return pMod->pEpoTab;
      }
    }
#endif
    if( flags & LOCATE_NOERR ) return 0;
183860
183861
183862
183863
183864
183865
183866
183867
183868
183869
183870
183871
183872
183873
183874
183875
183876
#ifdef SQLITE_ENABLE_DBPAGE_VTAB
  sqlite3DbpageRegister,
#endif
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
  sqlite3DbstatRegister,
#endif
  sqlite3TestExtInit,
#if !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
  sqlite3JsonTableFunctions,
#endif
#ifdef SQLITE_ENABLE_STMTVTAB
  sqlite3StmtVtabInit,
#endif
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
  sqlite3VdbeBytecodeVtabInit,
#endif
#ifdef SQLITE_EXTRA_AUTOEXT







<
<
<







183865
183866
183867
183868
183869
183870
183871



183872
183873
183874
183875
183876
183877
183878
#ifdef SQLITE_ENABLE_DBPAGE_VTAB
  sqlite3DbpageRegister,
#endif
#ifdef SQLITE_ENABLE_DBSTAT_VTAB
  sqlite3DbstatRegister,
#endif
  sqlite3TestExtInit,



#ifdef SQLITE_ENABLE_STMTVTAB
  sqlite3StmtVtabInit,
#endif
#ifdef SQLITE_ENABLE_BYTECODE_VTAB
  sqlite3VdbeBytecodeVtabInit,
#endif
#ifdef SQLITE_EXTRA_AUTOEXT
211321
211322
211323
211324
211325
211326
211327
211328
211329
211330
211331
211332
211333
211334
211335
          break;
        }
        switch( (u8)zIn[1] ){
          case '\'':
            jsonAppendChar(pOut, '\'');
            break;
          case 'v':
            jsonAppendRawNZ(pOut, "\\u0009", 6);
            break;
          case 'x':
            if( sz2<4 ){
              pOut->eErr |= JSTRING_MALFORMED;
              sz2 = 2;
              break;
            }







|







211323
211324
211325
211326
211327
211328
211329
211330
211331
211332
211333
211334
211335
211336
211337
          break;
        }
        switch( (u8)zIn[1] ){
          case '\'':
            jsonAppendChar(pOut, '\'');
            break;
          case 'v':
            jsonAppendRawNZ(pOut, "\\u000b", 6);
            break;
          case 'x':
            if( sz2<4 ){
              pOut->eErr |= JSTRING_MALFORMED;
              sz2 = 2;
              break;
            }
212171
212172
212173
212174
212175
212176
212177
212178



212179




212180
212181
212182
212183
212184
212185
212186
212187
212188
212189
212190

212191
212192
212193
212194
212195
212196
212197


/*
** Return the value of the BLOB node at index i.
**
** If the value is a primitive, return it as an SQL value.
** If the value is an array or object, return it as either
** JSON text or the BLOB encoding, depending on the JSON_B flag



** on the userdata.




*/
static void jsonReturnFromBlob(
  JsonParse *pParse,          /* Complete JSON parse tree */
  u32 i,                      /* Index of the node */
  sqlite3_context *pCtx,      /* Return value for this function */
  int textOnly                /* return text JSON.  Disregard user-data */
){
  u32 n, sz;
  int rc;
  sqlite3 *db = sqlite3_context_db_handle(pCtx);


  n = jsonbPayloadSize(pParse, i, &sz);
  if( n==0 ){
    sqlite3_result_error(pCtx, "malformed JSON", -1);
    return;
  }
  switch( pParse->aBlob[i] & 0x0f ){
    case JSONB_NULL: {







|
>
>
>
|
>
>
>
>





|





>







212173
212174
212175
212176
212177
212178
212179
212180
212181
212182
212183
212184
212185
212186
212187
212188
212189
212190
212191
212192
212193
212194
212195
212196
212197
212198
212199
212200
212201
212202
212203
212204
212205
212206
212207


/*
** Return the value of the BLOB node at index i.
**
** If the value is a primitive, return it as an SQL value.
** If the value is an array or object, return it as either
** JSON text or the BLOB encoding, depending on the eMode flag
** as follows:
**
**     eMode==0     JSONB if the JSON_B flag is set in userdata or
**                  text if the JSON_B flag is omitted from userdata.
**
**     eMode==1     Text
**
**     eMode==2     JSONB
*/
static void jsonReturnFromBlob(
  JsonParse *pParse,          /* Complete JSON parse tree */
  u32 i,                      /* Index of the node */
  sqlite3_context *pCtx,      /* Return value for this function */
  int eMode                   /* Format of return: text of JSONB */
){
  u32 n, sz;
  int rc;
  sqlite3 *db = sqlite3_context_db_handle(pCtx);

  assert( eMode>=0 && eMode<=2 );
  n = jsonbPayloadSize(pParse, i, &sz);
  if( n==0 ){
    sqlite3_result_error(pCtx, "malformed JSON", -1);
    return;
  }
  switch( pParse->aBlob[i] & 0x0f ){
    case JSONB_NULL: {
212302
212303
212304
212305
212306
212307
212308

212309





212310
212311
212312
212313
212314
212315
212316
212317
      assert( iOut<=nOut );
      zOut[iOut] = 0;
      sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
      break;
    }
    case JSONB_ARRAY:
    case JSONB_OBJECT: {

      int flags = textOnly ? 0 : SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx));





      if( flags & JSON_BLOB ){
        sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
      }else{
        jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
      }
      break;
    }
    default: {







>
|
>
>
>
>
>
|







212312
212313
212314
212315
212316
212317
212318
212319
212320
212321
212322
212323
212324
212325
212326
212327
212328
212329
212330
212331
212332
212333
      assert( iOut<=nOut );
      zOut[iOut] = 0;
      sqlite3_result_text(pCtx, zOut, iOut, SQLITE_DYNAMIC);
      break;
    }
    case JSONB_ARRAY:
    case JSONB_OBJECT: {
      if( eMode==0 ){
        if( (SQLITE_PTR_TO_INT(sqlite3_user_data(pCtx)) & JSON_BLOB)!=0 ){
          eMode = 2;
        }else{
          eMode = 1;
        }
      }
      if( eMode==2 ){
        sqlite3_result_blob(pCtx, &pParse->aBlob[i], sz+n, SQLITE_TRANSIENT);
      }else{
        jsonReturnTextJsonFromBlob(pCtx, &pParse->aBlob[i], sz+n);
      }
      break;
    }
    default: {
213950
213951
213952
213953
213954
213955
213956

213957
213958
213959
213960
213961
213962
213963
213964
213965
213966
213967


213968
213969
213970
213971
213972
213973
213974
  sqlite3_vtab_cursor base;  /* Base class - must be first */
  u32 iRowid;                /* The rowid */
  u32 i;                     /* Index in sParse.aBlob[] of current row */
  u32 iEnd;                  /* EOF when i equals or exceeds this value */
  u32 nRoot;                 /* Size of the root path in bytes */
  u8 eType;                  /* Type of the container for element i */
  u8 bRecursive;             /* True for json_tree().  False for json_each() */

  u32 nParent;               /* Current nesting depth */
  u32 nParentAlloc;          /* Space allocated for aParent[] */
  JsonParent *aParent;       /* Parent elements of i */
  sqlite3 *db;               /* Database connection */
  JsonString path;           /* Current path */
  JsonParse sParse;          /* Parse of the input JSON */
};
typedef struct JsonEachConnection JsonEachConnection;
struct JsonEachConnection {
  sqlite3_vtab base;         /* Base class - must be first */
  sqlite3 *db;               /* Database connection */


};


/* Constructor for the json_each virtual table */
static int jsonEachConnect(
  sqlite3 *db,
  void *pAux,







>











>
>







213966
213967
213968
213969
213970
213971
213972
213973
213974
213975
213976
213977
213978
213979
213980
213981
213982
213983
213984
213985
213986
213987
213988
213989
213990
213991
213992
213993
  sqlite3_vtab_cursor base;  /* Base class - must be first */
  u32 iRowid;                /* The rowid */
  u32 i;                     /* Index in sParse.aBlob[] of current row */
  u32 iEnd;                  /* EOF when i equals or exceeds this value */
  u32 nRoot;                 /* Size of the root path in bytes */
  u8 eType;                  /* Type of the container for element i */
  u8 bRecursive;             /* True for json_tree().  False for json_each() */
  u8 eMode;                  /* 1 for json_each().  2 for jsonb_each() */
  u32 nParent;               /* Current nesting depth */
  u32 nParentAlloc;          /* Space allocated for aParent[] */
  JsonParent *aParent;       /* Parent elements of i */
  sqlite3 *db;               /* Database connection */
  JsonString path;           /* Current path */
  JsonParse sParse;          /* Parse of the input JSON */
};
typedef struct JsonEachConnection JsonEachConnection;
struct JsonEachConnection {
  sqlite3_vtab base;         /* Base class - must be first */
  sqlite3 *db;               /* Database connection */
  u8 eMode;                  /* 1 for json_each().  2 for jsonb_each() */
  u8 bRecursive;             /* True for json_tree().  False for json_each() */
};


/* Constructor for the json_each virtual table */
static int jsonEachConnect(
  sqlite3 *db,
  void *pAux,
214003
214004
214005
214006
214007
214008
214009


214010
214011
214012
214013
214014
214015
214016
214017
214018
214019
214020
214021
214022
214023
214024
214025
214026
214027
214028
214029


214030
214031
214032
214033
214034
214035
214036
214037
214038
214039
214040
214041
214042
214043
214044
214045
214046
214047
214048
214049
214050
214051
                    "json HIDDEN,root HIDDEN)");
  if( rc==SQLITE_OK ){
    pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ) return SQLITE_NOMEM;
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
    pNew->db = db;


  }
  return rc;
}

/* destructor for json_each virtual table */
static int jsonEachDisconnect(sqlite3_vtab *pVtab){
  JsonEachConnection *p = (JsonEachConnection*)pVtab;
  sqlite3DbFree(p->db, pVtab);
  return SQLITE_OK;
}

/* constructor for a JsonEachCursor object for json_each(). */
static int jsonEachOpenEach(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  JsonEachConnection *pVtab = (JsonEachConnection*)p;
  JsonEachCursor *pCur;

  UNUSED_PARAMETER(p);
  pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur));
  if( pCur==0 ) return SQLITE_NOMEM;
  pCur->db = pVtab->db;


  jsonStringZero(&pCur->path);
  *ppCursor = &pCur->base;
  return SQLITE_OK;
}

/* constructor for a JsonEachCursor object for json_tree(). */
static int jsonEachOpenTree(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  int rc = jsonEachOpenEach(p, ppCursor);
  if( rc==SQLITE_OK ){
    JsonEachCursor *pCur = (JsonEachCursor*)*ppCursor;
    pCur->bRecursive = 1;
  }
  return rc;
}

/* Reset a JsonEachCursor back to its original state.  Free any memory
** held. */
static void jsonEachCursorReset(JsonEachCursor *p){
  jsonParseReset(&p->sParse);
  jsonStringReset(&p->path);
  sqlite3DbFree(p->db, p->aParent);
  p->iRowid = 0;







>
>











|
|







>
>





<
<
<
<
<
<
<
<
<
<







214022
214023
214024
214025
214026
214027
214028
214029
214030
214031
214032
214033
214034
214035
214036
214037
214038
214039
214040
214041
214042
214043
214044
214045
214046
214047
214048
214049
214050
214051
214052
214053
214054
214055
214056
214057










214058
214059
214060
214061
214062
214063
214064
                    "json HIDDEN,root HIDDEN)");
  if( rc==SQLITE_OK ){
    pNew = (JsonEachConnection*)sqlite3DbMallocZero(db, sizeof(*pNew));
    *ppVtab = (sqlite3_vtab*)pNew;
    if( pNew==0 ) return SQLITE_NOMEM;
    sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS);
    pNew->db = db;
    pNew->eMode = argv[0][4]=='b' ? 2 : 1;
    pNew->bRecursive = argv[0][4+pNew->eMode]=='t';
  }
  return rc;
}

/* destructor for json_each virtual table */
static int jsonEachDisconnect(sqlite3_vtab *pVtab){
  JsonEachConnection *p = (JsonEachConnection*)pVtab;
  sqlite3DbFree(p->db, pVtab);
  return SQLITE_OK;
}

/* constructor for a JsonEachCursor object for json_each()/json_tree(). */
static int jsonEachOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
  JsonEachConnection *pVtab = (JsonEachConnection*)p;
  JsonEachCursor *pCur;

  UNUSED_PARAMETER(p);
  pCur = sqlite3DbMallocZero(pVtab->db, sizeof(*pCur));
  if( pCur==0 ) return SQLITE_NOMEM;
  pCur->db = pVtab->db;
  pCur->eMode = pVtab->eMode;
  pCur->bRecursive = pVtab->bRecursive;
  jsonStringZero(&pCur->path);
  *ppCursor = &pCur->base;
  return SQLITE_OK;
}











/* Reset a JsonEachCursor back to its original state.  Free any memory
** held. */
static void jsonEachCursorReset(JsonEachCursor *p){
  jsonParseReset(&p->sParse);
  jsonStringReset(&p->path);
  sqlite3DbFree(p->db, p->aParent);
  p->iRowid = 0;
214242
214243
214244
214245
214246
214247
214248
214249
214250
214251
214252
214253
214254
214255
214256
        assert( p->eType==JSONB_ARRAY );
        sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey);
      }
      break;
    }
    case JEACH_VALUE: {
      u32 i = jsonSkipLabel(p);
      jsonReturnFromBlob(&p->sParse, i, ctx, 1);
      if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
        sqlite3_result_subtype(ctx, JSON_SUBTYPE);
      }
      break;
    }
    case JEACH_TYPE: {
      u32 i = jsonSkipLabel(p);







|







214255
214256
214257
214258
214259
214260
214261
214262
214263
214264
214265
214266
214267
214268
214269
        assert( p->eType==JSONB_ARRAY );
        sqlite3_result_int64(ctx, p->aParent[p->nParent-1].iKey);
      }
      break;
    }
    case JEACH_VALUE: {
      u32 i = jsonSkipLabel(p);
      jsonReturnFromBlob(&p->sParse, i, ctx, p->eMode);
      if( (p->sParse.aBlob[i] & 0x0f)>=JSONB_ARRAY ){
        sqlite3_result_subtype(ctx, JSON_SUBTYPE);
      }
      break;
    }
    case JEACH_TYPE: {
      u32 i = jsonSkipLabel(p);
214486
214487
214488
214489
214490
214491
214492
214493
214494
214495
214496
214497
214498
214499
214500
214501
214502
214503
214504
214505
214506
214507
214508
214509
214510
214511
214512
214513
214514
214515
214516
214517
214518
214519
214520
214521
214522
214523
214524
214525
214526
214527
214528
214529
static sqlite3_module jsonEachModule = {
  0,                         /* iVersion */
  0,                         /* xCreate */
  jsonEachConnect,           /* xConnect */
  jsonEachBestIndex,         /* xBestIndex */
  jsonEachDisconnect,        /* xDisconnect */
  0,                         /* xDestroy */
  jsonEachOpenEach,          /* xOpen - open a cursor */
  jsonEachClose,             /* xClose - close a cursor */
  jsonEachFilter,            /* xFilter - configure scan constraints */
  jsonEachNext,              /* xNext - advance a cursor */
  jsonEachEof,               /* xEof - check for end of scan */
  jsonEachColumn,            /* xColumn - read data */
  jsonEachRowid,             /* xRowid - read data */
  0,                         /* xUpdate */
  0,                         /* xBegin */
  0,                         /* xSync */
  0,                         /* xCommit */
  0,                         /* xRollback */
  0,                         /* xFindMethod */
  0,                         /* xRename */
  0,                         /* xSavepoint */
  0,                         /* xRelease */
  0,                         /* xRollbackTo */
  0,                         /* xShadowName */
  0                          /* xIntegrity */
};

/* The methods of the json_tree virtual table. */
static sqlite3_module jsonTreeModule = {
  0,                         /* iVersion */
  0,                         /* xCreate */
  jsonEachConnect,           /* xConnect */
  jsonEachBestIndex,         /* xBestIndex */
  jsonEachDisconnect,        /* xDisconnect */
  0,                         /* xDestroy */
  jsonEachOpenTree,          /* xOpen - open a cursor */
  jsonEachClose,             /* xClose - close a cursor */
  jsonEachFilter,            /* xFilter - configure scan constraints */
  jsonEachNext,              /* xNext - advance a cursor */
  jsonEachEof,               /* xEof - check for end of scan */
  jsonEachColumn,            /* xColumn - read data */
  jsonEachRowid,             /* xRowid - read data */
  0,                         /* xUpdate */







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







214499
214500
214501
214502
214503
214504
214505
214506





























214507
214508
214509
214510
214511
214512
214513
static sqlite3_module jsonEachModule = {
  0,                         /* iVersion */
  0,                         /* xCreate */
  jsonEachConnect,           /* xConnect */
  jsonEachBestIndex,         /* xBestIndex */
  jsonEachDisconnect,        /* xDisconnect */
  0,                         /* xDestroy */
  jsonEachOpen,              /* xOpen - open a cursor */





























  jsonEachClose,             /* xClose - close a cursor */
  jsonEachFilter,            /* xFilter - configure scan constraints */
  jsonEachNext,              /* xNext - advance a cursor */
  jsonEachEof,               /* xEof - check for end of scan */
  jsonEachColumn,            /* xColumn - read data */
  jsonEachRowid,             /* xRowid - read data */
  0,                         /* xUpdate */
214604
214605
214606
214607
214608
214609
214610
214611

214612
214613
214614
214615
214616
214617
214618
214619
214620
214621
214622

214623

214624
214625

214626
214627
214628
214629
214630
214631
214632
214633
  };
  sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
#endif
}

#if  !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
/*
** Register the JSON table-valued functions

*/
SQLITE_PRIVATE int sqlite3JsonTableFunctions(sqlite3 *db){
  int rc = SQLITE_OK;
  static const struct {
    const char *zName;
    sqlite3_module *pModule;
  } aMod[] = {
    { "json_each",            &jsonEachModule               },
    { "json_tree",            &jsonTreeModule               },
  };
  unsigned int i;

  for(i=0; i<sizeof(aMod)/sizeof(aMod[0]) && rc==SQLITE_OK; i++){

    rc = sqlite3_create_module(db, aMod[i].zName, aMod[i].pModule, 0);
  }

  return rc;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */

/************** End of json.c ************************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15







|
>

|
|
|
<
<
<
<
|

<
>
|
>
|
|
>
|







214588
214589
214590
214591
214592
214593
214594
214595
214596
214597
214598
214599
214600




214601
214602

214603
214604
214605
214606
214607
214608
214609
214610
214611
214612
214613
214614
214615
214616
  };
  sqlite3InsertBuiltinFuncs(aJsonFunc, ArraySize(aJsonFunc));
#endif
}

#if  !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON)
/*
** Register the JSON table-valued function named zName and return a
** pointer to its Module object.  Return NULL if something goes wrong.
*/
SQLITE_PRIVATE Module *sqlite3JsonVtabRegister(sqlite3 *db, const char *zName){
  unsigned int i;
  static const char *azModule[] = {




    "json_each", "json_tree", "jsonb_each", "jsonb_tree"
  };

  assert( sqlite3HashFind(&db->aModule, zName)==0 );
  for(i=0; i<sizeof(azModule)/sizeof(azModule[0]); i++){
    if( sqlite3StrICmp(azModule[i],zName)==0 ){
      return sqlite3VtabCreateModule(db, azModule[i], &jsonEachModule, 0, 0);
    }
  }
  return 0;
}
#endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_JSON) */

/************** End of json.c ************************************************/
/************** Begin file rtree.c *******************************************/
/*
** 2001 September 15
234699
234700
234701
234702
234703
234704
234705

234706
234707
234708
234709
234710
234711
234712
      sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
      sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
    }
  }

  assert( sApply.bRebase || sApply.rebase.nBuf==0 );
  if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){

    *ppRebase = (void*)sApply.rebase.aBuf;
    *pnRebase = sApply.rebase.nBuf;
    sApply.rebase.aBuf = 0;
  }
  sessionUpdateFree(&sApply);
  sqlite3_finalize(sApply.pInsert);
  sqlite3_finalize(sApply.pDelete);







>







234682
234683
234684
234685
234686
234687
234688
234689
234690
234691
234692
234693
234694
234695
234696
      sqlite3_exec(db, "ROLLBACK TO changeset_apply", 0, 0, 0);
      sqlite3_exec(db, "RELEASE changeset_apply", 0, 0, 0);
    }
  }

  assert( sApply.bRebase || sApply.rebase.nBuf==0 );
  if( rc==SQLITE_OK && bPatchset==0 && sApply.bRebase ){
    assert( ppRebase!=0 && pnRebase!=0 );
    *ppRebase = (void*)sApply.rebase.aBuf;
    *pnRebase = sApply.rebase.nBuf;
    sApply.rebase.aBuf = 0;
  }
  sessionUpdateFree(&sApply);
  sqlite3_finalize(sApply.pInsert);
  sqlite3_finalize(sApply.pDelete);
252412
252413
252414
252415
252416
252417
252418
252419
252420
252421
252422
252423
252424
252425
252426
  union {
    Fts5Structure sFts;
    u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
  } uFts;
  fts5StructureInvalidate(p);
  fts5IndexDiscardData(p);
  pTmp = &uFts.sFts;
  memset(pTmp, 0, SZ_FTS5STRUCTURE(1));
  if( p->pConfig->bContentlessDelete ){
    pTmp->nOriginCntr = 1;
  }
  fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
  fts5StructureWrite(p, pTmp);
  return fts5IndexReturn(p);
}







|







252396
252397
252398
252399
252400
252401
252402
252403
252404
252405
252406
252407
252408
252409
252410
  union {
    Fts5Structure sFts;
    u8 tmpSpace[SZ_FTS5STRUCTURE(1)];
  } uFts;
  fts5StructureInvalidate(p);
  fts5IndexDiscardData(p);
  pTmp = &uFts.sFts;
  memset(uFts.tmpSpace, 0, sizeof(uFts.tmpSpace));
  if( p->pConfig->bContentlessDelete ){
    pTmp->nOriginCntr = 1;
  }
  fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0);
  fts5StructureWrite(p, pTmp);
  return fts5IndexReturn(p);
}
258720
258721
258722
258723
258724
258725
258726
258727
258728
258729
258730
258731
258732
258733
258734
static void fts5SourceIdFunc(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "fts5: 2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232", -1, SQLITE_TRANSIENT);
}

/*
** Implementation of fts5_locale(LOCALE, TEXT) function.
**
** If parameter LOCALE is NULL, or a zero-length string, then a copy of
** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as







|







258704
258705
258706
258707
258708
258709
258710
258711
258712
258713
258714
258715
258716
258717
258718
static void fts5SourceIdFunc(
  sqlite3_context *pCtx,          /* Function call context */
  int nArg,                       /* Number of args */
  sqlite3_value **apUnused        /* Function arguments */
){
  assert( nArg==0 );
  UNUSED_PARAM2(nArg, apUnused);
  sqlite3_result_text(pCtx, "fts5: 2025-09-26 11:47:13 d022ee167b90a7c32049a93d476e869270018017f60551185024409730d77640", -1, SQLITE_TRANSIENT);
}

/*
** Implementation of fts5_locale(LOCALE, TEXT) function.
**
** If parameter LOCALE is NULL, or a zero-length string, then a copy of
** TEXT is returned. Otherwise, both LOCALE and TEXT are interpreted as
Changes to extsrc/sqlite3.h.
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.51.0"
#define SQLITE_VERSION_NUMBER 3051000
#define SQLITE_SOURCE_ID      "2025-09-24 19:10:58 821cc0e421bc14a68ebaee507e38a900e0c84ff6ba7ee95bf796cad387755232"
#define SQLITE_SCM_BRANCH     "trunk"
#define SQLITE_SCM_TAGS       ""
#define SQLITE_SCM_DATETIME   "2025-09-24T19:10:58.215Z"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|


|







144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.51.0"
#define SQLITE_VERSION_NUMBER 3051000
#define SQLITE_SOURCE_ID      "2025-09-26 13:14:20 911c745f88c0ee8569e67bbcbbab034264f8c981b505aadac3ce7289486a1a68"
#define SQLITE_SCM_BRANCH     "trunk"
#define SQLITE_SCM_TAGS       ""
#define SQLITE_SCM_DATETIME   "2025-09-26T13:14:20.156Z"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
Changes to src/regexp.c.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
**
**
**  The following regular expression syntax is supported:
**
**     X*      zero or more occurrences of X
**     X+      one or more occurrences of X
**     X?      zero or one occurrences of X
**     X{p,q}  between p and q occurrences of X
**     (X)     match X
**     X|Y     X or Y
**     ^X      X occurring at the beginning of the string
**     X$      X occurring at the end of the string
**     .       Match any single character
**     \c      Character c where c is one of \{}()[]|*+?.
**     \c      C-language escapes for c in afnrtv.  ex: \t or \n







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
**
**
**  The following regular expression syntax is supported:
**
**     X*      zero or more occurrences of X
**     X+      one or more occurrences of X
**     X?      zero or one occurrences of X
**     X{p,q}  between p and q occurrences of X,    0 <= p,q <= 999
**     (X)     match X
**     X|Y     X or Y
**     ^X      X occurring at the beginning of the string
**     X$      X occurring at the end of the string
**     .       Match any single character
**     \c      Character c where c is one of \{}()[]|*+?.
**     \c      C-language escapes for c in afnrtv.  ex: \t or \n
51
52
53
54
55
56
57



58
59
60




61
62
63

64
65
66
67
68
69
70
** A nondeterministic finite automaton (NFA) is used for matching, so the
** performance is bounded by O(N*M) where N is the size of the regular
** expression and M is the size of the input string.  The matcher never
** exhibits exponential behavior.  Note that the X{p,q} operator expands
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.



*/
#include "config.h"
#include "regexp.h"





/* The end-of-input character */
#define RE_EOF            0    /* End of input */


/* The NFA is implemented as sequence of opcodes taken from the following
** set.  Each opcode has a single integer argument.
*/
#define RE_OP_MATCH       1    /* Match the one character in the argument */
#define RE_OP_ANY         2    /* Match any one character.  (Implements ".") */
#define RE_OP_ANYSTAR     3    /* Special optimized version of .* */







>
>
>



>
>
>
>



>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
** A nondeterministic finite automaton (NFA) is used for matching, so the
** performance is bounded by O(N*M) where N is the size of the regular
** expression and M is the size of the input string.  The matcher never
** exhibits exponential behavior.  Note that the X{p,q} operator expands
** to p copies of X following by q-p copies of X? and that the size of the
** regular expression in the O(N*M) performance bound is computed after
** this expansion.
**
** To help prevent DoS attacks, the values of p and q in the "{p,q}" syntax
** are limited to SQLITE_MAX_REGEXP_REPEAT, default 999.
*/
#include "config.h"
#include "regexp.h"

#ifndef SQLITE_MAX_REGEXP_REPEAT
# define SQLITE_MAX_REGEXP_REPEAT 999
#endif

/* The end-of-input character */
#define RE_EOF            0    /* End of input */
#define RE_START  0xfffffff    /* Start of input - larger than an UTF-8 */

/* The NFA is implemented as sequence of opcodes taken from the following
** set.  Each opcode has a single integer argument.
*/
#define RE_OP_MATCH       1    /* Match the one character in the argument */
#define RE_OP_ANY         2    /* Match any one character.  (Implements ".") */
#define RE_OP_ANYSTAR     3    /* Special optimized version of .* */
78
79
80
81
82
83
84

85
86
87
88
89
90
91
#define RE_OP_WORD       11    /* Perl word character [A-Za-z0-9_] */
#define RE_OP_NOTWORD    12    /* Not a perl word character */
#define RE_OP_DIGIT      13    /* digit:  [0-9] */
#define RE_OP_NOTDIGIT   14    /* Not a digit */
#define RE_OP_SPACE      15    /* space:  [ \t\n\r\v\f] */
#define RE_OP_NOTSPACE   16    /* Not a digit */
#define RE_OP_BOUNDARY   17    /* Boundary between word and non-word */


/* Each opcode is a "state" in the NFA */
typedef unsigned short ReStateNumber;

/* Because this is an NFA and not a DFA, multiple states can be active at
** once.  An instance of the following object records all active states in
** the NFA.  The implementation is optimized for the common case where the







>







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#define RE_OP_WORD       11    /* Perl word character [A-Za-z0-9_] */
#define RE_OP_NOTWORD    12    /* Not a perl word character */
#define RE_OP_DIGIT      13    /* digit:  [0-9] */
#define RE_OP_NOTDIGIT   14    /* Not a digit */
#define RE_OP_SPACE      15    /* space:  [ \t\n\r\v\f] */
#define RE_OP_NOTSPACE   16    /* Not a digit */
#define RE_OP_BOUNDARY   17    /* Boundary between word and non-word */
#define RE_OP_ATSTART    18    /* Currently at the start of the string */

/* Each opcode is a "state" in the NFA */
typedef unsigned short ReStateNumber;

/* Because this is an NFA and not a DFA, multiple states can be active at
** once.  An instance of the following object records all active states in
** the NFA.  The implementation is optimized for the common case where the
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208

209
210
211
212
213
214
215
*/
int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
  ReStateSet aStateSet[2], *pThis, *pNext;
  ReStateNumber aSpace[100];
  ReStateNumber *pToFree;
  unsigned int i = 0;
  unsigned int iSwap = 0;
  int c = RE_EOF+1;
  int cPrev = 0;
  int rc = 0;
  ReInput in;

  in.z = zIn;
  in.i = 0;
  in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);

  /* Look for the initial prefix match, if there is one. */
  if( pRe->nInit ){
    unsigned char x = pRe->zInit[0];
    while( in.i+pRe->nInit<=in.mx
     && (zIn[in.i]!=x ||
         strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
    ){
      in.i++;
    }
    if( in.i+pRe->nInit>in.mx ) return 0;

  }

  if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
    pToFree = 0;
    aStateSet[0].aState = aSpace;
  }else{
    pToFree = fossil_malloc( sizeof(ReStateNumber)*2*pRe->nState );







|


















>







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
*/
int re_match(ReCompiled *pRe, const unsigned char *zIn, int nIn){
  ReStateSet aStateSet[2], *pThis, *pNext;
  ReStateNumber aSpace[100];
  ReStateNumber *pToFree;
  unsigned int i = 0;
  unsigned int iSwap = 0;
  int c = RE_START;
  int cPrev = 0;
  int rc = 0;
  ReInput in;

  in.z = zIn;
  in.i = 0;
  in.mx = nIn>=0 ? nIn : (int)strlen((char const*)zIn);

  /* Look for the initial prefix match, if there is one. */
  if( pRe->nInit ){
    unsigned char x = pRe->zInit[0];
    while( in.i+pRe->nInit<=in.mx
     && (zIn[in.i]!=x ||
         strncmp((const char*)zIn+in.i, (const char*)pRe->zInit, pRe->nInit)!=0)
    ){
      in.i++;
    }
    if( in.i+pRe->nInit>in.mx ) return 0;
    c = RE_START-1;
  }

  if( pRe->nState<=(sizeof(aSpace)/(sizeof(aSpace[0])*2)) ){
    pToFree = 0;
    aStateSet[0].aState = aSpace;
  }else{
    pToFree = fossil_malloc( sizeof(ReStateNumber)*2*pRe->nState );
229
230
231
232
233
234
235




236
237
238
239
240
241
242
    pNext->nState = 0;
    for(i=0; i<pThis->nState; i++){
      int x = pThis->aState[i];
      switch( pRe->aOp[x] ){
        case RE_OP_MATCH: {
          if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
          break;




        }
        case RE_OP_ANY: {
          if( c!=0 ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_WORD: {
          if( re_word_char(c) ) re_add_state(pNext, x+1);







>
>
>
>







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
    pNext->nState = 0;
    for(i=0; i<pThis->nState; i++){
      int x = pThis->aState[i];
      switch( pRe->aOp[x] ){
        case RE_OP_MATCH: {
          if( pRe->aArg[x]==c ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_ATSTART: {
          if( cPrev==RE_START ) re_add_state(pThis, x+1);
          break;
        }
        case RE_OP_ANY: {
          if( c!=0 ) re_add_state(pNext, x+1);
          break;
        }
        case RE_OP_WORD: {
          if( re_word_char(c) ) re_add_state(pNext, x+1);
311
312
313
314
315
316
317


318
319
320
321
322
323
324
325
          if( hit ) re_add_state(pNext, x+n);
          break;
        }
      }
    }
  }
  for(i=0; i<pNext->nState; i++){


    if( pRe->aOp[pNext->aState[i]]==RE_OP_ACCEPT ){ rc = 1; break; }
  }
re_match_end:
  fossil_free(pToFree);
  return rc;
}

/* Resize the opcode and argument arrays for an RE under construction.







>
>
|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
          if( hit ) re_add_state(pNext, x+n);
          break;
        }
      }
    }
  }
  for(i=0; i<pNext->nState; i++){
    int x = pNext->aState[i];
    while( pRe->aOp[x]==RE_OP_GOTO ) x += pRe->aArg[x];
    if( pRe->aOp[x]==RE_OP_ACCEPT ){ rc = 1; break; }
  }
re_match_end:
  fossil_free(pToFree);
  return rc;
}

/* Resize the opcode and argument arrays for an RE under construction.
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  int iStart;
  unsigned c;
  const char *zErr;
  while( (c = p->xNextChar(&p->sIn))!=0 ){
    iStart = p->nState;
    switch( c ){
      case '|':
      case '$':
      case ')': {
        p->sIn.i--;
        return 0;
      }
      case '(': {
        zErr = re_subcompile_re(p);
        if( zErr ) return zErr;







<







482
483
484
485
486
487
488

489
490
491
492
493
494
495
  int iStart;
  unsigned c;
  const char *zErr;
  while( (c = p->xNextChar(&p->sIn))!=0 ){
    iStart = p->nState;
    switch( c ){
      case '|':

      case ')': {
        p->sIn.i--;
        return 0;
      }
      case '(': {
        zErr = re_subcompile_re(p);
        if( zErr ) return zErr;
502
503
504
505
506
507
508
509








510
511
512
513
514




515
516
517
518
519




520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
        re_append(p, RE_OP_FORK, iPrev - p->nState);
        break;
      }
      case '?': {
        if( iPrev<0 ) return "'?' without operand";
        re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
        break;
      }








      case '{': {
        int m = 0, n = 0;
        int sz, j;
        if( iPrev<0 ) return "'{m,n}' without operand";
        while( (c=rePeek(p))>='0' && c<='9' ){ m = m*10 + c - '0'; p->sIn.i++; }




        n = m;
        if( c==',' ){
          p->sIn.i++;
          n = 0;
          while( (c=rePeek(p))>='0' && c<='9' ){ n = n*10 + c-'0'; p->sIn.i++; }




        }
        if( c!='}' ) return "unmatched '{'";
        if( n>0 && n<m ) return "n less than m in '{m,n}'";
        p->sIn.i++;
        sz = p->nState - iPrev;
        if( m==0 ){
          if( n==0 ) return "both m and n are zero in '{m,n}'";
          re_insert(p, iPrev, RE_OP_FORK, sz+1);

          n--;
        }else{
          for(j=1; j<m; j++) re_copy(p, iPrev, sz);
        }
        for(j=m; j<n; j++){
          re_append(p, RE_OP_FORK, sz+1);
          re_copy(p, iPrev, sz);
        }
        if( n==0 && m>0 ){
          re_append(p, RE_OP_FORK, -sz);
        }
        break;
      }
      case '[': {
        int iFirst = p->nState;
        if( rePeek(p)=='^' ){
          re_append(p, RE_OP_CC_EXC, 0);
          p->sIn.i++;
        }else{
          re_append(p, RE_OP_CC_INC, 0);
        }
        while( (c = p->xNextChar(&p->sIn))!=0 ){








>
>
>
>
>
>
>
>

|
|

|
>
>
>
>




|
>
>
>
>








>














|







517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
        re_append(p, RE_OP_FORK, iPrev - p->nState);
        break;
      }
      case '?': {
        if( iPrev<0 ) return "'?' without operand";
        re_insert(p, iPrev, RE_OP_FORK, p->nState - iPrev+1);
        break;
      }
      case '$': {
        re_append(p, RE_OP_MATCH, RE_EOF);
        break;
      }
      case '^': {
        re_append(p, RE_OP_ATSTART, 0);
        break;
      }
      case '{': {
        unsigned int m = 0, n = 0;
        unsigned int sz, j;
        if( iPrev<0 ) return "'{m,n}' without operand";
        while( (c=rePeek(p))>='0' && c<='9' ){
          m = m*10 + c - '0';
          if( m>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
          p->sIn.i++;
        }
        n = m;
        if( c==',' ){
          p->sIn.i++;
          n = 0;
          while( (c=rePeek(p))>='0' && c<='9' ){
            n = n*10 + c-'0';
            if( n>SQLITE_MAX_REGEXP_REPEAT ) return "integer too large";
            p->sIn.i++;
          }
        }
        if( c!='}' ) return "unmatched '{'";
        if( n>0 && n<m ) return "n less than m in '{m,n}'";
        p->sIn.i++;
        sz = p->nState - iPrev;
        if( m==0 ){
          if( n==0 ) return "both m and n are zero in '{m,n}'";
          re_insert(p, iPrev, RE_OP_FORK, sz+1);
          iPrev++;
          n--;
        }else{
          for(j=1; j<m; j++) re_copy(p, iPrev, sz);
        }
        for(j=m; j<n; j++){
          re_append(p, RE_OP_FORK, sz+1);
          re_copy(p, iPrev, sz);
        }
        if( n==0 && m>0 ){
          re_append(p, RE_OP_FORK, -sz);
        }
        break;
      }
      case '[': {
        unsigned int iFirst = p->nState;
        if( rePeek(p)=='^' ){
          re_append(p, RE_OP_CC_EXC, 0);
          p->sIn.i++;
        }else{
          re_append(p, RE_OP_CC_INC, 0);
        }
        while( (c = p->xNextChar(&p->sIn))!=0 ){
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
            re_append(p, RE_OP_CC_RANGE, c);
          }else{
            re_append(p, RE_OP_CC_VALUE, c);
          }
          if( rePeek(p)==']' ){ p->sIn.i++; break; }
        }
        if( c==0 ) return "unclosed '['";
        p->aArg[iFirst] = p->nState - iFirst;
        break;
      }
      case '\\': {
        int specialOp = 0;
        switch( rePeek(p) ){
          case 'b': specialOp = RE_OP_BOUNDARY;   break;
          case 'd': specialOp = RE_OP_DIGIT;      break;







|







591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
            re_append(p, RE_OP_CC_RANGE, c);
          }else{
            re_append(p, RE_OP_CC_VALUE, c);
          }
          if( rePeek(p)==']' ){ p->sIn.i++; break; }
        }
        if( c==0 ) return "unclosed '['";
        if( p->nState>iFirst ) p->aArg[iFirst] = p->nState - iFirst;
        break;
      }
      case '\\': {
        int specialOp = 0;
        switch( rePeek(p) ){
          case 'b': specialOp = RE_OP_BOUNDARY;   break;
          case 'd': specialOp = RE_OP_DIGIT;      break;
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
  pRe->sIn.i = 0;
  pRe->sIn.mx = (int)strlen(zIn);
  zErr = re_subcompile_re(pRe);
  if( zErr ){
    re_free(pRe);
    return zErr;
  }
  if( rePeek(pRe)=='$' && pRe->sIn.i+1>=pRe->sIn.mx ){
    re_append(pRe, RE_OP_MATCH, RE_EOF);
    re_append(pRe, RE_OP_ACCEPT, 0);
    *ppRe = pRe;
  }else if( pRe->sIn.i>=pRe->sIn.mx ){
    re_append(pRe, RE_OP_ACCEPT, 0);
    *ppRe = pRe;
  }else{
    re_free(pRe);
    return "unrecognized character";
  }

  /* The following is a performance optimization.  If the regex begins with
  ** ".*" (if the input regex lacks an initial "^") and afterwards there are
  ** one or more matching characters, enter those matching characters into
  ** zInit[].  The re_match() routine can then search ahead in the input
  ** string looking for the initial match without having to run the whole
  ** regex engine over the string.  Do not worry able trying to match
  ** unicode characters beyond plane 0 - those are very rare and this is
  ** just an optimization. */
  if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
    for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
      unsigned x = pRe->aArg[i];
      if( x<=127 ){
        pRe->zInit[j++] = (unsigned char)x;
      }else if( x<=0xfff ){
        pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
        pRe->zInit[j++] = 0x80 | (x&0x3f);
      }else if( x<=0xffff ){
        pRe->zInit[j++] = (unsigned char)(0xd0 | (x>>12));
        pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
        pRe->zInit[j++] = 0x80 | (x&0x3f);
      }else{
        break;
      }
    }
    if( j>0 && pRe->zInit[j-1]==0 ) j--;







<
<
<
<
|












|





|

|



|







671
672
673
674
675
676
677




678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
  pRe->sIn.i = 0;
  pRe->sIn.mx = (int)strlen(zIn);
  zErr = re_subcompile_re(pRe);
  if( zErr ){
    re_free(pRe);
    return zErr;
  }




  if( pRe->sIn.i>=pRe->sIn.mx ){
    re_append(pRe, RE_OP_ACCEPT, 0);
    *ppRe = pRe;
  }else{
    re_free(pRe);
    return "unrecognized character";
  }

  /* The following is a performance optimization.  If the regex begins with
  ** ".*" (if the input regex lacks an initial "^") and afterwards there are
  ** one or more matching characters, enter those matching characters into
  ** zInit[].  The re_match() routine can then search ahead in the input
  ** string looking for the initial match without having to run the whole
  ** regex engine over the string.  Do not worry about trying to match
  ** unicode characters beyond plane 0 - those are very rare and this is
  ** just an optimization. */
  if( pRe->aOp[0]==RE_OP_ANYSTAR && !noCase ){
    for(j=0, i=1; j<(int)sizeof(pRe->zInit)-2 && pRe->aOp[i]==RE_OP_MATCH; i++){
      unsigned x = pRe->aArg[i];
      if( x<=0x7f ){
        pRe->zInit[j++] = (unsigned char)x;
      }else if( x<=0x7ff ){
        pRe->zInit[j++] = (unsigned char)(0xc0 | (x>>6));
        pRe->zInit[j++] = 0x80 | (x&0x3f);
      }else if( x<=0xffff ){
        pRe->zInit[j++] = (unsigned char)(0xe0 | (x>>12));
        pRe->zInit[j++] = 0x80 | ((x>>6)&0x3f);
        pRe->zInit[j++] = 0x80 | (x&0x3f);
      }else{
        break;
      }
    }
    if( j>0 && pRe->zInit[j-1]==0 ) j--;
Changes to www/grep.md.
97
98
99
100
101
102
103





104
105
106
107
108
109
110
| `\S`    | Non-whitespace character: `[^ \t\r\n\v\f]`

There are several restrictions in Fossil `grep` relative to a fully
POSIX compatible regular expression engine. Among them are:

*   There is currently no support for POSIX character classes such as
    `[:lower:]`.






*   Fossil `grep` does not currently attempt to take your operating
    system's locale settings into account when doing this match.  Since
    Fossil has no way to mark a given file as having a particular
    encoding, Fossil `grep` assumes the input files are in UTF-8 format.

    This means Fossil `grep` will not work correctly if the files in







>
>
>
>
>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
| `\S`    | Non-whitespace character: `[^ \t\r\n\v\f]`

There are several restrictions in Fossil `grep` relative to a fully
POSIX compatible regular expression engine. Among them are:

*   There is currently no support for POSIX character classes such as
    `[:lower:]`.

*   The values of `p` and `q` in the "`{p,q}`" syntax can be no greater
    than 999.  This is because the NFA that is used for regular expression
    matching is proportional in size to the largest p or q value, and hence
    allowing arbitrarily large values could result in a DoS attack.

*   Fossil `grep` does not currently attempt to take your operating
    system's locale settings into account when doing this match.  Since
    Fossil has no way to mark a given file as having a particular
    encoding, Fossil `grep` assumes the input files are in UTF-8 format.

    This means Fossil `grep` will not work correctly if the files in