/ Check-in [53f2100a]
Login

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

Overview
Comment:Merge updates from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | zonefile
Files: files | file ages | folders
SHA3-256: 53f2100a296f64d206f1caf2d754820a7898bb33b31a6ab2169957d228d5d2a0
User & Date: mistachkin 2018-02-23 13:45:05
Context
2018-02-23
13:58
Avoid running a test case that requires zstd in non-SQLITE_HAVE_ZSTD builds. check-in: d716dff4 user: dan tags: zonefile
13:45
Merge updates from trunk. check-in: 53f2100a user: mistachkin tags: zonefile
13:38
Fix harmless compiler warnings in the zipfile extension seen with MSVC. check-in: 15c587cf user: mistachkin tags: trunk
2018-02-22
21:06
Add tests cases and fix some minor zonefile problems. check-in: f4d42162 user: dan tags: zonefile
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.in.

587
588
589
590
591
592
593

594
595
596
597
598
599
600
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000

FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT = 

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)







>







587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_SRC = $(TOP)/test/fuzzcheck.c $(TOP)/test/ossfuzz.c
DBFUZZ_OPT = 

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#
all:	sqlite3.h libsqlite3.la sqlite3$(TEXE) $(HAVE_TCL:1=libtclsqlite3.la)

Changes to Makefile.msc.

1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
....
2248
2249
2250
2251
2252
2253
2254

2255
2256
2257
2258
2259
2260
2261
!ENDIF

# <<mark>>
# Extra compiler options for various test tools.
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0

................................................................................
TESTFIXTURE_FLAGS = -DTCLSH_INIT_PROC=sqlite3TestInit -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB

TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)

TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
!IF $(USE_AMALGAMATION)==0
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
!ELSE







|







 







>







1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
....
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
!ENDIF

# <<mark>>
# Extra compiler options for various test tools.
#
MPTESTER_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_FTS5
FUZZERSHELL_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1
FUZZCHECK_COMPILE_OPTS = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5 -DSQLITE_OSS_FUZZ -DSQLITE_MAX_MEMORY=50000000 -DSQLITE_PRINTF_PRECISION_LIMIT=1000
FUZZCHECK_SRC = $(TOP)\test\fuzzcheck.c $(TOP)\test\ossfuzz.c
OSSSHELL_SRC = $(TOP)\test\ossshell.c $(TOP)\test\ossfuzz.c
DBFUZZ_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION
KV_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
DBSELFTEST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5
ST_COMPILE_OPTS = -DSQLITE_THREADSAFE=0

................................................................................
TESTFIXTURE_FLAGS = -DTCLSH_INIT_PROC=sqlite3TestInit -DSQLITE_TEST=1 -DSQLITE_CRASH_TEST=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERVER=1 -DSQLITE_PRIVATE=""
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_CORE $(NO_WARN)
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_SERIES_CONSTRAINT_VERIFY=1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_DEFAULT_PAGE_SIZE=1024
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) -DSQLITE_ENABLE_JSON1
TESTFIXTURE_FLAGS = $(TESTFIXTURE_FLAGS) $(TEST_CCONV_OPTS)

TESTFIXTURE_SRC0 = $(TESTEXT) $(TESTSRC2)
TESTFIXTURE_SRC1 = $(TESTEXT) $(SQLITE3C)
!IF $(USE_AMALGAMATION)==0
TESTFIXTURE_SRC = $(TESTSRC) $(TOP)\src\tclsqlite.c $(TESTFIXTURE_SRC0)
!ELSE

Changes to README.md.

10
11
12
13
14
15
16
17
18
19
20
21

22
23
24
25

26
27
28
29
30
31
32

## Obtaining The Code

SQLite sources are managed using the
[Fossil](https://www.fossil-scm.org/), a distributed version control system
that was specifically designed to support SQLite development.
If you do not want to use Fossil, you can download tarballs or ZIP
archives as follows:

  *  Lastest trunk check-in:
     <https://www.sqlite.org/src/tarball/sqlite.tar.gz> or
     <https://www.sqlite.org/src/zip/sqlite.zip>.


  *  Latest release:
     <https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release> or
     <https://www.sqlite.org/src/zip/sqlite.zip?r=release>.


  *  For other check-ins, substitute an appropriate branch name or
     tag or hash prefix for "release" in the URLs of the previous
     bullet.  Or browse the [timeline](https://www.sqlite.org/src/timeline)
     to locate the check-in desired, click on its information page link,
     then click on the "Tarball" or "ZIP Archive" links on the information
     page.







|

|
|
|
>

|
|
|
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

## Obtaining The Code

SQLite sources are managed using the
[Fossil](https://www.fossil-scm.org/), a distributed version control system
that was specifically designed to support SQLite development.
If you do not want to use Fossil, you can download tarballs or ZIP
archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows:

  *  Lastest trunk check-in as
     [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz),
     [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip), or
     [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar).

  *  Latest release as
     [Tarball](https://www.sqlite.org/src/tarball/sqlite.tar.gz?r=release),
     [ZIP-archive](https://www.sqlite.org/src/zip/sqlite.zip?r=release), or
     [SQLite-archive](https://www.sqlite.org/src/sqlar/sqlite.sqlar?r=release).

  *  For other check-ins, substitute an appropriate branch name or
     tag or hash prefix for "release" in the URLs of the previous
     bullet.  Or browse the [timeline](https://www.sqlite.org/src/timeline)
     to locate the check-in desired, click on its information page link,
     then click on the "Tarball" or "ZIP Archive" links on the information
     page.

Changes to ext/fts3/fts3_write.c.

5525
5526
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5538
5539
....
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
5648
5649
  sqlite3_vtab *pVtab,            /* FTS3 vtab object */
  int nArg,                       /* Size of argument array */
  sqlite3_value **apVal,          /* Array of arguments */
  sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
){
  Fts3Table *p = (Fts3Table *)pVtab;
  int rc = SQLITE_OK;             /* Return Code */
  int isRemove = 0;               /* True for an UPDATE or DELETE */
  u32 *aSzIns = 0;                /* Sizes of inserted documents */
  u32 *aSzDel = 0;                /* Sizes of deleted documents */
  int nChng = 0;                  /* Net change in number of documents */
  int bInsertDone = 0;

  /* At this point it must be known if the %_stat table exists or not.
  ** So bHasStat may not be 2.  */
................................................................................
    goto update_out;
  }

  /* If this is a DELETE or UPDATE operation, remove the old record. */
  if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
    assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
    rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);
    isRemove = 1;
  }
  
  /* If this is an INSERT or UPDATE operation, insert the new record. */
  if( nArg>1 && rc==SQLITE_OK ){
    int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]);
    if( bInsertDone==0 ){
      rc = fts3InsertData(p, apVal, pRowid);
      if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
        rc = FTS_CORRUPT_VTAB;
      }
    }
    if( rc==SQLITE_OK && (!isRemove || *pRowid!=p->iPrevDocid ) ){
      rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
    }
    if( rc==SQLITE_OK ){
      assert( p->iPrevDocid==*pRowid );
      rc = fts3InsertTerms(p, iLangid, apVal, aSzIns);
    }
    if( p->bHasDocsize ){







<







 







<











|







5525
5526
5527
5528
5529
5530
5531

5532
5533
5534
5535
5536
5537
5538
....
5622
5623
5624
5625
5626
5627
5628

5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647
  sqlite3_vtab *pVtab,            /* FTS3 vtab object */
  int nArg,                       /* Size of argument array */
  sqlite3_value **apVal,          /* Array of arguments */
  sqlite_int64 *pRowid            /* OUT: The affected (or effected) rowid */
){
  Fts3Table *p = (Fts3Table *)pVtab;
  int rc = SQLITE_OK;             /* Return Code */

  u32 *aSzIns = 0;                /* Sizes of inserted documents */
  u32 *aSzDel = 0;                /* Sizes of deleted documents */
  int nChng = 0;                  /* Net change in number of documents */
  int bInsertDone = 0;

  /* At this point it must be known if the %_stat table exists or not.
  ** So bHasStat may not be 2.  */
................................................................................
    goto update_out;
  }

  /* If this is a DELETE or UPDATE operation, remove the old record. */
  if( sqlite3_value_type(apVal[0])!=SQLITE_NULL ){
    assert( sqlite3_value_type(apVal[0])==SQLITE_INTEGER );
    rc = fts3DeleteByRowid(p, apVal[0], &nChng, aSzDel);

  }
  
  /* If this is an INSERT or UPDATE operation, insert the new record. */
  if( nArg>1 && rc==SQLITE_OK ){
    int iLangid = sqlite3_value_int(apVal[2 + p->nColumn + 2]);
    if( bInsertDone==0 ){
      rc = fts3InsertData(p, apVal, pRowid);
      if( rc==SQLITE_CONSTRAINT && p->zContentTbl==0 ){
        rc = FTS_CORRUPT_VTAB;
      }
    }
    if( rc==SQLITE_OK ){
      rc = fts3PendingTermsDocid(p, 0, iLangid, *pRowid);
    }
    if( rc==SQLITE_OK ){
      assert( p->iPrevDocid==*pRowid );
      rc = fts3InsertTerms(p, iLangid, apVal, aSzIns);
    }
    if( p->bHasDocsize ){

Changes to ext/misc/spellfix.c.

14
15
16
17
18
19
20






21
22
23
24
25
26
27
...
647
648
649
650
651
652
653









































































654
655
656
657
658
659
660
...
681
682
683
684
685
686
687

688
689
690
691
692
693
694
...
718
719
720
721
722
723
724






725
726
727
728
729
730
731
...
745
746
747
748
749
750
751

752
753
754
755
756
757
758
759
760
761
762

763
764
765
766
767
768
769
...
772
773
774
775
776
777
778

779
780
781
782
783
784
785
786
...
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870

871
872
873
874
875
876
877
878
879
880
881
882
...
932
933
934
935
936
937
938
939
940

941
942
943
944
945
946
947
....
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
....
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
** to search a large vocabulary for close matches.  See separate
** documentation (http://www.sqlite.org/spellfix1.html) for details.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1

#ifndef SQLITE_AMALGAMATION






# include <string.h>
# include <stdio.h>
# include <stdlib.h>
# include <assert.h>
# define ALWAYS(X)  1
# define NEVER(X)   0
  typedef unsigned char u8;
................................................................................
  memset(p, 0, sizeof(*p));
}
static void editDist3ConfigDelete(void *pIn){
  EditDist3Config *p = (EditDist3Config*)pIn;
  editDist3ConfigClear(p);
  sqlite3_free(p);
}










































































/*
** Load all edit-distance weights from a table.
*/
static int editDist3ConfigLoad(
  EditDist3Config *p,      /* The edit distance configuration to load */
  sqlite3 *db,            /* Load from this database */
................................................................................
    int nTo = zTo ? sqlite3_column_bytes(pStmt, 2) : 0;
    int iCost = sqlite3_column_int(pStmt, 3);

    assert( zFrom!=0 || nFrom==0 );
    assert( zTo!=0 || nTo==0 );
    if( nFrom>100 || nTo>100 ) continue;
    if( iCost<0 ) continue;

    if( pLang==0 || iLang!=iLangPrev ){
      EditDist3Lang *pNew;
      pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0]));
      if( pNew==0 ){ rc = SQLITE_NOMEM; break; }
      p->a = pNew;
      pLang = &p->a[p->nLang];
      p->nLang++;
................................................................................
      memcpy(pCost->a + nFrom, zTo, nTo);
      pCost->pNext = pLang->pCost;
      pLang->pCost = pCost; 
    }
  }
  rc2 = sqlite3_finalize(pStmt);
  if( rc==SQLITE_OK ) rc = rc2;






  return rc;
}

/*
** Return the length (in bytes) of a utf-8 character.  Or return a maximum
** of N.
*/
................................................................................
}

/*
** Return TRUE (non-zero) if the To side of the given cost matches
** the given string.
*/
static int matchTo(EditDist3Cost *p, const char *z, int n){

  if( p->nTo>n ) return 0;
  if( strncmp(p->a+p->nFrom, z, p->nTo)!=0 ) return 0;
  return 1;
}

/*
** Return TRUE (non-zero) if the From side of the given cost matches
** the given string.
*/
static int matchFrom(EditDist3Cost *p, const char *z, int n){
  assert( p->nFrom<=n );

  if( strncmp(p->a, z, p->nFrom)!=0 ) return 0;
  return 1;
}

/*
** Return TRUE (non-zero) of the next FROM character and the next TO
** character are the same.
................................................................................
  EditDist3FromString *pStr,  /* Left hand string */
  int n1,                     /* Index of comparison character on the left */
  const char *z2,             /* Right-handl comparison character */
  int n2                      /* Bytes remaining in z2[] */
){
  int b1 = pStr->a[n1].nByte;
  if( b1>n2 ) return 0;

  if( memcmp(pStr->z+n1, z2, b1)!=0 ) return 0;
  return 1;
}

/*
** Delete an EditDist3FromString objecct
*/
static void editDist3FromStringDelete(EditDist3FromString *p){
................................................................................
  }
  return pStr;
}

/*
** Update entry m[i] such that it is the minimum of its current value
** and m[j]+iCost.
**
** If the iCost is 1,000,000 or greater, then consider the cost to be
** infinite and skip the update.
*/
static void updateCost(
  unsigned int *m,
  int i,
  int j,
  int iCost
){

  assert( iCost>=0 );
  if( iCost<10000 ){
    unsigned int b = m[j] + iCost;
    if( b<m[i] ) m[i] = b;
  }
}

/*
** How much stack space (int bytes) to use for Wagner matrix in 
** editDist3Core().  If more space than this is required, the entire
** matrix is taken from the heap.  To reduce the load on the memory
** allocator, make this value as large as practical for the
................................................................................
  memset(a2, 0, sizeof(a2[0])*n2);

  /* Fill in the a1[] matrix for all characters of the TO string */
  for(i2=0; i2<n2; i2++){
    a2[i2].nByte = utf8Len((unsigned char)z2[i2], n2-i2);
    for(p=pLang->pCost; p; p=p->pNext){
      EditDist3Cost **apNew;
      if( p->nFrom>0 ) continue;
      if( i2+p->nTo>n2 ) continue;

      if( matchTo(p, z2+i2, n2-i2)==0 ) continue;
      a2[i2].nIns++;
      apNew = sqlite3_realloc64(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns);
      if( apNew==0 ){
        res = -1;  /* Out of memory */
        goto editDist3Abort;
      }
................................................................................
  if( zPattern==0 ){
    x.rc = SQLITE_NOMEM;
    goto filter_exit;
  }
  nPattern = (int)strlen(zPattern);
  if( zPattern[nPattern-1]=='*' ) nPattern--;
  zSql = sqlite3_mprintf(
     "SELECT id, word, rank, k1"
     "  FROM \"%w\".\"%w_vocab\""
     " WHERE langid=%d AND k2>=?1 AND k2<?2",
     p->zDbName, p->zTableName, iLang
  );
  if( zSql==0 ){
    x.rc = SQLITE_NOMEM;
    pStmt = 0;
................................................................................
      sqlite3_free(zK1);
      return SQLITE_NOMEM;
    }
    if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
      if( sqlite3_value_type(argv[1])==SQLITE_NULL ){
        spellfix1DbExec(&rc, db,
               "INSERT INTO \"%w\".\"%w_vocab\"(rank,langid,word,k1,k2) "
               "VALUES(%d,%d,%Q,%Q,%Q)",
               p->zDbName, p->zTableName,
               iRank, iLang, zWord, zK1, zK2
        );
      }else{
        newRowid = sqlite3_value_int64(argv[1]);
        spellfix1DbExec(&rc, db,
            "INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
            "VALUES(%lld,%d,%d,%Q,%Q,%Q)",
            zConflict, p->zDbName, p->zTableName,
            newRowid, iRank, iLang, zWord, zK1, zK2
        );
      }
      *pRowid = sqlite3_last_insert_rowid(db);
    }else{
      rowid = sqlite3_value_int64(argv[0]);
      newRowid = *pRowid = sqlite3_value_int64(argv[1]);
      spellfix1DbExec(&rc, db,
             "UPDATE OR %s \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
             " word=%Q, k1=%Q, k2=%Q WHERE id=%lld",
             zConflict, p->zDbName, p->zTableName, newRowid, iRank, iLang,
             zWord, zK1, zK2, rowid
      );
    }
    sqlite3_free(zK1);
    sqlite3_free(zK2);
  }
  return rc;
}







>
>
>
>
>
>







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







>







 







>
>
>
>
>
>







 







>











>







 







>
|







 







<
<
<







>

|
|
|
<







 







|

>







 







|







 







|

|





|

|








|

|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
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
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
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
...
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
...
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
...
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
...
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
...
943
944
945
946
947
948
949



950
951
952
953
954
955
956
957
958
959
960
961

962
963
964
965
966
967
968
....
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
....
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
....
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
** to search a large vocabulary for close matches.  See separate
** documentation (http://www.sqlite.org/spellfix1.html) for details.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1

#ifndef SQLITE_AMALGAMATION
# if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
#  define NDEBUG 1
# endif
# if defined(NDEBUG) && defined(SQLITE_DEBUG)
#  undef NDEBUG
# endif
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
# include <assert.h>
# define ALWAYS(X)  1
# define NEVER(X)   0
  typedef unsigned char u8;
................................................................................
  memset(p, 0, sizeof(*p));
}
static void editDist3ConfigDelete(void *pIn){
  EditDist3Config *p = (EditDist3Config*)pIn;
  editDist3ConfigClear(p);
  sqlite3_free(p);
}

/* Compare the FROM values of two EditDist3Cost objects, for sorting.
** Return negative, zero, or positive if the A is less than, equal to,
** or greater than B.
*/
static int editDist3CostCompare(EditDist3Cost *pA, EditDist3Cost *pB){
  int n = pA->nFrom;
  int rc;
  if( n>pB->nFrom ) n = pB->nFrom;
  rc = strncmp(pA->a, pB->a, n);
  if( rc==0 ) rc = pA->nFrom - pB->nFrom;
  return rc;
}

/*
** Merge together two sorted lists of EditDist3Cost objects, in order
** of increasing FROM.
*/
static EditDist3Cost *editDist3CostMerge(
  EditDist3Cost *pA,
  EditDist3Cost *pB
){
  EditDist3Cost *pHead = 0;
  EditDist3Cost **ppTail = &pHead;
  EditDist3Cost *p;
  while( pA && pB ){
    if( editDist3CostCompare(pA,pB)<=0 ){
      p = pA;
      pA = pA->pNext;
    }else{
      p = pB;
      pB = pB->pNext;
    }
    *ppTail = p;
    ppTail =  &p->pNext;
  }
  if( pA ){
    *ppTail = pA;
  }else{
    *ppTail = pB;
  }
  return pHead;
}

/*
** Sort a list of EditDist3Cost objects into order of increasing FROM
*/
static EditDist3Cost *editDist3CostSort(EditDist3Cost *pList){
  EditDist3Cost *ap[60], *p;
  int i;
  int mx = 0;
  ap[0] = 0;
  ap[1] = 0;
  while( pList ){
    p = pList;
    pList = p->pNext;
    p->pNext = 0;
    for(i=0; ap[i]; i++){
      p = editDist3CostMerge(ap[i],p);
      ap[i] = 0;
    }
    ap[i] = p;
    if( i>mx ){
      mx = i;
      ap[i+1] = 0;
    }
  }
  p = 0;
  for(i=0; i<=mx; i++){
    if( ap[i] ) p = editDist3CostMerge(p,ap[i]);
  }
  return p;
}

/*
** Load all edit-distance weights from a table.
*/
static int editDist3ConfigLoad(
  EditDist3Config *p,      /* The edit distance configuration to load */
  sqlite3 *db,            /* Load from this database */
................................................................................
    int nTo = zTo ? sqlite3_column_bytes(pStmt, 2) : 0;
    int iCost = sqlite3_column_int(pStmt, 3);

    assert( zFrom!=0 || nFrom==0 );
    assert( zTo!=0 || nTo==0 );
    if( nFrom>100 || nTo>100 ) continue;
    if( iCost<0 ) continue;
    if( iCost>10000 ) continue;   /* Costs above 10K are considered infinite */
    if( pLang==0 || iLang!=iLangPrev ){
      EditDist3Lang *pNew;
      pNew = sqlite3_realloc64(p->a, (p->nLang+1)*sizeof(p->a[0]));
      if( pNew==0 ){ rc = SQLITE_NOMEM; break; }
      p->a = pNew;
      pLang = &p->a[p->nLang];
      p->nLang++;
................................................................................
      memcpy(pCost->a + nFrom, zTo, nTo);
      pCost->pNext = pLang->pCost;
      pLang->pCost = pCost; 
    }
  }
  rc2 = sqlite3_finalize(pStmt);
  if( rc==SQLITE_OK ) rc = rc2;
  if( rc==SQLITE_OK ){
    int iLang;
    for(iLang=0; iLang<p->nLang; iLang++){
      p->a[iLang].pCost = editDist3CostSort(p->a[iLang].pCost);
    }
  }
  return rc;
}

/*
** Return the length (in bytes) of a utf-8 character.  Or return a maximum
** of N.
*/
................................................................................
}

/*
** Return TRUE (non-zero) if the To side of the given cost matches
** the given string.
*/
static int matchTo(EditDist3Cost *p, const char *z, int n){
  if( p->a[p->nFrom]!=z[0] ) return 0;
  if( p->nTo>n ) return 0;
  if( strncmp(p->a+p->nFrom, z, p->nTo)!=0 ) return 0;
  return 1;
}

/*
** Return TRUE (non-zero) if the From side of the given cost matches
** the given string.
*/
static int matchFrom(EditDist3Cost *p, const char *z, int n){
  assert( p->nFrom<=n );
  if( p->a[0]!=z[0] ) return 0;
  if( strncmp(p->a, z, p->nFrom)!=0 ) return 0;
  return 1;
}

/*
** Return TRUE (non-zero) of the next FROM character and the next TO
** character are the same.
................................................................................
  EditDist3FromString *pStr,  /* Left hand string */
  int n1,                     /* Index of comparison character on the left */
  const char *z2,             /* Right-handl comparison character */
  int n2                      /* Bytes remaining in z2[] */
){
  int b1 = pStr->a[n1].nByte;
  if( b1>n2 ) return 0;
  if( pStr->z[n1]!=z2[0] ) return 0;
  if( strncmp(pStr->z+n1, z2, b1)!=0 ) return 0;
  return 1;
}

/*
** Delete an EditDist3FromString objecct
*/
static void editDist3FromStringDelete(EditDist3FromString *p){
................................................................................
  }
  return pStr;
}

/*
** Update entry m[i] such that it is the minimum of its current value
** and m[j]+iCost.



*/
static void updateCost(
  unsigned int *m,
  int i,
  int j,
  int iCost
){
  unsigned int b;
  assert( iCost>=0 );
  assert( iCost<10000 );
  b = m[j] + iCost;
  if( b<m[i] ) m[i] = b;

}

/*
** How much stack space (int bytes) to use for Wagner matrix in 
** editDist3Core().  If more space than this is required, the entire
** matrix is taken from the heap.  To reduce the load on the memory
** allocator, make this value as large as practical for the
................................................................................
  memset(a2, 0, sizeof(a2[0])*n2);

  /* Fill in the a1[] matrix for all characters of the TO string */
  for(i2=0; i2<n2; i2++){
    a2[i2].nByte = utf8Len((unsigned char)z2[i2], n2-i2);
    for(p=pLang->pCost; p; p=p->pNext){
      EditDist3Cost **apNew;
      if( p->nFrom>0 ) break;
      if( i2+p->nTo>n2 ) continue;
      if( p->a[0]>z2[i2] ) break;
      if( matchTo(p, z2+i2, n2-i2)==0 ) continue;
      a2[i2].nIns++;
      apNew = sqlite3_realloc64(a2[i2].apIns, sizeof(*apNew)*a2[i2].nIns);
      if( apNew==0 ){
        res = -1;  /* Out of memory */
        goto editDist3Abort;
      }
................................................................................
  if( zPattern==0 ){
    x.rc = SQLITE_NOMEM;
    goto filter_exit;
  }
  nPattern = (int)strlen(zPattern);
  if( zPattern[nPattern-1]=='*' ) nPattern--;
  zSql = sqlite3_mprintf(
     "SELECT id, word, rank, coalesce(k1,word)"
     "  FROM \"%w\".\"%w_vocab\""
     " WHERE langid=%d AND k2>=?1 AND k2<?2",
     p->zDbName, p->zTableName, iLang
  );
  if( zSql==0 ){
    x.rc = SQLITE_NOMEM;
    pStmt = 0;
................................................................................
      sqlite3_free(zK1);
      return SQLITE_NOMEM;
    }
    if( sqlite3_value_type(argv[0])==SQLITE_NULL ){
      if( sqlite3_value_type(argv[1])==SQLITE_NULL ){
        spellfix1DbExec(&rc, db,
               "INSERT INTO \"%w\".\"%w_vocab\"(rank,langid,word,k1,k2) "
               "VALUES(%d,%d,%Q,nullif(%Q,%Q),%Q)",
               p->zDbName, p->zTableName,
               iRank, iLang, zWord, zK1, zWord, zK2
        );
      }else{
        newRowid = sqlite3_value_int64(argv[1]);
        spellfix1DbExec(&rc, db,
            "INSERT OR %s INTO \"%w\".\"%w_vocab\"(id,rank,langid,word,k1,k2) "
            "VALUES(%lld,%d,%d,%Q,nullif(%Q,%Q),%Q)",
            zConflict, p->zDbName, p->zTableName,
            newRowid, iRank, iLang, zWord, zK1, zWord, zK2
        );
      }
      *pRowid = sqlite3_last_insert_rowid(db);
    }else{
      rowid = sqlite3_value_int64(argv[0]);
      newRowid = *pRowid = sqlite3_value_int64(argv[1]);
      spellfix1DbExec(&rc, db,
             "UPDATE OR %s \"%w\".\"%w_vocab\" SET id=%lld, rank=%d, langid=%d,"
             " word=%Q, k1=nullif(%Q,%Q), k2=%Q WHERE id=%lld",
             zConflict, p->zDbName, p->zTableName, newRowid, iRank, iLang,
             zWord, zK1, zWord, zK2, rowid
      );
    }
    sqlite3_free(zK1);
    sqlite3_free(zK2);
  }
  return rc;
}

Changes to ext/misc/zipfile.c.

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
....
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
....
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
....
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
....
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
  i64 JD = (i64)2440588 + mUnixTime / (24*60*60);

  int A, B, C, D, E;
  int yr, mon, day;
  int hr, min, sec;

  A = (int)((JD - 1867216.25)/36524.25);
  A = JD + 1 + A - (A/4);
  B = A + 1524;
  C = (int)((B - 122.1)/365.25);
  D = (36525*(C&32767))/100;
  E = (int)((B-D)/30.6001);

  day = B - D - (int)(30.6001*E);
  mon = (E<14 ? E-1 : E-13);
................................................................................
        pNew->cds.iCompression = (u16)iMethod;
        zipfileMtimeToDos(&pNew->cds, mTime);
        pNew->cds.crc32 = iCrc32;
        pNew->cds.szCompressed = nData;
        pNew->cds.szUncompressed = (u32)sz;
        pNew->cds.iExternalAttr = (mode<<16);
        pNew->cds.iOffset = (u32)pTab->szCurrent;
        pNew->cds.nFile = nPath;
        pNew->mUnixTime = (u32)mTime;
        rc = zipfileAppendEntry(pTab, pNew, pData, nData);
        zipfileAddEntry(pTab, pOld, pNew);
      }
    }
  }

................................................................................
    rc = SQLITE_ERROR;
    goto zipfile_step_out;
  }

  /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
  ** deflate compression) or NULL (choose automatically).  */
  if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
    iMethod = sqlite3_value_int64(pMethod);
    if( iMethod!=0 && iMethod!=8 ){
      zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
      rc = SQLITE_ERROR;
      goto zipfile_step_out;
    }
  }

................................................................................
    }
  }

  /* Assemble the ZipfileEntry object for the new zip archive entry */
  e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
  e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
  e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
  e.cds.iCompression = iMethod;
  zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
  e.cds.crc32 = iCrc32;
  e.cds.szCompressed = nData;
  e.cds.szUncompressed = szUncompressed;
  e.cds.iExternalAttr = (mode<<16);
  e.cds.iOffset = p->body.n;
  e.cds.nFile = nName;
  e.cds.zFile = zName;

  /* Append the LFH to the body of the new archive */
  nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
  if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
  p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);

................................................................................
  int nZip;
  u8 *aZip;

  p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
  if( p==0 ) return;
  if( p->nEntry>0 ){
    memset(&eocd, 0, sizeof(eocd));
    eocd.nEntry = p->nEntry;
    eocd.nEntryTotal = p->nEntry;
    eocd.nSize = p->cds.n;
    eocd.iOffset = p->body.n;

    nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
    aZip = (u8*)sqlite3_malloc(nZip);
    if( aZip==0 ){
      sqlite3_result_error_nomem(pCtx);







|







 







|







 







|







 







|






|







 







|
|







733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
....
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
....
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
....
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
....
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
  i64 JD = (i64)2440588 + mUnixTime / (24*60*60);

  int A, B, C, D, E;
  int yr, mon, day;
  int hr, min, sec;

  A = (int)((JD - 1867216.25)/36524.25);
  A = (int)(JD + 1 + A - (A/4));
  B = A + 1524;
  C = (int)((B - 122.1)/365.25);
  D = (36525*(C&32767))/100;
  E = (int)((B-D)/30.6001);

  day = B - D - (int)(30.6001*E);
  mon = (E<14 ? E-1 : E-13);
................................................................................
        pNew->cds.iCompression = (u16)iMethod;
        zipfileMtimeToDos(&pNew->cds, mTime);
        pNew->cds.crc32 = iCrc32;
        pNew->cds.szCompressed = nData;
        pNew->cds.szUncompressed = (u32)sz;
        pNew->cds.iExternalAttr = (mode<<16);
        pNew->cds.iOffset = (u32)pTab->szCurrent;
        pNew->cds.nFile = (u16)nPath;
        pNew->mUnixTime = (u32)mTime;
        rc = zipfileAppendEntry(pTab, pNew, pData, nData);
        zipfileAddEntry(pTab, pOld, pNew);
      }
    }
  }

................................................................................
    rc = SQLITE_ERROR;
    goto zipfile_step_out;
  }

  /* Inspect the 'method' parameter. This must be either 0 (store), 8 (use
  ** deflate compression) or NULL (choose automatically).  */
  if( pMethod && SQLITE_NULL!=sqlite3_value_type(pMethod) ){
    iMethod = (int)sqlite3_value_int64(pMethod);
    if( iMethod!=0 && iMethod!=8 ){
      zErr = sqlite3_mprintf("illegal method value: %d", iMethod);
      rc = SQLITE_ERROR;
      goto zipfile_step_out;
    }
  }

................................................................................
    }
  }

  /* Assemble the ZipfileEntry object for the new zip archive entry */
  e.cds.iVersionMadeBy = ZIPFILE_NEWENTRY_MADEBY;
  e.cds.iVersionExtract = ZIPFILE_NEWENTRY_REQUIRED;
  e.cds.flags = ZIPFILE_NEWENTRY_FLAGS;
  e.cds.iCompression = (u16)iMethod;
  zipfileMtimeToDos(&e.cds, (u32)e.mUnixTime);
  e.cds.crc32 = iCrc32;
  e.cds.szCompressed = nData;
  e.cds.szUncompressed = szUncompressed;
  e.cds.iExternalAttr = (mode<<16);
  e.cds.iOffset = p->body.n;
  e.cds.nFile = (u16)nName;
  e.cds.zFile = zName;

  /* Append the LFH to the body of the new archive */
  nByte = ZIPFILE_LFH_FIXED_SZ + e.cds.nFile + 9;
  if( (rc = zipfileBufferGrow(&p->body, nByte)) ) goto zipfile_step_out;
  p->body.n += zipfileSerializeLFH(&e, &p->body.a[p->body.n]);

................................................................................
  int nZip;
  u8 *aZip;

  p = (ZipfileCtx*)sqlite3_aggregate_context(pCtx, sizeof(ZipfileCtx));
  if( p==0 ) return;
  if( p->nEntry>0 ){
    memset(&eocd, 0, sizeof(eocd));
    eocd.nEntry = (u16)p->nEntry;
    eocd.nEntryTotal = (u16)p->nEntry;
    eocd.nSize = p->cds.n;
    eocd.iOffset = p->body.n;

    nZip = p->body.n + p->cds.n + ZIPFILE_EOCD_FIXED_SZ;
    aZip = (u8*)sqlite3_malloc(nZip);
    if( aZip==0 ){
      sqlite3_result_error_nomem(pCtx);

Changes to main.mk.

516
517
518
519
520
521
522

523
524
525
526
527
528
529
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000

DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#







>







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
SHELL_OPT += -DSQLITE_ENABLE_DBPAGE_VTAB
SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB
SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC
SHELL_OPT += -DSQLITE_INTROSPECTION_PRAGMAS
FUZZERSHELL_OPT = -DSQLITE_ENABLE_JSON1
FUZZCHECK_OPT = -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MEMSYS5
FUZZCHECK_OPT += -DSQLITE_MAX_MEMORY=50000000
FUZZCHECK_OPT += -DSQLITE_PRINTF_PRECISION_LIMIT=1000
DBFUZZ_OPT =
KV_OPT = -DSQLITE_THREADSAFE=0 -DSQLITE_DIRECT_OVERFLOW_READ
ST_OPT = -DSQLITE_THREADSAFE=0

# This is the default Makefile target.  The objects listed here
# are what get build when you type just "make" with no arguments.
#

Changes to src/attach.c.

499
500
501
502
503
504
505








506
507
508
509
510
511
512
      return 1;
    }
    if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
      return 1;








    }
    pSelect = pSelect->pPrior;
  }
  return 0;
}
int sqlite3FixExpr(
  DbFixer *pFix,     /* Context of the fixation */







>
>
>
>
>
>
>
>







499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
      return 1;
    }
    if( sqlite3FixExprList(pFix, pSelect->pOrderBy) ){
      return 1;
    }
    if( sqlite3FixExpr(pFix, pSelect->pLimit) ){
      return 1;
    }
    if( pSelect->pWith ){
      int i;
      for(i=0; i<pSelect->pWith->nCte; i++){
        if( sqlite3FixSelect(pFix, pSelect->pWith->a[i].pSelect) ){
          return 1;
        }
      }
    }
    pSelect = pSelect->pPrior;
  }
  return 0;
}
int sqlite3FixExpr(
  DbFixer *pFix,     /* Context of the fixation */

Changes to src/btree.c.

4384
4385
4386
4387
4388
4389
4390








4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
** BtCursor.info structure.  If it is not already valid, call
** btreeParseCell() to fill it in.
**
** BtCursor.info is a cache of the information in the current cell.
** Using this cache reduces the number of calls to btreeParseCell().
*/
#ifndef NDEBUG








  static void assertCellInfo(BtCursor *pCur){
    CellInfo info;
    memset(&info, 0, sizeof(info));
    btreeParseCell(pCur->pPage, pCur->ix, &info);
    assert( CORRUPT_DB || memcmp(&info, &pCur->info, sizeof(info))==0 );
  }
#else
  #define assertCellInfo(x)
#endif
static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
  if( pCur->info.nSize==0 ){
    pCur->curFlags |= BTCF_ValidNKey;







>
>
>
>
>
>
>
>




|







4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
** BtCursor.info structure.  If it is not already valid, call
** btreeParseCell() to fill it in.
**
** BtCursor.info is a cache of the information in the current cell.
** Using this cache reduces the number of calls to btreeParseCell().
*/
#ifndef NDEBUG
  static int cellInfoEqual(CellInfo *a, CellInfo *b){
    if( a->nKey!=b->nKey ) return 0;
    if( a->pPayload!=b->pPayload ) return 0;
    if( a->nPayload!=b->nPayload ) return 0;
    if( a->nLocal!=b->nLocal ) return 0;
    if( a->nSize!=b->nSize ) return 0;
    return 1;
  }
  static void assertCellInfo(BtCursor *pCur){
    CellInfo info;
    memset(&info, 0, sizeof(info));
    btreeParseCell(pCur->pPage, pCur->ix, &info);
    assert( CORRUPT_DB || cellInfoEqual(&info, &pCur->info) );
  }
#else
  #define assertCellInfo(x)
#endif
static SQLITE_NOINLINE void getCellInfo(BtCursor *pCur){
  if( pCur->info.nSize==0 ){
    pCur->curFlags |= BTCF_ValidNKey;

Changes to src/global.c.

254
255
256
257
258
259
260







261
262
263
264
265
266
267
** Constant tokens for values 0 and 1.
*/
const Token sqlite3IntTokens[] = {
   { "0", 1 },
   { "1", 1 }
};









/*
** The value of the "pending" byte must be 0x40000000 (1 byte past the
** 1-gibabyte boundary) in a compatible database.  SQLite never uses
** the database page that contains the pending byte.  It never attempts
** to read or write that page.  The pending byte page is set aside
** for use by the VFS layers as space for managing file locks.







>
>
>
>
>
>
>







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
** Constant tokens for values 0 and 1.
*/
const Token sqlite3IntTokens[] = {
   { "0", 1 },
   { "1", 1 }
};

#ifdef VDBE_PROFILE
/*
** The following performance counter can be used in place of
** sqlite3Hwtime() for profiling.  This is a no-op on standard builds.
*/
sqlite3_uint64 sqlite3NProfileCnt = 0;
#endif

/*
** The value of the "pending" byte must be 0x40000000 (1 byte past the
** 1-gibabyte boundary) in a compatible database.  SQLite never uses
** the database page that contains the pending byte.  It never attempts
** to read or write that page.  The pending byte page is set aside
** for use by the VFS layers as space for managing file locks.

Changes to src/mutex_unix.c.

46
47
48
49
50
51
52
53

54
55
56
57
58
59
60
61
62
63
64
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
177
178
179
180
181
182
183



184
185
186
187
188
189
190



191
192
193
194
195
196
197
...
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
#if SQLITE_MUTEX_NREF
  volatile int nRef;         /* Number of entrances */
  volatile pthread_t owner;  /* Thread that is within this mutex */
  int trace;                 /* True to trace changes */
#endif
};
#if SQLITE_MUTEX_NREF
#define SQLITE3_MUTEX_INITIALIZER {PTHREAD_MUTEX_INITIALIZER,0,0,(pthread_t)0,0}

#elif defined(SQLITE_ENABLE_API_ARMOR)
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { PTHREAD_MUTEX_INITIALIZER }
#endif

/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use only inside assert() statements.  On some platforms,
** there might be race conditions that can cause these routines to
** deliver incorrect results.  In particular, if pthread_equal() is
................................................................................
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  But for the static 
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
static sqlite3_mutex *pthreadMutexAlloc(int iType){
  static sqlite3_mutex staticMutexes[] = {
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER,
    SQLITE3_MUTEX_INITIALIZER
  };
  sqlite3_mutex *p;
  switch( iType ){
    case SQLITE_MUTEX_RECURSIVE: {
      p = sqlite3MallocZero( sizeof(*p) );
      if( p ){
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
................................................................................
        /* Use a recursive mutex if it is available */
        pthread_mutexattr_t recursiveAttr;
        pthread_mutexattr_init(&recursiveAttr);
        pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(&p->mutex, &recursiveAttr);
        pthread_mutexattr_destroy(&recursiveAttr);
#endif



      }
      break;
    }
    case SQLITE_MUTEX_FAST: {
      p = sqlite3MallocZero( sizeof(*p) );
      if( p ){
        pthread_mutex_init(&p->mutex, 0);



      }
      break;
    }
    default: {
#ifdef SQLITE_ENABLE_API_ARMOR
      if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
        (void)SQLITE_MISUSE_BKPT;
................................................................................
      }
#endif
      p = &staticMutexes[iType-2];
      break;
    }
  }
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
  if( p ) p->id = iType;
#endif
  return p;
}


/*
** This routine deallocates a previously







|
>

|

|







 







|
|
|
|
|
|
|
|
|
|
|
|







 







>
>
>







>
>
>







 







|







46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
#if SQLITE_MUTEX_NREF
  volatile int nRef;         /* Number of entrances */
  volatile pthread_t owner;  /* Thread that is within this mutex */
  int trace;                 /* True to trace changes */
#endif
};
#if SQLITE_MUTEX_NREF
# define SQLITE3_MUTEX_INITIALIZER(id) \
     {PTHREAD_MUTEX_INITIALIZER,id,0,(pthread_t)0,0}
#elif defined(SQLITE_ENABLE_API_ARMOR)
# define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER, id }
#else
#define SQLITE3_MUTEX_INITIALIZER(id) { PTHREAD_MUTEX_INITIALIZER }
#endif

/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use only inside assert() statements.  On some platforms,
** there might be race conditions that can cause these routines to
** deliver incorrect results.  In particular, if pthread_equal() is
................................................................................
** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc()
** returns a different mutex on every call.  But for the static 
** mutex types, the same mutex is returned on every call that has
** the same type number.
*/
static sqlite3_mutex *pthreadMutexAlloc(int iType){
  static sqlite3_mutex staticMutexes[] = {
    SQLITE3_MUTEX_INITIALIZER(2),
    SQLITE3_MUTEX_INITIALIZER(3),
    SQLITE3_MUTEX_INITIALIZER(4),
    SQLITE3_MUTEX_INITIALIZER(5),
    SQLITE3_MUTEX_INITIALIZER(6),
    SQLITE3_MUTEX_INITIALIZER(7),
    SQLITE3_MUTEX_INITIALIZER(8),
    SQLITE3_MUTEX_INITIALIZER(9),
    SQLITE3_MUTEX_INITIALIZER(10),
    SQLITE3_MUTEX_INITIALIZER(11),
    SQLITE3_MUTEX_INITIALIZER(12),
    SQLITE3_MUTEX_INITIALIZER(13)
  };
  sqlite3_mutex *p;
  switch( iType ){
    case SQLITE_MUTEX_RECURSIVE: {
      p = sqlite3MallocZero( sizeof(*p) );
      if( p ){
#ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
................................................................................
        /* Use a recursive mutex if it is available */
        pthread_mutexattr_t recursiveAttr;
        pthread_mutexattr_init(&recursiveAttr);
        pthread_mutexattr_settype(&recursiveAttr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(&p->mutex, &recursiveAttr);
        pthread_mutexattr_destroy(&recursiveAttr);
#endif
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
        p->id = SQLITE_MUTEX_RECURSIVE;
#endif
      }
      break;
    }
    case SQLITE_MUTEX_FAST: {
      p = sqlite3MallocZero( sizeof(*p) );
      if( p ){
        pthread_mutex_init(&p->mutex, 0);
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
        p->id = SQLITE_MUTEX_FAST;
#endif
      }
      break;
    }
    default: {
#ifdef SQLITE_ENABLE_API_ARMOR
      if( iType-2<0 || iType-2>=ArraySize(staticMutexes) ){
        (void)SQLITE_MISUSE_BKPT;
................................................................................
      }
#endif
      p = &staticMutexes[iType-2];
      break;
    }
  }
#if SQLITE_MUTEX_NREF || defined(SQLITE_ENABLE_API_ARMOR)
  assert( p==0 || p->id==iType );
#endif
  return p;
}


/*
** This routine deallocates a previously

Changes to src/mutex_w32.c.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
235
236
237
238
239
240
241
242
243
244
245

246
247
248
249
250

251
252
253
254
255
256
257
*/
struct sqlite3_mutex {
  CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
  int id;                    /* Mutex type */
#ifdef SQLITE_DEBUG
  volatile int nRef;         /* Number of enterances */
  volatile DWORD owner;      /* Thread holding this mutex */
  volatile int trace;        /* True to trace changes */
#endif
};

/*
** These are the initializer values used when declaring a "static" mutex
** on Win32.  It should be noted that all mutexes require initialization
** on the Win32 platform.
*/
#define SQLITE_W32_MUTEX_INITIALIZER { 0 }

#ifdef SQLITE_DEBUG
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0, \
                                    0L, (DWORD)0, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER { SQLITE_W32_MUTEX_INITIALIZER, 0 }
#endif

#ifdef SQLITE_DEBUG
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use only inside assert() statements.
*/
................................................................................
#endif
}

/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER,
  SQLITE3_MUTEX_INITIALIZER
};

static int winMutex_isInit = 0;
static int winMutex_isNt = -1; /* <0 means "need to query" */

/* As the winMutexInit() and winMutexEnd() functions are called as part
** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
................................................................................
#ifdef SQLITE_ENABLE_API_ARMOR
      if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
        (void)SQLITE_MISUSE_BKPT;
        return 0;
      }
#endif
      p = &winMutex_staticMutexes[iType-2];
      p->id = iType;
#ifdef SQLITE_DEBUG
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC
      p->trace = 1;

#endif
#endif
      break;
    }
  }

  return p;
}


/*
** This routine deallocates a previously
** allocated mutex.  SQLite is careful to deallocate every







|











|


|







 







|
|
|
|
|
|
|
|
|
|
|
|







 







<


<
>





>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
..
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
...
235
236
237
238
239
240
241

242
243

244
245
246
247
248
249
250
251
252
253
254
255
256
257
*/
struct sqlite3_mutex {
  CRITICAL_SECTION mutex;    /* Mutex controlling the lock */
  int id;                    /* Mutex type */
#ifdef SQLITE_DEBUG
  volatile int nRef;         /* Number of enterances */
  volatile DWORD owner;      /* Thread holding this mutex */
  volatile LONG trace;       /* True to trace changes */
#endif
};

/*
** These are the initializer values used when declaring a "static" mutex
** on Win32.  It should be noted that all mutexes require initialization
** on the Win32 platform.
*/
#define SQLITE_W32_MUTEX_INITIALIZER { 0 }

#ifdef SQLITE_DEBUG
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id, \
                                    0L, (DWORD)0, 0 }
#else
#define SQLITE3_MUTEX_INITIALIZER(id) { SQLITE_W32_MUTEX_INITIALIZER, id }
#endif

#ifdef SQLITE_DEBUG
/*
** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
** intended for use only inside assert() statements.
*/
................................................................................
#endif
}

/*
** Initialize and deinitialize the mutex subsystem.
*/
static sqlite3_mutex winMutex_staticMutexes[] = {
  SQLITE3_MUTEX_INITIALIZER(2),
  SQLITE3_MUTEX_INITIALIZER(3),
  SQLITE3_MUTEX_INITIALIZER(4),
  SQLITE3_MUTEX_INITIALIZER(5),
  SQLITE3_MUTEX_INITIALIZER(6),
  SQLITE3_MUTEX_INITIALIZER(7),
  SQLITE3_MUTEX_INITIALIZER(8),
  SQLITE3_MUTEX_INITIALIZER(9),
  SQLITE3_MUTEX_INITIALIZER(10),
  SQLITE3_MUTEX_INITIALIZER(11),
  SQLITE3_MUTEX_INITIALIZER(12),
  SQLITE3_MUTEX_INITIALIZER(13)
};

static int winMutex_isInit = 0;
static int winMutex_isNt = -1; /* <0 means "need to query" */

/* As the winMutexInit() and winMutexEnd() functions are called as part
** of the sqlite3_initialize() and sqlite3_shutdown() processing, the
................................................................................
#ifdef SQLITE_ENABLE_API_ARMOR
      if( iType-2<0 || iType-2>=ArraySize(winMutex_staticMutexes) ){
        (void)SQLITE_MISUSE_BKPT;
        return 0;
      }
#endif
      p = &winMutex_staticMutexes[iType-2];

#ifdef SQLITE_DEBUG
#ifdef SQLITE_WIN32_MUTEX_TRACE_STATIC

      InterlockedCompareExchange(&p->trace, 1, 0);
#endif
#endif
      break;
    }
  }
  assert( p==0 || p->id==iType );
  return p;
}


/*
** This routine deallocates a previously
** allocated mutex.  SQLite is careful to deallocate every

Changes to src/os_unix.c.

464
465
466
467
468
469
470

471



472
473
474
475
476
477
478
....
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
#if defined(HAVE_FCHOWN)
  { "fchown",       (sqlite3_syscall_ptr)fchown,          0 },
#else
  { "fchown",       (sqlite3_syscall_ptr)0,               0 },
#endif
#define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)


  { "geteuid",      (sqlite3_syscall_ptr)geteuid,         0 },



#define osGeteuid   ((uid_t(*)(void))aSyscall[21].pCurrent)

#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
  { "mmap",         (sqlite3_syscall_ptr)mmap,            0 },
#else
  { "mmap",         (sqlite3_syscall_ptr)0,               0 },
#endif
................................................................................
  assert( n==1 || lockType!=F_RDLCK );

  /* Locks are within range */
  assert( n>=1 && n<=SQLITE_SHM_NLOCK );

  if( pShmNode->h>=0 ){
    /* Initialize the locking parameters */
    memset(&f, 0, sizeof(f));
    f.l_type = lockType;
    f.l_whence = SEEK_SET;
    f.l_start = ofst;
    f.l_len = n;

    rc = osFcntl(pShmNode->h, F_SETLK, &f);
    rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
  }

  /* Update the global lock state and do debug tracing */
#ifdef SQLITE_DEBUG
  { u16 mask;







>

>
>
>







 







<




<







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
....
4176
4177
4178
4179
4180
4181
4182

4183
4184
4185
4186

4187
4188
4189
4190
4191
4192
4193
#if defined(HAVE_FCHOWN)
  { "fchown",       (sqlite3_syscall_ptr)fchown,          0 },
#else
  { "fchown",       (sqlite3_syscall_ptr)0,               0 },
#endif
#define osFchown    ((int(*)(int,uid_t,gid_t))aSyscall[20].pCurrent)

#if defined(HAVE_FCHOWN)
  { "geteuid",      (sqlite3_syscall_ptr)geteuid,         0 },
#else
  { "geteuid",      (sqlite3_syscall_ptr)0,               0 },
#endif
#define osGeteuid   ((uid_t(*)(void))aSyscall[21].pCurrent)

#if !defined(SQLITE_OMIT_WAL) || SQLITE_MAX_MMAP_SIZE>0
  { "mmap",         (sqlite3_syscall_ptr)mmap,            0 },
#else
  { "mmap",         (sqlite3_syscall_ptr)0,               0 },
#endif
................................................................................
  assert( n==1 || lockType!=F_RDLCK );

  /* Locks are within range */
  assert( n>=1 && n<=SQLITE_SHM_NLOCK );

  if( pShmNode->h>=0 ){
    /* Initialize the locking parameters */

    f.l_type = lockType;
    f.l_whence = SEEK_SET;
    f.l_start = ofst;
    f.l_len = n;

    rc = osFcntl(pShmNode->h, F_SETLK, &f);
    rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
  }

  /* Update the global lock state and do debug tracing */
#ifdef SQLITE_DEBUG
  { u16 mask;

Changes to src/printf.c.

202
203
204
205
206
207
208





209
210
211
212
213
214
215
...
620
621
622
623
624
625
626

627






628



629



















630
631
632
633
634
635
636
637

638
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
683
684
685
686
687
...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
...
738
739
740
741
742
743
744
745



746
747
748
749
750
751
752
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
#endif
  PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
  char buf[etBUFSIZE];       /* Conversion buffer */






  bufpt = 0;
  if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
    pArgList = va_arg(ap, PrintfArguments*);
    bArgList = 1;
  }else{
    bArgList = 0;
  }
................................................................................
        buf[0] = '%';
        bufpt = buf;
        length = 1;
        break;
      case etCHARX:
        if( bArgList ){
          bufpt = getTextArg(pArgList);

          c = bufpt ? bufpt[0] : 0;






        }else{



          c = va_arg(ap,int);



















        }
        if( precision>1 ){
          width -= precision-1;
          if( width>1 && !flag_leftjustify ){
            sqlite3AppendChar(pAccum, width-1, ' ');
            width = 0;
          }
          sqlite3AppendChar(pAccum, precision-1, c);

        }
        length = 1;
        buf[0] = c;

        bufpt = buf;
        break;

      case etSTRING:
      case etDYNSTRING:
        if( bArgList ){
          bufpt = getTextArg(pArgList);
          xtype = etSTRING;
        }else{
          bufpt = va_arg(ap,char*);
        }
        if( bufpt==0 ){
          bufpt = "";
        }else if( xtype==etDYNSTRING ){












          zExtra = bufpt;
        }
        if( precision>=0 ){









          for(length=0; length<precision && bufpt[length]; length++){}

        }else{
          length = 0x7fffffff & (int)strlen(bufpt);
        }






        break;
      case etSQLESCAPE:           /* Escape ' characters */
      case etSQLESCAPE2:          /* Escape ' and enclose in '...' */
      case etSQLESCAPE3: {        /* Escape " characters */
        int i, j, k, n, isnull;
        int needQuote;
        char ch;
        char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
        char *escarg;

        if( bArgList ){
          escarg = getTextArg(pArgList);
        }else{
          escarg = va_arg(ap,char*);
        }
        isnull = escarg==0;
        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");





        k = precision;
        for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
          if( ch==q )  n++;



        }
        needQuote = !isnull && xtype==etSQLESCAPE2;
        n += i + 3;
        if( n>etBUFSIZE ){
          bufpt = zExtra = sqlite3Malloc( n );
          if( bufpt==0 ){
            setStrAccumError(pAccum, STRACCUM_NOMEM);
................................................................................
        for(i=0; i<k; i++){
          bufpt[j++] = ch = escarg[i];
          if( ch==q ) bufpt[j++] = ch;
        }
        if( needQuote ) bufpt[j++] = q;
        bufpt[j] = 0;
        length = j;
        /* The precision in %q and %Q means how many input characters to
        ** consume, not the length of the output...
        ** if( precision>=0 && precision<length ) length = precision; */
        break;
      }
      case etTOKEN: {
        Token *pToken;
        if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
        pToken = va_arg(ap, Token*);
        assert( bArgList==0 );
        if( pToken && pToken->n ){
................................................................................
        assert( xtype==etINVALID );
        return;
      }
    }/* End switch over the format type */
    /*
    ** The text of the conversion is pointed to by "bufpt" and is
    ** "length" characters long.  The field width is "width".  Do
    ** the output.



    */
    width -= length;
    if( width>0 ){
      if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
      sqlite3StrAccumAppend(pAccum, bufpt, length);
      if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
    }else{







>
>
>
>
>







 







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







|
>
|
<
<
>

|
>











>
>
>
>
>
>
>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
|
>



>
>
>
>
>
>

|
|
|













>
>
>
>
>



>
>
>







 







|
<
<
<







 







|
>
>
>







202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
...
625
626
627
628
629
630
631
632
633
634
635
636
637
638
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
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
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
...
767
768
769
770
771
772
773
774



775
776
777
778
779
780
781
...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
  double rounder;            /* Used for rounding floating point values */
  etByte flag_dp;            /* True if decimal point should be shown */
  etByte flag_rtz;           /* True if trailing zeros should be removed */
#endif
  PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */
  char buf[etBUFSIZE];       /* Conversion buffer */

  /* pAccum never starts out with an empty buffer that was obtained from 
  ** malloc().  This precondition is required by the mprintf("%z...")
  ** optimization. */
  assert( pAccum->nChar>0 || (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );

  bufpt = 0;
  if( (pAccum->printfFlags & SQLITE_PRINTF_SQLFUNC)!=0 ){
    pArgList = va_arg(ap, PrintfArguments*);
    bArgList = 1;
  }else{
    bArgList = 0;
  }
................................................................................
        buf[0] = '%';
        bufpt = buf;
        length = 1;
        break;
      case etCHARX:
        if( bArgList ){
          bufpt = getTextArg(pArgList);
          length = 1;
          if( bufpt ){
            buf[0] = c = *(bufpt++);
            if( (c&0xc0)==0xc0 ){
              while( length<4 && (bufpt[0]&0xc0)==0x80 ){
                buf[length++] = *(bufpt++);
              }
            }
          }else{
            buf[0] = 0;
          }
        }else{
          unsigned int ch = va_arg(ap,unsigned int);
          if( ch<0x00080 ){
            buf[0] = ch & 0xff;
            length = 1;
          }else if( ch<0x00800 ){
            buf[0] = 0xc0 + (u8)((ch>>6)&0x1f);
            buf[1] = 0x80 + (u8)(ch & 0x3f);
            length = 2;
          }else if( ch<0x10000 ){
            buf[0] = 0xe0 + (u8)((ch>>12)&0x0f);
            buf[1] = 0x80 + (u8)((ch>>6) & 0x3f);
            buf[2] = 0x80 + (u8)(ch & 0x3f);
            length = 3;
          }else{
            buf[0] = 0xf0 + (u8)((ch>>18) & 0x07);
            buf[1] = 0x80 + (u8)((ch>>12) & 0x3f);
            buf[2] = 0x80 + (u8)((ch>>6) & 0x3f);
            buf[3] = 0x80 + (u8)(ch & 0x3f);
            length = 4;
          }
        }
        if( precision>1 ){
          width -= precision-1;
          if( width>1 && !flag_leftjustify ){
            sqlite3AppendChar(pAccum, width-1, ' ');
            width = 0;
          }
          while( precision-- > 1 ){
            sqlite3StrAccumAppend(pAccum, buf, length);
          }


        }
        bufpt = buf;
        flag_altform2 = 1;
        goto adjust_width_for_utf8;
      case etSTRING:
      case etDYNSTRING:
        if( bArgList ){
          bufpt = getTextArg(pArgList);
          xtype = etSTRING;
        }else{
          bufpt = va_arg(ap,char*);
        }
        if( bufpt==0 ){
          bufpt = "";
        }else if( xtype==etDYNSTRING ){
          if( pAccum->nChar==0 && pAccum->mxAlloc && width==0 && precision<0 ){
            /* Special optimization for sqlite3_mprintf("%z..."):
            ** Extend an existing memory allocation rather than creating
            ** a new one. */
            assert( (pAccum->printfFlags&SQLITE_PRINTF_MALLOCED)==0 );
            pAccum->zText = bufpt;
            pAccum->nAlloc = sqlite3DbMallocSize(pAccum->db, bufpt);
            pAccum->nChar = 0x7fffffff & (int)strlen(bufpt);
            pAccum->printfFlags |= SQLITE_PRINTF_MALLOCED;
            length = 0;
            break;
          }
          zExtra = bufpt;
        }
        if( precision>=0 ){
          if( flag_altform2 ){
            /* Set length to the number of bytes needed in order to display
            ** precision characters */
            unsigned char *z = (unsigned char*)bufpt;
            while( precision-- > 0 && z[0] ){
              SQLITE_SKIP_UTF8(z);
            }
            length = (int)(z - (unsigned char*)bufpt);
          }else{
            for(length=0; length<precision && bufpt[length]; length++){}
          }
        }else{
          length = 0x7fffffff & (int)strlen(bufpt);
        }
      adjust_width_for_utf8:
        if( flag_altform2 && width>0 ){
          /* Adjust width to account for extra bytes in UTF-8 characters */
          int ii = length - 1;
          while( ii>=0 ) if( (bufpt[ii--] & 0xc0)==0x80 ) width++;
        }
        break;
      case etSQLESCAPE:           /* %q: Escape ' characters */
      case etSQLESCAPE2:          /* %Q: Escape ' and enclose in '...' */
      case etSQLESCAPE3: {        /* %w: Escape " characters */
        int i, j, k, n, isnull;
        int needQuote;
        char ch;
        char q = ((xtype==etSQLESCAPE3)?'"':'\'');   /* Quote character */
        char *escarg;

        if( bArgList ){
          escarg = getTextArg(pArgList);
        }else{
          escarg = va_arg(ap,char*);
        }
        isnull = escarg==0;
        if( isnull ) escarg = (xtype==etSQLESCAPE2 ? "NULL" : "(NULL)");
        /* For %q, %Q, and %w, the precision is the number of byte (or
        ** characters if the ! flags is present) to use from the input.
        ** Because of the extra quoting characters inserted, the number
        ** of output characters may be larger than the precision.
        */
        k = precision;
        for(i=n=0; k!=0 && (ch=escarg[i])!=0; i++, k--){
          if( ch==q )  n++;
          if( flag_altform2 && (ch&0xc0)==0xc0 ){
            while( (escarg[i+1]&0xc0)==0x80 ){ i++; }
          }
        }
        needQuote = !isnull && xtype==etSQLESCAPE2;
        n += i + 3;
        if( n>etBUFSIZE ){
          bufpt = zExtra = sqlite3Malloc( n );
          if( bufpt==0 ){
            setStrAccumError(pAccum, STRACCUM_NOMEM);
................................................................................
        for(i=0; i<k; i++){
          bufpt[j++] = ch = escarg[i];
          if( ch==q ) bufpt[j++] = ch;
        }
        if( needQuote ) bufpt[j++] = q;
        bufpt[j] = 0;
        length = j;
        goto adjust_width_for_utf8;



      }
      case etTOKEN: {
        Token *pToken;
        if( (pAccum->printfFlags & SQLITE_PRINTF_INTERNAL)==0 ) return;
        pToken = va_arg(ap, Token*);
        assert( bArgList==0 );
        if( pToken && pToken->n ){
................................................................................
        assert( xtype==etINVALID );
        return;
      }
    }/* End switch over the format type */
    /*
    ** The text of the conversion is pointed to by "bufpt" and is
    ** "length" characters long.  The field width is "width".  Do
    ** the output.  Both length and width are in bytes, not characters,
    ** at this point.  If the "!" flag was present on string conversions
    ** indicating that width and precision should be expressed in characters,
    ** then the values have been translated prior to reaching this point.
    */
    width -= length;
    if( width>0 ){
      if( !flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
      sqlite3StrAccumAppend(pAccum, bufpt, length);
      if( flag_leftjustify ) sqlite3AppendChar(pAccum, width, ' ');
    }else{

Changes to src/shell.c.in.

1065
1066
1067
1068
1069
1070
1071

1072
1073
1074
1075
1076
1077
1078
....
3254
3255
3256
3257
3258
3259
3260

3261
3262
3263
3264
3265
3266
3267
....
3449
3450
3451
3452
3453
3454
3455




3456
3457
3458
3459
3460
3461
3462
....
6303
6304
6305
6306
6307
6308
6309


6310
6311
6312
6313
6314
6315
6316
....
7981
7982
7983
7984
7985
7986
7987

7988
7989
7990
7991
7992
7993
7994
....
8090
8091
8092
8093
8094
8095
8096
8097







8098

8099
8100
8101
8102
8103
8104
8105







8106
8107
8108
8109


8110

8111

8112
8113
8114
8115
8116
8117
8118
....
8230
8231
8232
8233
8234
8235
8236


8237
8238
8239
8240
8241
8242
8243

/* Allowed values for ShellState.openMode
*/
#define SHELL_OPEN_UNSPEC     0      /* No open-mode specified */
#define SHELL_OPEN_NORMAL     1      /* Normal database file */
#define SHELL_OPEN_APPENDVFS  2      /* Use appendvfs */
#define SHELL_OPEN_ZIPFILE    3      /* Use the zipfile virtual table */


/*
** 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 */
................................................................................
  "                         tcl      TCL list elements\n"
  ".nullvalue STRING      Use STRING in place of NULL values\n"
  ".once (-e|-x|FILE)     Output for the next SQL command only to FILE\n"
  "                         or invoke system text editor (-e) or spreadsheet (-x)\n"
  "                         on the output.\n"
  ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
  "                         The --new option starts with an empty file\n"

  ".output ?FILE?         Send output to FILE or stdout\n"
  ".print STRING...       Print literal STRING\n"
  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
  ".quit                  Exit this program\n"
  ".read FILENAME         Execute SQL in FILENAME\n"
  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
  ".save FILE             Write in-memory database into FILE\n"
................................................................................
        sqlite3_open_v2(p->zDbFilename, &p->db, 
           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
        break;
      }
      case SHELL_OPEN_ZIPFILE: {
        sqlite3_open(":memory:", &p->db);
        break;




      }
      case SHELL_OPEN_UNSPEC:
      case SHELL_OPEN_NORMAL: {
        sqlite3_open(p->zDbFilename, &p->db);
        break;
      }
    }
................................................................................
        newFlag = 1;
#ifdef SQLITE_HAVE_ZIP
      }else if( optionMatch(z, "zip") ){
        p->openMode = SHELL_OPEN_ZIPFILE;
#endif
      }else if( optionMatch(z, "append") ){
        p->openMode = SHELL_OPEN_APPENDVFS;


      }else if( z[0]=='-' ){
        utf8_printf(stderr, "unknown option: %s\n", z);
        rc = 1;
        goto meta_command_exit;
      }
    }
    /* If a filename is specified, try to open it first */
................................................................................
#ifdef SQLITE_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
  "   -newline SEP         set output row separator. Default: '\\n'\n"
  "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
  "   -pagecache SIZE N    use N slots of SZ bytes each for page cache memory\n"
  "   -quote               set output mode to 'quote'\n"

  "   -separator SEP       set output column separator. Default: '|'\n"
  "   -stats               print memory stats before each finalize\n"
  "   -version             show SQLite version\n"
  "   -vfs NAME            use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
  "   -vfstrace            enable tracing of all VFS calls\n"
#endif
................................................................................
  if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
    utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
            sqlite3_sourceid(), SQLITE_SOURCE_ID);
    exit(1);
  }
#endif
  main_init(&data);
  sqlite3_initialize();







#if !SQLITE_SHELL_IS_UTF8

  argv = sqlite3_malloc64(sizeof(argv[0])*argc);
  if( argv==0 ){
    raw_printf(stderr, "out of memory\n");
    exit(1);
  }
  for(i=0; i<argc; i++){
    argv[i] = sqlite3_win32_unicode_to_utf8(wargv[i]);







    if( argv[i]==0 ){
      raw_printf(stderr, "out of memory\n");
      exit(1);
    }


  }

#endif

  assert( argc>=1 && argv && argv[0] );
  Argv0 = argv[0];

  /* Make sure we have a valid signal handler early, before anything
  ** else is done.
  */
#ifdef SIGINT
................................................................................
      }
#ifdef SQLITE_HAVE_ZIP
    }else if( strcmp(z,"-zip")==0 ){
      data.openMode = SHELL_OPEN_ZIPFILE;
#endif
    }else if( strcmp(z,"-append")==0 ){
      data.openMode = SHELL_OPEN_APPENDVFS;


    }
  }
  if( data.zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
    warnInmemoryDb = argc==1;
#else







>







 







>







 







>
>
>
>







 







>
>







 







>







 







<
>
>
>
>
>
>
>

>
|





|
>
>
>
>
>
>
>




>
>

>

>







 







>
>







1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
....
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
....
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
....
6309
6310
6311
6312
6313
6314
6315
6316
6317
6318
6319
6320
6321
6322
6323
6324
....
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
....
8099
8100
8101
8102
8103
8104
8105

8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
....
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272

/* Allowed values for ShellState.openMode
*/
#define SHELL_OPEN_UNSPEC     0      /* No open-mode specified */
#define SHELL_OPEN_NORMAL     1      /* Normal database file */
#define SHELL_OPEN_APPENDVFS  2      /* Use appendvfs */
#define SHELL_OPEN_ZIPFILE    3      /* Use the zipfile virtual table */
#define SHELL_OPEN_READONLY   4      /* Open a normal database read-only */

/*
** 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 */
................................................................................
  "                         tcl      TCL list elements\n"
  ".nullvalue STRING      Use STRING in place of NULL values\n"
  ".once (-e|-x|FILE)     Output for the next SQL command only to FILE\n"
  "                         or invoke system text editor (-e) or spreadsheet (-x)\n"
  "                         on the output.\n"
  ".open ?OPTIONS? ?FILE? Close existing database and reopen FILE\n"
  "                         The --new option starts with an empty file\n"
  "                         Other options: --readonly --append --zip\n"
  ".output ?FILE?         Send output to FILE or stdout\n"
  ".print STRING...       Print literal STRING\n"
  ".prompt MAIN CONTINUE  Replace the standard prompts\n"
  ".quit                  Exit this program\n"
  ".read FILENAME         Execute SQL in FILENAME\n"
  ".restore ?DB? FILE     Restore content of DB (default \"main\") from FILE\n"
  ".save FILE             Write in-memory database into FILE\n"
................................................................................
        sqlite3_open_v2(p->zDbFilename, &p->db, 
           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, "apndvfs");
        break;
      }
      case SHELL_OPEN_ZIPFILE: {
        sqlite3_open(":memory:", &p->db);
        break;
      }
      case SHELL_OPEN_READONLY: {
        sqlite3_open_v2(p->zDbFilename, &p->db, SQLITE_OPEN_READONLY, 0);
        break;
      }
      case SHELL_OPEN_UNSPEC:
      case SHELL_OPEN_NORMAL: {
        sqlite3_open(p->zDbFilename, &p->db);
        break;
      }
    }
................................................................................
        newFlag = 1;
#ifdef SQLITE_HAVE_ZIP
      }else if( optionMatch(z, "zip") ){
        p->openMode = SHELL_OPEN_ZIPFILE;
#endif
      }else if( optionMatch(z, "append") ){
        p->openMode = SHELL_OPEN_APPENDVFS;
      }else if( optionMatch(z, "readonly") ){
        p->openMode = SHELL_OPEN_READONLY;
      }else if( z[0]=='-' ){
        utf8_printf(stderr, "unknown option: %s\n", z);
        rc = 1;
        goto meta_command_exit;
      }
    }
    /* If a filename is specified, try to open it first */
................................................................................
#ifdef SQLITE_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
  "   -newline SEP         set output row separator. Default: '\\n'\n"
  "   -nullvalue TEXT      set text string for NULL values. Default ''\n"
  "   -pagecache SIZE N    use N slots of SZ bytes each for page cache memory\n"
  "   -quote               set output mode to 'quote'\n"
  "   -readonly            open the database read-only\n"
  "   -separator SEP       set output column separator. Default: '|'\n"
  "   -stats               print memory stats before each finalize\n"
  "   -version             show SQLite version\n"
  "   -vfs NAME            use NAME as the default VFS\n"
#ifdef SQLITE_ENABLE_VFSTRACE
  "   -vfstrace            enable tracing of all VFS calls\n"
#endif
................................................................................
  if( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,60)!=0 ){
    utf8_printf(stderr, "SQLite header and source version mismatch\n%s\n%s\n",
            sqlite3_sourceid(), SQLITE_SOURCE_ID);
    exit(1);
  }
#endif
  main_init(&data);


  /* On Windows, we must translate command-line arguments into UTF-8.
  ** The SQLite memory allocator subsystem has to be enabled in order to
  ** do this.  But we want to run an sqlite3_shutdown() afterwards so that
  ** subsequent sqlite3_config() calls will work.  So copy all results into
  ** memory that does not come from the SQLite memory allocator.
  */
#if !SQLITE_SHELL_IS_UTF8
  sqlite3_initialize();
  argv = malloc(sizeof(argv[0])*argc);
  if( argv==0 ){
    raw_printf(stderr, "out of memory\n");
    exit(1);
  }
  for(i=0; i<argc; i++){
    char *z = sqlite3_win32_unicode_to_utf8(wargv[i]);
    int n;
    if( z==0 ){
      raw_printf(stderr, "out of memory\n");
      exit(1);
    }
    n = (int)strlen(z);
    argv[i] = malloc( n+1 );
    if( argv[i]==0 ){
      raw_printf(stderr, "out of memory\n");
      exit(1);
    }
    memcpy(argv[i], z, n+1);
    sqlite3_free(z);
  }
  sqlite3_shutdown();
#endif

  assert( argc>=1 && argv && argv[0] );
  Argv0 = argv[0];

  /* Make sure we have a valid signal handler early, before anything
  ** else is done.
  */
#ifdef SIGINT
................................................................................
      }
#ifdef SQLITE_HAVE_ZIP
    }else if( strcmp(z,"-zip")==0 ){
      data.openMode = SHELL_OPEN_ZIPFILE;
#endif
    }else if( strcmp(z,"-append")==0 ){
      data.openMode = SHELL_OPEN_APPENDVFS;
    }else if( strcmp(z,"-readonly")==0 ){
      data.openMode = SHELL_OPEN_READONLY;
    }
  }
  if( data.zDbFilename==0 ){
#ifndef SQLITE_OMIT_MEMORYDB
    data.zDbFilename = ":memory:";
    warnInmemoryDb = argc==1;
#else

Changes to src/sqlite.h.in.

2492
2493
2494
2495
2496
2497
2498
2499

2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
....
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
void sqlite3_free_table(char **result);

/*
** CAPI3REF: Formatted String Printing Functions
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
** These routines understand most of the common K&R formatting options,

** plus some additional non-standard formats, detailed below.
** Note that some of the more obscure formatting options from recent
** C-library standards are omitted from this implementation.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc()].
** The strings returned by these two routines should be
** released by [sqlite3_free()].  ^Both routines return a
** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
** the standard C library.  The result is written into the
** buffer supplied as the second parameter whose size is given by
** the first parameter. Note that the order of the
** first two parameters is reversed from snprintf().)^  This is an
................................................................................
** guarantees that the buffer is always zero-terminated.  ^The first
** parameter "n" is the total size of the buffer, including space for
** the zero terminator.  So the longest string that can be completely
** written will be n-1 characters.
**
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
**
** These routines all implement some additional formatting
** options that are useful for constructing SQL statements.
** All of the usual printf() formatting options apply.  In addition, there
** is are "%q", "%Q", "%w" and "%z" options.
**
** ^(The %q option works like %s in that it substitutes a nul-terminated
** string from the argument list.  But %q also doubles every '\'' character.
** %q is designed for use inside a string literal.)^  By doubling each '\''
** character it escapes that character and allows it to be inserted into
** the string.
**
** For example, assume the string variable zText contains text as follows:
**
** <blockquote><pre>
**  char *zText = "It's a happy day!";
** </pre></blockquote>
**
** One can use this text in an SQL statement as follows:
**
** <blockquote><pre>
**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);
**  sqlite3_exec(db, zSQL, 0, 0, 0);
**  sqlite3_free(zSQL);
** </pre></blockquote>
**
** Because the %q format string is used, the '\'' character in zText
** is escaped and the SQL generated is as follows:
**
** <blockquote><pre>
**  INSERT INTO table1 VALUES('It''s a happy day!')
** </pre></blockquote>
**
** This is correct.  Had we used %s instead of %q, the generated SQL
** would have looked like this:
**
** <blockquote><pre>
**  INSERT INTO table1 VALUES('It's a happy day!');
** </pre></blockquote>
**
** This second example is an SQL syntax error.  As a general rule you should
** always use %q instead of %s when inserting text into a string literal.
**
** ^(The %Q option works like %q except it also adds single quotes around
** the outside of the total string.  Additionally, if the parameter in the
** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
** single quotes).)^  So, for example, one could say:
**
** <blockquote><pre>
**  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
**  sqlite3_exec(db, zSQL, 0, 0, 0);
**  sqlite3_free(zSQL);
** </pre></blockquote>
**
** The code above will render a correct SQL statement in the zSQL
** variable even if the zText variable is a NULL pointer.
**
** ^(The "%w" formatting option is like "%q" except that it expects to
** be contained within double-quotes instead of single quotes, and it
** escapes the double-quote character instead of the single-quote
** character.)^  The "%w" formatting option is intended for safely inserting
** table and column names into a constructed SQL statement.
**
** ^(The "%z" formatting option works like "%s" but with the
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
*/
char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
char *sqlite3_snprintf(int,char*,const char*, ...);
char *sqlite3_vsnprintf(int,char*,const char*, va_list);

/*







|
>
|
<
|


|


|







 







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







2492
2493
2494
2495
2496
2497
2498
2499
2500
2501

2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
....
2525
2526
2527
2528
2529
2530
2531
2532
































































2533
2534
2535
2536
2537
2538
2539
void sqlite3_free_table(char **result);

/*
** CAPI3REF: Formatted String Printing Functions
**
** These routines are work-alikes of the "printf()" family of functions
** from the standard C library.
** These routines understand most of the common formatting options from
** the standard library printf() 
** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).

** See the [built-in printf()] documentation for details.
**
** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
** results into memory obtained from [sqlite3_malloc64()].
** The strings returned by these two routines should be
** released by [sqlite3_free()].  ^Both routines return a
** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough
** memory to hold the resulting string.
**
** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from
** the standard C library.  The result is written into the
** buffer supplied as the second parameter whose size is given by
** the first parameter. Note that the order of the
** first two parameters is reversed from snprintf().)^  This is an
................................................................................
** guarantees that the buffer is always zero-terminated.  ^The first
** parameter "n" is the total size of the buffer, including space for
** the zero terminator.  So the longest string that can be completely
** written will be n-1 characters.
**
** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf().
**
** See also:  [built-in printf()], [printf() SQL function]
































































*/
char *sqlite3_mprintf(const char*,...);
char *sqlite3_vmprintf(const char*, va_list);
char *sqlite3_snprintf(int,char*,const char*, ...);
char *sqlite3_vsnprintf(int,char*,const char*, va_list);

/*

Changes to src/sqliteInt.h.

4065
4066
4067
4068
4069
4070
4071



4072
4073
4074
4075
4076
4077
4078
extern const Token sqlite3IntTokens[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern FuncDefHash sqlite3BuiltinFunctions;
#ifndef SQLITE_OMIT_WSD
extern int sqlite3PendingByte;
#endif
#endif



void sqlite3RootPageMoved(sqlite3*, int, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);







>
>
>







4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
extern const Token sqlite3IntTokens[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
extern FuncDefHash sqlite3BuiltinFunctions;
#ifndef SQLITE_OMIT_WSD
extern int sqlite3PendingByte;
#endif
#endif
#ifdef VDBE_PROFILE
extern sqlite3_uint64 sqlite3NProfileCnt;
#endif
void sqlite3RootPageMoved(sqlite3*, int, int, int);
void sqlite3Reindex(Parse*, Token*, Token*);
void sqlite3AlterFunctions(void);
void sqlite3AlterRenameTable(Parse*, SrcList*, Token*);
int sqlite3GetToken(const unsigned char *, int *);
void sqlite3NestedParse(Parse*, const char*, ...);
void sqlite3ExpirePreparedStatements(sqlite3*);

Changes to src/test_config.c.

496
497
498
499
500
501
502






503
504
505
506
507
508
509
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "0", TCL_GLOBAL_ONLY);
#endif

Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);







#ifdef SQLITE_OMIT_OR_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY);
#endif








>
>
>
>
>
>







496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
  Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "memorymanage", "0", TCL_GLOBAL_ONLY);
#endif

Tcl_SetVar2(interp, "sqlite_options", "mergesort", "1", TCL_GLOBAL_ONLY);

#ifdef SQLITE_ENABLE_NULL_TRIM
  Tcl_SetVar2(interp, "sqlite_options", "null_trim", "1", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "null_trim", "0", TCL_GLOBAL_ONLY);
#endif

#ifdef SQLITE_OMIT_OR_OPTIMIZATION
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "0", TCL_GLOBAL_ONLY);
#else
  Tcl_SetVar2(interp, "sqlite_options", "or_opt", "1", TCL_GLOBAL_ONLY);
#endif

Changes to src/vacuum.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

  /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc!=SQLITE_OK ) return rc;
  while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
    const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
    assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
    if( zSubSql ){
      assert( zSubSql[0]!='S' );
      rc = execSql(db, pzErrMsg, zSubSql);
      if( rc!=SQLITE_OK ) break;
    }
  }
  assert( rc!=SQLITE_ROW );
  if( rc==SQLITE_DONE ) rc = SQLITE_OK;
  if( rc ){







|
|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

  /* printf("SQL: [%s]\n", zSql); fflush(stdout); */
  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
  if( rc!=SQLITE_OK ) return rc;
  while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){
    const char *zSubSql = (const char*)sqlite3_column_text(pStmt,0);
    assert( sqlite3_strnicmp(zSql,"SELECT",6)==0 );
    assert( sqlite3_strnicmp(zSubSql,"SELECT",6)!=0 || CORRUPT_DB );
    if( zSubSql && zSubSql[0]!='S' ){
      rc = execSql(db, pzErrMsg, zSubSql);
      if( rc!=SQLITE_OK ) break;
    }
  }
  assert( rc!=SQLITE_ROW );
  if( rc==SQLITE_DONE ) rc = SQLITE_OK;
  if( rc ){

Changes to src/vdbe.c.

644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
....
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
  for(pOp=&aOp[p->pc]; 1; pOp++){
    /* Errors are detected by individual opcodes, with an immediate
    ** jumps to abort_due_to_error. */
    assert( rc==SQLITE_OK );

    assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
    start = sqlite3Hwtime();
#endif
    nVmStep++;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
#endif

    /* Only allow tracing if SQLITE_DEBUG is defined.
................................................................................
** readability.  From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
    }

#ifdef VDBE_PROFILE
    {
      u64 endTime = sqlite3Hwtime();
      if( endTime>start ) pOrigOp->cycles += endTime - start;
      pOrigOp->cnt++;
    }
#endif

    /* The following code adds nothing to the actual functionality
    ** of the program.  It is only here for testing and debugging.







|







 







|







644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
....
7229
7230
7231
7232
7233
7234
7235
7236
7237
7238
7239
7240
7241
7242
7243
  for(pOp=&aOp[p->pc]; 1; pOp++){
    /* Errors are detected by individual opcodes, with an immediate
    ** jumps to abort_due_to_error. */
    assert( rc==SQLITE_OK );

    assert( pOp>=aOp && pOp<&aOp[p->nOp]);
#ifdef VDBE_PROFILE
    start = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
#endif
    nVmStep++;
#ifdef SQLITE_ENABLE_STMT_SCANSTATUS
    if( p->anExec ) p->anExec[(int)(pOp-aOp)]++;
#endif

    /* Only allow tracing if SQLITE_DEBUG is defined.
................................................................................
** readability.  From this point on down, the normal indentation rules are
** restored.
*****************************************************************************/
    }

#ifdef VDBE_PROFILE
    {
      u64 endTime = sqlite3NProfileCnt ? sqlite3NProfileCnt : sqlite3Hwtime();
      if( endTime>start ) pOrigOp->cycles += endTime - start;
      pOrigOp->cnt++;
    }
#endif

    /* The following code adds nothing to the actual functionality
    ** of the program.  It is only here for testing and debugging.

Changes to src/wal.c.

550
551
552
553
554
555
556
557




558
559
560
561
562
563
564
...
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597










598
599
600
601
602
603
604
....
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
....
2887
2888
2889
2890
2891
2892
2893

2894
2895
2896
2897
2898
2899
2900
** so.  It is safe to enlarge the wal-index if pWal->writeLock is true
** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
**
** If this call is successful, *ppPage is set to point to the wal-index
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
** then an SQLite error code is returned and *ppPage is set to 0.
*/
static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){




  int rc = SQLITE_OK;

  /* Enlarge the pWal->apWiData[] array if required */
  if( pWal->nWiData<=iPage ){
    int nByte = sizeof(u32*)*(iPage+1);
    volatile u32 **apNew;
    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
................................................................................
    memset((void*)&apNew[pWal->nWiData], 0,
           sizeof(u32*)*(iPage+1-pWal->nWiData));
    pWal->apWiData = apNew;
    pWal->nWiData = iPage+1;
  }

  /* Request a pointer to the required page from the VFS */
  if( pWal->apWiData[iPage]==0 ){
    if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
      pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
      if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
    }else{
      rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
          pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
      );
      assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
      testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
      if( (rc&0xff)==SQLITE_READONLY ){
        pWal->readOnly |= WAL_SHM_RDONLY;
        if( rc==SQLITE_READONLY ){
          rc = SQLITE_OK;
        }
      }
    }
  }

  *ppPage = pWal->apWiData[iPage];
  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
  return rc;










}

/*
** Return a pointer to the WalCkptInfo structure in the wal-index.
*/
static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
  assert( pWal->nWiData>0 && pWal->apWiData[0] );
................................................................................
  **     This condition filters out normal hash-table collisions.
  **
  **   (iFrame<=iLast): 
  **     This condition filters out entries that were added to the hash
  **     table after the current read-transaction had started.
  */
  iMinHash = walFramePage(pWal->minFrame);
  for(iHash=walFramePage(iLast); iHash>=iMinHash && iRead==0; iHash--){
    volatile ht_slot *aHash;      /* Pointer to hash table */
    volatile u32 *aPgno;          /* Pointer to array of page numbers */
    u32 iZero;                    /* Frame number corresponding to aPgno[0] */
    int iKey;                     /* Hash slot index */
    int nCollide;                 /* Number of hash collisions remaining */
    int rc;                       /* Error code */

................................................................................
        assert( iFrame>iRead || CORRUPT_DB );
        iRead = iFrame;
      }
      if( (nCollide--)==0 ){
        return SQLITE_CORRUPT_BKPT;
      }
    }

  }

#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
  /* If expensive assert() statements are available, do a linear search
  ** of the wal-index file content. Make sure the results agree with the
  ** result obtained using the hash indexes above.  */
  {







|
>
>
>
>







 







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







>
>
>
>
>
>
>
>
>
>







 







|







 







>







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
...
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593

594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
....
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
....
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
** so.  It is safe to enlarge the wal-index if pWal->writeLock is true
** or pWal->exclusiveMode==WAL_HEAPMEMORY_MODE.
**
** If this call is successful, *ppPage is set to point to the wal-index
** page and SQLITE_OK is returned. If an error (an OOM or VFS error) occurs,
** then an SQLite error code is returned and *ppPage is set to 0.
*/
static SQLITE_NOINLINE int walIndexPageRealloc(
  Wal *pWal,               /* The WAL context */
  int iPage,               /* The page we seek */
  volatile u32 **ppPage    /* Write the page pointer here */
){
  int rc = SQLITE_OK;

  /* Enlarge the pWal->apWiData[] array if required */
  if( pWal->nWiData<=iPage ){
    int nByte = sizeof(u32*)*(iPage+1);
    volatile u32 **apNew;
    apNew = (volatile u32 **)sqlite3_realloc64((void *)pWal->apWiData, nByte);
................................................................................
    memset((void*)&apNew[pWal->nWiData], 0,
           sizeof(u32*)*(iPage+1-pWal->nWiData));
    pWal->apWiData = apNew;
    pWal->nWiData = iPage+1;
  }

  /* Request a pointer to the required page from the VFS */
  assert( pWal->apWiData[iPage]==0 );
  if( pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ){
    pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ);
    if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT;
  }else{
    rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
        pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
    );
    assert( pWal->apWiData[iPage]!=0 || rc!=SQLITE_OK || pWal->writeLock==0 );
    testcase( pWal->apWiData[iPage]==0 && rc==SQLITE_OK );
    if( (rc&0xff)==SQLITE_READONLY ){
      pWal->readOnly |= WAL_SHM_RDONLY;
      if( rc==SQLITE_READONLY ){
        rc = SQLITE_OK;

      }
    }
  }

  *ppPage = pWal->apWiData[iPage];
  assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
  return rc;
}
static int walIndexPage(
  Wal *pWal,               /* The WAL context */
  int iPage,               /* The page we seek */
  volatile u32 **ppPage    /* Write the page pointer here */
){
  if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){
    return walIndexPageRealloc(pWal, iPage, ppPage);
  }
  return SQLITE_OK;
}

/*
** Return a pointer to the WalCkptInfo structure in the wal-index.
*/
static volatile WalCkptInfo *walCkptInfo(Wal *pWal){
  assert( pWal->nWiData>0 && pWal->apWiData[0] );
................................................................................
  **     This condition filters out normal hash-table collisions.
  **
  **   (iFrame<=iLast): 
  **     This condition filters out entries that were added to the hash
  **     table after the current read-transaction had started.
  */
  iMinHash = walFramePage(pWal->minFrame);
  for(iHash=walFramePage(iLast); iHash>=iMinHash; iHash--){
    volatile ht_slot *aHash;      /* Pointer to hash table */
    volatile u32 *aPgno;          /* Pointer to array of page numbers */
    u32 iZero;                    /* Frame number corresponding to aPgno[0] */
    int iKey;                     /* Hash slot index */
    int nCollide;                 /* Number of hash collisions remaining */
    int rc;                       /* Error code */

................................................................................
        assert( iFrame>iRead || CORRUPT_DB );
        iRead = iFrame;
      }
      if( (nCollide--)==0 ){
        return SQLITE_CORRUPT_BKPT;
      }
    }
    if( iRead ) break;
  }

#ifdef SQLITE_ENABLE_EXPENSIVE_ASSERT
  /* If expensive assert() statements are available, do a linear search
  ** of the wal-index file content. Make sure the results agree with the
  ** result obtained using the hash indexes above.  */
  {

Changes to src/wherecode.c.

1391
1392
1393
1394
1395
1396
1397
1398








1399
1400
1401
1402
1403
1404
1405
      testcase( pStart->wtFlags & TERM_VIRTUAL );
      pX = pStart->pExpr;
      assert( pX!=0 );
      testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
      if( sqlite3ExprIsVector(pX->pRight) ){
        r1 = rTemp = sqlite3GetTempReg(pParse);
        codeExprOrVector(pParse, pX->pRight, r1, 1);
        op = aMoveOp[(pX->op - TK_GT) | 0x0001];








      }else{
        r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
        disableTerm(pLevel, pStart);
        op = aMoveOp[(pX->op - TK_GT)];
      }
      sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1);
      VdbeComment((v, "pk"));







|
>
>
>
>
>
>
>
>







1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
      testcase( pStart->wtFlags & TERM_VIRTUAL );
      pX = pStart->pExpr;
      assert( pX!=0 );
      testcase( pStart->leftCursor!=iCur ); /* transitive constraints */
      if( sqlite3ExprIsVector(pX->pRight) ){
        r1 = rTemp = sqlite3GetTempReg(pParse);
        codeExprOrVector(pParse, pX->pRight, r1, 1);
        testcase( pX->op==TK_GT );
        testcase( pX->op==TK_GE );
        testcase( pX->op==TK_LT );
        testcase( pX->op==TK_LE );
        op = aMoveOp[((pX->op - TK_GT - 1) & 0x3) | 0x1];
        assert( pX->op!=TK_GT || op==OP_SeekGE );
        assert( pX->op!=TK_GE || op==OP_SeekGE );
        assert( pX->op!=TK_LT || op==OP_SeekLE );
        assert( pX->op!=TK_LE || op==OP_SeekLE );
      }else{
        r1 = sqlite3ExprCodeTemp(pParse, pX->pRight, &rTemp);
        disableTerm(pLevel, pStart);
        op = aMoveOp[(pX->op - TK_GT)];
      }
      sqlite3VdbeAddOp3(v, op, iCur, addrBrk, r1);
      VdbeComment((v, "pk"));

Changes to src/whereexpr.c.

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

      pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
      transferJoinMarkings(pNew, pExpr);
      idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
      exprAnalyze(pSrc, pWC, idxNew);
    }
    pTerm = &pWC->a[idxTerm];
    pTerm->wtFlags = TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
    pTerm->eOperator = 0;
  }

  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
  ** a virtual term for each vector component. The expression object
  ** used by each such virtual term is pExpr (the full vector IN(...) 
  ** expression). The WhereTerm.iField variable identifies the index within







|







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

      pNew = sqlite3PExpr(pParse, pExpr->op, pLeft, pRight);
      transferJoinMarkings(pNew, pExpr);
      idxNew = whereClauseInsert(pWC, pNew, TERM_DYNAMIC);
      exprAnalyze(pSrc, pWC, idxNew);
    }
    pTerm = &pWC->a[idxTerm];
    pTerm->wtFlags |= TERM_CODED|TERM_VIRTUAL;  /* Disable the original */
    pTerm->eOperator = 0;
  }

  /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create
  ** a virtual term for each vector component. The expression object
  ** used by each such virtual term is pExpr (the full vector IN(...) 
  ** expression). The WhereTerm.iField variable identifies the index within

Changes to test/fts4onepass.test.

138
139
140
141
142
143
144
145














146
    do_execsql_test  3.$tn.$tn2.b { SELECT rowid, content FROM ft2 } $content
    do_execsql_test  3.$tn.$tn2.c { 
      INSERT INTO ft2(ft2) VALUES('integrity-check');
    }
  }
  eval $tcl2
}















finish_test








>
>
>
>
>
>
>
>
>
>
>
>
>
>

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    do_execsql_test  3.$tn.$tn2.b { SELECT rowid, content FROM ft2 } $content
    do_execsql_test  3.$tn.$tn2.c { 
      INSERT INTO ft2(ft2) VALUES('integrity-check');
    }
  }
  eval $tcl2
}

do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE zt USING fts4(a, b);
  INSERT INTO zt(rowid, a, b) VALUES(1, 'unus duo', NULL);
  INSERT INTO zt(rowid, a, b) VALUES(2, NULL, NULL);

  BEGIN;
    UPDATE zt SET b='septum' WHERE rowid = 1;
    UPDATE zt SET b='octo' WHERE rowid = 1;
  COMMIT;

  SELECT count(*) FROM zt_segdir;
} {3}


finish_test

Changes to test/func6.test.

17
18
19
20
21
22
23





24
25
26
27
28
29
30
..
47
48
49
50
51
52
53







54
55
56
57
58
59
60
..
99
100
101
102
103
104
105





106
107
108

109
110
111
112
113
114
115
116
117
118
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !offset_sql_func {
  finish_test
  return
}






do_execsql_test func6-100 {
  PRAGMA page_size=4096;
  PRAGMA auto_vacuum=NONE;
  CREATE TABLE t1(a,b,c,d);
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
   INSERT INTO t1(a,b,c,d) SELECT printf('abc%03x',x), x, 1000-x, NULL FROM c;
................................................................................
# Each argument is either an integer between 0 and 65535, a text value, or
# an empty string representing an SQL NULL. This command builds an SQLite
# record containing the values passed as arguments and returns it encoded
# as a hex string.
proc hexrecord {args} {
  set hdr ""
  set body ""







  foreach x $args {
    if {$x==""} {
      append hdr 00
    } elseif {[string is integer $x]==0} {
      set n [string length $x]
      append hdr [format %02x [expr $n*2 + 13]]
      append body [binary encode hex $x]
................................................................................
  set rec [hexrecord {*}[lrange $args 1 end]]
  offset_contains_record $offset $::F $rec
}
set F [loadhex test.db]
db func offrec offrec

# Test the sanity of the tests.





do_execsql_test func6-105 {
  SELECT sqlite_offset(d) FROM t1 ORDER BY rowid LIMIT 1;
} {8179}

do_test func6-106 {
  set r [hexrecord abc001 1 999 {}]
  offset_contains_record 8179 $F $r
} 0

set z100 [string trim [string repeat "0 " 100]]

# Test offsets within table b-tree t1.
do_execsql_test func6-110 {
  SELECT offrec(sqlite_offset(d), a, b, c, d) FROM t1 ORDER BY rowid







>
>
>
>
>







 







>
>
>
>
>
>
>







 







>
>
>
>
>


<
>


|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
..
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
...
111
112
113
114
115
116
117
118
119
120
121
122
123
124

125
126
127
128
129
130
131
132
133
134
135
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
ifcapable !offset_sql_func {
  finish_test
  return
}

set bNullTrim 0
ifcapable null_trim {
  set bNullTrim 1
}

do_execsql_test func6-100 {
  PRAGMA page_size=4096;
  PRAGMA auto_vacuum=NONE;
  CREATE TABLE t1(a,b,c,d);
  WITH RECURSIVE c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100)
   INSERT INTO t1(a,b,c,d) SELECT printf('abc%03x',x), x, 1000-x, NULL FROM c;
................................................................................
# Each argument is either an integer between 0 and 65535, a text value, or
# an empty string representing an SQL NULL. This command builds an SQLite
# record containing the values passed as arguments and returns it encoded
# as a hex string.
proc hexrecord {args} {
  set hdr ""
  set body ""

  if {$::bNullTrim} {
    while {[llength $args] && [lindex $args end]=={}} {
      set args [lrange $args 0 end-1]
    }
  }

  foreach x $args {
    if {$x==""} {
      append hdr 00
    } elseif {[string is integer $x]==0} {
      set n [string length $x]
      append hdr [format %02x [expr $n*2 + 13]]
      append body [binary encode hex $x]
................................................................................
  set rec [hexrecord {*}[lrange $args 1 end]]
  offset_contains_record $offset $::F $rec
}
set F [loadhex test.db]
db func offrec offrec

# Test the sanity of the tests.
if {$bNullTrim} {
  set offset 8180
} else {
  set offset 8179
}
do_execsql_test func6-105 {
  SELECT sqlite_offset(d) FROM t1 ORDER BY rowid LIMIT 1;

} $offset
do_test func6-106 {
  set r [hexrecord abc001 1 999 {}]
  offset_contains_record $offset $F $r
} 0

set z100 [string trim [string repeat "0 " 100]]

# Test offsets within table b-tree t1.
do_execsql_test func6-110 {
  SELECT offrec(sqlite_offset(d), a, b, c, d) FROM t1 ORDER BY rowid

Changes to test/printf2.test.

144
145
146
147
148
149
150

























151































152

153
do_execsql_test printf2-4.9 {
  SELECT printf('|%,d|%,d|',123456789,-123456789);
} {|123,456,789|-123,456,789|}
do_execsql_test printf2-4.10 {
  SELECT printf('|%,d|%,d|',1234567890,-1234567890);
} {|1,234,567,890|-1,234,567,890|}




























































finish_test







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>

144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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
do_execsql_test printf2-4.9 {
  SELECT printf('|%,d|%,d|',123456789,-123456789);
} {|123,456,789|-123,456,789|}
do_execsql_test printf2-4.10 {
  SELECT printf('|%,d|%,d|',1234567890,-1234567890);
} {|1,234,567,890|-1,234,567,890|}

# 2018-02-19.  Unicode characters with %c
do_execsql_test printf2-5.100 {
  SELECT printf('(%8c)',char(11106));
} {{(       ⭢)}}
do_execsql_test printf2-5.101 {
  SELECT printf('(%-8c)',char(11106));
} {{(⭢       )}}
do_execsql_test printf2-5.102 {
  SELECT printf('(%5.3c)',char(1492));
} {{(  ההה)}}
do_execsql_test printf2-5.103 {
  SELECT printf('(%-5.3c)',char(1492));
} {{(ההה  )}}
do_execsql_test printf2-5.104 {
  SELECT printf('(%3.3c)',char(1492));
} {{(ההה)}}
do_execsql_test printf2-5.105 {
  SELECT printf('(%-3.3c)',char(1492));
} {{(ההה)}}
do_execsql_test printf2-5.104 {
  SELECT printf('(%2c)',char(1513));
} {{( ש)}}
do_execsql_test printf2-5.106 {
  SELECT printf('(%-2c)',char(1513));
} {{(ש )}}

# 2018-02-19.  Unicode characters with the "!" flag in %s and friends.
do_execsql_test printf2-6.100 {
  SELECT printf('(%!.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {(הנה)}
do_execsql_test printf2-6.101 {
  SELECT printf('(%.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {(הנה)}
do_execsql_test printf2-6.102 {
  SELECT printf('(%!5.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {{(  הנה)}}
do_execsql_test printf2-6.103 {
  SELECT printf('(%8.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {{(  הנה)}}
do_execsql_test printf2-6.104 {
  SELECT printf('(%!-5.3s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {{(הנה  )}}
do_execsql_test printf2-6.105 {
  SELECT printf('(%-8.6s)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {{(הנה  )}}
do_execsql_test printf2-6.106 {
  SELECT printf('(%!.3Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {('הנה')}
do_execsql_test printf2-6.107 {
  SELECT printf('(%.6Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {('הנה')}
do_execsql_test printf2-6.108 {
  SELECT printf('(%!7.3Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {{(  'הנה')}}
do_execsql_test printf2-6.109 {
  SELECT printf('(%10.6Q)','הנה מה־טוב ומה־נעים שבת אחים גם־יחד');
} {{(  'הנה')}}


finish_test

Changes to test/rowvalue.test.

433
434
435
436
437
438
439
440

441










































































































442
} {1 1 1 1 2 1}
do_execsql_test 18.6 {
  SELECT * FROM b3 JOIN b4 ON b4.a = b3.a
  WHERE (b3.a, b3.b) IN ( SELECT a, b FROM b5 ); 
} {1 1 1 1 2 1}

 
finish_test












































































































finish_test







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

433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
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
} {1 1 1 1 2 1}
do_execsql_test 18.6 {
  SELECT * FROM b3 JOIN b4 ON b4.a = b3.a
  WHERE (b3.a, b3.b) IN ( SELECT a, b FROM b5 ); 
} {1 1 1 1 2 1}

 
# 2018-02-13 Ticket https://www.sqlite.org/src/tktview/f484b65f3d6230593c3
# Incorrect result from a row-value comparison in the WHERE clause.
#
do_execsql_test 19.1 {
  DROP TABLE IF EXISTS t1;
  CREATE TABLE t1(a INTEGER PRIMARY KEY,b);
  INSERT INTO t1(a,b) VALUES(1,11),(2,22),(3,33),(4,44);
  SELECT * FROM t1 WHERE (a,b)>(0,0) ORDER BY a;
} {1 11 2 22 3 33 4 44}
do_execsql_test 19.2 {
  SELECT * FROM t1 WHERE (a,b)>=(0,0) ORDER BY a;
} {1 11 2 22 3 33 4 44}
do_execsql_test 19.3 {
  SELECT * FROM t1 WHERE (a,b)<(5,0) ORDER BY a DESC;
} {4 44 3 33 2 22 1 11}
do_execsql_test 19.4 {
  SELECT * FROM t1 WHERE (a,b)<=(5,0) ORDER BY a DESC;
} {4 44 3 33 2 22 1 11}
do_execsql_test 19.5 {
  SELECT * FROM t1 WHERE (a,b)>(3,0) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.6 {
  SELECT * FROM t1 WHERE (a,b)>=(3,0) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.7 {
  SELECT * FROM t1 WHERE (a,b)<(3,0) ORDER BY a DESC;
} {2 22 1 11}
do_execsql_test 19.8 {
  SELECT * FROM t1 WHERE (a,b)<=(3,0) ORDER BY a DESC;
} {2 22 1 11}
do_execsql_test 19.9 {
  SELECT * FROM t1 WHERE (a,b)>(3,32) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.10 {
  SELECT * FROM t1 WHERE (a,b)>(3,33) ORDER BY a;
} {4 44}
do_execsql_test 19.11 {
  SELECT * FROM t1 WHERE (a,b)>=(3,33) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.12 {
  SELECT * FROM t1 WHERE (a,b)>=(3,34) ORDER BY a;
} {4 44}
do_execsql_test 19.13 {
  SELECT * FROM t1 WHERE (a,b)<(3,34) ORDER BY a DESC;
} {3 33 2 22 1 11}
do_execsql_test 19.14 {
  SELECT * FROM t1 WHERE (a,b)<(3,33) ORDER BY a DESC;
} {2 22 1 11}
do_execsql_test 19.15 {
  SELECT * FROM t1 WHERE (a,b)<=(3,33) ORDER BY a DESC;
} {3 33 2 22 1 11}
do_execsql_test 19.16 {
  SELECT * FROM t1 WHERE (a,b)<=(3,32) ORDER BY a DESC;
} {2 22 1 11}
do_execsql_test 19.21 {
  SELECT * FROM t1 WHERE (0,0)<(a,b) ORDER BY a;
} {1 11 2 22 3 33 4 44}
do_execsql_test 19.22 {
  SELECT * FROM t1 WHERE (0,0)<=(a,b) ORDER BY a;
} {1 11 2 22 3 33 4 44}
do_execsql_test 19.23 {
  SELECT * FROM t1 WHERE (5,0)>(a,b) ORDER BY a DESC;
} {4 44 3 33 2 22 1 11}
do_execsql_test 19.24 {
  SELECT * FROM t1 WHERE (5,0)>=(a,b) ORDER BY a DESC;
} {4 44 3 33 2 22 1 11}
do_execsql_test 19.25 {
  SELECT * FROM t1 WHERE (3,0)<(a,b) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.26 {
  SELECT * FROM t1 WHERE (3,0)<=(a,b) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.27 {
  SELECT * FROM t1 WHERE (3,0)>(a,b) ORDER BY a DESC;
} {2 22 1 11}
do_execsql_test 19.28 {
  SELECT * FROM t1 WHERE (3,0)>=(a,b) ORDER BY a DESC;
} {2 22 1 11}
do_execsql_test 19.29 {
  SELECT * FROM t1 WHERE (3,32)<(a,b) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.30 {
  SELECT * FROM t1 WHERE (3,33)<(a,b) ORDER BY a;
} {4 44}
do_execsql_test 19.31 {
  SELECT * FROM t1 WHERE (3,33)<=(a,b) ORDER BY a;
} {3 33 4 44}
do_execsql_test 19.32 {
  SELECT * FROM t1 WHERE (3,34)<=(a,b) ORDER BY a;
} {4 44}
do_execsql_test 19.33 {
  SELECT * FROM t1 WHERE (3,34)>(a,b) ORDER BY a DESC;
} {3 33 2 22 1 11}
do_execsql_test 19.34 {
  SELECT * FROM t1 WHERE (3,33)>(a,b) ORDER BY a DESC;
} {2 22 1 11}
do_execsql_test 19.35 {
  SELECT * FROM t1 WHERE (3,33)>=(a,b) ORDER BY a DESC;
} {3 33 2 22 1 11}
do_execsql_test 19.36 {
  SELECT * FROM t1 WHERE (3,32)>=(a,b) ORDER BY a DESC;
} {2 22 1 11}

# 2018-02-18: Memory leak nexted row-value.  Detected by OSSFuzz.
#
do_catchsql_test 20.1 {
  SELECT 1 WHERE (2,(2,0)) IS (2,(2,0));
} {0 1}

finish_test

Changes to test/spellfix.test.

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    SELECT word, distance FROM t3 WHERE rowid = 10;
  } {keener {}
    {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
  }
  do_tracesql_test 6.2.3 {
    SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
  } {keener 300
    {SELECT id, word, rank, k1  FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
  }
}

#------------------------------------------------------------------------- 
# Test that the spellfix1 table supports conflict handling (OR REPLACE 
# and so on).
#







|







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    SELECT word, distance FROM t3 WHERE rowid = 10;
  } {keener {}
    {SELECT word, rank, NULL, langid, id FROM "main"."t3_vocab" WHERE rowid=?}
  }
  do_tracesql_test 6.2.3 {
    SELECT word, distance FROM t3 WHERE rowid = 10 AND word MATCH 'kiiner';
  } {keener 300
    {SELECT id, word, rank, coalesce(k1,word)  FROM "main"."t3_vocab" WHERE langid=0 AND k2>=?1 AND k2<?2}
  }
}

#------------------------------------------------------------------------- 
# Test that the spellfix1 table supports conflict handling (OR REPLACE 
# and so on).
#

Added test/spellfix4.test.



































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
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
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
# 2018-02-14
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
#
# Test cases for the editdist3() function in the spellfix extension.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix spellfix4

ifcapable !vtab { finish_test ; return }

load_static_extension db spellfix

do_execsql_test 100 {
  CREATE TABLE cost1(iLang, cFrom, cTo, iCost);
  INSERT INTO cost1 VALUES
    (0, '', '?',  97),
    (0, '?', '',  98),
    (0, '?', '?', 99),
    (0, 'm', 'n', 50),
    (0, 'n', 'm', 50)
  ;
  SELECT editdist3('cost1');
  SELECT editdist3('anchor','amchor');
} {{} 50}
do_execsql_test 110 {
  SELECT editdist3('anchor','anchoxr');
} {97}
do_execsql_test 111 {
  SELECT editdist3('anchor','xanchor');
} {97}
do_execsql_test 112 {
  SELECT editdist3('anchor','anchorx');
} {97}
do_execsql_test 120 {
  SELECT editdist3('anchor','anchr');
} {98}
do_execsql_test 121 {
  SELECT editdist3('anchor','ancho');
} {98}
do_execsql_test 122 {
  SELECT editdist3('anchor','nchor');
} {98}
do_execsql_test 130 {
  SELECT editdist3('anchor','anchur');
} {99}
do_execsql_test 131 {
  SELECT editdist3('anchor','onchor');
} {99}
do_execsql_test 132 {
  SELECT editdist3('anchor','anchot');
} {99}
do_execsql_test 140 {
  SELECT editdist3('anchor','omchor');
} {149}

do_execsql_test 200 {
  INSERT INTO cost1 VALUES
    (0, 'a', 'ä', 5),
    (0, 'ss', 'ß', 8)
  ;
  SELECT editdist3('cost1');
  SELECT editdist3('strasse','straße');
  SELECT editdist3('straße','strasse');
} {{} 8 196}
do_execsql_test 210 {
  SELECT editdist3('baume','bäume');
} {5}
do_execsql_test 220 {
  SELECT editdist3('baum','bäume');
} {102}
do_execsql_test 230 {
  INSERT INTO cost1 VALUES
    (0, 'ä', 'a', 5),
    (0, 'ß', 'ss', 8)
  ;
  SELECT editdist3('cost1');
  SELECT editdist3('strasse','straße');
  SELECT editdist3('straße','strasse');
} {{} 8 8}

do_execsql_test 300 {
  DELETE FROM cost1;
  INSERT INTO cost1 VALUES
    (0, '', '?',  97),
    (0, '?', '',  98),
    (0, '?', '?', 99),
    (0, 'a', 'e', 50),
    (0, 'a', 'i', 70),
    (0, 'a', 'o', 75),
    (0, 'a', 'u', 81),
    (0, 'e', 'a', 50),
    (0, 'e', 'i', 52),
    (0, 'e', 'o', 72),
    (0, 'e', 'u', 82),
    (0, 'i', 'a', 70),
    (0, 'i', 'e', 52),
    (0, 'i', 'o', 75),
    (0, 'i', 'u', 83),
    (0, 'o', 'a', 75),
    (0, 'o', 'e', 72),
    (0, 'o', 'i', 75),
    (0, 'o', 'u', 40),
    (0, 'u', 'a', 81),
    (0, 'u', 'e', 82),
    (0, 'u', 'i', 83),
    (0, 'u', 'o', 40),
    (0, 'm', 'n', 45),
    (0, 'n', 'm', 45)
  ;
  CREATE TABLE words(x TEXT);
  INSERT INTO words VALUES
   ('abraham'),
   ('action'),
   ('africa'),
   ('aladdin'),
   ('alert'),
   ('alien'),
   ('amazon'),
   ('analog'),
   ('animal'),
   ('apollo'),
   ('archive'),
   ('arnold'),
   ('aspirin'),
   ('august'),
   ('average'),
   ('bahama'),
   ('bambino'),
   ('barcode'),
   ('bazooka'),
   ('belgium'),
   ('between'),
   ('biology'),
   ('blonde'),
   ('border'),
   ('brave'),
   ('british'),
   ('bucket'),
   ('button'),
   ('caesar'),
   ('camilla'),
   ('cannon'),
   ('caramel'),
   ('carpet'),
   ('catalog'),
   ('century'),
   ('chaos'),
   ('chef'),
   ('china'),
   ('circus'),
   ('classic'),
   ('clinic'),
   ('coconut'),
   ('combine'),
   ('complex'),
   ('congo'),
   ('convert'),
   ('cosmos'),
   ('crack'),
   ('crown'),
   ('cyclone'),
   ('deal'),
   ('delete'),
   ('denver'),
   ('detail'),
   ('diana'),
   ('direct'),
   ('dolby'),
   ('double'),
   ('dublin'),
   ('echo'),
   ('edition'),
   ('electra'),
   ('emotion'),
   ('enjoy'),
   ('escape'),
   ('everest'),
   ('exile'),
   ('express'),
   ('family'),
   ('ferrari'),
   ('filter'),
   ('fish'),
   ('florida'),
   ('ford'),
   ('forum'),
   ('frank'),
   ('frozen'),
   ('gallery'),
   ('garlic'),
   ('geneva'),
   ('gibson'),
   ('gloria'),
   ('gordon'),
   ('gravity'),
   ('ground'),
   ('habitat'),
   ('harlem'),
   ('hazard'),
   ('herbert'),
   ('hobby'),
   ('house'),
   ('icon'),
   ('immune'),
   ('india'),
   ('inside'),
   ('isotope'),
   ('jamaica'),
   ('jazz'),
   ('joker'),
   ('juliet'),
   ('jupiter'),
   ('kevin'),
   ('korea'),
   ('latin'),
   ('legal'),
   ('lexicon'),
   ('limbo'),
   ('lithium'),
   ('logo'),
   ('lucas'),
   ('madrid'),
   ('major'),
   ('manual'),
   ('mars'),
   ('maximum'),
   ('medical'),
   ('mental'),
   ('meter'),
   ('miguel'),
   ('mimosa'),
   ('miranda'),
   ('modern'),
   ('money'),
   ('morgan'),
   ('motor'),
   ('mystic'),
   ('nebula'),
   ('network'),
   ('nice'),
   ('nitro'),
   ('norway'),
   ('nurse'),
   ('octavia'),
   ('olympic'),
   ('opus'),
   ('orient'),
   ('othello'),
   ('pacific'),
   ('panama'),
   ('paper'),
   ('parking'),
   ('pasta'),
   ('paul'),
   ('people'),
   ('permit'),
   ('phrase'),
   ('pilgrim'),
   ('planet'),
   ('pocket'),
   ('police'),
   ('popular'),
   ('prefer'),
   ('presto'),
   ('private'),
   ('project'),
   ('proxy'),
   ('python'),
   ('quota'),
   ('rainbow'),
   ('raymond'),
   ('region'),
   ('report'),
   ('reward'),
   ('risk'),
   ('robot'),
   ('rose'),
   ('russian'),
   ('sailor'),
   ('salt'),
   ('saturn'),
   ('scorpio'),
   ('second'),
   ('seminar'),
   ('shadow'),
   ('shave'),
   ('shock'),
   ('silence'),
   ('sinatra'),
   ('sleep'),
   ('social'),
   ('sonata'),
   ('spain'),
   ('sphere'),
   ('spray'),
   ('state'),
   ('stone'),
   ('strong'),
   ('sugar'),
   ('supreme'),
   ('swing'),
   ('talent'),
   ('telecom'),
   ('thermos'),
   ('tina'),
   ('tommy'),
   ('torso'),
   ('trade'),
   ('trick'),
   ('tropic'),
   ('turtle'),
   ('uniform'),
   ('user'),
   ('vega'),
   ('vertigo'),
   ('village'),
   ('visible'),
   ('vocal'),
   ('voyage'),
   ('weekend'),
   ('winter'),
   ('year'),
   ('zipper')
  ;
  SELECT editdist3('cost1');
} {{}}
do_execsql_test 310 {
  SELECT editdist3(a.x,b.x), a.x, b.x
    FROM words a, words b
   WHERE a.x<b.x
   ORDER BY 1, 2
   LIMIT 20
} {139 bucket pocket 144 meter motor 149 manual mental 169 crack trick 173 sinatra sonata 174 edition emotion 174 major motor 174 risk rose 174 state stone 194 deal detail 196 alert talent 196 analog catalog 196 deal legal 196 ford forum 196 risk trick 196 stone strong 197 china tina 197 congo logo 197 diana tina 197 florida gloria}
do_execsql_test 320 {
  SELECT md5sum(ed||'/'||sx||'/'||sy||',') FROM (
      SELECT editdist3(a.x,b.x) AS ed, a.x AS sx, b.x AS sy
        FROM words a, words b
       WHERE a.x<b.x
       ORDER BY 1, 2
  )
} {69d0a31872203a775e19325ea98cd053}

finish_test

Added test/with4.test.









































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 2018-02-15
#
# The author disclaims copyright to this source code.  In place of
# a legal notice, here is a blessing:
#
#    May you do good and not evil.
#    May you find forgiveness for yourself and forgive others.
#    May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the WITH clause in TRIGGERs and VIEWs.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix with4

ifcapable {!cte} {
  finish_test
  return
}

do_execsql_test 100 {
  ATTACH ':memory:' AS aux;
  CREATE TABLE main.t1(a,b);
  CREATE TABLE aux.t2(x,y);
  INSERT INTO t1 VALUES(1,2);
  INSERT INTO t2 VALUES(3,4);
} {}
do_catchsql_test 110 {
  CREATE VIEW v1 AS SELECT * FROM t1, aux.t2;
} {1 {view v1 cannot reference objects in database aux}}
do_catchsql_test 120 {
  CREATE VIEW v2 AS WITH v(m,n) AS (SELECT x,y FROM aux.t2) SELECT * FROM t1, v;
} {1 {view v2 cannot reference objects in database aux}}
do_catchsql_test 130 {
  CREATE VIEW v2 AS WITH v(m,n) AS (SELECT 5,?2) SELECT * FROM t1, v;
} {1 {parameters are not allowed in views}}

do_catchsql_test 200 {
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
     WITH v(m,n) AS (SELECT x,y FROM aux.t2) SELECT * FROM t1, v;
  END;
} {1 {trigger r1 cannot reference objects in database aux}}
do_catchsql_test 210 {
  CREATE TRIGGER r1 AFTER INSERT ON t1 BEGIN
     WITH v(m,n) AS (SELECT 5,?2) SELECT * FROM t1, v;
  END;
} {1 {trigger cannot use variables}}

finish_test

Changes to tool/speed-check.sh.

35
36
37
38
39
40
41


42
43
44
45
46
47
48
..
57
58
59
60
61
62
63
64



65
66

67
68
69
70
71
72
73
..
74
75
76
77
78
79
80

81
82
83
84
85
86
87
...
128
129
130
131
132
133
134



135
136
137
138
139



140
141
142
143
144
145
146
...
159
160
161
162
163
164
165




166
167
168
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED"
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK"
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_SHARED_CACHE"
LEAN_OPTS="$LEAN_OPTS -DSQLITE_USE_ALLOCA"
BASELINE="trunk"
doExplain=0
doCachegrind=1


while test "$1" != ""; do
  case $1 in
    --reprepare)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --autovacuum)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
................................................................................
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --nomemstat)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --temp)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS --temp 6"
        ;;



    --wal)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal"

        ;;
    --size)
        shift; SIZE=$1
        ;;
    --cachesize)
        shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1"
        ;;
................................................................................
    --explain)
        doExplain=1
        ;;
    --vdbeprofile)
        rm -f vdbe_profile.out
        CC_OPTS="$CC_OPTS -DVDBE_PROFILE"
        doCachegrind=0

        ;;
    --lean)
        CC_OPTS="$CC_OPTS $LEAN_OPTS"
        ;;
    --clang)
        CC=clang
        ;;
................................................................................
        ;;
    *)
	BASELINE=$1
        ;;
  esac
  shift
done



SPEEDTEST_OPTS="$SPEEDTEST_OPTS --size $SIZE"
echo "NAME           = $NAME" | tee summary-$NAME.txt
echo "SPEEDTEST_OPTS = $SPEEDTEST_OPTS" | tee -a summary-$NAME.txt
echo "CC_OPTS        = $CC_OPTS" | tee -a summary-$NAME.txt
rm -f cachegrind.out.* speedtest1 speedtest1.db sqlite3.o



$CC -g -Os -Wall -I. $CC_OPTS -c sqlite3.c
size sqlite3.o | tee -a summary-$NAME.txt
if test $doExplain -eq 1; then
  $CC -g -Os -Wall -I. $CC_OPTS \
     -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
    ./shell.c ./sqlite3.c -o sqlite3 -ldl -lpthread
fi
................................................................................
  cg_anno.tcl cachegrind.out.* >cout-$NAME.txt
  echo '*****************************************************' >>cout-$NAME.txt
  sed 's/^[0-9=-]\{9\}/==00000==/' summary-$NAME.txt >>cout-$NAME.txt
fi
if test $doExplain -eq 1; then
  ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt
fi




if test "$NAME" != "$BASELINE"; then
  fossil test-diff --tk -c 20 cout-$BASELINE.txt cout-$NAME.txt
fi







>
>







 








>
>
>

<
>







 







>







 







>
>
>





>
>
>







 







>
>
>
>
|


35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
59
60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_DEPRECATED"
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_PROGRESS_CALLBACK"
LEAN_OPTS="$LEAN_OPTS -DSQLITE_OMIT_SHARED_CACHE"
LEAN_OPTS="$LEAN_OPTS -DSQLITE_USE_ALLOCA"
BASELINE="trunk"
doExplain=0
doCachegrind=1
doVdbeProfile=0
doWal=1
while test "$1" != ""; do
  case $1 in
    --reprepare)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --autovacuum)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
................................................................................
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --nomemstat)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS $1"
        ;;
    --temp)
        SPEEDTEST_OPTS="$SPEEDTEST_OPTS --temp 6"
        ;;
    --legacy)
	doWal=0
        ;;
    --wal)

        doWal=1
        ;;
    --size)
        shift; SIZE=$1
        ;;
    --cachesize)
        shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --cachesize $1"
        ;;
................................................................................
    --explain)
        doExplain=1
        ;;
    --vdbeprofile)
        rm -f vdbe_profile.out
        CC_OPTS="$CC_OPTS -DVDBE_PROFILE"
        doCachegrind=0
        doVdbeProfile=1
        ;;
    --lean)
        CC_OPTS="$CC_OPTS $LEAN_OPTS"
        ;;
    --clang)
        CC=clang
        ;;
................................................................................
        ;;
    *)
	BASELINE=$1
        ;;
  esac
  shift
done
if test $doWal -eq 1; then
  SPEEDTEST_OPTS="$SPEEDTEST_OPTS --journal wal"
fi
SPEEDTEST_OPTS="$SPEEDTEST_OPTS --size $SIZE"
echo "NAME           = $NAME" | tee summary-$NAME.txt
echo "SPEEDTEST_OPTS = $SPEEDTEST_OPTS" | tee -a summary-$NAME.txt
echo "CC_OPTS        = $CC_OPTS" | tee -a summary-$NAME.txt
rm -f cachegrind.out.* speedtest1 speedtest1.db sqlite3.o
if test $doVdbeProfile -eq 1; then
  rm -f vdbe_profile.out
fi
$CC -g -Os -Wall -I. $CC_OPTS -c sqlite3.c
size sqlite3.o | tee -a summary-$NAME.txt
if test $doExplain -eq 1; then
  $CC -g -Os -Wall -I. $CC_OPTS \
     -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
    ./shell.c ./sqlite3.c -o sqlite3 -ldl -lpthread
fi
................................................................................
  cg_anno.tcl cachegrind.out.* >cout-$NAME.txt
  echo '*****************************************************' >>cout-$NAME.txt
  sed 's/^[0-9=-]\{9\}/==00000==/' summary-$NAME.txt >>cout-$NAME.txt
fi
if test $doExplain -eq 1; then
  ./speedtest1 --explain $SPEEDTEST_OPTS | ./sqlite3 >explain-$NAME.txt
fi
if test $doVdbeProfile -eq 1; then
  tclsh ../sqlite/tool/vdbe_profile.tcl >vdbeprofile-$NAME.txt
  open vdbeprofile-$NAME.txt
fi
if test "$NAME" != "$BASELINE" -a $doVdbeProfile -ne 1; then
  fossil test-diff --tk -c 20 cout-$BASELINE.txt cout-$NAME.txt
fi