SQLite

Check-in [127173e0ba]
Login

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

Overview
Comment:Merge recent trunk enhancements into the wal2 branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | wal2
Files: files | file ages | folders
SHA3-256: 127173e0baba8839d5922a2537dc42e6bb64ed1499b0700bf3e95d42c2f260b3
User & Date: drh 2021-10-04 11:44:28.073
Context
2021-10-21
14:01
Merge recent trunk enhancements into the wal2 branch. (check-in: 7e2bc836f6 user: drh tags: wal2)
2021-10-04
12:02
Merge recent trunk changes into the begin-concurrent-pnu-wal2 branch. (check-in: bce02eaa0c user: drh tags: begin-concurrent-pnu-wal2)
11:44
Merge recent trunk enhancements into the wal2 branch. (check-in: 127173e0ba user: drh tags: wal2)
11:10
Fix query plans created by whereShortCut() so that they always check transitive constraints that drive an index. The is analogous to the [f1f9b5de3c59489b] check-in, just for whereShortCut() rather than the full query planner. Fix for the issue described by forum post a65cacbf5e1c41ba. (check-in: 8b24c17706 user: drh tags: trunk)
2021-08-09
18:26
Merge recent trunk enhancements into the wal2 branch. (check-in: 84dac820a0 user: drh tags: wal2)
Changes
Unified Diff Ignore Whitespace Patch
Changes to Makefile.in.
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
  $(TOP)/ext/misc/remember.c \
  $(TOP)/ext/misc/series.c \
  $(TOP)/ext/misc/spellfix.c \
  $(TOP)/ext/misc/totype.c \
  $(TOP)/ext/misc/unionvtab.c \
  $(TOP)/ext/misc/wholenumber.c \
  $(TOP)/ext/misc/zipfile.c \
  $(TOP)/ext/userauth/userauth.c


# Source code to the library files needed by the test fixture
#
TESTSRC2 = \
  $(TOP)/src/attach.c \
  $(TOP)/src/backup.c \
  $(TOP)/src/bitvec.c \







|
>







465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
  $(TOP)/ext/misc/remember.c \
  $(TOP)/ext/misc/series.c \
  $(TOP)/ext/misc/spellfix.c \
  $(TOP)/ext/misc/totype.c \
  $(TOP)/ext/misc/unionvtab.c \
  $(TOP)/ext/misc/wholenumber.c \
  $(TOP)/ext/misc/zipfile.c \
  $(TOP)/ext/userauth/userauth.c \
  $(TOP)/ext/rtree/test_rtreedoc.c

# Source code to the library files needed by the test fixture
#
TESTSRC2 = \
  $(TOP)/src/attach.c \
  $(TOP)/src/backup.c \
  $(TOP)/src/bitvec.c \
Changes to Makefile.msc.
1583
1584
1585
1586
1587
1588
1589

1590
1591
1592
1593
1594
1595
1596
  $(TOP)\ext\misc\regexp.c \
  $(TOP)\ext\misc\remember.c \
  $(TOP)\ext\misc\series.c \
  $(TOP)\ext\misc\spellfix.c \
  $(TOP)\ext\misc\totype.c \
  $(TOP)\ext\misc\unionvtab.c \
  $(TOP)\ext\misc\wholenumber.c \

  fts5.c

# If use of zlib is enabled, add the "zipfile.c" source file.
#
!IF $(USE_ZLIB)!=0
TESTEXT = $(TESTEXT) $(TOP)\ext\misc\zipfile.c
!ENDIF







>







1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
  $(TOP)\ext\misc\regexp.c \
  $(TOP)\ext\misc\remember.c \
  $(TOP)\ext\misc\series.c \
  $(TOP)\ext\misc\spellfix.c \
  $(TOP)\ext\misc\totype.c \
  $(TOP)\ext\misc\unionvtab.c \
  $(TOP)\ext\misc\wholenumber.c \
  $(TOP)\ext\rtree\test_rtreedoc.c \
  fts5.c

# If use of zlib is enabled, add the "zipfile.c" source file.
#
!IF $(USE_ZLIB)!=0
TESTEXT = $(TESTEXT) $(TOP)\ext\misc\zipfile.c
!ENDIF
Changes to ext/expert/expert1.test.
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# Tables with names that require quotes.
#
do_setup_rec_test $tn.9.1 {
  CREATE TABLE "t t"(a, b, c);
} {
  SELECT * FROM "t t" WHERE a=?
} {
  CREATE INDEX 't t_idx_00000061' ON 't t'(a);
  SEARCH t t USING INDEX t t_idx_00000061 (a=?) 
}

do_setup_rec_test $tn.9.2 {
  CREATE TABLE "t t"(a, b, c);
} {
  SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
} {
  CREATE INDEX 't t_idx_00000062' ON 't t'(b);
  SEARCH t t USING INDEX t t_idx_00000062 (b>? AND b<?)
}

# Columns with names that require quotes.
#
do_setup_rec_test $tn.10.1 {
  CREATE TABLE t3(a, "b b", c);







|








|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
# Tables with names that require quotes.
#
do_setup_rec_test $tn.9.1 {
  CREATE TABLE "t t"(a, b, c);
} {
  SELECT * FROM "t t" WHERE a=?
} {
  CREATE INDEX "t t_idx_00000061" ON "t t"(a);
  SEARCH t t USING INDEX t t_idx_00000061 (a=?) 
}

do_setup_rec_test $tn.9.2 {
  CREATE TABLE "t t"(a, b, c);
} {
  SELECT * FROM "t t" WHERE b BETWEEN ? AND ?
} {
  CREATE INDEX "t t_idx_00000062" ON "t t"(b);
  SEARCH t t USING INDEX t t_idx_00000062 (b>? AND b<?)
}

# Columns with names that require quotes.
#
do_setup_rec_test $tn.10.1 {
  CREATE TABLE t3(a, "b b", c);
Changes to ext/expert/sqlite3expert.c.
909
910
911
912
913
914
915













916
917
918
919
920
921
922
    }
  }
  idxFinalize(&rc, pIdxList);

  *pRc = rc;
  return 0;
}














static int idxCreateFromCons(
  sqlite3expert *p,
  IdxScan *pScan,
  IdxConstraint *pEq, 
  IdxConstraint *pTail
){







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







909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
    }
  }
  idxFinalize(&rc, pIdxList);

  *pRc = rc;
  return 0;
}

/* Callback for sqlite3_exec() with query with leading count(*) column.
 * The first argument is expected to be an int*, referent to be incremented
 * if that leading column is not exactly '0'.
 */
static int countNonzeros(void* pCount, int nc,
                         char* azResults[], char* azColumns[]){
  (void)azColumns;  /* Suppress unused parameter warning */
  if( nc>0 && (azResults[0][0]!='0' || azResults[0][1]!=0) ){
    *((int *)pCount) += 1;
  }
  return 0;
}

static int idxCreateFromCons(
  sqlite3expert *p,
  IdxScan *pScan,
  IdxConstraint *pEq, 
  IdxConstraint *pTail
){
936
937
938
939
940
941
942

943


944

945
946
947

948
949


















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



962

963
964
965
966
967
968
969
    for(pCons=pTail; pCons; pCons=pCons->pLink){
      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
    }

    if( rc==SQLITE_OK ){
      /* Hash the list of columns to come up with a name for the index */
      const char *zTable = pScan->pTab->zName;

      char *zName;                /* Index name */


      int i;

      for(i=0; zCols[i]; i++){
        h += ((h<<3) + zCols[i]);
      }

      zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
      if( zName==0 ){ 


















        rc = SQLITE_NOMEM;
      }else{
        if( idxIdentifierRequiresQuotes(zTable) ){
          zFmt = "CREATE INDEX '%q' ON %Q(%s)";
        }else{
          zFmt = "CREATE INDEX %s ON %s(%s)";
        }
        zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
        if( !zIdx ){
          rc = SQLITE_NOMEM;
        }else{
          rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);



          idxHashAdd(&rc, &p->hIdx, zName, zIdx);

        }
        sqlite3_free(zName);
        sqlite3_free(zIdx);
      }
    }

    sqlite3_free(zCols);







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


|
|








>
>
>
|
>







949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
    for(pCons=pTail; pCons; pCons=pCons->pLink){
      zCols = idxAppendColDefn(&rc, zCols, pTab, pCons);
    }

    if( rc==SQLITE_OK ){
      /* Hash the list of columns to come up with a name for the index */
      const char *zTable = pScan->pTab->zName;
      int quoteTable = idxIdentifierRequiresQuotes(zTable);
      char *zName = 0;          /* Index name */
      int collisions = 0;
      do{
        int i;
        char *zFind;
        for(i=0; zCols[i]; i++){
          h += ((h<<3) + zCols[i]);
        }
        sqlite3_free(zName);
        zName = sqlite3_mprintf("%s_idx_%08x", zTable, h);
        if( zName==0 ) break;
        /* Is is unique among table, view and index names? */
        zFmt = "SELECT count(*) FROM sqlite_schema WHERE name=%Q"
          " AND type in ('index','table','view')";
        zFind = sqlite3_mprintf(zFmt, zName);
        i = 0;
        rc = sqlite3_exec(dbm, zFind, countNonzeros, &i, 0);
        assert(rc==SQLITE_OK);
        sqlite3_free(zFind);
        if( i==0 ){
          collisions = 0;
          break;
        }
        ++collisions;
      }while( collisions<50 && zName!=0 );
      if( collisions ){
        /* This return means "Gave up trying to find a unique index name." */
        rc = SQLITE_BUSY_TIMEOUT;
      }else if( zName==0 ){
        rc = SQLITE_NOMEM;
      }else{
        if( quoteTable ){
          zFmt = "CREATE INDEX \"%w\" ON \"%w\"(%s)";
        }else{
          zFmt = "CREATE INDEX %s ON %s(%s)";
        }
        zIdx = sqlite3_mprintf(zFmt, zName, zTable, zCols);
        if( !zIdx ){
          rc = SQLITE_NOMEM;
        }else{
          rc = sqlite3_exec(dbm, zIdx, 0, 0, p->pzErrmsg);
          if( rc!=SQLITE_OK ){
            rc = SQLITE_BUSY_TIMEOUT;
          }else{
            idxHashAdd(&rc, &p->hIdx, zName, zIdx);
          }
        }
        sqlite3_free(zName);
        sqlite3_free(zIdx);
      }
    }

    sqlite3_free(zCols);
1879
1880
1881
1882
1883
1884
1885




1886
1887
1888
1889
1890
1891
1892

  /* Do trigger processing to collect any extra IdxScan structures */
  rc = idxProcessTriggers(p, pzErr);

  /* Create candidate indexes within the in-memory database file */
  if( rc==SQLITE_OK ){
    rc = idxCreateCandidates(p);




  }

  /* Generate the stat1 data */
  if( rc==SQLITE_OK ){
    rc = idxPopulateStat1(p, pzErr);
  }








>
>
>
>







1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936

  /* Do trigger processing to collect any extra IdxScan structures */
  rc = idxProcessTriggers(p, pzErr);

  /* Create candidate indexes within the in-memory database file */
  if( rc==SQLITE_OK ){
    rc = idxCreateCandidates(p);
  }else if ( rc==SQLITE_BUSY_TIMEOUT ){
    if( pzErr )
      *pzErr = sqlite3_mprintf("Cannot find a unique index name to propose.");
    return rc;
  }

  /* Generate the stat1 data */
  if( rc==SQLITE_OK ){
    rc = idxPopulateStat1(p, pzErr);
  }

Changes to ext/fts5/fts5_index.c.
692
693
694
695
696
697
698

699
700
701
702
703
704
705
    p->rc = rc;
    p->nRead++;
  }

  assert( (pRet==0)==(p->rc!=SQLITE_OK) );
  return pRet;
}


/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().
*/
static void fts5DataRelease(Fts5Data *pData){
  sqlite3_free(pData);







>







692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
    p->rc = rc;
    p->nRead++;
  }

  assert( (pRet==0)==(p->rc!=SQLITE_OK) );
  return pRet;
}


/*
** Release a reference to data record returned by an earlier call to
** fts5DataRead().
*/
static void fts5DataRelease(Fts5Data *pData){
  sqlite3_free(pData);
832
833
834
835
836
837
838




































839
840
841
842
843
844
845
}
int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){
  if( p->pStruct!=(Fts5Structure*)pStruct ){
    return SQLITE_ABORT;
  }
  return SQLITE_OK;
}





































/*
** Deserialize and return the structure record currently stored in serialized
** form within buffer pData/nData.
**
** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
** are over-allocated by one slot. This allows the structure contents







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







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
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
}
int sqlite3Fts5StructureTest(Fts5Index *p, void *pStruct){
  if( p->pStruct!=(Fts5Structure*)pStruct ){
    return SQLITE_ABORT;
  }
  return SQLITE_OK;
}

/*
** Ensure that structure object (*pp) is writable.
**
** This function is a no-op if (*pRc) is not SQLITE_OK when it is called. If
** an error occurs, (*pRc) is set to an SQLite error code before returning.
*/
static void fts5StructureMakeWritable(int *pRc, Fts5Structure **pp){
  Fts5Structure *p = *pp;
  if( *pRc==SQLITE_OK && p->nRef>1 ){
    int nByte = sizeof(Fts5Structure)+(p->nLevel-1)*sizeof(Fts5StructureLevel);
    Fts5Structure *pNew;
    pNew = (Fts5Structure*)sqlite3Fts5MallocZero(pRc, nByte);
    if( pNew ){
      int i;
      memcpy(pNew, p, nByte);
      for(i=0; i<p->nLevel; i++) pNew->aLevel[i].aSeg = 0;
      for(i=0; i<p->nLevel; i++){
        Fts5StructureLevel *pLvl = &pNew->aLevel[i];
        nByte = sizeof(Fts5StructureSegment) * pNew->aLevel[i].nSeg;
        pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(pRc, nByte);
        if( pLvl->aSeg==0 ){
          for(i=0; i<p->nLevel; i++){
            sqlite3_free(pNew->aLevel[i].aSeg);
          }
          sqlite3_free(pNew);
          return;
        }
        memcpy(pLvl->aSeg, p->aLevel[i].aSeg, nByte);
      }
      p->nRef--;
      pNew->nRef = 1;
    }
    *pp = pNew;
  }
}

/*
** Deserialize and return the structure record currently stored in serialized
** form within buffer pData/nData.
**
** The Fts5Structure.aLevel[] and each Fts5StructureLevel.aSeg[] array
** are over-allocated by one slot. This allows the structure contents
934
935
936
937
938
939
940

941
942
943

944
945
946
947
948
949
950
  }

  *ppOut = pRet;
  return rc;
}

/*

**
*/
static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){

  if( *pRc==SQLITE_OK ){
    Fts5Structure *pStruct = *ppStruct;
    int nLevel = pStruct->nLevel;
    sqlite3_int64 nByte = (
        sizeof(Fts5Structure) +                  /* Main structure */
        sizeof(Fts5StructureLevel) * (nLevel+1)  /* aLevel[] array */
    );







>
|


>







971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
  }

  *ppOut = pRet;
  return rc;
}

/*
** Add a level to the Fts5Structure.aLevel[] array of structure object
** (*ppStruct).
*/
static void fts5StructureAddLevel(int *pRc, Fts5Structure **ppStruct){
  fts5StructureMakeWritable(pRc, ppStruct);
  if( *pRc==SQLITE_OK ){
    Fts5Structure *pStruct = *ppStruct;
    int nLevel = pStruct->nLevel;
    sqlite3_int64 nByte = (
        sizeof(Fts5Structure) +                  /* Main structure */
        sizeof(Fts5StructureLevel) * (nLevel+1)  /* aLevel[] array */
    );
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
  Fts5DlidxIter *pDlidx = pIter->pDlidx;
  Fts5Data *pLast = 0;
  int pgnoLast = 0;

  if( pDlidx ){
    int iSegid = pIter->pSeg->iSegid;
    pgnoLast = fts5DlidxIterPgno(pDlidx);
    pLast = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
  }else{
    Fts5Data *pLeaf = pIter->pLeaf;         /* Current leaf data */

    /* Currently, Fts5SegIter.iLeafOffset points to the first byte of
    ** position-list content for the current rowid. Back it up so that it
    ** points to the start of the position-list size field. */
    int iPoslist;







|







2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
  Fts5DlidxIter *pDlidx = pIter->pDlidx;
  Fts5Data *pLast = 0;
  int pgnoLast = 0;

  if( pDlidx ){
    int iSegid = pIter->pSeg->iSegid;
    pgnoLast = fts5DlidxIterPgno(pDlidx);
    pLast = fts5LeafRead(p, FTS5_SEGMENT_ROWID(iSegid, pgnoLast));
  }else{
    Fts5Data *pLeaf = pIter->pLeaf;         /* Current leaf data */

    /* Currently, Fts5SegIter.iLeafOffset points to the first byte of
    ** position-list content for the current rowid. Back it up so that it
    ** points to the start of the position-list size field. */
    int iPoslist;
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
      int pgno;
      Fts5StructureSegment *pSeg = pIter->pSeg;

      /* The last rowid in the doclist may not be on the current page. Search
      ** forward to find the page containing the last rowid.  */
      for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
        i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
        Fts5Data *pNew = fts5DataRead(p, iAbs);
        if( pNew ){
          int iRowid, bTermless;
          iRowid = fts5LeafFirstRowidOff(pNew);
          bTermless = fts5LeafIsTermless(pNew);
          if( iRowid ){
            SWAPVAL(Fts5Data*, pNew, pLast);
            pgnoLast = pgno;







|







2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
      int pgno;
      Fts5StructureSegment *pSeg = pIter->pSeg;

      /* The last rowid in the doclist may not be on the current page. Search
      ** forward to find the page containing the last rowid.  */
      for(pgno=pIter->iLeafPgno+1; !p->rc && pgno<=pSeg->pgnoLast; pgno++){
        i64 iAbs = FTS5_SEGMENT_ROWID(pSeg->iSegid, pgno);
        Fts5Data *pNew = fts5LeafRead(p, iAbs);
        if( pNew ){
          int iRowid, bTermless;
          iRowid = fts5LeafFirstRowidOff(pNew);
          bTermless = fts5LeafIsTermless(pNew);
          if( iRowid ){
            SWAPVAL(Fts5Data*, pNew, pLast);
            pgnoLast = pgno;
2171
2172
2173
2174
2175
2176
2177




2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
  */
  if( pLast ){
    int iOff;
    fts5DataRelease(pIter->pLeaf);
    pIter->pLeaf = pLast;
    pIter->iLeafPgno = pgnoLast;
    iOff = fts5LeafFirstRowidOff(pLast);




    iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
    pIter->iLeafOffset = iOff;

    if( fts5LeafIsTermless(pLast) ){
      pIter->iEndofDoclist = pLast->nn+1;
    }else{
      pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
    }

  }

  fts5SegIterReverseInitPage(p, pIter);
}

/*
** Iterator pIter currently points to the first rowid of a doclist.







>
>
>
>








<







2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228

2229
2230
2231
2232
2233
2234
2235
  */
  if( pLast ){
    int iOff;
    fts5DataRelease(pIter->pLeaf);
    pIter->pLeaf = pLast;
    pIter->iLeafPgno = pgnoLast;
    iOff = fts5LeafFirstRowidOff(pLast);
    if( iOff>pLast->szLeaf ){
      p->rc = FTS5_CORRUPT;
      return;
    }
    iOff += fts5GetVarint(&pLast->p[iOff], (u64*)&pIter->iRowid);
    pIter->iLeafOffset = iOff;

    if( fts5LeafIsTermless(pLast) ){
      pIter->iEndofDoclist = pLast->nn+1;
    }else{
      pIter->iEndofDoclist = fts5LeafFirstTermOff(pLast);
    }

  }

  fts5SegIterReverseInitPage(p, pIter);
}

/*
** Iterator pIter currently points to the first rowid of a doclist.
Added ext/fts5/test/fts5corrupt5.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
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
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
# 2015 Apr 24
#
# 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 tests that FTS5 handles corrupt databases (i.e. internal
# inconsistencies in the backing tables) correctly. In this case 
# "correctly" means without crashing.
#

source [file join [file dirname [info script]] fts5_common.tcl]
set testprefix fts5corrupt3

# If SQLITE_ENABLE_FTS5 is defined, omit this file.
ifcapable !fts5 {
  finish_test
  return
}
sqlite3_fts5_may_be_corrupt 1
database_may_be_corrupt

#-------------------------------------------------------------------------
# dbsqlfuzz crash-0f47112aa7520cf08c6a835a88fdff8c2a32a188
#
reset_db
do_test 1.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
.open --hexdb
| size 24576 pagesize 4096 filename crash-0f47112aa7520c.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53   ...............S
|    112: 0e e8 0e 8b 0e 33 0e 0f 00 00 00 00 00 00 00 00   .....3..........
|   3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22   ................
|   3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62   ......1tablebbbb
|   3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62   .CREATE TABLE bb
|   3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65   (a)V.......table
|   3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66   t1_configt1_conf
|   3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20   ig.CREATE TABLE 
|   3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52   't1_config'(k PR
|   3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49   IMARY KEY, v) WI
|   3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21   THOUT ROWID[...!
|   3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73   !...tablet1_docs
|   3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52   izet1_docsize.CR
|   3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64   EATE TABLE 't1_d
|   3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47   ocsize'(id INTEG
|   3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20   ER PRIMARY KEY, 
|   3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81   sz BLOB)i.......
|   3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69   -tablet1_idxt1_i
|   3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20   dx.CREATE TABLE 
|   3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20   't1_idx'(segid, 
|   3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d   term, pgno, PRIM
|   3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74   ARY KEY(segid, t
|   3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f   erm)) WITHOUT RO
|   3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c   WIDU........tabl
|   3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02   et1_datat1_data.
|   3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31   CREATE TABLE 't1
|   3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45   _data'(id INTEGE
|   3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62   R PRIMARY KEY, b
|   4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11   lock BLOB)T.....
|   4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41   ...tablet1t1CREA
|   4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45   TE VIRTUAL TABLE
|   4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61    t1 USING fts5(a
|   4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33   ,b,prefix=.1,2,3
|   4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29   ,4., content=..)
| page 2 offset 4096
|      0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4   ..j.7.L....L....
|     16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad   ...m.K.,........
|     32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5   ...l.K.)........
|     48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5   ...v.T.1........
|     64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0   ...s.T.2........
|     80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 00 00 00 00   ...~.H..........
|   2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00   ................
|   2384: 30 00 00 00 01 01 03 35 00 03 01 11 12 02 01 12   0......5........
|   2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00   ............>...
|   2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68   ....4tabl.....wh
|   2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c   er.............<
|   2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e   .....4fts4.....n
|   2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03   umb.............
|   2480: 00 3c 00 00 00 16 04 33 74 68 65 03 06 01 01 04   .<.....3the.....
|   2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80   ..whe...........
|   2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01   ...<.....3num...
|   2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80   ....tab.........
|   2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02   .....8.....2wh..
|   2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80   ...3fts.........
|   2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02   .....6.....2ta..
|   2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80   ...h............
|   2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01   ....<.....2nu...
|   2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80   ....of..........
|   2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03   ......8.....2ft.
|   2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80   ....is..........
|   2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08   ......6.....1t..
|   2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80   ......w.........
|   2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01   .....:.....1n...
|   2720: 01 02 05 01 00 6f 03 06 01 01 06 04 09 18 8c 80   .....o..........
|   2736: 80 80 80 06 03 00 36 00 00 00 03 04 02 31 66 03   ......6......1f.
|   2752: 02 02 01 01 69 03 06 01 01 03 04 f6 1c 8c 80 80   ....i...........
|   2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03   .....>.....0the.
|   2784: f6 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15   ......where.....
|   2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06   ........0.......
|   2816: 06 30 74 61 62 6c 65 0f 42 03 07 1c 8c 81 80 80   .0table.B.......
|   2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65   ....>.....0numbe
|   2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c   r.......of......
|   2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02   .......,........
|   2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03   0n..............
|   2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03   .<.....0fts4aux.
|   2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00   ....is........*.
|   2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88   .....$..........
|   2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80   ................
|   2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77   ......>.....4row
|   2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b   s.......ther....
|   2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01   .........0......
|   3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80   ...4betw........
|   3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77   .....<......3row
|   3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88   .......the......
|   3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04   .......<........
|   3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08   3are.....bet....
|   3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 13 32   .........<.....2
|   3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06   th........3and..
|   3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16   ...........<....
|   3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01   .2in.......ro...
|   3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00   .............6..
|   3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02   ....2ar.....be..
|   3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 9e 00   ............<...
|   3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02   ..1t........2an.
|   3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00   ..............8.
|   3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06   ....1n.......r..
|   3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00   ..............4.
|   3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01   ....1b.....i....
|   3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00   ............8...
|   3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01   ...12.....a.....
|   3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00   ............<...
|   3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02   ..0there.....11.
|   3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00   ..............0.
|   3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07   .......0the.....
|   3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01   ..........>.....
|   3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73   ...0n.......rows
|   3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00   .............<..
|   3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02   ...0between.....
|   3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a   in.............:
|   3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02   .....0and.......
|   3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00   re..............
|   3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32   4.....01.......2
|   3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00   ................
|   3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00   .............<..
|   3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65   ...4tabl.......e
|   3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c   rm.............<
|   3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70   .....4each.....p
|   3584: 72 65 73 01 02 05 04 08 1a 84 80 80 80 80 0f 03   res.............
|   3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02   .:.....3ter.....
|   3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e   he..............
|   3632: 03 00 3c 00 00 00 16 04 33 80 72 65 01 02 05 01   ..<.....3.re....
|   3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80   .tab............
|   3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02   ....:.....3for..
|   3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80   ...ts...........
|   3696: 80 80 0c 03 00 3c 00 00 00 17 03 32 74 68 01 06   .....<.....2th..
|   3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84   .....3eac.......
|   3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61   .......6.....2ta
|   3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80   .......e........
|   3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01   ......8.....2in.
|   3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80   ......pr........
|   3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01   ......6.....2fo.
|   3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80   ....t...........
|   3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04   .....<.....1t...
|   3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84   ......2ea.......
|   3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01   .......4.....1i.
|   3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80   ......p.........
|   3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03   .....6.....1e...
|   3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80   ..f.............
|   3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01   ....<.....0term.
|   3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80   ....he..........
|   3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 64 61 62   ............0dab
|   3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03   le..............
|   3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74   .0......0present
|   4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00   .............<..
|   4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e   ...0fts.......in
|   4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a   ...............:
|   4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 13 66   .....0each.....f
|   4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00   or..............
|   4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04   ................
| page 3 offset 8192
|      0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1   ....2.O.........
|     16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0   ................
|     32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f   .........x.q.h._
|     48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13   .V.M.A.8./.&....
|     64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd   ................
|     80: 0e c3 0e ba 0e 00 00 00 00 00 00 00 00 00 00 00   ................
|   3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08   ................
|   3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e   .....4t ......4.
|   3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03   ......3th.......
|   3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10   3n.......2w.....
|   3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04   ..2t.......2n...
|   3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08   ....2.......1t..
|   3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c   .....1n.......1.
|   3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03   ......0th.......
|   3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01   0t.......0nu....
|   3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01   ...0n...........
|   3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04   ...4r.......4 ..
|   3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72   ....3r.......3ar
|   3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02   .......2t.......
|   3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01   2i.......2ar....
|   3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08   ...1t.......1n..
|   3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32   .....1b.......12
|   3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01   .......0ther....
|   3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08   ...0t.......0n..
|   3936: 14 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61   .....0b.......0a
|   3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22   .............4t.
|   3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e   .....4 .....3te.
|   3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a   .....3p......3f.
|   4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74   .....2th......2t
|   4016: 16 01 64 09 10 01 32 69 14 07 04 09 10 01 32 66   ..d...2i......2f
|   4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69   ......1t......1i
|   4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65   ......1......0te
|   4064: 0a 06 04 09 10 01 30 74 08 07 04 09 10 01 30 70   ......0t......0p
|   4080: 06 08 04 09 12 00 00 00 00 00 00 00 00 00 00 00   ................
| page 4 offset 12288
|   4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10   ................
|   4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04   ................
| page 5 offset 16384
|      0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 00 00 00 00 00   ................
| end crash-0f47112aa7520c.db
  }]
} {}

do_catchsql_test 1.1 {
  SELECT * FROM t1('R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
} {1 {database disk image is malformed}}

#-------------------------------------------------------------------------
#
reset_db
do_test 2.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {

.open --hexdb
| size 24576 pagesize 4096 filename sql047467.txt.db
| page 1 offset 0
|      0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00   SQLite format 3.
|     16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 00   .....@  ........
|     96: 00 00 00 00 0d 00 00 00 06 0e 0f 00 0f aa 0f 53   ...............S
|    112: 0e e8 0e 8b 0e 33 0e 0f 01 00 00 00 00 00 00 00   .....3..........
|   3584: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 22   ................
|   3600: 06 06 17 11 11 01 31 74 61 62 6c 65 62 62 62 62   ......1tablebbbb
|   3616: 06 43 52 45 41 54 45 20 54 41 42 4c 45 20 62 62   .CREATE TABLE bb
|   3632: 28 61 29 56 05 06 17 1f 1f 01 7d 74 61 62 6c 65   (a)V.......table
|   3648: 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 6f 6e 66   t1_configt1_conf
|   3664: 69 67 05 43 52 45 41 54 45 20 54 41 42 4c 45 20   ig.CREATE TABLE 
|   3680: 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b 20 50 52   't1_config'(k PR
|   3696: 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 20 57 49   IMARY KEY, v) WI
|   3712: 54 48 4f 55 54 20 52 4f 57 49 44 5b 04 07 17 21   THOUT ROWID[...!
|   3728: 21 01 81 01 74 61 62 6c 65 74 31 5f 64 6f 63 73   !...tablet1_docs
|   3744: 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 04 43 52   izet1_docsize.CR
|   3760: 45 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 64   EATE TABLE 't1_d
|   3776: 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 54 45 47   ocsize'(id INTEG
|   3792: 45 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20   ER PRIMARY KEY, 
|   3808: 73 7a 20 42 4c 4f 42 29 69 03 07 17 19 19 01 81   sz BLOB)i.......
|   3824: 2d 74 61 62 6c 65 74 31 5f 69 64 78 74 31 5f 69   -tablet1_idxt1_i
|   3840: 64 78 03 43 52 45 41 54 45 20 54 41 42 4c 45 20   dx.CREATE TABLE 
|   3856: 27 74 31 5f 69 64 78 27 28 73 65 67 69 64 2c 20   't1_idx'(segid, 
|   3872: 74 65 72 6d 2c 20 70 67 6e 6f 2c 20 50 52 49 4d   term, pgno, PRIM
|   3888: 41 52 59 20 4b 45 59 28 73 65 67 69 64 2c 20 74   ARY KEY(segid, t
|   3904: 65 72 6d 29 29 20 57 49 54 48 4f 55 54 20 52 4f   erm)) WITHOUT RO
|   3920: 57 49 44 55 02 07 17 1b 1b 01 81 01 74 61 62 6c   WIDU........tabl
|   3936: 65 74 31 5f 64 61 74 61 74 31 5f 64 61 74 61 02   et1_datat1_data.
|   3952: 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 31   CREATE TABLE 't1
|   3968: 5f 64 61 74 61 27 28 69 64 20 49 4e 54 45 47 45   _data'(id INTEGE
|   3984: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62   R PRIMARY KEY, b
|   4000: 6c 6f 63 6b 20 42 4c 4f 42 29 54 01 07 17 11 11   lock BLOB)T.....
|   4016: 08 81 15 74 61 62 6c 65 74 31 74 31 43 52 45 41   ...tablet1t1CREA
|   4032: 54 45 20 56 49 52 54 55 41 4c 20 54 41 42 4c 45   TE VIRTUAL TABLE
|   4048: 20 74 31 20 55 53 49 4e 47 20 66 74 73 35 28 61    t1 USING fts5(a
|   4064: 2c 62 2c 70 72 65 66 69 78 3d 22 31 2c 32 2c 33   ,b,prefix=.1,2,3
|   4080: 2c 34 22 2c 20 63 6f 6e 74 65 6e 74 3d 22 22 29   ,4., content=..)
| page 2 offset 4096
|      0: 0d 0b 6a 00 37 09 4c 02 0f e7 09 4c 0f c6 0f a4   ..j.7.L....L....
|     16: 0f 88 0f 6d 0f 4b 0f 2c 0f 0e 0e ec 0e cd 0e ad   ...m.K.,........
|     32: 0e 8e 0e 6c 0e 4b 0e 29 0e 08 0d e6 0d c4 0d b5   ...l.K.)........
|     48: 0d 97 0d 76 0d 54 0d 31 0d 15 0c f3 0c d3 0c b5   ...v.T.1........
|     64: 0c 95 0c 73 0c 54 0c 32 0c 10 0b ee 0b cc 0b b0   ...s.T.2........
|     80: 0b 8d 0b 7e 0b 48 0b 2e 0b 0b 0a ef 00 00 00 00   ...~.H..........
|   2368: 00 00 00 00 00 00 00 00 00 00 00 00 15 0a 03 00   ................
|   2384: 30 00 00 00 01 01 03 35 00 03 01 11 12 02 01 12   0......5........
|   2400: 03 01 11 1c 8c 80 80 80 80 10 03 00 3e 00 00 00   ............>...
|   2416: 17 01 05 05 34 74 61 62 6c 03 02 03 01 04 77 68   ....4tabl.....wh
|   2432: 65 72 03 02 06 09 1b 8c 80 80 80 80 0f 03 00 3c   er.............<
|   2448: 00 00 00 16 05 34 66 74 73 34 03 02 02 01 04 6e   .....4fts4.....n
|   2464: 75 6d 62 03 06 01 04 09 1b 8c 80 80 80 80 0e 03   umb.............
|   2480: 00 3b ff f0 00 16 04 33 74 68 65 03 06 01 01 04   .;.....3the.....
|   2496: 01 03 77 68 65 03 02 04 04 0a 1b 8c 80 80 80 80   ..whe...........
|   2512: 0d 03 00 3c 00 00 00 16 04 33 6e 75 6d 03 06 01   ...<.....3num...
|   2528: 01 05 01 03 74 61 62 03 02 03 04 0a 19 8c 80 80   ....tab.........
|   2544: 80 80 0c 03 00 38 00 00 00 14 03 32 77 68 03 02   .....8.....2wh..
|   2560: 04 00 04 33 66 74 73 03 02 02 04 07 18 8c 80 80   ...3fts.........
|   2576: 80 80 0b 03 00 36 00 00 00 13 03 32 74 61 03 02   .....6.....2ta..
|   2592: 03 02 01 68 03 06 01 01 04 04 07 1b 8c 80 80 80   ...h............
|   2608: 80 0a 03 00 3c 00 00 00 16 03 32 6e 75 03 06 01   ....<.....2nu...
|   2624: 01 05 01 02 6f 66 03 06 01 01 06 04 09 19 8c 80   ....of..........
|   2640: 80 80 80 09 03 00 38 00 00 00 14 03 32 66 74 03   ......8.....2ft.
|   2656: 02 02 01 02 69 73 03 06 01 01 03 04 07 18 8c 80   ....is..........
|   2672: 80 80 80 08 03 00 36 00 00 00 13 02 31 74 03 08   ......6.....1t..
|   2688: 03 01 01 04 01 01 77 03 02 04 04 09 1a 8c 80 80   ......w.........
|   2704: 80 80 07 03 00 3a 00 00 00 15 02 31 6e 03 08 01   .....:.....1n...
|   2720: 01 02 05 01 00 6f 03 06 01 01 06 14 09 18 8c 80   .....o..........
|   2736: 80 80 80 06 03 00 36 00 00 00 03 04 02 31 66 03   ......6......1f.
|   2752: 02 02 01 01 69 03 06 01 01 03 04 f6 1c 8c 80 80   ....i...........
|   2768: 80 80 05 03 00 3e 00 00 00 17 04 30 74 68 65 03   .....>.....0the.
|   2784: f6 01 01 04 01 05 77 68 65 72 65 03 02 04 0a 15   ......where.....
|   2800: 8c 80 80 80 80 04 03 00 30 00 00 00 11 01 01 06   ........0.......
|   2816: 06 30 74 61 62 6c 65 0f 42 03 07 1c 8c 81 80 80   .0table.B.......
|   2832: 80 03 03 00 3e 00 00 00 17 07 30 6e 75 6d 62 65   ....>.....0numbe
|   2848: 72 03 06 01 01 05 01 02 6f 66 03 06 04 0d 13 8c   r.......of......
|   2864: 80 80 80 80 02 03 00 2c 00 00 00 0f 01 01 03 02   .......,........
|   2880: 30 6e 03 06 01 01 02 07 1b 8c 80 80 80 80 01 03   0n..............
|   2896: 00 3c 00 00 00 16 08 30 66 74 73 34 61 75 78 03   .<.....0fts4aux.
|   2912: 02 02 01 02 69 73 03 06 04 0c 00 00 00 14 2a 00   ....is........*.
|   2928: 00 00 01 01 02 24 00 02 01 01 12 02 01 12 08 88   .....$..........
|   2944: 80 80 80 80 12 03 00 16 00 00 00 05 02 1c 88 80   ................
|   2960: 80 80 80 11 03 00 3e 00 00 00 17 05 34 72 6f 77   ......>.....4row
|   2976: 73 02 06 01 01 05 01 04 74 68 65 72 02 02 04 0b   s.......ther....
|   2992: 15 88 80 80 80 80 10 03 00 30 00 00 00 11 02 01   .........0......
|   3008: 01 07 05 34 62 65 74 77 02 02 04 08 1b 88 80 80   ...4betw........
|   3024: 80 80 0f 03 00 3c 00 00 00 16 04 04 33 72 6f 77   .....<......3row
|   3040: 02 06 01 01 05 01 03 74 68 65 02 08 05 0a 1b 88   .......the......
|   3056: 80 80 80 80 0e 03 00 3c 00 00 00 16 01 01 02 04   .......<........
|   3072: 33 61 72 65 02 02 03 01 03 62 65 74 02 02 07 08   3are.....bet....
|   3088: 1b 88 80 80 80 80 0d 03 00 3c 00 00 00 16 13 32   .........<.....2
|   3104: 74 68 02 08 02 01 01 07 00 04 33 61 6e 64 02 06   th........3and..
|   3120: 04 0a 1b 88 80 80 80 80 0c 03 00 3c 00 00 00 16   ...........<....
|   3136: 03 32 69 6e 02 06 01 01 06 01 02 72 6f 02 06 01   .2in.......ro...
|   3152: 01 05 04 09 18 88 80 80 80 80 0b 03 00 36 00 00   .............6..
|   3168: 00 13 02 03 32 61 72 02 02 03 01 02 62 65 02 02   ....2ar.....be..
|   3184: 04 05 07 1b 88 80 80 80 80 0a 03 00 3c 00 94 50   ............<..P
|   3200: 16 02 31 74 02 08 02 01 01 07 00 03 32 61 6e 02   ..1t........2an.
|   3216: 06 01 01 04 09 19 88 80 80 80 80 09 03 00 38 00   ..............8.
|   3232: 00 00 14 02 31 6e 02 06 01 01 03 01 01 72 02 06   ....1n.......r..
|   3248: 01 01 05 04 08 17 88 80 80 80 80 08 03 00 34 00   ..............4.
|   3264: 00 00 12 02 31 62 02 02 04 01 01 69 02 06 01 01   ....1b.....i....
|   3280: 06 04 06 19 88 80 80 80 80 07 03 00 38 00 00 00   ............8...
|   3296: 14 04 02 31 32 02 02 05 01 01 61 02 08 03 01 01   ...12.....a.....
|   3312: 02 05 06 1b 88 80 80 80 80 06 03 00 3c 00 00 00   ............<...
|   3328: 16 06 30 74 68 65 72 65 02 02 02 00 02 31 31 02   ..0there.....11.
|   3344: 06 01 01 04 0a 15 88 80 80 80 80 05 03 00 30 00   ..............0.
|   3360: 00 00 11 01 01 05 04 30 74 68 65 02 06 01 01 07   .......0the.....
|   3376: 07 1c 88 80 80 80 80 04 03 00 3e 00 00 00 17 01   ..........>.....
|   3392: 01 06 02 30 6e 02 06 01 01 03 01 04 72 6f 77 73   ...0n.......rows
|   3408: 02 06 07 08 1b 88 80 80 80 80 03 03 00 3c 00 00   .............<..
|   3424: 00 16 08 30 62 65 74 77 65 65 6e 02 02 04 01 02   ...0between.....
|   3440: 69 6e 02 06 04 0c 1a 88 80 80 80 80 02 03 00 3a   in.............:
|   3456: 00 00 00 15 04 30 61 6e 64 02 06 01 01 02 02 02   .....0and.......
|   3472: 72 65 02 02 03 04 0a 17 88 80 80 80 80 01 03 00   re..............
|   3488: 34 00 00 00 12 02 30 31 02 06 01 01 04 01 01 32   4.....01.......2
|   3504: 02 02 05 04 08 08 84 80 80 80 80 12 03 00 16 00   ................
|   3520: 00 00 05 04 1b 84 80 80 80 80 11 03 00 3c 00 00   .............<..
|   3536: 00 16 05 34 74 61 62 6c 01 06 01 01 05 02 03 65   ...4tabl.......e
|   3552: 72 6d 01 02 04 0b 1b 84 80 80 80 80 10 03 00 3c   rm.............<
|   3568: 00 00 00 16 05 34 65 61 63 68 01 02 03 01 04 70   .....4each.....p
|   3584: 72 65 73 01 02 05 04 08 1a 84 80 80 80 80 0f 03   res.............
|   3600: 00 3a 00 00 00 15 04 33 74 65 72 01 02 04 02 02   .:.....3ter.....
|   3616: 68 65 01 06 01 01 03 04 08 1b 84 80 80 80 80 0e   he..............
|   3632: 03 00 3c 00 00 00 16 04 33 80 72 65 01 02 05 01   ..<.....3.re....
|   3648: 03 74 61 62 01 06 01 01 05 04 08 1a 84 80 80 80   .tab............
|   3664: 80 0d 03 00 3a 00 00 00 15 04 33 66 6f 72 01 02   ....:.....3for..
|   3680: 02 02 02 74 73 01 06 01 01 04 04 08 1b 84 80 80   ...ts...........
|   3696: 80 80 0c 03 00 3c 00 00 00 17 03 32 74 68 01 06   .....<.....2th..
|   3712: 01 01 03 00 04 33 65 61 63 01 02 03 04 09 18 84   .....3eac.......
|   3728: 80 80 80 80 0b 03 00 36 00 00 00 13 03 32 74 61   .......6.....2ta
|   3744: 01 06 01 01 05 02 01 65 01 02 04 04 09 19 84 80   .......e........
|   3760: 80 80 80 0a 03 00 38 00 00 00 14 03 32 69 6e 01   ......8.....2in.
|   3776: 06 01 01 02 01 02 70 72 01 02 05 04 09 18 84 80   ......pr........
|   3792: 80 80 80 09 03 00 36 00 00 00 13 03 32 66 6f 01   ......6.....2fo.
|   3808: 02 02 02 01 74 01 06 01 01 04 04 07 1b 84 80 80   ....t...........
|   3824: 80 80 08 03 00 3c 00 00 00 16 02 31 74 01 0a 04   .....<.....1t...
|   3840: 01 01 03 04 00 03 32 65 61 01 02 03 04 0a 17 84   ......2ea.......
|   3856: 80 80 80 80 07 03 00 34 00 00 00 12 02 31 69 01   .......4.....1i.
|   3872: 06 01 01 02 01 01 70 01 02 05 04 08 18 84 80 80   ......p.........
|   3888: 80 80 06 03 00 36 00 00 00 13 02 31 65 01 02 03   .....6.....1e...
|   3904: 01 01 66 01 08 02 01 01 04 04 06 1b 84 80 80 80   ..f.............
|   3920: 80 05 03 00 3c 00 00 00 16 05 30 74 65 72 6d 01   ....<.....0term.
|   3936: 02 04 02 02 68 65 01 06 01 01 03 04 09 14 84 80   ....he..........
|   3952: 80 80 80 04 03 00 2e 00 00 00 10 06 30 64 61 62   ............0dab
|   3968: 6c 65 01 06 01 01 05 04 15 84 80 80 80 80 03 03   le..............
|   3984: 00 30 00 00 00 11 02 08 30 70 72 65 73 65 6e 74   .0......0present
|   4000: 01 02 05 05 1b 84 80 80 80 80 02 03 00 3c 00 00   .............<..
|   4016: 00 16 04 30 66 74 73 01 06 01 01 04 01 02 69 6e   ...0fts.......in
|   4032: 01 06 01 01 04 0a 1a 84 80 80 80 80 01 03 00 3a   ...............:
|   4048: 00 00 00 15 05 30 65 61 63 68 01 02 03 01 13 66   .....0each.....f
|   4064: 6f 72 01 02 02 04 09 06 01 03 00 12 03 0b 0f 00   or..............
|   4080: 00 08 8c 80 80 80 80 11 03 00 16 00 00 00 05 04   ................
| page 3 offset 8192
|      0: 0a 00 00 00 32 0e 4f 00 0f fa 0f f1 0f e9 0f e1   ....2.O.........
|     16: 0f d8 0f d1 0f c9 0f c1 0f b9 0f b1 0f a9 0f a0   ................
|     32: 0f 98 0f 90 0f 87 0f 80 0f 78 0f 71 0f 68 0f 5f   .........x.q.h._
|     48: 0f 56 0f 4d 0f 41 0f 38 0f 2f 0f 26 0f 1d 0f 13   .V.M.A.8./.&....
|     64: 0f 0a 0f 01 0e f7 0e ee 0e e6 0e dd 0e d6 0e cd   ................
|     80: 0e c3 0e ba 0e 00 00 00 00 00 00 00 00 00 00 00   ................
|   3648: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08   ................
|   3664: 04 01 10 01 03 34 74 20 07 04 01 0e 01 03 34 1e   .....4t ......4.
|   3680: 09 04 01 12 01 03 33 74 68 1c 08 04 01 10 01 03   ......3th.......
|   3696: 33 6e 1a 08 04 01 10 01 03 32 77 18 08 04 01 10   3n.......2w.....
|   3712: 01 03 32 74 16 08 04 01 10 01 03 32 6e 14 07 04   ..2t.......2n...
|   3728: 01 0e 01 03 32 12 08 04 01 10 01 03 31 74 10 08   ....2.......1t..
|   3744: 04 01 10 01 03 31 6e 0e 07 04 01 0e 01 03 31 0c   .....1n.......1.
|   3760: 09 04 01 12 01 03 30 74 68 0a 08 04 01 10 01 03   ......0th.......
|   3776: 30 74 08 09 04 01 12 01 03 30 6e 75 06 08 04 01   0t.......0nu....
|   3792: 10 01 03 30 6e 04 06 04 01 0c 01 03 02 08 04 01   ...0n...........
|   3808: 10 01 02 34 72 22 07 04 01 0e 01 02 34 20 08 04   ...4r.......4 ..
|   3824: 01 10 01 02 33 72 1e 09 04 01 12 01 02 33 61 72   ....3r.......3ar
|   3840: 1c 08 04 01 10 01 02 32 74 1a 08 04 01 10 01 02   .......2t.......
|   3856: 32 69 18 09 04 01 12 01 02 32 61 72 16 08 04 01   2i.......2ar....
|   3872: 10 01 02 31 74 14 08 04 01 10 01 02 31 6e 12 08   ...1t.......1n..
|   3888: 04 01 10 01 02 31 62 10 08 04 01 10 01 02 31 32   .....1b.......12
|   3904: 0e 0b 04 01 16 01 02 30 74 68 65 72 0c 08 04 01   .......0ther....
|   3920: 10 01 02 30 74 0a 08 04 01 10 01 02 30 6e 08 08   ...0t.......0n..
|   3936: 14 01 10 01 02 30 62 06 08 04 01 10 01 02 30 61   .....0b.......0a
|   3952: 04 06 04 01 0c 01 02 02 07 04 09 10 01 34 74 22   .............4t.
|   3968: 06 04 09 0e 01 34 20 08 04 09 12 01 33 74 65 1e   .....4 .....3te.
|   3984: 07 04 09 10 01 33 70 1c 07 04 09 10 01 33 66 1a   .....3p......3f.
|   4000: 08 04 09 12 01 32 74 68 18 07 04 09 10 01 32 74   .....2th......2t
|   4016: 16 01 64 09 10 01 32 69 14 07 04 09 10 01 32 66   ..d...2i......2f
|   4032: 12 07 04 09 10 01 31 74 10 07 04 09 10 01 31 69   ......1t......1i
|   4048: 0e 06 04 09 0e 01 31 0c 08 04 09 12 01 30 74 65   ......1......0te
|   4064: 0a 06 04 09 10 01 30 74 08 07 04 09 10 01 30 70   ......0t......0p
|   4080: 06 08 04 09 12 00 00 00 00 00 00 00 00 00 00 00   ................
| page 4 offset 12288
|   4064: 00 00 00 00 00 00 00 00 00 00 00 05 03 03 00 10   ................
|   4080: 03 05 05 02 03 00 10 04 06 05 01 03 00 10 04 04   ................
| page 5 offset 16384
|      0: 0a 00 00 00 02 0f eb 00 0f eb 0f f4 00 00 00 00   ................
|   4064: 00 00 00 00 00 00 00 00 00 00 00 08 03 15 01 70   ...............p
|   4080: 67 73 7a 18 0b 03 1b 01 76 65 72 73 69 6f 6e 04   gsz.....version.
| page 6 offset 20480
|      0: 0d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
|   4080: 00 00 03 03 02 01 03 03 02 02 01 00 00 00 00 00   ................
| end sql047467.txt.db
}]} {}

do_catchsql_test 2.1 {
SELECT * FROM t1('R*R*R*R*') WHERE (a,b)<=(current_date,0) ORDER BY rowid DESC;
} {1 {database disk image is malformed}}


sqlite3_fts5_may_be_corrupt 0
finish_test

Changes to ext/fts5/test/fts5vocab2.test.
251
252
253
254
255
256
257


























258
259
260
    }
  } msg] $msg
} {1 {query aborted}}

do_execsql_test 5.2 {
  SELECT * FROM t1
} {one two three four five}


























finish_test









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



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
    }
  } msg] $msg
} {1 {query aborted}}

do_execsql_test 5.2 {
  SELECT * FROM t1
} {one two three four five}

#-------------------------------------------------------------------------
# Check that the fts5 table cannot be written while there are vocab 
# cursors open.
reset_db
do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE t1 USING fts5(a);
  CREATE VIRTUAL TABLE v1 USING fts5vocab(t1, instance);
  WITH s(i) AS (
    VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<10000
  )
  INSERT INTO t1 SELECT 
    'State Emergency Service (SES), Rural Fire Service (RFS) and Volunteers'
  FROM s;
}

do_catchsql_test 5.1 {
  INSERT INTO t1 SELECT rowid FROM v1
} {1 {query aborted}}

do_catchsql_test 5.2 {
  DELETE FROM t1 WHERE rowid>100;
  INSERT INTO t1 SELECT randomblob(3000) FROM v1
} {1 {query aborted}}


finish_test


Changes to ext/misc/fileio.c.
68
69
70
71
72
73
74





75
76
77
78
79
80
81
**            symlink, a text value containing the text of the link. For a
**            directory, NULL.
**
**   If a non-NULL value is specified for the optional $dir parameter and
**   $path is a relative path, then $path is interpreted relative to $dir. 
**   And the paths returned in the "name" column of the table are also 
**   relative to directory $dir.





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








>
>
>
>
>







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
**            symlink, a text value containing the text of the link. For a
**            directory, NULL.
**
**   If a non-NULL value is specified for the optional $dir parameter and
**   $path is a relative path, then $path is interpreted relative to $dir. 
**   And the paths returned in the "name" column of the table are also 
**   relative to directory $dir.
**
** Notes on building this extension for Windows:
**   Unless linked statically with the SQLite library, a preprocessor
**   symbol, FILEIO_WIN32_DLL, must be #define'd to create a stand-alone
**   DLL form of this extension for WIN32. See its use below for details.
*/
#include "sqlite3ext.h"
SQLITE_EXTENSION_INIT1
#include <stdio.h>
#include <string.h>
#include <assert.h>

221
222
223
224
225
226
227
















228
229
230
231
232
233
234

  fileIntervals.LowPart = pFileTime->dwLowDateTime;
  fileIntervals.HighPart = pFileTime->dwHighDateTime;

  return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
}

















/*
** This function attempts to normalize the time values found in the stat()
** buffer to UTC.  This is necessary on Win32, where the runtime library
** appears to return these values as local times.
*/
static void statTimesToUtc(
  const char *zPath,







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







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

  fileIntervals.LowPart = pFileTime->dwLowDateTime;
  fileIntervals.HighPart = pFileTime->dwHighDateTime;

  return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
}


#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
#  /* To allow a standalone DLL, use this next replacement function: */
#  undef sqlite3_win32_utf8_to_unicode
#  define sqlite3_win32_utf8_to_unicode utf8_to_utf16
#
LPWSTR utf8_to_utf16(const char *z){
  int nAllot = MultiByteToWideChar(CP_UTF8, 0, z, -1, NULL, 0);
  LPWSTR rv = sqlite3_malloc(nAllot * sizeof(WCHAR));
  if( rv!=0 && 0 < MultiByteToWideChar(CP_UTF8, 0, z, -1, rv, nAllot) )
    return rv;
  sqlite3_free(rv);
  return 0;
}
#endif

/*
** This function attempts to normalize the time values found in the stat()
** buffer to UTC.  This is necessary on Win32, where the runtime library
** appears to return these values as local times.
*/
static void statTimesToUtc(
  const char *zPath,
994
995
996
997
998
999
1000








                                 lsModeFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = fsdirRegister(db);
  }
  return rc;
}















>
>
>
>
>
>
>
>
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
                                 lsModeFunc, 0, 0);
  }
  if( rc==SQLITE_OK ){
    rc = fsdirRegister(db);
  }
  return rc;
}

#if defined(FILEIO_WIN32_DLL) && (defined(_WIN32) || defined(WIN32))
/* To allow a standalone DLL, make test_windirent.c use the same
 * redefined SQLite API calls as the above extension code does.
 * Just pull in this .c to accomplish this. As a beneficial side
 * effect, this extension becomes a single translation unit. */
#  include "test_windirent.c"
#endif
Changes to ext/misc/ieee754.c.
190
191
192
193
194
195
196



197

198
199
200
201
202
203
204
    while( m!=0 && ((m>>32)&0xfff00000)==0 ){
      m <<= 1;
      e--;
    }
    e += 1075;
    if( e<=0 ){
      /* Subnormal */



      m >>= 1-e;

      e = 0;
    }else if( e>0x7ff ){
      e = 0x7ff;
    }
    a = m & ((((sqlite3_int64)1)<<52)-1);
    a |= e<<52;
    if( isNeg ) a |= ((sqlite3_uint64)1)<<63;







>
>
>
|
>







190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
    while( m!=0 && ((m>>32)&0xfff00000)==0 ){
      m <<= 1;
      e--;
    }
    e += 1075;
    if( e<=0 ){
      /* Subnormal */
      if( 1-e >= 64 ){
        m = 0;
      }else{
        m >>= 1-e;
      }
      e = 0;
    }else if( e>0x7ff ){
      e = 0x7ff;
    }
    a = m & ((((sqlite3_int64)1)<<52)-1);
    a |= e<<52;
    if( isNeg ) a |= ((sqlite3_uint64)1)<<63;
Changes to ext/misc/json1.c.
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
        }
        i = i*10 + v;
      }
      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
      sqlite3_result_int64(pCtx, i);
      int_done:
      break;
      int_as_real: i=0; /* no break */ deliberate_fall_through
    }
    case JSON_REAL: {
      double r;
#ifdef SQLITE_AMALGAMATION
      const char *z = pNode->u.zJContent;
      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
#else







|







601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
        }
        i = i*10 + v;
      }
      if( pNode->u.zJContent[0]=='-' ){ i = -i; }
      sqlite3_result_int64(pCtx, i);
      int_done:
      break;
      int_as_real: ; /* no break */ deliberate_fall_through
    }
    case JSON_REAL: {
      double r;
#ifdef SQLITE_AMALGAMATION
      const char *z = pNode->u.zJContent;
      sqlite3AtoF(z, &r, sqlite3Strlen30(z), SQLITE_UTF8);
#else
Changes to ext/misc/series.c.
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( sqlite3_libversion_number()<3008012 ){
    *pzErrMsg = sqlite3_mprintf(
        "generate_series() requires SQLite 3.8.12 or later");
    return SQLITE_ERROR;
  }
  rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
#endif
  return rc;







|







444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
  sqlite3 *db, 
  char **pzErrMsg, 
  const sqlite3_api_routines *pApi
){
  int rc = SQLITE_OK;
  SQLITE_EXTENSION_INIT2(pApi);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  if( sqlite3_libversion_number()<3008012 && pzErrMsg!=0 ){
    *pzErrMsg = sqlite3_mprintf(
        "generate_series() requires SQLite 3.8.12 or later");
    return SQLITE_ERROR;
  }
  rc = sqlite3_create_module(db, "generate_series", &seriesModule, 0);
#endif
  return rc;
Changes to ext/misc/zipfile.c.
557
558
559
560
561
562
563

564
565
566
567
568
569
570
  return (aBuf[1] << 8) + aBuf[0];
}

/*
** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
*/
static u32 zipfileGetU32(const u8 *aBuf){

  return ((u32)(aBuf[3]) << 24)
       + ((u32)(aBuf[2]) << 16)
       + ((u32)(aBuf[1]) <<  8)
       + ((u32)(aBuf[0]) <<  0);
}

/*







>







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
  return (aBuf[1] << 8) + aBuf[0];
}

/*
** Read and return a 32-bit little-endian unsigned integer from buffer aBuf.
*/
static u32 zipfileGetU32(const u8 *aBuf){
  if( aBuf==0 ) return 0;
  return ((u32)(aBuf[3]) << 24)
       + ((u32)(aBuf[2]) << 16)
       + ((u32)(aBuf[1]) <<  8)
       + ((u32)(aBuf[0]) <<  0);
}

/*
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
      ZipfileLFH lfh;
      if( pFile ){
        rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
      }else{
        aRead = (u8*)&aBlob[pNew->cds.iOffset];
      }

      rc = zipfileReadLFH(aRead, &lfh);
      if( rc==SQLITE_OK ){
        pNew->iDataOff =  pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
        pNew->iDataOff += lfh.nFile + lfh.nExtra;
        if( aBlob && pNew->cds.szCompressed ){
          pNew->aData = &pNew->aExtra[nExtra];
          memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
        }







|







860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
      ZipfileLFH lfh;
      if( pFile ){
        rc = zipfileReadData(pFile, aRead, szFix, pNew->cds.iOffset, pzErr);
      }else{
        aRead = (u8*)&aBlob[pNew->cds.iOffset];
      }

      if( rc==SQLITE_OK ) rc = zipfileReadLFH(aRead, &lfh);
      if( rc==SQLITE_OK ){
        pNew->iDataOff =  pNew->cds.iOffset + ZIPFILE_LFH_FIXED_SZ;
        pNew->iDataOff += lfh.nFile + lfh.nExtra;
        if( aBlob && pNew->cds.szCompressed ){
          pNew->aData = &pNew->aExtra[nExtra];
          memcpy(pNew->aData, &aBlob[pNew->iDataOff], pNew->cds.szCompressed);
        }
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
  FILE *pFile,                    /* Read from this file if aBlob==0 */
  ZipfileEOCD *pEOCD              /* Object to populate */
){
  u8 *aRead = pTab->aBuffer;      /* Temporary buffer */
  int nRead;                      /* Bytes to read from file */
  int rc = SQLITE_OK;


  if( aBlob==0 ){
    i64 iOff;                     /* Offset to read from */
    i64 szFile;                   /* Total size of file in bytes */
    fseek(pFile, 0, SEEK_END);
    szFile = (i64)ftell(pFile);
    if( szFile==0 ){
      memset(pEOCD, 0, sizeof(ZipfileEOCD));
      return SQLITE_OK;
    }
    nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
    iOff = szFile - nRead;
    rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
  }else{
    nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));







>






<







1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149

1150
1151
1152
1153
1154
1155
1156
  FILE *pFile,                    /* Read from this file if aBlob==0 */
  ZipfileEOCD *pEOCD              /* Object to populate */
){
  u8 *aRead = pTab->aBuffer;      /* Temporary buffer */
  int nRead;                      /* Bytes to read from file */
  int rc = SQLITE_OK;

  memset(pEOCD, 0, sizeof(ZipfileEOCD));
  if( aBlob==0 ){
    i64 iOff;                     /* Offset to read from */
    i64 szFile;                   /* Total size of file in bytes */
    fseek(pFile, 0, SEEK_END);
    szFile = (i64)ftell(pFile);
    if( szFile==0 ){

      return SQLITE_OK;
    }
    nRead = (int)(MIN(szFile, ZIPFILE_BUFFER_SIZE));
    iOff = szFile - nRead;
    rc = zipfileReadData(pFile, aRead, nRead, iOff, &pTab->base.zErrMsg);
  }else{
    nRead = (int)(MIN(nBlob, ZIPFILE_BUFFER_SIZE));
Changes to ext/rtree/rtree.c.
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
  #include "sqlite3ext.h"
  SQLITE_EXTENSION_INIT1
#else
  #include "sqlite3.h"
#endif
int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */





#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
# undef NDEBUG
#endif









#endif


#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

/*  The following macro is used to suppress compiler warnings.







>
>
>
>
|












>
>
>
>
>
>
>
>
>

>







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
  #include "sqlite3ext.h"
  SQLITE_EXTENSION_INIT1
#else
  #include "sqlite3.h"
#endif
int sqlite3GetToken(const unsigned char*,int*); /* In the SQLite core */

/*
** If building separately, we will need some setup that is normally
** found in sqliteInt.h
*/
#if !defined(SQLITE_AMALGAMATION)
#include "sqlite3rtree.h"
typedef sqlite3_int64 i64;
typedef sqlite3_uint64 u64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
#if !defined(NDEBUG) && !defined(SQLITE_DEBUG)
# define NDEBUG 1
#endif
#if defined(NDEBUG) && defined(SQLITE_DEBUG)
# undef NDEBUG
#endif
#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_MUTATION_TEST)
# define ALWAYS(X)      (1)
# define NEVER(X)       (0)
#elif !defined(NDEBUG)
# define ALWAYS(X)      ((X)?1:(assert(0),0))
# define NEVER(X)       ((X)?(assert(0),1):0)
#else
# define ALWAYS(X)      (X)
# define NEVER(X)       (X)
#endif
#endif /* !defined(SQLITE_AMALGAMATION) */

#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>

/*  The following macro is used to suppress compiler warnings.
131
132
133
134
135
136
137

138

139
140
141
142
143
144
145
  int iNodeSize;              /* Size in bytes of each node in the node table */
  u8 nDim;                    /* Number of dimensions */
  u8 nDim2;                   /* Twice the number of dimensions */
  u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
  u8 nBytesPerCell;           /* Bytes consumed per cell */
  u8 inWrTrans;               /* True if inside write transaction */
  u8 nAux;                    /* # of auxiliary columns in %_rowid */

  u8 nAuxNotNull;             /* Number of initial not-null aux columns */

#ifdef SQLITE_DEBUG
  u8 bCorrupt;                /* Shadow table corruption detected */
#endif
  int iDepth;                 /* Current depth of the r-tree structure */
  char *zDb;                  /* Name of database containing r-tree table */
  char *zName;                /* Name of r-tree table */ 
  u32 nBusy;                  /* Current number of users of this structure */







>

>







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
  int iNodeSize;              /* Size in bytes of each node in the node table */
  u8 nDim;                    /* Number of dimensions */
  u8 nDim2;                   /* Twice the number of dimensions */
  u8 eCoordType;              /* RTREE_COORD_REAL32 or RTREE_COORD_INT32 */
  u8 nBytesPerCell;           /* Bytes consumed per cell */
  u8 inWrTrans;               /* True if inside write transaction */
  u8 nAux;                    /* # of auxiliary columns in %_rowid */
#ifdef SQLITE_ENABLE_GEOPOLY
  u8 nAuxNotNull;             /* Number of initial not-null aux columns */
#endif
#ifdef SQLITE_DEBUG
  u8 bCorrupt;                /* Shadow table corruption detected */
#endif
  int iDepth;                 /* Current depth of the r-tree structure */
  char *zDb;                  /* Name of database containing r-tree table */
  char *zName;                /* Name of r-tree table */ 
  u32 nBusy;                  /* Current number of users of this structure */
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
  if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
    sqlite3_blob *pBlob = pRtree->pNodeBlob;
    pRtree->pNodeBlob = 0;
    sqlite3_blob_close(pBlob);
  }
}

/*
** Check to see if pNode is the same as pParent or any of the parents
** of pParent.
*/
static int nodeInParentChain(const RtreeNode *pNode, const RtreeNode *pParent){
  do{
    if( pNode==pParent ) return 1;
    pParent = pParent->pParent;
  }while( pParent );
  return 0;
}

/*
** Obtain a reference to an r-tree node.
*/
static int nodeAcquire(
  Rtree *pRtree,             /* R-tree structure */
  i64 iNode,                 /* Node number to load */
  RtreeNode *pParent,        /* Either the parent node or NULL */
  RtreeNode **ppNode         /* OUT: Acquired node */
){
  int rc = SQLITE_OK;
  RtreeNode *pNode = 0;

  /* Check if the requested node is already in the hash table. If so,
  ** increase its reference count and return it.
  */
  if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){
    if( pParent && !pNode->pParent ){
      if( nodeInParentChain(pNode, pParent) ){
        RTREE_IS_CORRUPT(pRtree);
        return SQLITE_CORRUPT_VTAB;
      }
      pParent->nRef++;
      pNode->pParent = pParent;
    }else if( pParent && pNode->pParent && pParent!=pNode->pParent ){
      RTREE_IS_CORRUPT(pRtree);
      return SQLITE_CORRUPT_VTAB;
    }
    pNode->nRef++;
    *ppNode = pNode;
    return SQLITE_OK;
  }







<
<
<
<
<
<
<
<
<
<
<
<
















<
<
<
<
<
<
<
|







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
  if( pRtree->pNodeBlob && pRtree->inWrTrans==0 && pRtree->nCursor==0 ){
    sqlite3_blob *pBlob = pRtree->pNodeBlob;
    pRtree->pNodeBlob = 0;
    sqlite3_blob_close(pBlob);
  }
}













/*
** Obtain a reference to an r-tree node.
*/
static int nodeAcquire(
  Rtree *pRtree,             /* R-tree structure */
  i64 iNode,                 /* Node number to load */
  RtreeNode *pParent,        /* Either the parent node or NULL */
  RtreeNode **ppNode         /* OUT: Acquired node */
){
  int rc = SQLITE_OK;
  RtreeNode *pNode = 0;

  /* Check if the requested node is already in the hash table. If so,
  ** increase its reference count and return it.
  */
  if( (pNode = nodeHashLookup(pRtree, iNode))!=0 ){







    if( pParent && pParent!=pNode->pParent ){
      RTREE_IS_CORRUPT(pRtree);
      return SQLITE_CORRUPT_VTAB;
    }
    pNode->nRef++;
    *ppNode = pNode;
    return SQLITE_OK;
  }
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769

  /* If the root node was just loaded, set pRtree->iDepth to the height
  ** of the r-tree structure. A height of zero means all data is stored on
  ** the root node. A height of one means the children of the root node
  ** are the leaves, and so on. If the depth as specified on the root node
  ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
  */
  if( pNode && rc==SQLITE_OK && iNode==1 ){
    pRtree->iDepth = readInt16(pNode->zData);
    if( pRtree->iDepth>RTREE_MAX_DEPTH ){
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
    }
  }








|







752
753
754
755
756
757
758
759
760
761
762
763
764
765
766

  /* If the root node was just loaded, set pRtree->iDepth to the height
  ** of the r-tree structure. A height of zero means all data is stored on
  ** the root node. A height of one means the children of the root node
  ** are the leaves, and so on. If the depth as specified on the root node
  ** is greater than RTREE_MAX_DEPTH, the r-tree structure must be corrupt.
  */
  if( rc==SQLITE_OK && pNode && iNode==1 ){
    pRtree->iDepth = readInt16(pNode->zData);
    if( pRtree->iDepth>RTREE_MAX_DEPTH ){
      rc = SQLITE_CORRUPT_VTAB;
      RTREE_IS_CORRUPT(pRtree);
    }
  }

1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372

1373
1374
1375
1376
1377
1378
1379

/*
** Return the index of the cell containing a pointer to node pNode
** in its parent. If pNode is the root node, return -1.
*/
static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){
  RtreeNode *pParent = pNode->pParent;
  if( pParent ){
    return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex);
  }
  *piIndex = -1;
  return SQLITE_OK;

}

/*
** Compare two search points.  Return negative, zero, or positive if the first
** is less than, equal to, or greater than the second.
**
** The rScore is the primary key.  Smaller rScore values come first.







|

|
|
|
>







1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377

/*
** Return the index of the cell containing a pointer to node pNode
** in its parent. If pNode is the root node, return -1.
*/
static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode, int *piIndex){
  RtreeNode *pParent = pNode->pParent;
  if( ALWAYS(pParent) ){
    return nodeRowidIndex(pRtree, pParent, pNode->iNode, piIndex);
  }else{
    *piIndex = -1;
    return SQLITE_OK;
  }
}

/*
** Compare two search points.  Return negative, zero, or positive if the first
** is less than, equal to, or greater than the second.
**
** The rScore is the primary key.  Smaller rScore values come first.
1488
1489
1490
1491
1492
1493
1494

1495
1496
1497
1498
1499
1500
1501
1502
   || (pFirst->rScore==rScore && pFirst->iLevel>iLevel)
  ){
    if( pCur->bPoint ){
      int ii;
      pNew = rtreeEnqueue(pCur, rScore, iLevel);
      if( pNew==0 ) return 0;
      ii = (int)(pNew - pCur->aPoint) + 1;

      if( ii<RTREE_CACHE_SZ ){
        assert( pCur->aNode[ii]==0 );
        pCur->aNode[ii] = pCur->aNode[0];
      }else{
        nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]);
      }
      pCur->aNode[0] = 0;
      *pNew = pCur->sPoint;







>
|







1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
   || (pFirst->rScore==rScore && pFirst->iLevel>iLevel)
  ){
    if( pCur->bPoint ){
      int ii;
      pNew = rtreeEnqueue(pCur, rScore, iLevel);
      if( pNew==0 ) return 0;
      ii = (int)(pNew - pCur->aPoint) + 1;
      assert( ii==1 );
      if( ALWAYS(ii<RTREE_CACHE_SZ) ){
        assert( pCur->aNode[ii]==0 );
        pCur->aNode[ii] = pCur->aNode[0];
      }else{
        nodeRelease(RTREE_OF_CURSOR(pCur), pCur->aNode[0]);
      }
      pCur->aNode[0] = 0;
      *pNew = pCur->sPoint;
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
  if( p->aNode[i] ){
    nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]);
    p->aNode[i] = 0;
  }
  if( p->bPoint ){
    p->anQueue[p->sPoint.iLevel]--;
    p->bPoint = 0;
  }else if( p->nPoint ){
    p->anQueue[p->aPoint[0].iLevel]--;
    n = --p->nPoint;
    p->aPoint[0] = p->aPoint[n];
    if( n<RTREE_CACHE_SZ-1 ){
      p->aNode[1] = p->aNode[n+1];
      p->aNode[n+1] = 0;
    }







|







1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
  if( p->aNode[i] ){
    nodeRelease(RTREE_OF_CURSOR(p), p->aNode[i]);
    p->aNode[i] = 0;
  }
  if( p->bPoint ){
    p->anQueue[p->sPoint.iLevel]--;
    p->bPoint = 0;
  }else if( ALWAYS(p->nPoint) ){
    p->anQueue[p->aPoint[0].iLevel]--;
    n = --p->nPoint;
    p->aPoint[0] = p->aPoint[n];
    if( n<RTREE_CACHE_SZ-1 ){
      p->aNode[1] = p->aNode[n+1];
      p->aNode[n+1] = 0;
    }
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
** Rtree virtual table module xRowid method.
*/
static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
  RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
  int rc = SQLITE_OK;
  RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
  if( rc==SQLITE_OK && p ){
    *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell);
  }
  return rc;
}

/* 
** Rtree virtual table module xColumn method.
*/
static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  Rtree *pRtree = (Rtree *)cur->pVtab;
  RtreeCursor *pCsr = (RtreeCursor *)cur;
  RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
  RtreeCoord c;
  int rc = SQLITE_OK;
  RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);

  if( rc ) return rc;
  if( p==0 ) return SQLITE_OK;
  if( i==0 ){
    sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
  }else if( i<=pRtree->nDim2 ){
    nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
#ifndef SQLITE_RTREE_INT_ONLY
    if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
      sqlite3_result_double(ctx, c.f);







|

















|







1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
** Rtree virtual table module xRowid method.
*/
static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
  RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
  int rc = SQLITE_OK;
  RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);
  if( rc==SQLITE_OK && ALWAYS(p) ){
    *pRowid = nodeGetRowid(RTREE_OF_CURSOR(pCsr), pNode, p->iCell);
  }
  return rc;
}

/* 
** Rtree virtual table module xColumn method.
*/
static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
  Rtree *pRtree = (Rtree *)cur->pVtab;
  RtreeCursor *pCsr = (RtreeCursor *)cur;
  RtreeSearchPoint *p = rtreeSearchPointFirst(pCsr);
  RtreeCoord c;
  int rc = SQLITE_OK;
  RtreeNode *pNode = rtreeNodeOfFirstSearchPoint(pCsr, &rc);

  if( rc ) return rc;
  if( NEVER(p==0) ) return SQLITE_OK;
  if( i==0 ){
    sqlite3_result_int64(ctx, nodeGetRowid(pRtree, pNode, p->iCell));
  }else if( i<=pRtree->nDim2 ){
    nodeGetCoord(pRtree, pNode, p->iCell, i-1, &c);
#ifndef SQLITE_RTREE_INT_ONLY
    if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
      sqlite3_result_double(ctx, c.f);
1907
1908
1909
1910
1911
1912
1913

1914

1915

1916
1917
1918
1919
1920
1921
1922
            }
          }
        }
      }
    }
    if( rc==SQLITE_OK ){
      RtreeSearchPoint *pNew;

      pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));

      if( pNew==0 ) return SQLITE_NOMEM;

      pNew->id = 1;
      pNew->iCell = 0;
      pNew->eWithin = PARTLY_WITHIN;
      assert( pCsr->bPoint==1 );
      pCsr->aNode[0] = pRoot;
      pRoot = 0;
      RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:");







>

>
|
>







1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
            }
          }
        }
      }
    }
    if( rc==SQLITE_OK ){
      RtreeSearchPoint *pNew;
      assert( pCsr->bPoint==0 );  /* Due to the resetCursor() call above */
      pNew = rtreeSearchPointNew(pCsr, RTREE_ZERO, (u8)(pRtree->iDepth+1));
      if( NEVER(pNew==0) ){       /* Because pCsr->bPoint was FALSE */
        return SQLITE_NOMEM;
      }
      pNew->id = 1;
      pNew->iCell = 0;
      pNew->eWithin = PARTLY_WITHIN;
      assert( pCsr->bPoint==1 );
      pCsr->aNode[0] = pRoot;
      pRoot = 0;
      RTREE_QUEUE_TRACE(pCsr, "PUSH-Fm:");
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
  }

  assert( pIdxInfo->idxStr==0 );
  for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];

    if( bMatch==0 && p->usable 
     && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ 
    ){
      /* We have an equality constraint on the rowid. Use strategy 1. */
      int jj;
      for(jj=0; jj<ii; jj++){
        pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
        pIdxInfo->aConstraintUsage[jj].omit = 0;
      }







|







1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
  }

  assert( pIdxInfo->idxStr==0 );
  for(ii=0; ii<pIdxInfo->nConstraint && iIdx<(int)(sizeof(zIdxStr)-1); ii++){
    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];

    if( bMatch==0 && p->usable 
     && p->iColumn<=0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ 
    ){
      /* We have an equality constraint on the rowid. Use strategy 1. */
      int jj;
      for(jj=0; jj<ii; jj++){
        pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
        pIdxInfo->aConstraintUsage[jj].omit = 0;
      }
2238
2239
2240
2241
2242
2243
2244

2245
2246
2247
2248
2249





2250

2251
2252
2253
2254
2255
2256
2257
static int AdjustTree(
  Rtree *pRtree,                    /* Rtree table */
  RtreeNode *pNode,                 /* Adjust ancestry of this node. */
  RtreeCell *pCell                  /* This cell was just inserted */
){
  RtreeNode *p = pNode;
  int cnt = 0;

  while( p->pParent ){
    RtreeNode *pParent = p->pParent;
    RtreeCell cell;
    int iCell;






    if( (++cnt)>1000 || nodeParentIndex(pRtree, p, &iCell)  ){

      RTREE_IS_CORRUPT(pRtree);
      return SQLITE_CORRUPT_VTAB;
    }

    nodeGetCell(pRtree, pParent, iCell, &cell);
    if( !cellContains(pRtree, &cell, pCell) ){
      cellUnion(pRtree, &cell, pCell);







>





>
>
>
>
>
|
>







2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
static int AdjustTree(
  Rtree *pRtree,                    /* Rtree table */
  RtreeNode *pNode,                 /* Adjust ancestry of this node. */
  RtreeCell *pCell                  /* This cell was just inserted */
){
  RtreeNode *p = pNode;
  int cnt = 0;
  int rc;
  while( p->pParent ){
    RtreeNode *pParent = p->pParent;
    RtreeCell cell;
    int iCell;

    cnt++;
    if( NEVER(cnt>100) ){
      RTREE_IS_CORRUPT(pRtree);
      return SQLITE_CORRUPT_VTAB;
    }
    rc = nodeParentIndex(pRtree, p, &iCell);
    if( NEVER(rc!=SQLITE_OK) ){
      RTREE_IS_CORRUPT(pRtree);
      return SQLITE_CORRUPT_VTAB;
    }

    nodeGetCell(pRtree, pParent, iCell, &cell);
    if( !cellContains(pRtree, &cell, pCell) ){
      cellUnion(pRtree, &cell, pCell);
2532
2533
2534
2535
2536
2537
2538




2539
2540
2541
2542
2543
2544
2545
  RtreeNode *pNode, 
  int iHeight
){
  int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64);
  xSetMapping = ((iHeight==0)?rowidWrite:parentWrite);
  if( iHeight>0 ){
    RtreeNode *pChild = nodeHashLookup(pRtree, iRowid);




    if( pChild ){
      nodeRelease(pRtree, pChild->pParent);
      nodeReference(pNode);
      pChild->pParent = pNode;
    }
  }
  return xSetMapping(pRtree, iRowid, pNode->iNode);







>
>
>
>







2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
  RtreeNode *pNode, 
  int iHeight
){
  int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64);
  xSetMapping = ((iHeight==0)?rowidWrite:parentWrite);
  if( iHeight>0 ){
    RtreeNode *pChild = nodeHashLookup(pRtree, iRowid);
    RtreeNode *p;
    for(p=pNode; p; p=p->pParent){
      if( p==pChild ) return SQLITE_CORRUPT_VTAB;
    }
    if( pChild ){
      nodeRelease(pRtree, pChild->pParent);
      nodeReference(pNode);
      pChild->pParent = pNode;
    }
  }
  return xSetMapping(pRtree, iRowid, pNode->iNode);
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636

2637
2638
2639
2640
2641
2642
2643
2644
2645
    if( rc!=SQLITE_OK ){
      goto splitnode_out;
    }
  }else{
    RtreeNode *pParent = pLeft->pParent;
    int iCell;
    rc = nodeParentIndex(pRtree, pLeft, &iCell);
    if( rc==SQLITE_OK ){
      nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
      rc = AdjustTree(pRtree, pParent, &leftbbox);

    }
    if( rc!=SQLITE_OK ){
      goto splitnode_out;
    }
  }
  if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){
    goto splitnode_out;
  }








|


>

|







2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
    if( rc!=SQLITE_OK ){
      goto splitnode_out;
    }
  }else{
    RtreeNode *pParent = pLeft->pParent;
    int iCell;
    rc = nodeParentIndex(pRtree, pLeft, &iCell);
    if( ALWAYS(rc==SQLITE_OK) ){
      nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
      rc = AdjustTree(pRtree, pParent, &leftbbox);
      assert( rc==SQLITE_OK );
    }
    if( NEVER(rc!=SQLITE_OK) ){
      goto splitnode_out;
    }
  }
  if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){
    goto splitnode_out;
  }

2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
      /* Before setting pChild->pParent, test that we are not creating a
      ** loop of references (as we would if, say, pChild==pParent). We don't
      ** want to do this as it leads to a memory leak when trying to delete
      ** the referenced counted node structures.
      */
      iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
      for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent);
      if( !pTest ){
        rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent);
      }
    }
    rc = sqlite3_reset(pRtree->pReadParent);
    if( rc==SQLITE_OK ) rc = rc2;
    if( rc==SQLITE_OK && !pChild->pParent ){
      RTREE_IS_CORRUPT(pRtree);







|







2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
      /* Before setting pChild->pParent, test that we are not creating a
      ** loop of references (as we would if, say, pChild==pParent). We don't
      ** want to do this as it leads to a memory leak when trying to delete
      ** the referenced counted node structures.
      */
      iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
      for(pTest=pLeaf; pTest && pTest->iNode!=iNode; pTest=pTest->pParent);
      if( pTest==0 ){
        rc2 = nodeAcquire(pRtree, iNode, 0, &pChild->pParent);
      }
    }
    rc = sqlite3_reset(pRtree->pReadParent);
    if( rc==SQLITE_OK ) rc = rc2;
    if( rc==SQLITE_OK && !pChild->pParent ){
      RTREE_IS_CORRUPT(pRtree);
2737
2738
2739
2740
2741
2742
2743

2744
2745
2746
2747
2748
2749
2750

  /* Remove the entry in the parent cell. */
  rc = nodeParentIndex(pRtree, pNode, &iCell);
  if( rc==SQLITE_OK ){
    pParent = pNode->pParent;
    pNode->pParent = 0;
    rc = deleteCell(pRtree, pParent, iCell, iHeight+1);

  }
  rc2 = nodeRelease(pRtree, pParent);
  if( rc==SQLITE_OK ){
    rc = rc2;
  }
  if( rc!=SQLITE_OK ){
    return rc;







>







2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765

  /* Remove the entry in the parent cell. */
  rc = nodeParentIndex(pRtree, pNode, &iCell);
  if( rc==SQLITE_OK ){
    pParent = pNode->pParent;
    pNode->pParent = 0;
    rc = deleteCell(pRtree, pParent, iCell, iHeight+1);
    testcase( rc!=SQLITE_OK );
  }
  rc2 = nodeRelease(pRtree, pParent);
  if( rc==SQLITE_OK ){
    rc = rc2;
  }
  if( rc!=SQLITE_OK ){
    return rc;
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
      rc = SplitNode(pRtree, pNode, pCell, iHeight);
    }else{
      pRtree->iReinsertHeight = iHeight;
      rc = Reinsert(pRtree, pNode, pCell, iHeight);
    }
  }else{
    rc = AdjustTree(pRtree, pNode, pCell);
    if( rc==SQLITE_OK ){
      if( iHeight==0 ){
        rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
      }else{
        rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
      }
    }
  }







|







2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
      rc = SplitNode(pRtree, pNode, pCell, iHeight);
    }else{
      pRtree->iReinsertHeight = iHeight;
      rc = Reinsert(pRtree, pNode, pCell, iHeight);
    }
  }else{
    rc = AdjustTree(pRtree, pNode, pCell);
    if( ALWAYS(rc==SQLITE_OK) ){
      if( iHeight==0 ){
        rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
      }else{
        rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
      }
    }
  }
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
  ** the root node (the operation that Gutman's paper says to perform 
  ** in this scenario).
  */
  if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
    int rc2;
    RtreeNode *pChild = 0;
    i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
    rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
    if( rc==SQLITE_OK ){
      rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
    }
    rc2 = nodeRelease(pRtree, pChild);
    if( rc==SQLITE_OK ) rc = rc2;
    if( rc==SQLITE_OK ){
      pRtree->iDepth--;







|







3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
  ** the root node (the operation that Gutman's paper says to perform 
  ** in this scenario).
  */
  if( rc==SQLITE_OK && pRtree->iDepth>0 && NCELL(pRoot)==1 ){
    int rc2;
    RtreeNode *pChild = 0;
    i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
    rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);  /* tag-20210916a */
    if( rc==SQLITE_OK ){
      rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
    }
    rc2 = nodeRelease(pRtree, pChild);
    if( rc==SQLITE_OK ) rc = rc2;
    if( rc==SQLITE_OK ){
      pRtree->iDepth--;
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
*/
static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
  const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
  char *zSql;
  sqlite3_stmt *p;
  int rc;
  i64 nRow = 0;

  rc = sqlite3_table_column_metadata(
      db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
  );
  if( rc!=SQLITE_OK ){
    pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
    return rc==SQLITE_ERROR ? SQLITE_OK : rc;
  }
  zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
  if( zSql==0 ){
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
    if( rc==SQLITE_OK ){
      if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
      rc = sqlite3_finalize(p);
    }else if( rc!=SQLITE_NOMEM ){
      rc = SQLITE_OK;
    }

    if( rc==SQLITE_OK ){
      if( nRow==0 ){
        pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
      }else{
        pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
      }
    }
    sqlite3_free(zSql);
  }

  return rc;
}


/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.







|
















<
<
<
<
<
<
<
<
<
<



|







3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438










3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
** on sqlite_stat1 data. Otherwise, use RTREE_DEFAULT_ROWEST.
*/
static int rtreeQueryStat1(sqlite3 *db, Rtree *pRtree){
  const char *zFmt = "SELECT stat FROM %Q.sqlite_stat1 WHERE tbl = '%q_rowid'";
  char *zSql;
  sqlite3_stmt *p;
  int rc;
  i64 nRow = RTREE_MIN_ROWEST;

  rc = sqlite3_table_column_metadata(
      db, pRtree->zDb, "sqlite_stat1",0,0,0,0,0,0
  );
  if( rc!=SQLITE_OK ){
    pRtree->nRowEst = RTREE_DEFAULT_ROWEST;
    return rc==SQLITE_ERROR ? SQLITE_OK : rc;
  }
  zSql = sqlite3_mprintf(zFmt, pRtree->zDb, pRtree->zName);
  if( zSql==0 ){
    rc = SQLITE_NOMEM;
  }else{
    rc = sqlite3_prepare_v2(db, zSql, -1, &p, 0);
    if( rc==SQLITE_OK ){
      if( sqlite3_step(p)==SQLITE_ROW ) nRow = sqlite3_column_int64(p, 0);
      rc = sqlite3_finalize(p);










    }
    sqlite3_free(zSql);
  }
  pRtree->nRowEst = MAX(nRow, RTREE_MIN_ROWEST);
  return rc;
}


/*
** Return true if zName is the extension on one of the shadow tables used
** by this module.
3580
3581
3582
3583
3584
3585
3586

3587
3588
3589


3590
3591
3592
3593
3594
3595
3596
    }else{
      sqlite3_str *p = sqlite3_str_new(db);
      int ii;
      char *zSql;
      sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix);
      for(ii=0; ii<pRtree->nAux; ii++){
        if( ii ) sqlite3_str_append(p, ",", 1);

        if( ii<pRtree->nAuxNotNull ){
          sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii);
        }else{


          sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2);
        }
      }
      sqlite3_str_appendf(p, " WHERE rowid=?1");
      zSql = sqlite3_str_finish(p);
      if( zSql==0 ){
        rc = SQLITE_NOMEM;







>


|
>
>







3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
    }else{
      sqlite3_str *p = sqlite3_str_new(db);
      int ii;
      char *zSql;
      sqlite3_str_appendf(p, "UPDATE \"%w\".\"%w_rowid\"SET ", zDb, zPrefix);
      for(ii=0; ii<pRtree->nAux; ii++){
        if( ii ) sqlite3_str_append(p, ",", 1);
#ifdef SQLITE_ENABLE_GEOPOLY
        if( ii<pRtree->nAuxNotNull ){
          sqlite3_str_appendf(p,"a%d=coalesce(?%d,a%d)",ii,ii+2,ii);
        }else
#endif
        {
          sqlite3_str_appendf(p,"a%d=?%d",ii,ii+2);
        }
      }
      sqlite3_str_appendf(p, " WHERE rowid=?1");
      zSql = sqlite3_str_finish(p);
      if( zSql==0 ){
        rc = SQLITE_NOMEM;
4261
4262
4263
4264
4265
4266
4267
4268

4269

4270
4271
4272
4273
4274
4275
4276

  /* Find the number of auxiliary columns */
  if( check.rc==SQLITE_OK ){
    pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
    if( pStmt ){
      nAux = sqlite3_column_count(pStmt) - 2;
      sqlite3_finalize(pStmt);
    }

    check.rc = SQLITE_OK;

  }

  /* Find number of dimensions in the rtree table. */
  pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
  if( pStmt ){
    int rc;
    check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2;







|
>
|
>







4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286

  /* Find the number of auxiliary columns */
  if( check.rc==SQLITE_OK ){
    pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab);
    if( pStmt ){
      nAux = sqlite3_column_count(pStmt) - 2;
      sqlite3_finalize(pStmt);
    }else 
    if( check.rc!=SQLITE_NOMEM ){
      check.rc = SQLITE_OK;
    }
  }

  /* Find number of dimensions in the rtree table. */
  pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.%Q", zDb, zTab);
  if( pStmt ){
    int rc;
    check.nDim = (sqlite3_column_count(pStmt) - 1 - nAux) / 2;
4519
4520
4521
4522
4523
4524
4525
4526



4527
4528
4529
4530
4531
4532
4533
  void *pContext,              /* Extra data passed into the callback */
  void (*xDestructor)(void*)   /* Destructor for the extra data */
){
  RtreeGeomCallback *pGeomCtx;      /* Context object for new user-function */

  /* Allocate and populate the context object. */
  pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
  if( !pGeomCtx ) return SQLITE_NOMEM;



  pGeomCtx->xGeom = 0;
  pGeomCtx->xQueryFunc = xQueryFunc;
  pGeomCtx->xDestructor = xDestructor;
  pGeomCtx->pContext = pContext;
  return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, 
      (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback
  );







|
>
>
>







4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
  void *pContext,              /* Extra data passed into the callback */
  void (*xDestructor)(void*)   /* Destructor for the extra data */
){
  RtreeGeomCallback *pGeomCtx;      /* Context object for new user-function */

  /* Allocate and populate the context object. */
  pGeomCtx = (RtreeGeomCallback *)sqlite3_malloc(sizeof(RtreeGeomCallback));
  if( !pGeomCtx ){
    if( xDestructor ) xDestructor(pContext);
    return SQLITE_NOMEM;
  }
  pGeomCtx->xGeom = 0;
  pGeomCtx->xQueryFunc = xQueryFunc;
  pGeomCtx->xDestructor = xDestructor;
  pGeomCtx->pContext = pContext;
  return sqlite3_create_function_v2(db, zQueryFunc, -1, SQLITE_ANY, 
      (void *)pGeomCtx, geomCallback, 0, 0, rtreeFreeCallback
  );
Changes to ext/rtree/rtree1.test.
53
54
55
56
57
58
59
60
61
62



63
64
65
66
67
68
69
#

# Test creating and dropping an rtree table.
#
do_test rtree-1.1.1 {
  execsql { CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2, y1, y2) }
} {}
do_test rtree-1.1.2 {
  execsql { SELECT name FROM sqlite_master ORDER BY name }
} {t1 t1_node t1_parent t1_rowid}



do_test rtree-1.1.3 {
  execsql { 
    DROP TABLE t1; 
    SELECT name FROM sqlite_master ORDER BY name;
  }
} {}








|


>
>
>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#

# Test creating and dropping an rtree table.
#
do_test rtree-1.1.1 {
  execsql { CREATE VIRTUAL TABLE t1 USING rtree(ii, x1, x2, y1, y2) }
} {}
do_test rtree-1.1.2a {
  execsql { SELECT name FROM sqlite_master ORDER BY name }
} {t1 t1_node t1_parent t1_rowid}
do_execsql_test rtree-1.1.2b {
  SELECT name FROM pragma_table_list WHERE type='shadow' ORDER BY name;
} {t1_node t1_parent t1_rowid}
do_test rtree-1.1.3 {
  execsql { 
    DROP TABLE t1; 
    SELECT name FROM sqlite_master ORDER BY name;
  }
} {}

Changes to ext/rtree/rtreeA.test.
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
}

create_t1
populate_t1
do_test rtreeA-2.2.0 { truncate_node 1 200 } {}
do_corruption_tests rtreeA-2.2 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
  4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
}

#-------------------------------------------------------------------------
# Set the "depth" of the tree stored on the root node incorrectly. Test
# that this does not cause any problems.
#
create_t1
populate_t1
do_test rtreeA-3.1.0.1 { set_tree_depth t1 } {1}
do_test rtreeA-3.1.0.2 { set_tree_depth t1 3 } {3}
do_corruption_tests rtreeA-3.1 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
}

do_execsql_test rtreeA-3.1.0.3 {
  SELECT rtreecheck('main', 't1')!="ok"
} {1}

do_test rtreeA-3.2.0 { set_tree_depth t1 1000 } {1000}
do_corruption_tests rtreeA-3.2 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
}

create_t1
populate_t1
do_test rtreeA-3.3.0 { 
  execsql { DELETE FROM t1 WHERE rowid = 0 }
  set_tree_depth t1 65535
} {65535}
do_corruption_tests rtreeA-3.3 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
}

do_execsql_test rtreeA-3.3.3.4 {
  SELECT rtreecheck('main', 't1')
} {{Rtree depth out of range (65535)
Wrong number of entries in %_rowid table - expected 0, actual 499
Wrong number of entries in %_parent table - expected 0, actual 23}}

#-------------------------------------------------------------------------
# Set the "number of entries" field on some nodes incorrectly.
#
create_t1
populate_t1
do_test rtreeA-4.1.0 { 
  set_entry_count t1 1 4000
} {4000}
do_corruption_tests rtreeA-4.1 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
  4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
}

#-------------------------------------------------------------------------
# Remove entries from the %_parent table and check that this does not
# cause a crash.
#
create_t1
populate_t1
do_execsql_test rtreeA-5.1.0 { DELETE FROM t1_parent } {}
do_corruption_tests rtreeA-5.1 {
  1   "DELETE FROM t1 WHERE rowid = 5"
  2   "DELETE FROM t1"
}

do_execsql_test rtreeA-5.2 {
  SELECT rtreecheck('main', 't1')!="ok"
} {1}








|














|










|











|



















|












|







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
}

create_t1
populate_t1
do_test rtreeA-2.2.0 { truncate_node 1 200 } {}
do_corruption_tests rtreeA-2.2 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE +rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
  4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
}

#-------------------------------------------------------------------------
# Set the "depth" of the tree stored on the root node incorrectly. Test
# that this does not cause any problems.
#
create_t1
populate_t1
do_test rtreeA-3.1.0.1 { set_tree_depth t1 } {1}
do_test rtreeA-3.1.0.2 { set_tree_depth t1 3 } {3}
do_corruption_tests rtreeA-3.1 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE +rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
}

do_execsql_test rtreeA-3.1.0.3 {
  SELECT rtreecheck('main', 't1')!="ok"
} {1}

do_test rtreeA-3.2.0 { set_tree_depth t1 1000 } {1000}
do_corruption_tests rtreeA-3.2 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE +rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
}

create_t1
populate_t1
do_test rtreeA-3.3.0 { 
  execsql { DELETE FROM t1 WHERE rowid = 0 }
  set_tree_depth t1 65535
} {65535}
do_corruption_tests rtreeA-3.3 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE +rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
}

do_execsql_test rtreeA-3.3.3.4 {
  SELECT rtreecheck('main', 't1')
} {{Rtree depth out of range (65535)
Wrong number of entries in %_rowid table - expected 0, actual 499
Wrong number of entries in %_parent table - expected 0, actual 23}}

#-------------------------------------------------------------------------
# Set the "number of entries" field on some nodes incorrectly.
#
create_t1
populate_t1
do_test rtreeA-4.1.0 { 
  set_entry_count t1 1 4000
} {4000}
do_corruption_tests rtreeA-4.1 {
  1   "SELECT * FROM t1"
  2   "SELECT * FROM t1 WHERE +rowid=5"
  3   "INSERT INTO t1 VALUES(1000, 1, 2, 3, 4)"
  4   "SELECT * FROM t1 WHERE x1<10 AND x2>12"
}

#-------------------------------------------------------------------------
# Remove entries from the %_parent table and check that this does not
# cause a crash.
#
create_t1
populate_t1
do_execsql_test rtreeA-5.1.0 { DELETE FROM t1_parent } {}
do_corruption_tests rtreeA-5.1 {
  1   "DELETE FROM t1 WHERE +rowid = 5"
  2   "DELETE FROM t1"
}

do_execsql_test rtreeA-5.2 {
  SELECT rtreecheck('main', 't1')!="ok"
} {1}

Added ext/rtree/rtreedoc.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
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
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
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
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
618
619
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
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
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
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
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
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
# 2021 September 13
#
# 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.
#
#***********************************************************************
#
# The focus of this file is testing the r-tree extension.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
set testprefix rtreedoc

ifcapable !rtree {
  finish_test
  return
}

# This command returns the number of columns in table $tbl within the
# database opened by database handle $db
proc column_count {db tbl} {
  set nCol 0
  $db eval "PRAGMA table_info = $tbl" { incr nCol }
  return $nCol
}

proc column_name_list {db tbl} {
  set lCol [list]
  $db eval "PRAGMA table_info = $tbl" { 
    lappend lCol $name
  }
  return $lCol
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 3 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-1

# EVIDENCE-OF: R-15060-13876 A 1-dimensional R*Tree thus has 3 columns.
do_execsql_test 1.1.1 { CREATE VIRTUAL TABLE rt1 USING rtree(id, x1,x2) }
do_test         1.1.2 { column_count db rt1 } 3

# EVIDENCE-OF: R-19353-19546 A 2-dimensional R*Tree has 5 columns.
do_execsql_test 1.2.1 { CREATE VIRTUAL TABLE rt2 USING rtree(id,x1,x2, y1,y2) }
do_test         1.2.2 { column_count db rt2 } 5

# EVIDENCE-OF: R-13615-19528 A 3-dimensional R*Tree has 7 columns.
do_execsql_test 1.3.1 { 
  CREATE VIRTUAL TABLE rt3 USING rtree(id, x1,x2, y1,y2, z1,z2) 
}
do_test         1.3.2 { column_count db rt3 } 7

# EVIDENCE-OF: R-53479-41922 A 4-dimensional R*Tree has 9 columns.
do_execsql_test 1.4.1 { 
  CREATE VIRTUAL TABLE rt4 USING rtree(id, x1,x2, y1,y2, z1,z2, v1,v2) 
}
do_test         1.4.2 { column_count db rt4 } 9

# EVIDENCE-OF: R-13981-28768 And a 5-dimensional R*Tree has 11 columns.
do_execsql_test 1.5.1 { 
  CREATE VIRTUAL TABLE rt5 USING rtree(id, x1,x2, y1,y2, z1,z2, v1,v2, w1,w2)
}
do_test         1.5.2 { column_count db rt5 } 11


# Attempt to create r-tree tables with 6 and 7 dimensions.
#
# EVIDENCE-OF: R-61533-25862 The SQLite R*Tree implementation does not
# support R*Trees wider than 5 dimensions.
do_catchsql_test 2.1.1 { 
  CREATE VIRTUAL TABLE rt6 USING rtree(
    id, x1,x2, y1,y2, z1,z2, v1,v2, w1,w2, a1,a2
  )
} {1 {Too many columns for an rtree table}}
do_catchsql_test 2.1.2 { 
  CREATE VIRTUAL TABLE rt6 USING rtree(
    id, x1,x2, y1,y2, z1,z2, v1,v2, w1,w2, a1,a2, b1, b2
  )
} {1 {Too many columns for an rtree table}}

# Attempt to create r-tree tables with no columns, a single column, or
# an even number of columns. This and the tests above establish that:
#
# EVIDENCE-OF: R-16717-50504 Each R*Tree index is a virtual table with
# an odd number of columns between 3 and 11.
foreach {tn cols err} {
  1 ""                        "Too few columns for an rtree table"
  2 "x"                       "Too few columns for an rtree table"
  3 "x,y"                     "Too few columns for an rtree table"
  4 "a,b,c,d"                 "Wrong number of columns for an rtree table"
  5 "a,b,c,d,e,f"             "Wrong number of columns for an rtree table"
  6 "a,b,c,d,e,f,g,h"         "Wrong number of columns for an rtree table"
  7 "a,b,c,d,e,f,g,h,i,j"     "Wrong number of columns for an rtree table"
  8 "a,b,c,d,e,f,g,h,i,j,k,l" "Too many columns for an rtree table"
} {
  do_catchsql_test 3.$tn "
    CREATE VIRTUAL TABLE xyz USING rtree($cols)
  " [list 1 $err]
}

# EVIDENCE-OF: R-17874-21123 The first column of an SQLite R*Tree is
# similar to an integer primary key column of a normal SQLite table.
#
# EVIDENCE-OF: R-46619-65417 The first column is always a 64-bit signed
# integer primary key.
#
# EVIDENCE-OF: R-46866-24036 It may only store a 64-bit signed integer
# value.
#
# EVIDENCE-OF: R-00250-64843 If an attempt is made to insert any other
# non-integer value into this column, the r-tree module silently
# converts it to an integer before writing it into the database.
#
do_execsql_test 4.0 { CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2) }
foreach {tn val res} {
  1 10    10
  2 10.6  10
  3 10.99 10
  4 '123' 123
  5 X'313233'  123
  6 -10   -10
  7  9223372036854775807 9223372036854775807 
  8 -9223372036854775808 -9223372036854775808 
  9  '9223372036854775807' 9223372036854775807
  10  '-9223372036854775808' -9223372036854775808
  11  'hello+world' 0
} {
  do_execsql_test 4.$tn.1 "
    DELETE FROM rt;
    INSERT INTO rt VALUES($val, 10, 20);
  "
  do_execsql_test 4.$tn.2 {
    SELECT typeof(id), id FROM rt
  } [list integer $res]
}

# EVIDENCE-OF: R-15544-29079 Inserting a NULL value into this column
# causes SQLite to automatically generate a new unique primary key
# value.
do_execsql_test 5.1 {
  DELETE FROM rt;
  INSERT INTO rt VALUES(100, 1, 2);
  INSERT INTO rt VALUES(NULL, 1, 2);
}
do_execsql_test 5.2 { SELECT id FROM rt } {100 101}
do_execsql_test 5.3 { 
  INSERT INTO rt VALUES(9223372036854775807, 1, 2);
  INSERT INTO rt VALUES(NULL, 1, 2);
}
do_execsql_test 5.4 {
  SELECT count(*) FROM rt;
} 4
do_execsql_test 5.5 {
  SELECT id IN(100, 101, 9223372036854775807) FROM rt ORDER BY 1;
} {0 1 1 1}


# EVIDENCE-OF: R-64317-38978 The other columns are pairs, one pair per
# dimension, containing the minimum and maximum values for that
# dimension, respectively.
#
# Show this by observing that attempts to insert rows with max>min fail.
#
do_execsql_test 6.1 {
  CREATE VIRTUAL TABLE rtF USING rtree(id, x1,x2, y1,y2);
  CREATE VIRTUAL TABLE rtI USING rtree_i32(id, x1,x2, y1,y2, z1,z2);
}
foreach {tn x1 x2 y1 y2 ok} {
  1   10.3 20.1   30.9 40.2   1
  2   10.3 20.1   40.2 30.9   0
  3   10.3 30.9   20.1 40.2   1
  4   20.1 10.3   30.9 40.2   0
} {
  do_test 6.2.$tn {
    catch { db eval { INSERT INTO rtF VALUES(NULL, $x1, $x2, $y1, $y2) } }
  } [expr $ok==0]
}
foreach {tn x1 x2 y1 y2 z1 z2 ok} {
  1   10 20   30 40  50 60  1
  2   10 20   30 40  60 50  0
  3   10 20   30 50  40 60  1
  4   10 20   40 30  50 60  0
  5   10 30   20 40  50 60  1
  6   20 10   30 40  50 60  0
} {
  do_test 6.3.$tn {
    catch { db eval { INSERT INTO rtI VALUES(NULL,$x1,$x2,$y1,$y2,$z1,$z2) } }
  } [expr $ok==0]
}

# EVIDENCE-OF: R-08054-15429 The min/max-value pair columns are stored
# as 32-bit floating point values for "rtree" virtual tables or as
# 32-bit signed integers in "rtree_i32" virtual tables.
#
# Show this by showing that large values are rounded in ways consistent
# with those two 32-bit types.
do_execsql_test 7.1 {
  DELETE FROM rtI;
  INSERT INTO rtI VALUES(
    0, -2000000000, 2000000000, -5000000000, 5000000000,
    -1000000000000, 10000000000000
  );
  SELECT * FROM rtI;
} {
  0 -2000000000 2000000000 -705032704 705032704 727379968 1316134912
}
do_execsql_test 7.2 {
  DELETE FROM rtF;
  INSERT INTO rtF VALUES(
    0, -2000000000, 2000000000, 
    -1000000000000, 10000000000000
  );
  SELECT * FROM rtF;
} {
  0 -2000000000.0 2000000000.0 -1000000126976.0 10000000876544.0
}

# EVIDENCE-OF: R-47371-54529 Unlike regular SQLite tables which can
# store data in a variety of datatypes and formats, the R*Tree rigidly
# enforce these storage types.
#
# EVIDENCE-OF: R-39153-14977 If any other type of value is inserted into
# such a column, the r-tree module silently converts it to the required
# type before writing the new record to the database.
do_execsql_test 8.1 {
  DELETE FROM rtI;
  INSERT INTO rtI VALUES(
    1, 'hello world', X'616263', NULL, 44.5, 1000, 9999.9999
  );
  SELECT * FROM rtI;
} {
  1   0 0    0 44    1000 9999
}

do_execsql_test 8.2 {
  SELECT 
    typeof(x1), typeof(x2), typeof(y1), typeof(y2), typeof(z1), typeof(z2)
  FROM rtI
} {integer integer integer integer integer integer}

do_execsql_test 8.3 {
  DELETE FROM rtF;
  INSERT INTO rtF VALUES(
    1, 'hello world', X'616263', NULL, 44
  );
  SELECT * FROM rtF;
} {
  1   0.0 0.0    0.0 44.0
}
do_execsql_test 8.4 {
  SELECT 
    typeof(x1), typeof(x2), typeof(y1), typeof(y2)
  FROM rtF
} {real real real real}




#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 3.1 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-2
reset_db

foreach {tn name clist} {
  1 t1 "id x1 x2"
  2 t2 "id x1 x2   y1 y2   z1 z2"
} {
# EVIDENCE-OF: R-15142-18077 A new R*Tree index is created as follows:
# CREATE VIRTUAL TABLE <name> USING rtree(<column-names>);
  do_execsql_test 1.$tn.1 "
    CREATE VIRTUAL TABLE $name USING rtree([join $clist ,])
  "

# EVIDENCE-OF: R-51698-09302 The <name> is the name your
# application chooses for the R*Tree index and <column-names> is a
# comma separated list of between 3 and 11 columns.
  do_test 1.$tn.2 { column_name_list db $name } [list {*}$clist]

# EVIDENCE-OF: R-50130-53472 The virtual <name> table creates
# three shadow tables to actually store its content.
  do_execsql_test 1.$tn.3 {
    SELECT count(*) FROM sqlite_schema
  } [expr 1+3]

# EVIDENCE-OF: R-45256-35998 The names of these shadow tables are:
# <name>_node <name>_rowid <name>_parent
  do_execsql_test 1.$tn.4 {
    SELECT name FROM sqlite_schema WHERE rootpage>0 ORDER BY 1
  } [list ${name}_node ${name}_parent ${name}_rowid]

  do_execsql_test 1.$tn.5 "DROP TABLE $name"
}

# EVIDENCE-OF: R-11241-54478 As an example, consider creating a
# two-dimensional R*Tree index for use in spatial queries: CREATE
# VIRTUAL TABLE demo_index USING rtree( id, -- Integer primary key minX,
# maxX, -- Minimum and maximum X coordinate minY, maxY -- Minimum and
# maximum Y coordinate );
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE demo_index USING rtree(
      id,              -- Integer primary key
      minX, maxX,      -- Minimum and maximum X coordinate
      minY, maxY       -- Minimum and maximum Y coordinate
  );
  INSERT INTO demo_index VALUES(1,2,3,4,5);
  INSERT INTO demo_index VALUES(6,7,8,9,10);
}

# EVIDENCE-OF: R-02287-33529 The shadow tables are ordinary SQLite data
# tables.
#
# Ordinary tables. With ordinary sqlite_schema entries.
do_execsql_test 2.1 {
  SELECT type, name, sql FROM sqlite_schema WHERE sql NOT LIKE '%virtual%'
} {
  table demo_index_rowid 
    {CREATE TABLE "demo_index_rowid"(rowid INTEGER PRIMARY KEY,nodeno)} 
  table demo_index_node
    {CREATE TABLE "demo_index_node"(nodeno INTEGER PRIMARY KEY,data)} 
  table demo_index_parent
    {CREATE TABLE "demo_index_parent"(nodeno INTEGER PRIMARY KEY,parentnode)}
}

# EVIDENCE-OF: R-10863-13089 You can query them directly if you like,
# though this unlikely to reveal anything particularly useful.
#
# Querying:
do_execsql_test 2.2 {
  SELECT count(*) FROM demo_index_node;
  SELECT count(*) FROM demo_index_rowid;
  SELECT count(*) FROM demo_index_parent;
} {1 2 0}

# EVIDENCE-OF: R-05650-46070 And you can UPDATE, DELETE, INSERT or even
# DROP the shadow tables, though doing so will corrupt your R*Tree
# index.
do_execsql_test 2.3 {
  DELETE FROM demo_index_rowid;
  INSERT INTO demo_index_parent VALUES(2, 3);
  UPDATE demo_index_node SET data = 'hello world'
}
do_catchsql_test 2.4 {
  SELECT * FROM demo_index WHERE minX>10 AND maxX<30
} {1 {database disk image is malformed}}
do_execsql_test 2.5 {
  DROP TABLE demo_index_rowid
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 3.1.1 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-3
reset_db

# EVIDENCE-OF: R-44253-50720 In the argments to "rtree" in the CREATE
# VIRTUAL TABLE statement, the names of the columns are taken from the
# first token of each argument. All subsequent tokens within each
# argument are silently ignored.
#
foreach {tn cols lCol} {
  1 {(id TEXT, x1 TEXT, x2 TEXT, y1 TEXT, y2 TEXT)} {id x1 x2 y1 y2}
  2 {(id TEXT, x1 UNIQUE, x2 TEXT, y1 NOT NULL, y2 TEXT)} {id x1 x2 y1 y2}
  3 {(id, x1 DEFAULT 4, x2 TEXT, y1 NOT NULL, y2 TEXT)} {id x1 x2 y1 y2}
} {
  do_execsql_test 1.$tn.1 " CREATE VIRTUAL TABLE abc USING rtree $cols "
  do_test 1.$tn.2 { column_name_list db abc } $lCol

# EVIDENCE-OF: R-52032-06717 This means, for example, that if you try to
# give a column a type affinity or add a constraint such as UNIQUE or
# NOT NULL or DEFAULT to a column, those extra tokens are accepted as
# valid, but they do not change the behavior of the rtree.

  # Show there are no UNIQUE constraints
  do_execsql_test 1.$tn.3 {
    INSERT INTO abc VALUES(1, 10.0, 20.0, 10.0, 20.0);
    INSERT INTO abc VALUES(2, 10.0, 20.0, 10.0, 20.0);
  }

  # Show the default values have not been modified
  do_execsql_test 1.$tn.4 {
    INSERT INTO abc DEFAULT VALUES;
    SELECT * FROM abc WHERE rowid NOT IN (1,2)
  } {3 0.0 0.0 0.0 0.0}

  # Show that there are no NOT NULL constraints
  do_execsql_test 1.$tn.5 {
    INSERT INTO abc VALUES(NULL, NULL, NULL, NULL, NULL);
    SELECT * FROM abc WHERE rowid NOT IN (1,2,3)
  } {4 0.0 0.0 0.0 0.0}

# EVIDENCE-OF: R-06893-30579 In an RTREE virtual table, the first column
# always has a type affinity of INTEGER and all other data columns have
# a type affinity of REAL.
  do_execsql_test 1.$tn.5 {
    INSERT INTO abc VALUES('5', '5', '5', '5', '5');
    SELECT * FROM abc WHERE rowid NOT IN (1,2,3,4)
  } {5 5.0 5.0 5.0 5.0}
  do_execsql_test 1.$tn.6 {
    SELECT type FROM pragma_table_info('abc') ORDER BY cid
  } {INT REAL REAL REAL REAL}

  do_execsql_test 1.$tn.7 " CREATE VIRTUAL TABLE abc2 USING rtree_i32 $cols "

# EVIDENCE-OF: R-06224-52418 In an RTREE_I32 virtual table, all columns
# have type affinity of INTEGER.
  do_execsql_test 1.$tn.8 {
    INSERT INTO abc2 VALUES('6.0', '6.0', '6.0', '6.0', '6.0');
    SELECT * FROM abc2
  } {6 6 6 6 6}
  do_execsql_test 1.$tn.9 {
    SELECT type FROM pragma_table_info('abc2') ORDER BY cid
  } {INT INT INT INT INT}


  do_execsql_test 1.$tn.10 {
    DROP TABLE abc;
    DROP TABLE abc2;
  }
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 3.2 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-4
reset_db

# EVIDENCE-OF: R-36195-31555 The usual INSERT, UPDATE, and DELETE
# commands work on an R*Tree index just like on regular tables.
#
# Create a regular table and an rtree table. Perform INSERT, UPDATE and
# DELETE operations, then observe that the contents of the two tables
# are identical.
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rt USING rtree(id, x1, x2);
  CREATE TABLE t1(id INTEGER PRIMARY KEY, x1 REAL, x2 REAL);
}
foreach {tn sql} {
  1 "INSERT INTO %TBL% VALUES(5, 11,12)"
  2 "INSERT INTO %TBL% VALUES(11, -11,14.5)"
  3 "UPDATE %TBL% SET x1=-99 WHERE id=11"
  4 "DELETE FROM %TBL% WHERE x2=14.5"
  5 "DELETE FROM %TBL%"
} {
  set sql1 [string map {%TBL% rt} $sql]
  set sql2 [string map {%TBL% t1} $sql]
  do_execsql_test 1.$tn.0 $sql1
  do_execsql_test 1.$tn.1 $sql2

  set data1 [execsql {SELECT * FROM rt ORDER BY 1}]
  set data2 [execsql {SELECT * FROM t1 ORDER BY 1}]

  set res [expr {$data1==$data2}]
  do_test 1.$tn.2 {set res} 1 
}

# EVIDENCE-OF: R-56987-45305
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE demo_index USING rtree(
      id,              -- Integer primary key
      minX, maxX,      -- Minimum and maximum X coordinate
      minY, maxY       -- Minimum and maximum Y coordinate
  );

  INSERT INTO demo_index VALUES
    (28215, -80.781227, -80.604706, 35.208813, 35.297367),
    (28216, -80.957283, -80.840599, 35.235920, 35.367825),
    (28217, -80.960869, -80.869431, 35.133682, 35.208233),
    (28226, -80.878983, -80.778275, 35.060287, 35.154446),
    (28227, -80.745544, -80.555382, 35.130215, 35.236916),
    (28244, -80.844208, -80.841988, 35.223728, 35.225471),
    (28262, -80.809074, -80.682938, 35.276207, 35.377747),
    (28269, -80.851471, -80.735718, 35.272560, 35.407925),
    (28270, -80.794983, -80.728966, 35.059872, 35.161823),
    (28273, -80.994766, -80.875259, 35.074734, 35.172836),
    (28277, -80.876793, -80.767586, 35.001709, 35.101063),
    (28278, -81.058029, -80.956375, 35.044701, 35.223812),
    (28280, -80.844208, -80.841972, 35.225468, 35.227203),
    (28282, -80.846382, -80.844193, 35.223972, 35.225655);
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 3.3 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-5

do_execsql_test 1.0 {
  INSERT INTO demo_index 
    SELECT NULL, minX, maxX, minY+0.2, maxY+0.2 FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX+0.2, maxX+0.2, minY, maxY FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX, maxX, minY+0.4, maxY+0.4 FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX+0.4, maxX+0.4, minY, maxY FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX, maxX, minY+0.8, maxY+0.8 FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX+0.8, maxX+0.8, minY, maxY FROM demo_index;

  SELECT count(*) FROM demo_index;
} {896}

proc do_vmstep_test {tn sql expr} {
  execsql $sql
  set step [db status vmstep]
  do_test $tn.$step "expr {[subst $expr]}" 1
}

# EVIDENCE-OF: R-45880-07724 Any valid query will work against an R*Tree
# index.
do_execsql_test 1.1.0 {
  CREATE TABLE demo_tbl AS SELECT * FROM demo_index;
}
foreach {tn sql} {
  1  {SELECT * FROM %TBL% ORDER BY 1}
  2  {SELECT max(minX) FROM %TBL% ORDER BY 1}
  3  {SELECT max(minX) FROM %TBL% GROUP BY round(minY) ORDER BY 1}
} {
  set sql1 [string map {%TBL% demo_index} $sql]
  set sql2 [string map {%TBL% demo_tbl} $sql]

  do_execsql_test 1.1.$tn $sql1 [execsql $sql2]
}

# EVIDENCE-OF: R-60814-18273 The R*Tree implementation just makes some
# kinds of queries especially efficient.
#
# The second query is more efficient than the first.
do_vmstep_test 1.2.1 {SELECT * FROM demo_index WHERE +rowid=28269} {$step>2000}
do_vmstep_test 1.2.2 {SELECT * FROM demo_index WHERE rowid=28269} {$step<100}

# EVIDENCE-OF: R-37800-50174 Queries against the primary key are
# efficient: SELECT * FROM demo_index WHERE id=28269;
do_vmstep_test 2.2 { SELECT * FROM demo_index WHERE id=28269 } {$step < 100}

# EVIDENCE-OF: R-35847-18866 The big reason for using an R*Tree is so
# that you can efficiently do range queries against the coordinate
# ranges.
#
# EVIDENCE-OF: R-49927-54202
do_vmstep_test 2.3 { 
  SELECT id FROM demo_index
    WHERE minX<=-80.77470 AND maxX>=-80.77470
    AND minY<=35.37785  AND maxY>=35.37785;
} {$step < 100}

# EVIDENCE-OF: R-12823-37176 The query above will quickly locate all
# zipcodes that contain the SQLite main office in their bounding box,
# even if the R*Tree contains many entries.
#
do_execsql_test 2.4 { 
  SELECT id FROM demo_index
    WHERE minX<=-80.77470 AND maxX>=-80.77470
    AND minY<=35.37785  AND maxY>=35.37785;
} {
  28322 28269 
}

# EVIDENCE-OF: R-07351-00257 For example, to find all zipcode bounding
# boxes that overlap with the 28269 zipcode: SELECT A.id FROM demo_index
# AS A, demo_index AS B WHERE A.maxX>=B.minX AND A.minX<=B.maxX
# AND A.maxY>=B.minY AND A.minY<=B.maxY AND B.id=28269;
#
# Also check that it is efficient
#
# EVIDENCE-OF: R-39094-01937 This second query will find both 28269
# entry (since every bounding box overlaps with itself) and also other
# zipcode that is close enough to 28269 that their bounding boxes
# overlap.
#
# 28269 is there in the result.
#
do_vmstep_test 2.5.1 {
  SELECT A.id FROM demo_index AS A, demo_index AS B
    WHERE A.maxX>=B.minX AND A.minX<=B.maxX
    AND A.maxY>=B.minY AND A.minY<=B.maxY
    AND B.id=28269
} {$step < 100}
do_execsql_test 2.5.2 {
  SELECT A.id FROM demo_index AS A, demo_index AS B
    WHERE A.maxX>=B.minX AND A.minX<=B.maxX
    AND A.maxY>=B.minY AND A.minY<=B.maxY
    AND B.id=28269;
} {
  28293 28216 28322 28286 28269 
  28215 28336 28262 28291 28320 
  28313 28298 28287
}

# EVIDENCE-OF: R-02723-34107 Note that it is not necessary for all
# coordinates in an R*Tree index to be constrained in order for the
# index search to be efficient.
#
# EVIDENCE-OF: R-22490-27246 One might, for example, want to query all
# objects that overlap with the 35th parallel: SELECT id FROM demo_index
# WHERE maxY>=35.0 AND minY<=35.0;
do_vmstep_test 2.6.1 {
  SELECT id FROM demo_index
   WHERE maxY>=35.0  AND minY<=35.0;
} {$step < 100}
do_execsql_test 2.6.2 {
  SELECT id FROM demo_index
   WHERE maxY>=35.0  AND minY<=35.0;
} {}


#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 3.4 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-6
reset_db

# EVIDENCE-OF: R-08327-00674 By default, coordinates are stored in an
# R*Tree using 32-bit floating point values.
#
# EVIDENCE-OF: R-22000-53613 The default virtual table ("rtree") stores
# coordinates as single-precision (4-byte) floating point numbers.
#
# Show this by showing that rounding is consistent with 32-bit float
# rounding.
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rt USING rtree(id, a,b);
}
do_execsql_test 1.1 {
  INSERT INTO rt VALUES(14, -1000000000000, 1000000000000);
  SELECT * FROM rt;
} {14 -1000000126976.0 1000000126976.0}

# EVIDENCE-OF: R-39127-51288 When a coordinate cannot be exactly
# represented by a 32-bit floating point number, the lower-bound
# coordinates are rounded down and the upper-bound coordinates are
# rounded up.
foreach {tn val} {
  1 100000000000
  2 200000000000
  3 300000000000
  4 400000000000

  5 -100000000000
  6 -200000000000
  7 -300000000000
  8 -400000000000
} {
  set val [expr $val]
  do_execsql_test 2.$tn.0 {DELETE FROM rt}
  do_execsql_test 2.$tn.1 {INSERT INTO rt VALUES(23, $val, $val)}
  do_execsql_test 2.$tn.2 {
    SELECT $val>=a, $val<=b, a!=b FROM rt
  } {1 1 1}
}

do_execsql_test 3.0 {
  DROP TABLE rt;
  CREATE VIRTUAL TABLE rt USING rtree(id, x1,x2, y1,y2);
}

# EVIDENCE-OF: R-45870-62834 Thus, bounding boxes might be slightly
# larger than specified, but will never be any smaller.
foreach {tn x1 x2 y1 y2} {
  1 100000000000 200000000000 300000000000 400000000000
} {
  set val [expr $val]
  do_execsql_test 3.$tn.0 {DELETE FROM rt}
  do_execsql_test 3.$tn.1 {INSERT INTO rt VALUES(23, $x1, $x2, $y1, $y2)}
  do_execsql_test 3.$tn.2 {
    SELECT (x2-x1)*(y2-y1) >= ($x2-$x1)*($y2-$y1) FROM rt
  } {1}
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 3.5 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-7
reset_db

# EVIDENCE-OF: R-55979-39402 It is the nature of the Guttman R-Tree
# algorithm that any write might radically restructure the tree, and in
# the process change the scan order of the nodes.
#
# In the test below, the INSERT marked "THIS INSERT!!" does not affect
# the results of queries with an ORDER BY, but does affect the results
# of one without an ORDER BY. Therefore the INSERT changed the scan 
# order.
do_execsql_test 1.0 { 
  CREATE VIRTUAL TABLE rt USING rtree(id, minX, maxX);
  WITH s(i) AS (
    SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<51
  )
  INSERT INTO rt SELECT NULL, i%10, (i%10)+5 FROM s
}
do_execsql_test 1.1 { SELECT count(*) FROM rt_node } 1
do_test 1.2 {
  set res1 [db eval {SELECT * FROM rt WHERE maxX < 30}]
  set res1o [db eval {SELECT * FROM rt WHERE maxX < 30 ORDER BY +id}]

  db eval { INSERT INTO rt VALUES(NULL, 50, 50) }   ;# THIS INSERT!!

  set res2 [db eval {SELECT * FROM rt WHERE maxX < 30}]
  set res2o [db eval {SELECT * FROM rt WHERE maxX < 30 ORDER BY +id}]
  list [expr {$res1==$res2}] [expr {$res1o==$res2o}]
} {0 1}

do_execsql_test 1.3 { SELECT count(*) FROM rt_node } 3

# EVIDENCE-OF: R-00683-48865 For this reason, it is not generally
# possible to modify the R-Tree in the middle of a query of the R-Tree.
# Attempts to do so will fail with a SQLITE_LOCKED "database table is
# locked" error.
#
# SQLITE_LOCKED==6
#
do_test 1.4 {
  set nCnt 3
  db eval { SELECT * FROM rt WHERE minX>0 AND maxX<12 } {
    incr nCnt -1
    if {$nCnt==0} {
      set rc [catch {db eval {
        INSERT INTO rt VALUES(NULL, 51, 51);
      }} msg]
      set errorcode [db errorcode]
      break
    }
  }

  list $errorcode $rc $msg
} {6 1 {database table is locked}}

# EVIDENCE-OF: R-19740-29710 So, for example, suppose an application
# runs one query against an R-Tree like this: SELECT id FROM demo_index
# WHERE maxY>=35.0 AND minY<=35.0; Then for each "id" value
# returned, suppose the application creates an UPDATE statement like the
# following and binds the "id" value returned against the "?1"
# parameter: UPDATE demo_index SET maxY=maxY+0.5 WHERE id=?1;
#
# EVIDENCE-OF: R-52919-32711 Then the UPDATE might fail with an
# SQLITE_LOCKED error.
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE demo_index USING rtree(
      id,              -- Integer primary key
      minX, maxX,      -- Minimum and maximum X coordinate
      minY, maxY       -- Minimum and maximum Y coordinate
  );
  INSERT INTO demo_index VALUES
    (28215, -80.781227, -80.604706, 35.208813, 35.297367),
    (28216, -80.957283, -80.840599, 35.235920, 35.367825),
    (28217, -80.960869, -80.869431, 35.133682, 35.208233),
    (28226, -80.878983, -80.778275, 35.060287, 35.154446);
}
do_test 2.1 {
  db eval { SELECT id FROM demo_index WHERE maxY>=35.0  AND minY<=35.0 } {
    set rc [catch { 
      db eval { UPDATE demo_index SET maxY=maxY+0.5 WHERE id=$id } 
    } msg]
    set errorcode [db errorcode]
    break
  }
  list $errorcode $rc $msg
} {6 1 {database table is locked}}

# EVIDENCE-OF: R-32604-49843 Ordinary tables in SQLite are able to read
# and write at the same time.
#
do_execsql_test 3.0 {
  CREATE TABLE x1(a INTEGER PRIMARY KEY, b, c);
  INSERT INTO x1 VALUES(1, 1, 1);
  INSERT INTO x1 VALUES(2, 2, 2);
  INSERT INTO x1 VALUES(3, 3, 3);
  INSERT INTO x1 VALUES(4, 4, 4);
}
do_test 3.1 {
  set res [list]
  db eval { SELECT * FROM x1 } {
    lappend res $a $b $c
    switch -- $a {
      1 {
        db eval { INSERT INTO x1 VALUES(5, 5, 5) }
      }
      2 {
        db eval { UPDATE x1 SET c=20 WHERE a=2 }
      }
      3 {
        db eval { DELETE FROM x1 WHERE c IN (3,4) }
      }
    }
  }
  set res
} {1 1 1 2 2 2 3 3 3 5 5 5}
do_execsql_test 3.2 {
  SELECT * FROM x1
} {1 1 1  2 2 20  5 5 5}

# EVIDENCE-OF: R-06177-00576 And R-Tree can appear to read and write at
# the same time in some circumstances, if it can figure out how to
# reliably run the query to completion before starting the update.
#
# In 8.2, it can, it 8.1, it cannot.
do_test 8.1 {
  db eval { SELECT * FROM rt } {
    set rc [catch { db eval { INSERT INTO rt VALUES(53,53,53) } } msg]
    break;
  }
  list $rc $msg
} {1 {database table is locked}}
do_test 8.2 {
  db eval { SELECT * FROM rt ORDER BY +id } {
    set rc [catch { db eval { INSERT INTO rt VALUES(53,53,53) } } msg]
    break
  }
  list $rc $msg
} {0 {}}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 4 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-8
reset_db

# EVIDENCE-OF: R-21062-30088 For the example above, one might create an
# auxiliary table as follows: CREATE TABLE demo_data( id INTEGER PRIMARY
# KEY, -- primary key objname TEXT, -- name of the object objtype TEXT,
# -- object type boundary BLOB -- detailed boundary of object );
#
# One might.
#
do_execsql_test 1.0 {
  CREATE TABLE demo_data(
      id INTEGER PRIMARY KEY,  -- primary key
      objname TEXT,            -- name of the object
      objtype TEXT,            -- object type
      boundary BLOB            -- detailed boundary of object
  );
}

do_execsql_test 1.1 {
  CREATE VIRTUAL TABLE demo_index USING rtree(
      id,              -- Integer primary key
      minX, maxX,      -- Minimum and maximum X coordinate
      minY, maxY       -- Minimum and maximum Y coordinate
  );

  INSERT INTO demo_index VALUES
    (28215, -80.781227, -80.604706, 35.208813, 35.297367),
    (28216, -80.957283, -80.840599, 35.235920, 35.367825),
    (28217, -80.960869, -80.869431, 35.133682, 35.208233),
    (28226, -80.878983, -80.778275, 35.060287, 35.154446),
    (28227, -80.745544, -80.555382, 35.130215, 35.236916),
    (28244, -80.844208, -80.841988, 35.223728, 35.225471),
    (28262, -80.809074, -80.682938, 35.276207, 35.377747),
    (28269, -80.851471, -80.735718, 35.272560, 35.407925),
    (28270, -80.794983, -80.728966, 35.059872, 35.161823),
    (28273, -80.994766, -80.875259, 35.074734, 35.172836),
    (28277, -80.876793, -80.767586, 35.001709, 35.101063),
    (28278, -81.058029, -80.956375, 35.044701, 35.223812),
    (28280, -80.844208, -80.841972, 35.225468, 35.227203),
    (28282, -80.846382, -80.844193, 35.223972, 35.225655);

  INSERT INTO demo_index 
    SELECT NULL, minX, maxX, minY+0.2, maxY+0.2 FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX+0.2, maxX+0.2, minY, maxY FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX, maxX, minY+0.4, maxY+0.4 FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX+0.4, maxX+0.4, minY, maxY FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX, maxX, minY+0.8, maxY+0.8 FROM demo_index;
  INSERT INTO demo_index 
    SELECT NULL, minX+0.8, maxX+0.8, minY, maxY FROM demo_index;

  INSERT INTO demo_data(id) SELECT id FROM demo_index;

  SELECT count(*) FROM demo_index;
} {896}

set ::contained_in 0
proc contained_in {args} {incr ::contained_in ; return 0}
db func contained_in contained_in

# EVIDENCE-OF: R-32671-43888 Then an efficient way to find the specific
# ZIP code for the main SQLite office would be to run a query like this:
# SELECT objname FROM demo_data, demo_index WHERE
# demo_data.id=demo_index.id AND contained_in(demo_data.boundary,
# 35.37785, -80.77470) AND minX<=-80.77470 AND maxX>=-80.77470 AND
# minY<=35.37785 AND maxY>=35.37785;
do_vmstep_test 1.2 {
  SELECT objname FROM demo_data, demo_index
    WHERE demo_data.id=demo_index.id
    AND contained_in(demo_data.boundary, 35.37785, -80.77470)
    AND minX<=-80.77470 AND maxX>=-80.77470
    AND minY<=35.37785  AND maxY>=35.37785;
} {$step<100}
set ::contained_in1 $::contained_in

# EVIDENCE-OF: R-32761-23915 One would get the same answer without the
# use of the R*Tree index using the following simpler query: SELECT
# objname FROM demo_data WHERE contained_in(demo_data.boundary,
# 35.37785, -80.77470);
set ::contained_in 0
do_vmstep_test 1.3 {
  SELECT objname FROM demo_data
    WHERE contained_in(demo_data.boundary, 35.37785, -80.77470);
} {$step>3200}

# EVIDENCE-OF: R-40261-32799 The problem with this latter query is that
# it must apply the contained_in() function to all entries in the
# demo_data table.
#
# 896 of them, IIRC.
do_test 1.4 {
  set ::contained_in
} 896

# EVIDENCE-OF: R-24212-52761 The use of the R*Tree in the penultimate
# query reduces the number of calls to contained_in() function to a
# small subset of the entire table.
#
# 2 is a small subset of 896.
#
# EVIDENCE-OF: R-39057-63901 The R*Tree index did not find the exact
# answer itself, it merely limited the search space.
#
# contained_in() filtered out those 2 rows.
do_test 1.5 {
  set ::contained_in1
} {2}


#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 4.1 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-9
reset_db

# EVIDENCE-OF: R-46566-43213 Beginning with SQLite version 3.24.0
# (2018-06-04), r-tree tables can have auxiliary columns that store
# arbitrary data. Auxiliary columns can be used in place of secondary
# tables such as "demo_data".
#
# EVIDENCE-OF: R-41287-48160 Auxiliary columns are marked with a "+"
# symbol before the column name.
#
# This interface cannot conveniently be used to prove anything about 
# versions of SQLite prior to 3.24.0.
#
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rta USING rtree(
    id, u1,u2,  v1,v2,   +aux
  );

  INSERT INTO rta(aux) VALUES(NULL);
  INSERT INTO rta(aux) VALUES(45);
  INSERT INTO rta(aux) VALUES(22.3);
  INSERT INTO rta(aux) VALUES('hello');
  INSERT INTO rta(aux) VALUES(X'ABCD');

  SELECT typeof(aux), quote(aux) FROM rta;
} {
  null NULL
  integer 45
  real 22.3
  text 'hello'
  blob X'ABCD'
}

# EVIDENCE-OF: R-30514-26093 Auxiliary columns must come after all of
# the coordinate boundary columns.
foreach {tn cols} {
  1 "id x1,x2, +extra,  y1,y2"
  2 "extra, +id x1,x2, y1,y2"
  3 "id, x1,+x2, extra, y1,y2"
} {
  do_catchsql_test 2.$tn "
    CREATE VIRTUAL TABLE rrr USING rtree($cols)
  " {1 {Auxiliary rtree columns must be last}}
}
do_catchsql_test 3.0 {
  CREATE VIRTUAL TABLE rrr USING rtree(+id, extra, x1, x2);
} {1 {near "+": syntax error}}

# EVIDENCE-OF: R-01280-03635 An RTREE table can have no more than 100
# columns total. In other words, the count of columns including the
# integer primary key column, the coordinate boundary columns, and all
# auxiliary columns must be 100 or less.
do_catchsql_test 3.1 {
  CREATE VIRTUAL TABLE r1 USING rtree(intid, u1,u2,
    +c00, +c01, +c02, +c03, +c04, +c05, +c06, +c07, +c08, +c09,
    +c10, +c11, +c12, +c13, +c14, +c15, +c16, +c17, +c18, +c19,
    +c20, +c21, +c22, +c23, +c24, +c25, +c26, +c27, +c28, +c29,
    +c30, +c31, +c32, +c33, +c34, +c35, +c36, +c37, +c38, +c39,
    +c40, +c41, +c42, +c43, +c44, +c45, +c46, +c47, +c48, +c49,
    +c50, +c51, +c52, +c53, +c54, +c55, +c56, +c57, +c58, +c59,
    +c60, +c61, +c62, +c63, +c64, +c65, +c66, +c67, +c68, +c69,
    +c70, +c71, +c72, +c73, +c74, +c75, +c76, +c77, +c78, +c79,
    +c80, +c81, +c82, +c83, +c84, +c85, +c86, +c87, +c88, +c89,
    +c90, +c91, +c92, +c93, +c94, +c95, +c96
  );
} {0 {}}
do_catchsql_test 3.2 {
  DROP TABLE r1;
  CREATE VIRTUAL TABLE r1 USING rtree(intid, u1,u2,
    +c00, +c01, +c02, +c03, +c04, +c05, +c06, +c07, +c08, +c09,
    +c10, +c11, +c12, +c13, +c14, +c15, +c16, +c17, +c18, +c19,
    +c20, +c21, +c22, +c23, +c24, +c25, +c26, +c27, +c28, +c29,
    +c30, +c31, +c32, +c33, +c34, +c35, +c36, +c37, +c38, +c39,
    +c40, +c41, +c42, +c43, +c44, +c45, +c46, +c47, +c48, +c49,
    +c50, +c51, +c52, +c53, +c54, +c55, +c56, +c57, +c58, +c59,
    +c60, +c61, +c62, +c63, +c64, +c65, +c66, +c67, +c68, +c69,
    +c70, +c71, +c72, +c73, +c74, +c75, +c76, +c77, +c78, +c79,
    +c80, +c81, +c82, +c83, +c84, +c85, +c86, +c87, +c88, +c89,
    +c90, +c91, +c92, +c93, +c94, +c95, +c96, +c97
  );
} {1 {Too many columns for an rtree table}}
do_catchsql_test 3.3 {
  CREATE VIRTUAL TABLE r1 USING rtree(intid, u1,u2, v1,v2,
    +c00, +c01, +c02, +c03, +c04, +c05, +c06, +c07, +c08, +c09,
    +c10, +c11, +c12, +c13, +c14, +c15, +c16, +c17, +c18, +c19,
    +c20, +c21, +c22, +c23, +c24, +c25, +c26, +c27, +c28, +c29,
    +c30, +c31, +c32, +c33, +c34, +c35, +c36, +c37, +c38, +c39,
    +c40, +c41, +c42, +c43, +c44, +c45, +c46, +c47, +c48, +c49,
    +c50, +c51, +c52, +c53, +c54, +c55, +c56, +c57, +c58, +c59,
    +c60, +c61, +c62, +c63, +c64, +c65, +c66, +c67, +c68, +c69,
    +c70, +c71, +c72, +c73, +c74, +c75, +c76, +c77, +c78, +c79,
    +c80, +c81, +c82, +c83, +c84, +c85, +c86, +c87, +c88, +c89,
    +c90, +c91, +c92, +c93, +c94,
  );
} {0 {}}
do_catchsql_test 3.4 {
  DROP TABLE r1;
  CREATE VIRTUAL TABLE r1 USING rtree(intid, u1,u2, v1,v2,
    +c00, +c01, +c02, +c03, +c04, +c05, +c06, +c07, +c08, +c09,
    +c10, +c11, +c12, +c13, +c14, +c15, +c16, +c17, +c18, +c19,
    +c20, +c21, +c22, +c23, +c24, +c25, +c26, +c27, +c28, +c29,
    +c30, +c31, +c32, +c33, +c34, +c35, +c36, +c37, +c38, +c39,
    +c40, +c41, +c42, +c43, +c44, +c45, +c46, +c47, +c48, +c49,
    +c50, +c51, +c52, +c53, +c54, +c55, +c56, +c57, +c58, +c59,
    +c60, +c61, +c62, +c63, +c64, +c65, +c66, +c67, +c68, +c69,
    +c70, +c71, +c72, +c73, +c74, +c75, +c76, +c77, +c78, +c79,
    +c80, +c81, +c82, +c83, +c84, +c85, +c86, +c87, +c88, +c89,
    +c90, +c91, +c92, +c93, +c94, +c95,
  );
} {1 {Too many columns for an rtree table}}

# EVIDENCE-OF: R-05552-15084
do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE demo_index2 USING rtree(
      id,              -- Integer primary key
      minX, maxX,      -- Minimum and maximum X coordinate
      minY, maxY,      -- Minimum and maximum Y coordinate
      +objname TEXT,   -- name of the object
      +objtype TEXT,   -- object type
      +boundary BLOB   -- detailed boundary of object
  );
}
do_execsql_test 4.1 {
  CREATE VIRTUAL TABLE demo_index USING rtree(
      id,              -- Integer primary key
      minX, maxX,      -- Minimum and maximum X coordinate
      minY, maxY       -- Minimum and maximum Y coordinate
  );
  CREATE TABLE demo_data(
      id INTEGER PRIMARY KEY,  -- primary key
      objname TEXT,            -- name of the object
      objtype TEXT,            -- object type
      boundary BLOB            -- detailed boundary of object
  );

  INSERT INTO demo_index2(id) VALUES(1);
  INSERT INTO demo_index(id) VALUES(1);
  INSERT INTO demo_data(id) VALUES(1);
}
do_test 4.2 {
  catch { array unset R }
  db eval {SELECT * FROM demo_index2} R { set r1 [array names R] }
  catch { array unset R }
  db eval {SELECT * FROM demo_index NATURAL JOIN demo_data } R { 
    set r2 [array names R] 
  }
  expr {$r1==$r2}
} {1}

# EVIDENCE-OF: R-26099-32169 SELECT objname FROM demo_index2 WHERE
# contained_in(boundary, 35.37785, -80.77470) AND minX<=-80.77470 AND
# maxX>=-80.77470 AND minY<=35.37785 AND maxY>=35.37785;
do_execsql_test 4.3.1 {
  DELETE FROM demo_index2;
  INSERT INTO demo_index2(id,minX,maxX,minY,maxY) VALUES
    (28215, -80.781227, -80.604706, 35.208813, 35.297367),
    (28216, -80.957283, -80.840599, 35.235920, 35.367825),
    (28217, -80.960869, -80.869431, 35.133682, 35.208233),
    (28226, -80.878983, -80.778275, 35.060287, 35.154446),
    (28227, -80.745544, -80.555382, 35.130215, 35.236916),
    (28244, -80.844208, -80.841988, 35.223728, 35.225471),
    (28262, -80.809074, -80.682938, 35.276207, 35.377747),
    (28269, -80.851471, -80.735718, 35.272560, 35.407925),
    (28270, -80.794983, -80.728966, 35.059872, 35.161823),
    (28273, -80.994766, -80.875259, 35.074734, 35.172836),
    (28277, -80.876793, -80.767586, 35.001709, 35.101063),
    (28278, -81.058029, -80.956375, 35.044701, 35.223812),
    (28280, -80.844208, -80.841972, 35.225468, 35.227203),
    (28282, -80.846382, -80.844193, 35.223972, 35.225655);
}
set ::contained_in 0
proc contained_in {args} {
  incr ::contained_in
  return 0
}
db func contained_in contained_in
do_execsql_test 4.3.2 {
  SELECT objname FROM demo_index2
    WHERE contained_in(boundary, 35.37785, -80.77470)
    AND minX<=-80.77470 AND maxX>=-80.77470
    AND minY<=35.37785  AND maxY>=35.37785;
}
do_test 4.3.3 {
  # Function invoked only once because r-tree filtering happened first.
  set ::contained_in
} 1
set ::contained_in 0
do_execsql_test 4.3.4 {
  SELECT objname FROM demo_index2
    WHERE contained_in(boundary, 35.37785, -80.77470)
}
do_test 4.3.3 {
  # Function invoked 14 times because no r-tree filtering. Inefficient.
  set ::contained_in
} 14

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 4.1.1 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-9
reset_db

# EVIDENCE-OF: R-24021-02490 For auxiliary columns, only the name of the
# column matters. The type affinity is ignored.
#
# EVIDENCE-OF: R-39906-44154 Constraints such as NOT NULL, UNIQUE,
# REFERENCES, or CHECK are also ignored.
do_execsql_test 1.0 { PRAGMA foreign_keys = on }
foreach {tn auxcol nm} {
  1 "+extra INTEGER" extra
  2 "+extra TEXT"    extra
  3 "+extra BLOB"    extra
  4 "+extra REAL"    extra

  5 "+col NOT NULL"                 col
  6 "+col CHECK (col IS NOT NULL)"  col
  7 "+col REFERENCES tbl(x)"        col
} {
  do_execsql_test 1.$tn.1 "
    CREATE VIRTUAL TABLE rt USING rtree_i32(k, a,b, $auxcol)
  "

  # Check that the aux column has no affinity. Or NOT NULL constraint.
  # And that the aux column is the child key of an FK constraint.
  #
  do_execsql_test 1.$tn.2 "
    INSERT INTO rt($nm) VALUES(NULL), (45), (-123.2), ('456'), (X'ABCD');
    SELECT typeof($nm), quote($nm) FROM rt;
  " {
    null NULL
    integer 45
    real -123.2
    text '456'
    blob X'ABCD'
  }

  # Check that there is no UNIQUE constraint either.
  #
  do_execsql_test 1.$tn.3 "
    INSERT INTO rt($nm) VALUES('xyz'), ('xyz'), ('xyz');
  "

  do_execsql_test 1.$tn.2 {
    DROP TABLE rt
  }
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 5 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-10

# EVIDENCE-OF: R-21011-43790 If integer coordinates are desired, declare
# the table using "rtree_i32" instead: CREATE VIRTUAL TABLE intrtree
# USING rtree_i32(id,x0,x1,y0,y1,z0,z1);
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE intrtree USING rtree_i32(id,x0,x1,y0,y1,z0,z1);
  INSERT INTO intrtree DEFAULT VALUES;
  SELECT typeof(x0) FROM intrtree;
} {integer}

# EVIDENCE-OF: R-09193-49806 An rtree_i32 stores coordinates as 32-bit
# signed integers.
#
# Show that coordinates are cast in a way consistent with casting to
# a signed 32-bit integer.
do_execsql_test 1.1 {
  DELETE FROM intrtree;
  INSERT INTO intrtree VALUES(333,
      1<<44, (1<<44)+1,
      10000000000, 10000000001,
      -10000000001, -10000000000
  );
  SELECT * FROM intrtree;
} {
  333 0 1 1410065408 1410065409 -1410065409 -1410065408
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 7.1 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-11
reset_db

# This command assumes that the argument is a node blob for a 2 dimensional
# i32 r-tree table. It decodes and returns a list of cells from the node
# as a list. Each cell is itself a list of the following form:
#
#    {$rowid $minX $maxX $minY $maxY}
#
# For internal (non-leaf) nodes, the rowid is replaced by the child node
# number.
#
proc rnode {aData} {
  set nDim 2

  set nData [string length $aData]
  set nBytePerCell [expr (8 + 2*$nDim*4)]
  binary scan [string range $aData 2 3] S nCell

  set res [list]
  for {set i 0} {$i < $nCell} {incr i} {
    set iOff [expr $i*$nBytePerCell+4]
    set cell [string range $aData $iOff [expr $iOff+$nBytePerCell-1]]
    binary scan $cell WIIII rowid x1 x2 y1 y2
    lappend res [list $rowid $x1 $x2 $y1 $y2]
  }

  return $res
}

# aData must be a node blob. This command returns true if the node contains
# rowid $rowid, or false otherwise.
#
proc rnode_contains {aData rowid} {
  set L [rnode $aData]
  foreach cell $L {
    set r [lindex $cell 0]
    if {$r==$rowid} { return 1 }
  }
  return 0
}

proc rnode_replace_cell {aData iCell cell} {
  set aCell [binary format WIIII {*}$cell]
  set nDim 2
  set nBytePerCell [expr (8 + 2*$nDim*4)]
  set iOff [expr $iCell*$nBytePerCell+4]

  set aNew [binary format a*a*a* \
      [string range $aData 0 $iOff-1]     \
      $aCell     \
      [string range $aData $iOff+$nBytePerCell end] \
  ]
  return $aNew
}

db function rnode rnode
db function rnode_contains rnode_contains
db function rnode_replace_cell rnode_replace_cell

foreach {tn nm} {
  1 x1
  2 asdfghjkl
  3 hello_world
} {
  do_execsql_test 1.$tn.1 "
    CREATE VIRTUAL TABLE $nm USING rtree(a,b,c,d,e);
  "

  # EVIDENCE-OF: R-33789-46762 The content of an R*Tree index is actually
  # stored in three ordinary SQLite tables with names derived from the
  # name of the R*Tree.
  #
  # EVIDENCE-OF: R-39849-06566 This is their schema: CREATE TABLE
  # %_node(nodeno INTEGER PRIMARY KEY, data) CREATE TABLE %_parent(nodeno
  # INTEGER PRIMARY KEY, parentnode) CREATE TABLE %_rowid(rowid INTEGER
  # PRIMARY KEY, nodeno)
  #
  # EVIDENCE-OF: R-07489-10051 The "%" in the name of each shadow table is
  # replaced by the name of the R*Tree virtual table. So, if the name of
  # the R*Tree table is "xyz" then the three shadow tables would be
  # "xyz_node", "xyz_parent", and "xyz_rowid".
  do_execsql_test 1.$tn.2 {
    SELECT sql FROM sqlite_schema WHERE name!=$nm ORDER BY 1
  } [string map [list % $nm] "
    {CREATE TABLE \"%_node\"(nodeno INTEGER PRIMARY KEY,data)}
    {CREATE TABLE \"%_parent\"(nodeno INTEGER PRIMARY KEY,parentnode)}
    {CREATE TABLE \"%_rowid\"(rowid INTEGER PRIMARY KEY,nodeno)}
  "]

  do_execsql_test 1.$tn "DROP TABLE $nm"
}


# EVIDENCE-OF: R-51070-59303 There is one entry in the %_node table for
# each R*Tree node.
#
# The following creates a 6 node r-tree structure.
#
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE r1 USING rtree_i32(i, x1,x2, y1,y2);
  WITH t(i) AS (
    VALUES(1) UNION SELECT i+1 FROM t WHERE i<110
  )
  INSERT INTO r1 SELECT i, (i%10), (i%10)+2, (i%6), (i%7)+6 FROM t;
}
do_execsql_test 2.1 {
  SELECT count(*) FROM r1_node;
} 6

# EVIDENCE-OF: R-27261-09153 All nodes other than the root have an entry
# in the %_parent shadow table that identifies the parent node.
#
# In this case nodes 2-6 are the children of node 1.
#
do_execsql_test 2.3 {
  SELECT nodeno, parentnode FROM r1_parent
} {2 1  3 1  4 1  5 1  6 1}

# EVIDENCE-OF: R-02358-35037 The %_rowid shadow table maps entry rowids
# to the node that contains that entry.
#
do_execsql_test 2.4 {
  SELECT 'failed' FROM r1_rowid WHERE 0==rnode_contains(
    (SELECT data FROM r1_node WHERE nodeno=r1_rowid.nodeno), rowid
  )
}
do_test 2.5 {
  db eval { SELECT nodeno, data FROM r1_node WHERE nodeno!=1 } {
    set L [rnode $data]
    foreach cell $L {
      set rowid [lindex $cell 0]
      set rowid_nodeno 0
      db eval {SELECT nodeno AS rowid_nodeno FROM r1_rowid WHERE rowid=$rowid} {
        break
      }
      if {$rowid_nodeno!=$nodeno} { error "data mismatch!" }
    }
  }
} {}

# EVIDENCE-OF: R-65201-22208 Extra columns appended to the %_rowid table
# hold the content of auxiliary columns.
#
# EVIDENCE-OF: R-44161-28345 The names of these extra %_rowid columns
# are probably not the same as the actual auxiliary column names.
#
# In this case, the auxiliary columns are named "e1" and "e2". The
# extra %_rowid columns are named "a0" and "a1".
#
do_execsql_test 3.0 {
  CREATE VIRTUAL TABLE rtaux USING rtree(id, x1,x2, y1,y2, +e1, +e2);
  SELECT sql FROM sqlite_schema WHERE name='rtaux_rowid';
} {
  {CREATE TABLE "rtaux_rowid"(rowid INTEGER PRIMARY KEY,nodeno,a0,a1)}
}
do_execsql_test 3.1 {
  INSERT INTO rtaux(e1, e2) VALUES('hello', 'world'), (123, 456);
}
do_execsql_test 3.2 {
  SELECT a0, a1 FROM rtaux_rowid;
} {
  hello world  123 456
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 7.2 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc-12
reset_db
forcedelete test.db2

db function rnode rnode
db function rnode_contains rnode_contains
db function rnode_replace_cell rnode_replace_cell

# EVIDENCE-OF: R-13571-45795 The scalar SQL function rtreecheck(R) or
# rtreecheck(S,R) runs an integrity check on the rtree table named R
# contained within database S.
#
# EVIDENCE-OF: R-36011-59963 The function returns a human-language
# description of any problems found, or the string 'ok' if everything is
# ok.
#
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rt1 USING rtree(id, a, b);
  WITH s(i) AS (
    VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<200
  )
  INSERT INTO rt1 SELECT i, i, i FROM s;

  ATTACH 'test.db2' AS 'aux';
  CREATE VIRTUAL TABLE aux.rt1 USING rtree(id, a, b);
  INSERT INTO aux.rt1 SELECT * FROM rt1;
}

do_execsql_test 1.1.1 { SELECT rtreecheck('rt1'); } {ok}
do_execsql_test 1.1.2 { SELECT rtreecheck('main', 'rt1'); } {ok}
do_execsql_test 1.1.3 { SELECT rtreecheck('aux', 'rt1'); } {ok}
do_catchsql_test 1.1.4 { 
  SELECT rtreecheck('nosuchdb', 'rt1'); 
} {1 {SQL logic error}}

# Corrupt the table in database 'main':
do_execsql_test 1.2.1 { UPDATE rt1_node SET nodeno=21 WHERE nodeno=3; }
do_execsql_test 1.2.1 { SELECT rtreecheck('rt1')=='ok'; } {0}
do_execsql_test 1.2.2 { SELECT rtreecheck('main', 'rt1')=='ok'; } {0}
do_execsql_test 1.2.3 { SELECT rtreecheck('aux', 'rt1')=='ok'; } {1}
do_execsql_test 1.2.4 { UPDATE rt1_node SET nodeno=3 WHERE nodeno=21; }

# Corrupt the table in database 'aux':
do_execsql_test 1.2.1 { UPDATE aux.rt1_node SET nodeno=21 WHERE nodeno=3; }
do_execsql_test 1.2.1 { SELECT rtreecheck('rt1')=='ok'; } {1}
do_execsql_test 1.2.2 { SELECT rtreecheck('main', 'rt1')=='ok'; } {1}
do_execsql_test 1.2.3 { SELECT rtreecheck('aux', 'rt1')=='ok'; } {0}
do_execsql_test 1.2.4 { UPDATE rt1_node SET nodeno=3 WHERE nodeno=21; }

# EVIDENCE-OF: R-45759-33459 Example: To verify that an R*Tree named
# "demo_index" is well-formed and internally consistent, run: SELECT
# rtreecheck('demo_index');
do_execsql_test 2.0 {
  CREATE VIRTUAL TABLE demo_index USING rtree(id, x1,x2, y1,y2);
  INSERT INTO demo_index SELECT id, a, b, a, b FROM rt1;
}
do_execsql_test 2.1 { SELECT rtreecheck('demo_index') } {ok}
do_execsql_test 2.2 {
  UPDATE demo_index_rowid SET nodeno=44 WHERE rowid=44;
  SELECT rtreecheck('demo_index');
} {{Found (44 -> 44) in %_rowid table, expected (44 -> 4)}}


do_execsql_test 3.0 {
  CREATE VIRTUAL TABLE rt2 USING rtree_i32(id, a, b, c, d);
  WITH s(i) AS (
    VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<200
  )
  INSERT INTO rt2 SELECT i, i, i+2, i, i+2 FROM s;
}

# EVIDENCE-OF: R-02555-31045 for each dimension, (coord1 <= coord2).
#
execsql BEGIN
do_test 3.1 {
  set cell [
    lindex [execsql {SELECT rnode(data) FROM rt2_node WHERE nodeno=3}] 0 3
  ]
  set cell [list [lindex $cell 0]       \
    [lindex $cell 2] [lindex $cell 1]   \
    [lindex $cell 3] [lindex $cell 4]   \
  ]
  execsql { 
    UPDATE rt2_node SET data=rnode_replace_cell(data, 3, $cell) WHERE nodeno=3 
  }
  execsql { SELECT rtreecheck('rt2') }
} {{Dimension 0 of cell 3 on node 3 is corrupt}}
execsql ROLLBACK

# EVIDENCE-OF: R-13844-15873 unless the cell is on the root node, that
# the cell is bounded by the parent cell on the parent node.
#
execsql BEGIN
do_test 3.2 {
  set cell [
    lindex [execsql {SELECT rnode(data) FROM rt2_node WHERE nodeno=3}] 0 3
  ]
  lset cell 3 450
  lset cell 4 451
  execsql { 
    UPDATE rt2_node SET data=rnode_replace_cell(data, 3, $cell) WHERE nodeno=3 
  }
  execsql { SELECT rtreecheck('rt2') }
} {{Dimension 1 of cell 3 on node 3 is corrupt relative to parent}}
execsql ROLLBACK

# EVIDENCE-OF: R-02505-03621 for leaf nodes, that there is an entry in
# the %_rowid table corresponding to the cell's rowid value that points
# to the correct node.
#
execsql BEGIN
do_test 3.3 {
  execsql { 
    UPDATE rt2_rowid SET rowid=452 WHERE rowid=100
  }
  execsql { SELECT rtreecheck('rt2') }
} {{Mapping (100 -> 6) missing from %_rowid table}}
execsql ROLLBACK

# EVIDENCE-OF: R-50927-02218 for cells on non-leaf nodes, that there is
# an entry in the %_parent table mapping from the cell's child node to
# the node that it resides on.
#
execsql BEGIN
do_test 3.4.1 {
  execsql { 
    UPDATE rt2_parent SET parentnode=123 WHERE nodeno=3
  }
  execsql { SELECT rtreecheck('rt2') }
} {{Found (3 -> 123) in %_parent table, expected (3 -> 1)}}
execsql ROLLBACK
execsql BEGIN
do_test 3.4.2 {
  execsql { 
    UPDATE rt2_parent SET nodeno=123 WHERE nodeno=3
  }
  execsql { SELECT rtreecheck('rt2') }
} {{Mapping (3 -> 1) missing from %_parent table}}
execsql ROLLBACK

# EVIDENCE-OF: R-23235-09153 That there are the same number of entries
# in the %_rowid table as there are leaf cells in the r-tree structure,
# and that there is a leaf cell that corresponds to each entry in the
# %_rowid table.
execsql BEGIN
do_test 3.5 {
  execsql { INSERT INTO rt2_rowid VALUES(1000, 1000) }
  execsql { SELECT rtreecheck('rt2') }
} {{Wrong number of entries in %_rowid table - expected 200, actual 201}}
execsql ROLLBACK

# EVIDENCE-OF: R-62800-43436 That there are the same number of entries
# in the %_parent table as there are non-leaf cells in the r-tree
# structure, and that there is a non-leaf cell that corresponds to each
# entry in the %_parent table.
execsql BEGIN
do_test 3.6 {
  execsql { INSERT INTO rt2_parent VALUES(1000, 1000) }
  execsql { SELECT rtreecheck('rt2') }
} {{Wrong number of entries in %_parent table - expected 9, actual 10}}
execsql ROLLBACK



finish_test

Added ext/rtree/rtreedoc2.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
# 2021 September 13
#
# 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.
#
#***********************************************************************
#
# The focus of this file is testing the r-tree extension.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
set testprefix rtreedoc2

ifcapable !rtree {
  finish_test
  return
}

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 6 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc2-1

# EVIDENCE-OF: R-35254-48865 A call to one of the above APIs creates a
# new SQL function named by the second parameter (zQueryFunc or zGeom).
#
# [register_circle_geom db] registers new geometry callback "Qcircle"
# and legacy implementation "circle". Test that these do actually appear.
#
do_execsql_test 1.1.0 {
  SELECT * FROM pragma_function_list WHERE name IN('circle', 'qcircle');
} {
}
do_test 1.1 {
  register_circle_geom db
} {SQLITE_OK}
do_execsql_test 1.1.2 {
  SELECT * FROM pragma_function_list WHERE name = 'circle' AND enc='utf8';
} {
  circle 0 s utf8 -1 0
}
do_execsql_test 1.1.3 {
  SELECT * FROM pragma_function_list WHERE name = 'qcircle' AND enc='utf8';
} {
  qcircle 0 s utf8 -1 0
} 

do_execsql_test 1.2.0 { SELECT circle(1, 2, 3); } {{}}
do_execsql_test 1.2.1 { SELECT qcircle(1, 2, 3); } {{}}

# EVIDENCE-OF: R-61427-46983
do_execsql_test 1.3.0 {
  CREATE VIRTUAL TABLE demo_index USING rtree(id, x1,x2, y1,y2);
  INSERT INTO demo_index VALUES(10, 45,45,  24,24);
  INSERT INTO demo_index VALUES(20, 50,50,  28,28);
  INSERT INTO demo_index VALUES(30, 43,43,  22,22);
}
do_execsql_test 1.3.1 {
  SELECT id FROM demo_index WHERE id MATCH circle(45.3, 22.9, 5.0)
} {10 30}

# EVIDENCE-OF: R-16907-50223 The SQL syntax for custom queries is the
# same regardless of which interface, sqlite3_rtree_geometry_callback()
# or sqlite3_rtree_query_callback(), is used to register the SQL
# function.
do_execsql_test 1.3.2 {
  SELECT id FROM demo_index WHERE id MATCH qcircle(45.3, 22.9, 5.0, 1)
} {10 30}


# EVIDENCE-OF: R-59634-51678 When that SQL function appears on the
# right-hand side of the MATCH operator and the left-hand side of the
# MATCH operator is any column in the R*Tree virtual table, then the
# callback defined by the third argument (xQueryFunc or xGeom) is
# invoked to determine if a particular object or subtree overlaps the
# desired region.
proc box_geom {args} {
  lappend ::box_geom [concat [lindex $args 0] [lrange $args 2 end-1]]
  return ""
}
register_box_geom db box_geom
set box_geom [list]
do_execsql_test 1.3.2 {
  SELECT id FROM demo_index WHERE id MATCH box(43,46, 21,25);
} {10 30}
do_test 1.3.3 {
  set ::box_geom
} [list {*}{
  {box {43.0 46.0 21.0 25.0} {45.0 45.0 24.0 24.0}}
  {box {43.0 46.0 21.0 25.0} {50.0 50.0 28.0 28.0}} 
  {box {43.0 46.0 21.0 25.0} {43.0 43.0 22.0 22.0}}
}]

#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
# Section 6 of documentation.
#-------------------------------------------------------------------------
#-------------------------------------------------------------------------
set testprefix rtreedoc2-2

# EVIDENCE-OF: R-02424-24769 The second argument is the number of
# coordinates in each r-tree entry, and is always the same for any given
# R*Tree.
#
# EVIDENCE-OF: R-40260-16838 The number of coordinates is 2 for a
# 1-dimensional R*Tree, 4 for a 2-dimensional R*Tree, 6 for a
# 3-dimensional R*Tree, and so forth.
#
# The second argument refered to above is the length of the list passed
# as the 3rd parameter to the Tcl script.
#
do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rt1 USING rtree(id, x1,x2);
  CREATE VIRTUAL TABLE rt2 USING rtree(id, x1,x2, y1,y2);
  CREATE VIRTUAL TABLE rt3 USING rtree(id, x1,x2, y1,y2, z1,z2);

  INSERT INTO rt1 DEFAULT VALUES;
  INSERT INTO rt2 DEFAULT VALUES;
  INSERT INTO rt3 DEFAULT VALUES;
}
foreach {tn tbl nCoord} {
  1 rt1 2     
  2 rt2 4
  3 rt3 6
} {
  set ::box_geom [list]
  do_catchsql_test 1.$tn.1 "
    SELECT id FROM $tbl WHERE id MATCH box();
  " {1 {SQL logic error}}

  do_test 1.$tn.2 {
    llength [lindex $::box_geom 0 2]
  } $nCoord
}

# EVIDENCE-OF: R-28051-48608 If xGeom returns anything other than
# SQLITE_OK, then the r-tree query will abort with an error.
proc box_geom {args} {
  error "an error!"
}
do_catchsql_test 2.0 {
  SELECT * FROM rt2 WHERE id MATCH box(22,23, 24,25); 
} {1 {SQL logic error}}

do_execsql_test 3.0 {
  INSERT INTO rt1 VALUES(10, 10, 10);
  INSERT INTO rt1 VALUES(11, 11, 11);
  INSERT INTO rt1 VALUES(12, 12, 12);
  INSERT INTO rt1 VALUES(13, 13, 13);
  INSERT INTO rt1 VALUES(14, 14, 14);
}

# EVIDENCE-OF: R-53759-57366 The exact same sqlite3_rtree_geometry
# structure is used for every callback for same MATCH operator in the
# same query.
proc box_geom {args} {
  lappend ::ptr_list [lindex $args 4]
  return 0
}
set ::ptr_list [list]
do_execsql_test 3.1 {
  SELECT * FROM rt1 WHERE id MATCH box(1,1);
}
do_test 3.2 {
  set val [lindex $::ptr_list 0]
  foreach p $::ptr_list {
    if {$p!=$val} {error "pointer mismatch"}
  }
} {}

# EVIDENCE-OF: R-60247-35692 The contents of the sqlite3_rtree_geometry
# structure are initialized by SQLite but are not subsequently modified.
proc box_geom {args} {
  lappend ::box_geom [concat [lindex $args 0] [lrange $args 2 end-1]]
  if {[llength $::box_geom]==3} {
    return "zero"
  }
  return ""
}
set ::box_geom [list]
do_catchsql_test 3.2 {
  SELECT * FROM rt1 WHERE id MATCH box(1,1);
} {1 {SQL logic error}}
do_test 3.3 {
  set ::box_geom
} [list {*}{
  {box {1.0 1.0} {0.0 0.0}} 
  {box {1.0 1.0} {10.0 10.0}} 
  {box {1.0 1.0} {11.0 11.0}} 
  {box 0.0 {12.0 12.0}}
}]

# EVIDENCE-OF: R-31246-29731 The pContext member of the
# sqlite3_rtree_geometry structure is always set to a copy of the
# pContext argument passed to sqlite3_rtree_geometry_callback() when the
# callback is registered.
reset_db
do_execsql_test 4.0 {
  CREATE VIRTUAL TABLE r1 USING rtree(id, minX,maxX, minY,maxY);
  WITH s(i) AS (
    VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<120
  )
  INSERT INTO r1 SELECT i,i,i+1,  200,201 FROM s;
}
set ctx [register_box_geom db box_geom]
set ::box_geom [list]
proc box_geom {args} {
  lappend ::box_geom [lindex $args 1]
  return ""
}
do_execsql_test 4.1 {
  SELECT count(*) FROM r1 WHERE id MATCH box(0,150,199,201)
} 120
do_test 4.2 {
  foreach g $::box_geom {
    if {$g!=$ctx} {error "pointer mismatch"}
  }
} {}

# EVIDENCE-OF: R-09904-19077 The aParam[] array (size nParam) contains
# the parameter values passed to the SQL function on the right-hand side
# of the MATCH operator.
proc box_geom {args} {
  set ::box_geom [lindex $args 2]
}
foreach {tn q vals} {
  1 "SELECT count(*) FROM r1 WHERE id MATCH box(1,2,3)" {1.0 2.0 3.0}
  2 "SELECT count(*) FROM r1 WHERE id MATCH box(10001)" {10001.0}
  3 "SELECT count(*) FROM r1 WHERE id MATCH box(-10001)" {-10001.0}
} {
  do_catchsql_test 5.$tn.1 $q {1 {SQL logic error}}
  do_test 5.$tn.2 { set ::box_geom } $vals
}

do_execsql_test 5.0 {
  CREATE VIRTUAL TABLE myrtree USING rtree(id, x1,x2);
  INSERT INTO myrtree VALUES(1, 1, 1);
  INSERT INTO myrtree VALUES(2, 2, 2);
  INSERT INTO myrtree VALUES(3, 3, 3);
}

# EVIDENCE-OF: R-44448-00687 The pUser and xDelUser members of the
# sqlite3_rtree_geometry structure are initially set to NULL.
set ::box_geom_calls 0
proc box_geom {args} {
  incr ::box_geom_calls
  return user_is_zero
}
do_execsql_test 5.1.1 {
  SELECT * FROM myrtree WHERE id MATCH box(4, 5);
} 
do_test 5.1.2 { set ::box_geom_calls } 3


# EVIDENCE-OF: R-55837-00155 The pUser variable may be set by the
# callback implementation to any arbitrary value that may be useful to
# subsequent invocations of the callback within the same query (for
# example, a pointer to a complicated data structure used to test for
# region intersection).
#
# EVIDENCE-OF: R-34745-08839 If the xDelUser variable is set to a
# non-NULL value, then after the query has finished running SQLite
# automatically invokes it with the value of the pUser variable as the
# only argument.
#
set ::box_geom_calls 0
proc box_geom {args} {
  incr ::box_geom_calls
  switch -- $::box_geom_calls {
    1 {
      return user_is_zero
    }
    2 {
      return [list user box_geom_finalizer]
    }
  }
  return ""
}
proc box_geom_finalizer {} {
  set ::box_geom_finalizer "::box_geom_calls is $::box_geom_calls"
}
do_execsql_test 5.1.1 {
  SELECT * FROM myrtree WHERE id MATCH box(4, 5);
} 
do_test 5.1.2 { set ::box_geom_calls } 3
do_test 5.1.3 {
  set ::box_geom_finalizer
} {::box_geom_calls is 3}
 

# EVIDENCE-OF: R-28176-28813 The xGeom callback always does a
# depth-first search of the r-tree.
#
# For a breadth first search, final test case would return "B L" only.
#
do_execsql_test 6.0 {
  CREATE VIRTUAL TABLE xyz USING rtree(x, x1,x2, y1,y2);
  WITH s(i) AS (
    VALUES(1) UNION ALL SELECT i+1 FROM s WHERE i<15
  )
  INSERT INTO xyz SELECT NULL, one.i,one.i+1,  two.i,two.i+1 FROM s one, s two;
}
do_execsql_test 6.1 {
  SELECT count(*) FROM xyz_node
} {10}
proc box_geom {args} {
  set coords [lindex $args 3]
  set area [expr {
    ([lindex $coords 1]-[lindex $coords 0]) * 
    ([lindex $coords 3]-[lindex $coords 2])
  }]
  if {$area==1} {
    lappend ::box_geom_calls L
  } else {
    lappend ::box_geom_calls B
  }
}
set ::box_geom_calls [list]
do_execsql_test 6.2 {
  SELECT count(*) FROM xyz WHERE x MATCH box(0,20,0,20)
} 225
do_test 6.3 {
  set prev ""
  set box_calls [list]
  foreach c $::box_geom_calls {
    if {$c!=$prev} {
      lappend ::box_calls $c
      set prev $c
    }
  }
  set ::box_calls
} {B L B L B L B L B L B L B L B L B L}


finish_test

Added ext/rtree/rtreedoc3.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
# 2021 September 13
#
# 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.
#
#***********************************************************************
#
# The focus of this file is testing the r-tree extension.
#

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
}
source [file join [file dirname [info script]] rtree_util.tcl]
source $testdir/tester.tcl
set testprefix rtreedoc3

ifcapable !rtree {
  finish_test
  return
}


# This command assumes that the argument is a node blob for a 2 dimensional
# i32 r-tree table. It decodes and returns a list of cells from the node
# as a list. Each cell is itself a list of the following form:
#
#    {$rowid $minX $maxX $minY $maxY}
#
# For internal (non-leaf) nodes, the rowid is replaced by the child node
# number.
#
proc rnode_cells {aData} {
  set nDim 2

  set nData [string length $aData]
  set nBytePerCell [expr (8 + 2*$nDim*4)]
  binary scan [string range $aData 2 3] S nCell

  set res [list]
  for {set i 0} {$i < $nCell} {incr i} {
    set iOff [expr $i*$nBytePerCell+4]
    set cell [string range $aData $iOff [expr $iOff+$nBytePerCell-1]]
    binary scan $cell WIIII rowid x1 x2 y1 y2
    lappend res [list $rowid $x1 $x2 $y1 $y2]
  }

  return $res
}

# Interpret the first two bytes of the blob passed as the only parameter
# as a 16-bit big-endian integer and return the value. If this blob is
# the root node of an r-tree, this value is the height of the tree.
#
proc rnode_height {aData} {
  binary scan [string range $aData 0 1] S nHeight
  return $nHeight
}

# Return a blob containing node iNode of r-tree "rt".
#
proc rt_node_get {iNode} {
  db one { SELECT data FROM rt_node WHERE nodeno=$iNode }
}


#--------------------------------------------------------------
# API:
#
#    pq_init 
#      Initialize a new test.
#
#    pq_test_callback
#      Invoked each time the xQueryCallback function is called. This Tcl
#      command checks that the arguments that SQLite passed to xQueryCallback
#      are as expected.
#
#    pq_test_row
#      Invoked each time a row is returned. Checks that the row returned
#      was predicted by the documentation.
#
# DATA STRUCTURE:
#    The priority queue is stored as a Tcl list. The order of elements in 
#    the list is unimportant - it is just used as a set here. Each element
#    in the priority queue is itself a list. The first element is the
#    priority value for the entry (a real). Following this is a list of
#    key-value pairs that make up the entries fields.
#
proc pq_init {} {
  global Q 
  set Q(pri_queue)  [list]

  set nHeight [rnode_height [rt_node_get 1]]
  set nCell [llength [rnode_cells [rt_node_get 1]]]

  # EVIDENCE-OF: R-54708-13595 An R*Tree query is initialized by making
  # the root node the only entry in a priority queue sorted by rScore.
  lappend Q(pri_queue) [list 0.0 [list \
    iLevel [expr $nHeight+1] \
    iChild 1                 \
    iCurrent   0             \
  ]]
}

proc pq_extract {} {
  global Q
  if {[llength $Q(pri_queue)]==0} {
    error "priority queue is empty!"
  }

  # Find the priority queue entry with the lowest score.
  #
  # EVIDENCE-OF: R-47257-47871 Smaller scores are processed first.
  set iBest 0
  set rBestScore [lindex $Q(pri_queue) 0 0]
  for {set ii 1} {$ii < [llength $Q(pri_queue)]} {incr ii} {
    set rScore [expr [lindex $Q(pri_queue) $ii 0]]
    if {$rScore<$rBestScore} {
      set rBestScore $rScore
      set iBest $ii
    }
  }

  # Extract the entry with the lowest score from the queue and return it. 
  #
  # EVIDENCE-OF: R-60002-49798 The query proceeds by extracting the entry
  # from the priority queue that has the lowest score.
  set ret [lindex $Q(pri_queue) $iBest]
  set Q(pri_queue) [lreplace $Q(pri_queue) $iBest $iBest]

  return $ret
}

proc pq_new_entry {rScore iLevel cell} {
  global Q

  set rowid_name "iChild"
  if {$iLevel==0} { set rowid_name "iRowid" }

  set kv [list]
  lappend kv aCoord [lrange $cell 1 end]
  lappend kv iLevel $iLevel

  if {$iLevel==0} {
    lappend kv iRowid [lindex $cell 0]
  } else {
    lappend kv iChild [lindex $cell 0]
    lappend kv iCurrent 0
  }

  lappend Q(pri_queue) [list $rScore $kv]
}

proc pq_test_callback {L res} {
  #pq_debug "pq_test_callback $L -> $res"
  global Q

  array set G $L    ;# "Got" - as in stuff passed to xQuery

  # EVIDENCE-OF: R-65127-42665 If the extracted priority queue entry is a
  # node (a subtree), then the next child of that node is passed to the
  # xQueryFunc callback.
  #
  # If it had been a leaf, the row should have been returned, instead of
  # xQueryCallback being called on a child - as is happening here.
  foreach {rParentScore parent} [pq_extract] {}
  array set P $parent ;# "Parent" - as in parent of expected cell
  if {$P(iLevel)==0} { error "query callback mismatch (1)" }
  set child_node [rnode_cells [rt_node_get $P(iChild)]]
  set expected_cell [lindex $child_node $P(iCurrent)]
  set expected_coords [lrange $expected_cell 1 end]
  if {[llength $expected_coords] != [llength $G(aCoord)]} {
  puts [array get P]
  puts "E: $expected_coords  G: $G(aCoord)"
    error "coordinate mismatch in query callback (1)"
  }
  foreach a [lrange $expected_cell 1 end] b $G(aCoord) {
    if {$a!=$b} { error "coordinate mismatch in query callback (2)" }
  }

  # Check level is as expected
  #
  if {$G(iLevel) != $P(iLevel)-1} {
    error "iLevel mismatch in query callback (1)"
  }

  # Unless the callback returned NOT_WITHIN, add the entry to the priority
  # queue.
  #
  # EVIDENCE-OF: R-28754-35153 Those subelements for which the xQueryFunc
  # callback sets eWithin to PARTLY_WITHIN or FULLY_WITHIN are added to
  # the priority queue using the score supplied by the callback.
  #
  # EVIDENCE-OF: R-08681-45277 Subelements that return NOT_WITHIN are
  # discarded.
  set r [lindex $res 0]
  set rScore [lindex $res 1]
  if {$r!="fully" && $r!="partly" && $r!="not"} {
    error "unknown result: $r - expected \"fully\", \"partly\" or \"not\""
  }
  if {$r!="not"} {
    pq_new_entry $rScore [expr $P(iLevel)-1] $expected_cell
  }

  # EVIDENCE-OF: R-07194-63805 If the node has more children then it is
  # returned to the priority queue. Otherwise it is discarded.
  incr P(iCurrent)
  if {$P(iCurrent)<[llength $child_node]} {
    lappend Q(pri_queue) [list $rParentScore [array get P]]
  }
}

proc pq_test_result {id x1 x2 y1 y2} {
  #pq_debug "pq_test_result $id $x1 $x2 $y1 $y2"
  foreach {rScore next} [pq_extract] {}

  # The extracted entry must be a leaf (otherwise, xQueryCallback would
  # have been called on the extracted entries children instead of just
  # returning the data).
  #
  # EVIDENCE-OF: R-13214-54017 If that entry is a leaf (meaning that it is
  # an actual R*Tree entry and not a subtree) then that entry is returned
  # as one row of the query result.
  array set N $next
  if {$N(iLevel)!=0} { error "result row mismatch (1)" }

  if {$x1!=[lindex $N(aCoord) 0] || $x2!=[lindex $N(aCoord) 1]
   || $y1!=[lindex $N(aCoord) 2] || $y2!=[lindex $N(aCoord) 3]
  } {
    if {$N(iLevel)!=0} { error "result row mismatch (2)" }
  }

  if {$id!=$N(iRowid)} { error "result row mismatch (3)" }
}

proc pq_done {} {
  global Q
  # EVIDENCE-OF: R-57438-45968 The query runs until the priority queue is
  # empty.
  if {[llength $Q(pri_queue)]>0} {
    error "priority queue is not empty!"
  }
}

proc pq_debug {caption} {
  global Q

  puts "**** $caption ****"
  set i 0
  foreach q [lsort -real -index 0 $Q(pri_queue)] { 
    puts "PQ $i: $q" 
    incr i
  }
}

#--------------------------------------------------------------

proc box_query {a} {
  set res [list fully [expr rand()]]
  pq_test_callback $a $res
  return $res
}

register_box_query db box_query

do_execsql_test 1.0 {
  CREATE VIRTUAL TABLE rt USING rtree_i32(id,  x1,x2,  y1,y2);
  WITH s(i) AS (
    SELECT 0 UNION ALL SELECT i+1 FROM s WHERE i<64
  )
  INSERT INTO rt SELECT NULL, a.i, a.i+1, b.i, b.i+1 FROM s a, s b;
}

proc box_query {a} {
  set res [list fully [expr rand()]]
  pq_test_callback $a $res
  return $res
}

pq_init
db eval { SELECT id, x1,x2, y1,y2 FROM rt WHERE id MATCH qbox() } {
  pq_test_result $id $x1 $x2 $y1 $y2
}
pq_done

finish_test


Added ext/rtree/test_rtreedoc.c.


























































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
** 2010 August 28
**
** 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.
**
*************************************************************************
** Code for testing all sorts of SQLite interfaces. This code
** is not included in the SQLite library. 
*/

#include "sqlite3.h"
#if defined(INCLUDE_SQLITE_TCL_H)
#  include "sqlite_tcl.h"
#else
#  include "tcl.h"
#endif

/* Solely for the UNUSED_PARAMETER() macro. */
#include "sqliteInt.h"

#ifdef SQLITE_ENABLE_RTREE

typedef struct BoxGeomCtx BoxGeomCtx;
struct BoxGeomCtx {
  Tcl_Interp *interp;
  Tcl_Obj *pScript;
};

typedef struct BoxQueryCtx BoxQueryCtx;
struct BoxQueryCtx {
  Tcl_Interp *interp;
  Tcl_Obj *pScript;
};

static void testDelUser(void *pCtx){
  BoxGeomCtx *p = (BoxGeomCtx*)pCtx;
  Tcl_EvalObjEx(p->interp, p->pScript, 0);
  Tcl_DecrRefCount(p->pScript);
  sqlite3_free(p);
}

static int invokeTclGeomCb(
  const char *zName, 
  sqlite3_rtree_geometry *p, 
  int nCoord,
  sqlite3_rtree_dbl *aCoord
){
  int rc = SQLITE_OK;
  if( p->pContext ){
    char aPtr[64];
    BoxGeomCtx *pCtx = (BoxGeomCtx*)p->pContext;
    Tcl_Interp *interp = pCtx->interp;
    Tcl_Obj *pScript = 0;
    Tcl_Obj *pParam = 0;
    Tcl_Obj *pCoord = 0;
    int ii;
    Tcl_Obj *pRes;


    pScript = Tcl_DuplicateObj(pCtx->pScript);
    Tcl_IncrRefCount(pScript);
    Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(zName,-1));

    sqlite3_snprintf(sizeof(aPtr)-1, aPtr, "%p", (void*)p->pContext);
    Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(aPtr,-1));

    pParam = Tcl_NewObj();
    for(ii=0; ii<p->nParam; ii++){
      Tcl_ListObjAppendElement(
          interp, pParam, Tcl_NewDoubleObj(p->aParam[ii])
      );
    }
    Tcl_ListObjAppendElement(interp, pScript, pParam);

    pCoord = Tcl_NewObj();
    for(ii=0; ii<nCoord; ii++){
      Tcl_ListObjAppendElement(interp, pCoord, Tcl_NewDoubleObj(aCoord[ii]));
    }
    Tcl_ListObjAppendElement(interp, pScript, pCoord);

    sqlite3_snprintf(sizeof(aPtr)-1, aPtr, "%p", (void*)p);
    Tcl_ListObjAppendElement(interp, pScript, Tcl_NewStringObj(aPtr,-1));

    rc = Tcl_EvalObjEx(interp, pScript, 0);
    if( rc!=TCL_OK ){
      rc = SQLITE_ERROR;
    }else{
      int nObj = 0;
      Tcl_Obj **aObj = 0;

      pRes = Tcl_GetObjResult(interp);
      if( Tcl_ListObjGetElements(interp, pRes, &nObj, &aObj) ) return TCL_ERROR;
      if( nObj>0 ){
        const char *zCmd = Tcl_GetString(aObj[0]);
        if( 0==sqlite3_stricmp(zCmd, "zero") ){
          p->aParam[0] = 0.0;
          p->nParam = 1;
        }
        else if( 0==sqlite3_stricmp(zCmd, "user") ){
          if( p->pUser || p->xDelUser ){
            rc = SQLITE_ERROR;
          }else{
            BoxGeomCtx *pCtx = sqlite3_malloc(sizeof(BoxGeomCtx));
            if( pCtx==0 ){
              rc = SQLITE_NOMEM;
            }else{
              pCtx->interp = interp;
              pCtx->pScript = Tcl_DuplicateObj(pRes);
              Tcl_IncrRefCount(pCtx->pScript);
              Tcl_ListObjReplace(interp, pCtx->pScript, 0, 1, 0, 0);
              p->pUser = (void*)pCtx;
              p->xDelUser = testDelUser;
            }
          }
        }
        else if( 0==sqlite3_stricmp(zCmd, "user_is_zero") ){
          if( p->pUser || p->xDelUser ) rc = SQLITE_ERROR;
        }
      }
    }
  }
  return rc;
}

/*
# EVIDENCE-OF: R-00693-36727 The legacy xGeom callback is invoked with
# four arguments.

# EVIDENCE-OF: R-50437-53270 The first argument is a pointer to an
# sqlite3_rtree_geometry structure which provides information about how
# the SQL function was invoked.

# EVIDENCE-OF: R-00090-24248 The third argument, aCoord[], is an array
# of nCoord coordinates that defines a bounding box to be tested.

# EVIDENCE-OF: R-28207-40885 The last argument is a pointer into which
# the callback result should be written.

*/
static int box_geom(
  sqlite3_rtree_geometry *p,      /* R-50437-53270 */
  int nCoord,                     /* R-02424-24769 */
  sqlite3_rtree_dbl *aCoord,      /* R-00090-24248 */
  int *pRes                       /* R-28207-40885 */
){
  int ii;

  if( p->nParam!=nCoord ){
    invokeTclGeomCb("box", p, nCoord, aCoord);
    return SQLITE_ERROR;
  }
  if( invokeTclGeomCb("box", p, nCoord, aCoord) ) return SQLITE_ERROR;

  for(ii=0; ii<nCoord; ii+=2){
    if( aCoord[ii]>p->aParam[ii+1] || aCoord[ii+1]<p->aParam[ii] ){
      /* R-28207-40885 */
      *pRes = 0;
      return SQLITE_OK;
    }
  }

  /* R-28207-40885 */
  *pRes = 1;

  return SQLITE_OK;
}

static int SQLITE_TCLAPI register_box_geom(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
  extern const char *sqlite3ErrName(int);
  sqlite3 *db;
  BoxGeomCtx *pCtx;
  char aPtr[64];

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB SCRIPT");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;

  pCtx = (BoxGeomCtx*)ckalloc(sizeof(BoxGeomCtx*));
  pCtx->interp = interp;
  pCtx->pScript = Tcl_DuplicateObj(objv[2]);
  Tcl_IncrRefCount(pCtx->pScript);

  sqlite3_rtree_geometry_callback(db, "box", box_geom, (void*)pCtx);

  sqlite3_snprintf(64, aPtr, "%p", (void*)pCtx);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(aPtr, -1));
  return TCL_OK;
}

static int box_query(sqlite3_rtree_query_info *pInfo){
  const char *azParentWithin[] = {"not", "partly", "fully", 0};
  BoxQueryCtx *pCtx = (BoxQueryCtx*)pInfo->pContext;
  Tcl_Interp *interp = pCtx->interp;
  Tcl_Obj *pEval;
  Tcl_Obj *pArg;
  Tcl_Obj *pTmp = 0;
  int rc;
  int ii;

  pEval = Tcl_DuplicateObj(pCtx->pScript);
  Tcl_IncrRefCount(pEval);
  pArg = Tcl_NewObj();
  Tcl_IncrRefCount(pArg);

  /* aParam[] */
  pTmp = Tcl_NewObj();
  Tcl_IncrRefCount(pTmp);
  for(ii=0; ii<pInfo->nParam; ii++){
    Tcl_Obj *p = Tcl_NewDoubleObj(pInfo->aParam[ii]);
    Tcl_ListObjAppendElement(interp, pTmp, p);
  }
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("aParam", -1));
  Tcl_ListObjAppendElement(interp, pArg, pTmp);
  Tcl_DecrRefCount(pTmp);

  /* aCoord[] */
  pTmp = Tcl_NewObj();
  Tcl_IncrRefCount(pTmp);
  for(ii=0; ii<pInfo->nCoord; ii++){
    Tcl_Obj *p = Tcl_NewDoubleObj(pInfo->aCoord[ii]);
    Tcl_ListObjAppendElement(interp, pTmp, p);
  }
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("aCoord", -1));
  Tcl_ListObjAppendElement(interp, pArg, pTmp);
  Tcl_DecrRefCount(pTmp);

  /* anQueue[] */
  pTmp = Tcl_NewObj();
  Tcl_IncrRefCount(pTmp);
  for(ii=0; ii<=pInfo->mxLevel; ii++){
    Tcl_Obj *p = Tcl_NewIntObj((int)pInfo->anQueue[ii]);
    Tcl_ListObjAppendElement(interp, pTmp, p);
  }
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("anQueue", -1));
  Tcl_ListObjAppendElement(interp, pArg, pTmp);
  Tcl_DecrRefCount(pTmp);
  
  /* iLevel */
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("iLevel", -1));
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewIntObj(pInfo->iLevel));

  /* mxLevel */
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("mxLevel", -1));
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewIntObj(pInfo->mxLevel));

  /* iRowid */
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("iRowid", -1));
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewWideIntObj(pInfo->iRowid));

  /* rParentScore */
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("rParentScore", -1));
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewDoubleObj(pInfo->rParentScore));

  /* eParentWithin */
  assert( pInfo->eParentWithin==0 
       || pInfo->eParentWithin==1 
       || pInfo->eParentWithin==2 
  );
  Tcl_ListObjAppendElement(interp, pArg, Tcl_NewStringObj("eParentWithin", -1));
  Tcl_ListObjAppendElement(interp, pArg, 
      Tcl_NewStringObj(azParentWithin[pInfo->eParentWithin], -1)
  );

  Tcl_ListObjAppendElement(interp, pEval, pArg);
  rc = Tcl_EvalObjEx(interp, pEval, 0) ? SQLITE_ERROR : SQLITE_OK;

  if( rc==SQLITE_OK ){
    double rScore = 0.0;
    int nObj = 0;
    int eP = 0;
    Tcl_Obj **aObj = 0;
    Tcl_Obj *pRes = Tcl_GetObjResult(interp);

    if( Tcl_ListObjGetElements(interp, pRes, &nObj, &aObj) 
     || nObj!=2 
     || Tcl_GetDoubleFromObj(interp, aObj[1], &rScore)
     || Tcl_GetIndexFromObj(interp, aObj[0], azParentWithin, "value", 0, &eP)
    ){
      rc = SQLITE_ERROR;
    }else{
      pInfo->rScore = rScore;
      pInfo->eParentWithin = eP;
    }
  }

  Tcl_DecrRefCount(pArg);
  Tcl_DecrRefCount(pEval);
  return rc;
}

static void box_query_destroy(void *p){
  BoxQueryCtx *pCtx = (BoxQueryCtx*)p;
  Tcl_DecrRefCount(pCtx->pScript);
  ckfree(pCtx);
}

static int SQLITE_TCLAPI register_box_query(
  void * clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  extern int getDbPointer(Tcl_Interp*, const char*, sqlite3**);
  extern const char *sqlite3ErrName(int);
  sqlite3 *db;
  BoxQueryCtx *pCtx;

  if( objc!=3 ){
    Tcl_WrongNumArgs(interp, 1, objv, "DB SCRIPT");
    return TCL_ERROR;
  }
  if( getDbPointer(interp, Tcl_GetString(objv[1]), &db) ) return TCL_ERROR;

  pCtx = (BoxQueryCtx*)ckalloc(sizeof(BoxQueryCtx*));
  pCtx->interp = interp;
  pCtx->pScript = Tcl_DuplicateObj(objv[2]);
  Tcl_IncrRefCount(pCtx->pScript);

  sqlite3_rtree_query_callback(
      db, "qbox", box_query, (void*)pCtx, box_query_destroy
  );

  Tcl_ResetResult(interp);
  return TCL_OK;
}
#endif /* SQLITE_ENABLE_RTREE */


int Sqlitetestrtreedoc_Init(Tcl_Interp *interp){
#ifdef SQLITE_ENABLE_RTREE
  Tcl_CreateObjCommand(interp, "register_box_geom", register_box_geom, 0, 0);
  Tcl_CreateObjCommand(interp, "register_box_query", register_box_query, 0, 0);
#endif /* SQLITE_ENABLE_RTREE */
  return TCL_OK;
}

Changes to ext/session/sessionat.test.
16
17
18
19
20
21
22

23


24


25
26
27
28
29
30
31

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}




set testprefix sessionat



db close
sqlite3_shutdown
test_sqlite3_log log
proc log {code msg} { lappend ::log $code $msg }

proc reset_test {} {







>

>
>
|
>
>







16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

if {![info exists testdir]} {
  set testdir [file join [file dirname [info script]] .. .. test]
} 
source [file join [file dirname [info script]] session_common.tcl]
source $testdir/tester.tcl
ifcapable !session {finish_test; return}
set testprefix sessionat

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

db close
sqlite3_shutdown
test_sqlite3_log log
proc log {code msg} { lappend ::log $code $msg }

proc reset_test {} {
Changes to main.mk.
384
385
386
387
388
389
390
391

392
393
394
395
396
397
398
  $(TOP)/ext/misc/spellfix.c \
  $(TOP)/ext/misc/totype.c \
  $(TOP)/ext/misc/unionvtab.c \
  $(TOP)/ext/misc/wholenumber.c \
  $(TOP)/ext/misc/zipfile.c \
  $(TOP)/ext/fts5/fts5_tcl.c \
  $(TOP)/ext/fts5/fts5_test_mi.c \
  $(TOP)/ext/fts5/fts5_test_tok.c



#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c

TESTSRC2 = \
  $(TOP)/src/attach.c \







|
>







384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
  $(TOP)/ext/misc/spellfix.c \
  $(TOP)/ext/misc/totype.c \
  $(TOP)/ext/misc/unionvtab.c \
  $(TOP)/ext/misc/wholenumber.c \
  $(TOP)/ext/misc/zipfile.c \
  $(TOP)/ext/fts5/fts5_tcl.c \
  $(TOP)/ext/fts5/fts5_test_mi.c \
  $(TOP)/ext/fts5/fts5_test_tok.c \
  $(TOP)/ext/rtree/test_rtreedoc.c


#TESTSRC += $(TOP)/ext/fts2/fts2_tokenizer.c
#TESTSRC += $(TOP)/ext/fts3/fts3_tokenizer.c

TESTSRC2 = \
  $(TOP)/src/attach.c \
Changes to src/alter.c.
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
  if( !zNew ) goto exit_rename_column;
  assert( pNew->n>0 );
  bQuote = sqlite3Isquote(pNew->z[0]);
  sqlite3NestedParse(pParse, 
      "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
      " AND (type != 'index' OR tbl_name = %Q)"
      " AND sql NOT LIKE 'create virtual%%'",
      zDb,
      zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
      pTab->zName
  );

  sqlite3NestedParse(pParse, 
      "UPDATE temp." DFLT_SCHEMA_TABLE " SET "







|
<







643
644
645
646
647
648
649
650

651
652
653
654
655
656
657
  if( !zNew ) goto exit_rename_column;
  assert( pNew->n>0 );
  bQuote = sqlite3Isquote(pNew->z[0]);
  sqlite3NestedParse(pParse, 
      "UPDATE \"%w\"." DFLT_SCHEMA_TABLE " SET "
      "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) "
      "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' "
      " AND (type != 'index' OR tbl_name = %Q)",

      zDb,
      zDb, pTab->zName, iCol, zNew, bQuote, iSchema==1,
      pTab->zName
  );

  sqlite3NestedParse(pParse, 
      "UPDATE temp." DFLT_SCHEMA_TABLE " SET "
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
** routine is used to keep the mapping current.
**
** After the parse finishes, renameTokenFind() routine can be used
** to look up the actual token value that created some element in
** the parse tree.
*/
struct RenameToken {
  void *p;               /* Parse tree element created by token t */
  Token t;               /* The token that created parse tree element p */
  RenameToken *pNext;    /* Next is a list of all RenameToken objects */
};

/*
** The context of an ALTER TABLE RENAME COLUMN operation that gets passed
** down into the Walker.







|







685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
** routine is used to keep the mapping current.
**
** After the parse finishes, renameTokenFind() routine can be used
** to look up the actual token value that created some element in
** the parse tree.
*/
struct RenameToken {
  const void *p;         /* Parse tree element created by token t */
  Token t;               /* The token that created parse tree element p */
  RenameToken *pNext;    /* Next is a list of all RenameToken objects */
};

/*
** The context of an ALTER TABLE RENAME COLUMN operation that gets passed
** down into the Walker.
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
**
**     sqlite3_free(x);
**     if( x==y ) ...
**
** Technically, as x no longer points into a valid object or to the byte
** following a valid object, it may not be used in comparison operations.
*/
static void renameTokenCheckAll(Parse *pParse, void *pPtr){
  if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
    RenameToken *p;
    u8 i = 0;
    for(p=pParse->pRename; p; p=p->pNext){
      if( p->p ){
        assert( p->p!=pPtr );
        i += *(u8*)(p->p);
      }
    }







|

|







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
**
**     sqlite3_free(x);
**     if( x==y ) ...
**
** Technically, as x no longer points into a valid object or to the byte
** following a valid object, it may not be used in comparison operations.
*/
static void renameTokenCheckAll(Parse *pParse, const void *pPtr){
  if( pParse->nErr==0 && pParse->db->mallocFailed==0 ){
    const RenameToken *p;
    u8 i = 0;
    for(p=pParse->pRename; p; p=p->pNext){
      if( p->p ){
        assert( p->p!=pPtr );
        i += *(u8*)(p->p);
      }
    }
756
757
758
759
760
761
762
763




764
765
766
767
768
769
770
** to the list of RenameToken objects currently being built up
** in pParse->pRename.
**
** The pPtr argument is returned so that this routine can be used
** with tail recursion in tokenExpr() routine, for a small performance
** improvement.
*/
void *sqlite3RenameTokenMap(Parse *pParse, void *pPtr, Token *pToken){




  RenameToken *pNew;
  assert( pPtr || pParse->db->mallocFailed );
  renameTokenCheckAll(pParse, pPtr);
  if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){
    pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
    if( pNew ){
      pNew->p = pPtr;







|
>
>
>
>







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
** to the list of RenameToken objects currently being built up
** in pParse->pRename.
**
** The pPtr argument is returned so that this routine can be used
** with tail recursion in tokenExpr() routine, for a small performance
** improvement.
*/
const void *sqlite3RenameTokenMap(
  Parse *pParse,
  const void *pPtr,
  const Token *pToken
){
  RenameToken *pNew;
  assert( pPtr || pParse->db->mallocFailed );
  renameTokenCheckAll(pParse, pPtr);
  if( ALWAYS(pParse->eParseMode!=PARSE_MODE_UNMAP) ){
    pNew = sqlite3DbMallocZero(pParse->db, sizeof(RenameToken));
    if( pNew ){
      pNew->p = pPtr;
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
}

/*
** It is assumed that there is already a RenameToken object associated
** with parse tree element pFrom. This function remaps the associated token
** to parse tree element pTo.
*/
void sqlite3RenameTokenRemap(Parse *pParse, void *pTo, void *pFrom){
  RenameToken *p;
  renameTokenCheckAll(pParse, pTo);
  for(p=pParse->pRename; p; p=p->pNext){
    if( p->p==pFrom ){
      p->p = pTo;
      break;
    }
  }
}

/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
  Parse *pParse = pWalker->pParse;
  sqlite3RenameTokenRemap(pParse, 0, (void*)pExpr);

  return WRC_Continue;
}

/*
** Iterate through the Select objects that are part of WITH clauses attached
** to select statement pSelect.
*/







|















|
>







781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
}

/*
** It is assumed that there is already a RenameToken object associated
** with parse tree element pFrom. This function remaps the associated token
** to parse tree element pTo.
*/
void sqlite3RenameTokenRemap(Parse *pParse, const void *pTo, const void *pFrom){
  RenameToken *p;
  renameTokenCheckAll(pParse, pTo);
  for(p=pParse->pRename; p; p=p->pNext){
    if( p->p==pFrom ){
      p->p = pTo;
      break;
    }
  }
}

/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapExprCb(Walker *pWalker, Expr *pExpr){
  Parse *pParse = pWalker->pParse;
  sqlite3RenameTokenRemap(pParse, 0, (const void*)pExpr);
  sqlite3RenameTokenRemap(pParse, 0, (const void*)&pExpr->y.pTab);
  return WRC_Continue;
}

/*
** Iterate through the Select objects that are part of WITH clauses attached
** to select statement pSelect.
*/
824
825
826
827
828
829
830

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
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
883
884
885
886
    }
    for(i=0; i<pWith->nCte; i++){
      Select *p = pWith->a[i].pSelect;
      NameContext sNC;
      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pParse;
      if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC);

      sqlite3WalkSelect(pWalker, p);
      sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols);
    }
    if( pCopy && pParse->pWith==pCopy ){
      pParse->pWith = pCopy->pOuter;
    }
  }
}

/*
** Unmap all tokens in the IdList object passed as the second argument.
*/
static void unmapColumnIdlistNames(
  Parse *pParse,
  IdList *pIdList
){
  if( pIdList ){
    int ii;
    for(ii=0; ii<pIdList->nId; ii++){
      sqlite3RenameTokenRemap(pParse, 0, (void*)pIdList->a[ii].zName);
    }
  }
}

/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
  Parse *pParse = pWalker->pParse;
  int i;
  if( pParse->nErr ) return WRC_Abort;
  if( p->selFlags & (SF_View|SF_CopyCte) ){
    testcase( p->selFlags & SF_View );
    testcase( p->selFlags & SF_CopyCte );
    return WRC_Prune;
  }
  if( ALWAYS(p->pEList) ){
    ExprList *pList = p->pEList;
    for(i=0; i<pList->nExpr; i++){
      if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
        sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
      }
    }
  }
  if( ALWAYS(p->pSrc) ){  /* Every Select as a SrcList, even if it is empty */
    SrcList *pSrc = p->pSrc;
    for(i=0; i<pSrc->nSrc; i++){
      sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
      if( sqlite3WalkExpr(pWalker, pSrc->a[i].pOn) ) return WRC_Abort;
      unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
    }
  }

  renameWalkWith(pWalker, p);
  return WRC_Continue;
}







>














|




|











|
<
<














|







828
829
830
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
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
883
884
885
886
887
888
889
    }
    for(i=0; i<pWith->nCte; i++){
      Select *p = pWith->a[i].pSelect;
      NameContext sNC;
      memset(&sNC, 0, sizeof(sNC));
      sNC.pParse = pParse;
      if( pCopy ) sqlite3SelectPrep(sNC.pParse, p, &sNC);
      if( sNC.pParse->db->mallocFailed ) return;
      sqlite3WalkSelect(pWalker, p);
      sqlite3RenameExprlistUnmap(pParse, pWith->a[i].pCols);
    }
    if( pCopy && pParse->pWith==pCopy ){
      pParse->pWith = pCopy->pOuter;
    }
  }
}

/*
** Unmap all tokens in the IdList object passed as the second argument.
*/
static void unmapColumnIdlistNames(
  Parse *pParse,
  const IdList *pIdList
){
  if( pIdList ){
    int ii;
    for(ii=0; ii<pIdList->nId; ii++){
      sqlite3RenameTokenRemap(pParse, 0, (const void*)pIdList->a[ii].zName);
    }
  }
}

/*
** Walker callback used by sqlite3RenameExprUnmap().
*/
static int renameUnmapSelectCb(Walker *pWalker, Select *p){
  Parse *pParse = pWalker->pParse;
  int i;
  if( pParse->nErr ) return WRC_Abort;
  if( NEVER(p->selFlags & (SF_View|SF_CopyCte)) ){


    return WRC_Prune;
  }
  if( ALWAYS(p->pEList) ){
    ExprList *pList = p->pEList;
    for(i=0; i<pList->nExpr; i++){
      if( pList->a[i].zEName && pList->a[i].eEName==ENAME_NAME ){
        sqlite3RenameTokenRemap(pParse, 0, (void*)pList->a[i].zEName);
      }
    }
  }
  if( ALWAYS(p->pSrc) ){  /* Every Select as a SrcList, even if it is empty */
    SrcList *pSrc = p->pSrc;
    for(i=0; i<pSrc->nSrc; i++){
      sqlite3RenameTokenRemap(pParse, 0, (void*)pSrc->a[i].zName);
      sqlite3WalkExpr(pWalker, pSrc->a[i].pOn);
      unmapColumnIdlistNames(pParse, pSrc->a[i].pUsing);
    }
  }

  renameWalkWith(pWalker, p);
  return WRC_Continue;
}
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
** If the second argument passed to this function is not NULL and a matching
** RenameToken object is found, remove it from the Parse object and add it to
** the list maintained by the RenameCtx object.
*/
static RenameToken *renameTokenFind(
  Parse *pParse, 
  struct RenameCtx *pCtx, 
  void *pPtr
){
  RenameToken **pp;
  if( NEVER(pPtr==0) ){
    return 0;
  }
  for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
    if( (*pp)->p==pPtr ){







|







943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
** If the second argument passed to this function is not NULL and a matching
** RenameToken object is found, remove it from the Parse object and add it to
** the list maintained by the RenameCtx object.
*/
static RenameToken *renameTokenFind(
  Parse *pParse, 
  struct RenameCtx *pCtx, 
  const void *pPtr
){
  RenameToken **pp;
  if( NEVER(pPtr==0) ){
    return 0;
  }
  for(pp=&pParse->pRename; (*pp); pp=&(*pp)->pNext){
    if( (*pp)->p==pPtr ){
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
** pEList->a[i].zName) that matches the string in zOld, extract the 
** corresponding rename-token from Parse object pParse and add it
** to the RenameCtx pCtx.
*/
static void renameColumnElistNames(
  Parse *pParse, 
  RenameCtx *pCtx, 
  ExprList *pEList, 
  const char *zOld
){
  if( pEList ){
    int i;
    for(i=0; i<pEList->nExpr; i++){
      char *zName = pEList->a[i].zEName;
      if( ALWAYS(pEList->a[i].eEName==ENAME_NAME)
       && ALWAYS(zName!=0)
       && 0==sqlite3_stricmp(zName, zOld)
      ){
        renameTokenFind(pParse, pCtx, (void*)zName);
      }
    }
  }
}

/*
** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) 
** that matches the string in zOld, extract the corresponding rename-token 
** from Parse object pParse and add it to the RenameCtx pCtx.
*/
static void renameColumnIdlistNames(
  Parse *pParse, 
  RenameCtx *pCtx, 
  IdList *pIdList, 
  const char *zOld
){
  if( pIdList ){
    int i;
    for(i=0; i<pIdList->nId; i++){
      char *zName = pIdList->a[i].zName;
      if( 0==sqlite3_stricmp(zName, zOld) ){
        renameTokenFind(pParse, pCtx, (void*)zName);
      }
    }
  }
}


/*







|





|




|













|





|

|







1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
** pEList->a[i].zName) that matches the string in zOld, extract the 
** corresponding rename-token from Parse object pParse and add it
** to the RenameCtx pCtx.
*/
static void renameColumnElistNames(
  Parse *pParse, 
  RenameCtx *pCtx, 
  const ExprList *pEList, 
  const char *zOld
){
  if( pEList ){
    int i;
    for(i=0; i<pEList->nExpr; i++){
      const char *zName = pEList->a[i].zEName;
      if( ALWAYS(pEList->a[i].eEName==ENAME_NAME)
       && ALWAYS(zName!=0)
       && 0==sqlite3_stricmp(zName, zOld)
      ){
        renameTokenFind(pParse, pCtx, (const void*)zName);
      }
    }
  }
}

/*
** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) 
** that matches the string in zOld, extract the corresponding rename-token 
** from Parse object pParse and add it to the RenameCtx pCtx.
*/
static void renameColumnIdlistNames(
  Parse *pParse, 
  RenameCtx *pCtx, 
  const IdList *pIdList, 
  const char *zOld
){
  if( pIdList ){
    int i;
    for(i=0; i<pIdList->nId; i++){
      const char *zName = pIdList->a[i].zName;
      if( 0==sqlite3_stricmp(zName, zOld) ){
        renameTokenFind(pParse, pCtx, (const void*)zName);
      }
    }
  }
}


/*
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
      sParse.rc = SQLITE_OK;
      sqlite3SelectPrep(&sParse, pSelect, 0);
      rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
      if( rc==SQLITE_OK ){
        sqlite3WalkSelect(&sWalker, pSelect);
      }
      if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
    }else if( ALWAYS(IsOrdinaryTable(sParse.pNewTable)) ){
      /* A regular table */
      int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName);
      FKey *pFKey;
      sCtx.pTab = sParse.pNewTable;
      if( bFKOnly==0 ){
        if( iCol<sParse.pNewTable->nCol ){
          renameTokenFind(







|







1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
      sParse.rc = SQLITE_OK;
      sqlite3SelectPrep(&sParse, pSelect, 0);
      rc = (db->mallocFailed ? SQLITE_NOMEM : sParse.rc);
      if( rc==SQLITE_OK ){
        sqlite3WalkSelect(&sWalker, pSelect);
      }
      if( rc!=SQLITE_OK ) goto renameColumnFunc_done;
    }else if( IsOrdinaryTable(sParse.pNewTable) ){
      /* A regular table */
      int bFKOnly = sqlite3_stricmp(zTable, sParse.pNewTable->zName);
      FKey *pFKey;
      sCtx.pTab = sParse.pNewTable;
      if( bFKOnly==0 ){
        if( iCol<sParse.pNewTable->nCol ){
          renameTokenFind(
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
  }

  return;
}

static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_STRING && (pExpr->flags & EP_DblQuoted) ){
    renameTokenFind(pWalker->pParse, pWalker->u.pRename, (void*)pExpr);
  }
  return WRC_Continue;
}

/*
** The implementation of an SQL scalar function that rewrites DDL statements
** so that any string literals that use double-quotes are modified so that







|







1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
  }

  return;
}

static int renameQuotefixExprCb(Walker *pWalker, Expr *pExpr){
  if( pExpr->op==TK_STRING && (pExpr->flags & EP_DblQuoted) ){
    renameTokenFind(pWalker->pParse, pWalker->u.pRename, (const void*)pExpr);
  }
  return WRC_Continue;
}

/*
** The implementation of an SQL scalar function that rewrites DDL statements
** so that any string literals that use double-quotes are modified so that
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
** This function is called by the parser upon parsing an 
**
**     ALTER TABLE pSrc DROP COLUMN pName
**
** statement. Argument pSrc contains the possibly qualified name of the
** table being edited, and token pName the name of the column to drop.
*/
void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, Token *pName){
  sqlite3 *db = pParse->db;       /* Database handle */
  Table *pTab;                    /* Table to modify */
  int iDb;                        /* Index of db containing pTab in aDb[] */
  const char *zDb;                /* Database containing pTab ("main" etc.) */
  char *zCol = 0;                 /* Name of column to drop */
  int iCol;                       /* Index of column zCol in pTab->aCol[] */








|







2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
** This function is called by the parser upon parsing an 
**
**     ALTER TABLE pSrc DROP COLUMN pName
**
** statement. Argument pSrc contains the possibly qualified name of the
** table being edited, and token pName the name of the column to drop.
*/
void sqlite3AlterDropColumn(Parse *pParse, SrcList *pSrc, const Token *pName){
  sqlite3 *db = pParse->db;       /* Database handle */
  Table *pTab;                    /* Table to modify */
  int iDb;                        /* Index of db containing pTab in aDb[] */
  const char *zDb;                /* Database containing pTab ("main" etc.) */
  char *zCol = 0;                 /* Name of column to drop */
  int iCol;                       /* Index of column zCol in pTab->aCol[] */

Changes to src/analyze.c.
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
#ifdef SQLITE_ENABLE_STAT4
  if( mxSample ){
    n += sizeof(tRowcnt)*nColUp                  /* StatAccum.anLt */
      + sizeof(StatSample)*(nCol+mxSample)       /* StatAccum.aBest[], a[] */
      + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
  }
#endif
  db = sqlite3_context_db_handle(context);
  p = sqlite3DbMallocZero(db, n);
  if( p==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }

  p->db = db;







<







429
430
431
432
433
434
435

436
437
438
439
440
441
442
#ifdef SQLITE_ENABLE_STAT4
  if( mxSample ){
    n += sizeof(tRowcnt)*nColUp                  /* StatAccum.anLt */
      + sizeof(StatSample)*(nCol+mxSample)       /* StatAccum.aBest[], a[] */
      + sizeof(tRowcnt)*3*nColUp*(nCol+mxSample);
  }
#endif

  p = sqlite3DbMallocZero(db, n);
  if( p==0 ){
    sqlite3_result_error_nomem(context);
    return;
  }

  p->db = db;
848
849
850
851
852
853
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
883
884
885
886
887
888
889
890
891
892
893
894


895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919

920
921
922
923
924
925
926
927
928
929
    **   * "WHERE a=? AND b=?" matches 2 rows.
    **
    ** If D is the count of distinct values and K is the total number of 
    ** rows, then each estimate is computed as:
    **
    **        I = (K+D-1)/D
    */
    char *z;
    int i;

    char *zRet = sqlite3MallocZero( (p->nKeyCol+1)*25 );
    if( zRet==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }

    sqlite3_snprintf(24, zRet, "%llu", 
        p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);
    z = zRet + sqlite3Strlen30(zRet);
    for(i=0; i<p->nKeyCol; i++){
      u64 nDistinct = p->current.anDLt[i] + 1;
      u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
      sqlite3_snprintf(24, z, " %llu", iVal);
      z += sqlite3Strlen30(z);
      assert( p->current.anEq[i] );
    }
    assert( z[0]=='\0' && z>zRet );

    sqlite3_result_text(context, zRet, -1, sqlite3_free);
  }
#ifdef SQLITE_ENABLE_STAT4
  else if( eCall==STAT_GET_ROWID ){
    if( p->iGet<0 ){
      samplePushPrevious(p, 0);
      p->iGet = 0;
    }
    if( p->iGet<p->nSample ){
      StatSample *pS = p->a + p->iGet;
      if( pS->nRowid==0 ){
        sqlite3_result_int64(context, pS->u.iRowid);
      }else{
        sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
                            SQLITE_TRANSIENT);
      }
    }
  }else{
    tRowcnt *aCnt = 0;



    assert( p->iGet<p->nSample );
    switch( eCall ){
      case STAT_GET_NEQ:  aCnt = p->a[p->iGet].anEq; break;
      case STAT_GET_NLT:  aCnt = p->a[p->iGet].anLt; break;
      default: {
        aCnt = p->a[p->iGet].anDLt; 
        p->iGet++;
        break;
      }
    }

    {
      char *zRet = sqlite3MallocZero(p->nCol * 25);
      if( zRet==0 ){
        sqlite3_result_error_nomem(context);
      }else{
        int i;
        char *z = zRet;
        for(i=0; i<p->nCol; i++){
          sqlite3_snprintf(24, z, "%llu ", (u64)aCnt[i]);
          z += sqlite3Strlen30(z);
        }
        assert( z[0]=='\0' && z>zRet );
        z[-1] = '\0';

        sqlite3_result_text(context, zRet, -1, sqlite3_free);
      }
    }
  }
#endif /* SQLITE_ENABLE_STAT4 */
#ifndef SQLITE_DEBUG
  UNUSED_PARAMETER( argc );
#endif
}
static const FuncDef statGetFuncdef = {







|
|

<
<
<
<
<
|
|

<



|
<


<
|
<


















>
>











|
<
<
<
<
<
<
<
|
|
<
|
<
<
>
|
<
<







847
848
849
850
851
852
853
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
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898







899
900

901


902
903


904
905
906
907
908
909
910
    **   * "WHERE a=? AND b=?" matches 2 rows.
    **
    ** If D is the count of distinct values and K is the total number of 
    ** rows, then each estimate is computed as:
    **
    **        I = (K+D-1)/D
    */
    sqlite3_str sStat;   /* Text of the constructed "stat" line */
    int i;               /* Loop counter */






    sqlite3StrAccumInit(&sStat, 0, 0, 0, (p->nKeyCol+1)*100);
    sqlite3_str_appendf(&sStat, "%llu", 
        p->nSkipAhead ? (u64)p->nEst : (u64)p->nRow);

    for(i=0; i<p->nKeyCol; i++){
      u64 nDistinct = p->current.anDLt[i] + 1;
      u64 iVal = (p->nRow + nDistinct - 1) / nDistinct;
      sqlite3_str_appendf(&sStat, " %llu", iVal);

      assert( p->current.anEq[i] );
    }

    sqlite3ResultStrAccum(context, &sStat);

  }
#ifdef SQLITE_ENABLE_STAT4
  else if( eCall==STAT_GET_ROWID ){
    if( p->iGet<0 ){
      samplePushPrevious(p, 0);
      p->iGet = 0;
    }
    if( p->iGet<p->nSample ){
      StatSample *pS = p->a + p->iGet;
      if( pS->nRowid==0 ){
        sqlite3_result_int64(context, pS->u.iRowid);
      }else{
        sqlite3_result_blob(context, pS->u.aRowid, pS->nRowid,
                            SQLITE_TRANSIENT);
      }
    }
  }else{
    tRowcnt *aCnt = 0;
    sqlite3_str sStat;
    int i;

    assert( p->iGet<p->nSample );
    switch( eCall ){
      case STAT_GET_NEQ:  aCnt = p->a[p->iGet].anEq; break;
      case STAT_GET_NLT:  aCnt = p->a[p->iGet].anLt; break;
      default: {
        aCnt = p->a[p->iGet].anDLt; 
        p->iGet++;
        break;
      }
    }
    sqlite3StrAccumInit(&sStat, 0, 0, 0, p->nCol*100);







    for(i=0; i<p->nCol; i++){
      sqlite3_str_appendf(&sStat, "%llu ", (u64)aCnt[i]);

    }


    if( sStat.nChar ) sStat.nChar--;
    sqlite3ResultStrAccum(context, &sStat);


  }
#endif /* SQLITE_ENABLE_STAT4 */
#ifndef SQLITE_DEBUG
  UNUSED_PARAMETER( argc );
#endif
}
static const FuncDef statGetFuncdef = {
1836
1837
1838
1839
1840
1841
1842

1843
1844
1845


1846
1847
1848
1849
1850
1851
1852

/*
** Load content from the sqlite_stat4 table into 
** the Index.aSample[] arrays of all indices.
*/
static int loadStat4(sqlite3 *db, const char *zDb){
  int rc = SQLITE_OK;             /* Result codes from subroutines */


  assert( db->lookaside.bDisable );
  if( sqlite3FindTable(db, "sqlite_stat4", zDb) ){


    rc = loadStatTbl(db,
      "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
      "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
      zDb
    );
  }
  return rc;







>


|
>
>







1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836

/*
** Load content from the sqlite_stat4 table into 
** the Index.aSample[] arrays of all indices.
*/
static int loadStat4(sqlite3 *db, const char *zDb){
  int rc = SQLITE_OK;             /* Result codes from subroutines */
  const Table *pStat4;

  assert( db->lookaside.bDisable );
  if( (pStat4 = sqlite3FindTable(db, "sqlite_stat4", zDb))!=0
   && IsOrdinaryTable(pStat4)
  ){
    rc = loadStatTbl(db,
      "SELECT idx,count(*) FROM %Q.sqlite_stat4 GROUP BY idx", 
      "SELECT idx,neq,nlt,ndlt,sample FROM %Q.sqlite_stat4",
      zDb
    );
  }
  return rc;
1875
1876
1877
1878
1879
1880
1881

1882
1883
1884
1885
1886
1887
1888
*/
int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
  analysisInfo sInfo;
  HashElem *i;
  char *zSql;
  int rc = SQLITE_OK;
  Schema *pSchema = db->aDb[iDb].pSchema;


  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pBt!=0 );

  /* Clear any prior statistics */
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){







>







1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
*/
int sqlite3AnalysisLoad(sqlite3 *db, int iDb){
  analysisInfo sInfo;
  HashElem *i;
  char *zSql;
  int rc = SQLITE_OK;
  Schema *pSchema = db->aDb[iDb].pSchema;
  const Table *pStat1;

  assert( iDb>=0 && iDb<db->nDb );
  assert( db->aDb[iDb].pBt!=0 );

  /* Clear any prior statistics */
  assert( sqlite3SchemaMutexHeld(db, iDb, 0) );
  for(i=sqliteHashFirst(&pSchema->tblHash); i; i=sqliteHashNext(i)){
1897
1898
1899
1900
1901
1902
1903
1904


1905
1906
1907
1908
1909
1910
1911
    pIdx->aSample = 0;
#endif
  }

  /* Load new statistics out of the sqlite_stat1 table */
  sInfo.db = db;
  sInfo.zDatabase = db->aDb[iDb].zDbSName;
  if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)!=0 ){


    zSql = sqlite3MPrintf(db, 
        "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
    if( zSql==0 ){
      rc = SQLITE_NOMEM_BKPT;
    }else{
      rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
      sqlite3DbFree(db, zSql);







|
>
>







1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
    pIdx->aSample = 0;
#endif
  }

  /* Load new statistics out of the sqlite_stat1 table */
  sInfo.db = db;
  sInfo.zDatabase = db->aDb[iDb].zDbSName;
  if( (pStat1 = sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase))
   && IsOrdinaryTable(pStat1)
  ){
    zSql = sqlite3MPrintf(db, 
        "SELECT tbl,idx,stat FROM %Q.sqlite_stat1", sInfo.zDatabase);
    if( zSql==0 ){
      rc = SQLITE_NOMEM_BKPT;
    }else{
      rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0);
      sqlite3DbFree(db, zSql);
Changes to src/btree.c.
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
    if( page1[18]>3 ){
      pBt->btsFlags |= BTS_READ_ONLY;
    }
    if( page1[19]>3 ){
      goto page1_init_failed;
    }

    /* If the write version is set to 2, this database should be accessed
    ** in WAL mode. If the log is not already open, open it now. Then 
    ** return SQLITE_OK and return without populating BtShared.pPage1.
    ** The caller detects this and calls this function again. This is
    ** required as the version of page 1 currently in the page1 buffer
    ** may not be the latest version - there may be a newer one in the log
    ** file.
    */







|







3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
    if( page1[18]>3 ){
      pBt->btsFlags |= BTS_READ_ONLY;
    }
    if( page1[19]>3 ){
      goto page1_init_failed;
    }

    /* If the read version is set to 2, this database should be accessed
    ** in WAL mode. If the log is not already open, open it now. Then 
    ** return SQLITE_OK and return without populating BtShared.pPage1.
    ** The caller detects this and calls this function again. This is
    ** required as the version of page 1 currently in the page1 buffer
    ** may not be the latest version - there may be a newer one in the log
    ** file.
    */
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
        *pRes = 0;
        rc = sqlite3BtreeNext(pCur, 0);
        if( rc==SQLITE_OK ){
          getCellInfo(pCur);
          if( pCur->info.nKey==intKey ){
            return SQLITE_OK;
          }
        }else if( rc==SQLITE_DONE ){
          rc = SQLITE_OK;
        }else{
          return rc;
        }
      }
    }
  }

#ifdef SQLITE_DEBUG







|
<
<







5476
5477
5478
5479
5480
5481
5482
5483


5484
5485
5486
5487
5488
5489
5490
        *pRes = 0;
        rc = sqlite3BtreeNext(pCur, 0);
        if( rc==SQLITE_OK ){
          getCellInfo(pCur);
          if( pCur->info.nKey==intKey ){
            return SQLITE_OK;
          }
        }else if( rc!=SQLITE_DONE ){


          return rc;
        }
      }
    }
  }

#ifdef SQLITE_DEBUG
7323
7324
7325
7326
7327
7328
7329

7330
7331
7332
7333
7334
7335
7336
    int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
    assert( nCell>=nTail );
    nCell -= nTail;
  }

  pData = &aData[get2byteNotZero(&aData[hdr+5])];
  if( pData<pBegin ) goto editpage_fail;


  /* Add cells to the start of the page */
  if( iNew<iOld ){
    int nAdd = MIN(nNew,iOld-iNew);
    assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
    assert( nAdd>=0 );
    pCellptr = pPg->aCellIdx;







>







7321
7322
7323
7324
7325
7326
7327
7328
7329
7330
7331
7332
7333
7334
7335
    int nTail = pageFreeArray(pPg, iNewEnd, iOldEnd - iNewEnd, pCArray);
    assert( nCell>=nTail );
    nCell -= nTail;
  }

  pData = &aData[get2byteNotZero(&aData[hdr+5])];
  if( pData<pBegin ) goto editpage_fail;
  if( NEVER(pData>pPg->aDataEnd) ) goto editpage_fail;

  /* Add cells to the start of the page */
  if( iNew<iOld ){
    int nAdd = MIN(nNew,iOld-iNew);
    assert( (iOld-iNew)<nNew || nCell==0 || CORRUPT_DB );
    assert( nAdd>=0 );
    pCellptr = pPg->aCellIdx;
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
  assert( iOffset>=0 );
  ovflPgno = get4byte(pCur->info.pPayload + iOffset);
  pBt = pPage->pBt;
  ovflPageSize = pBt->usableSize - 4;
  do{
    rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
    if( rc ) return rc;
    if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 ){
      rc = SQLITE_CORRUPT_BKPT;
    }else{
      if( iOffset+ovflPageSize<(u32)nTotal ){
        ovflPgno = get4byte(pPage->aData);
      }else{
        ovflPageSize = nTotal - iOffset;
      }







|







8727
8728
8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
  assert( iOffset>=0 );
  ovflPgno = get4byte(pCur->info.pPayload + iOffset);
  pBt = pPage->pBt;
  ovflPageSize = pBt->usableSize - 4;
  do{
    rc = btreeGetPage(pBt, ovflPgno, &pPage, 0);
    if( rc ) return rc;
    if( sqlite3PagerPageRefcount(pPage->pDbPage)!=1 || pPage->isInit ){
      rc = SQLITE_CORRUPT_BKPT;
    }else{
      if( iOffset+ovflPageSize<(u32)nTotal ){
        ovflPgno = get4byte(pPage->aData);
      }else{
        ovflPageSize = nTotal - iOffset;
      }
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
9164
            ovflIn = get4byte(aIn);
            aIn += 4;
            nIn = pSrc->pBt->usableSize - 4;
          }
        }
      }while( rc==SQLITE_OK && nOut>0 );
  
      if( rc==SQLITE_OK && nRem>0 ){
        Pgno pgnoNew;
        MemPage *pNew = 0;
        rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
        put4byte(pPgnoOut, pgnoNew);
        if( ISAUTOVACUUM && pPageOut ){
          ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
        }







|







9149
9150
9151
9152
9153
9154
9155
9156
9157
9158
9159
9160
9161
9162
9163
            ovflIn = get4byte(aIn);
            aIn += 4;
            nIn = pSrc->pBt->usableSize - 4;
          }
        }
      }while( rc==SQLITE_OK && nOut>0 );
  
      if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){
        Pgno pgnoNew;
        MemPage *pNew = 0;
        rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0);
        put4byte(pPgnoOut, pgnoNew);
        if( ISAUTOVACUUM && pPageOut ){
          ptrmapPut(pBt, pgnoNew, PTRMAP_OVERFLOW2, pPageOut->pgno, &rc);
        }
Changes to src/build.c.
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
** Any quotation marks (ex:  "name", 'name', [name], or `name`) that
** surround the body of the token are removed.
**
** Tokens are often just pointers into the original SQL text and so
** are not \000 terminated and are not persistent.  The returned string
** is \000 terminated and is persistent.
*/
char *sqlite3NameFromToken(sqlite3 *db, Token *pName){
  char *zName;
  if( pName ){
    zName = sqlite3DbStrNDup(db, (char*)pName->z, pName->n);
    sqlite3Dequote(zName);
  }else{
    zName = 0;
  }
  return zName;
}








|


|







884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
** Any quotation marks (ex:  "name", 'name', [name], or `name`) that
** surround the body of the token are removed.
**
** Tokens are often just pointers into the original SQL text and so
** are not \000 terminated and are not persistent.  The returned string
** is \000 terminated and is persistent.
*/
char *sqlite3NameFromToken(sqlite3 *db, const Token *pName){
  char *zName;
  if( pName ){
    zName = sqlite3DbStrNDup(db, (const char*)pName->z, pName->n);
    sqlite3Dequote(zName);
  }else{
    zName = 0;
  }
  return zName;
}

1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
  pCol->hName = hName;
  sqlite3ColumnPropertiesFromName(p, pCol);
 
  if( sType.n==0 ){
    /* If there is no type specified, columns have the default affinity
    ** 'BLOB' with a default size of 4 bytes. */
    pCol->affinity = affinity;
    pCol->eType = eType;
    pCol->szEst = szEst;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
    if( affinity==SQLITE_AFF_BLOB ){
      if( 4>=sqlite3GlobalConfig.szSorterRef ){
        pCol->colFlags |= COLFLAG_SORTERREF;
      }
    }







|







1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
  pCol->hName = hName;
  sqlite3ColumnPropertiesFromName(p, pCol);
 
  if( sType.n==0 ){
    /* If there is no type specified, columns have the default affinity
    ** 'BLOB' with a default size of 4 bytes. */
    pCol->affinity = affinity;
    pCol->eCType = eType;
    pCol->szEst = szEst;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
    if( affinity==SQLITE_AFF_BLOB ){
      if( 4>=sqlite3GlobalConfig.szSorterRef ){
        pCol->colFlags |= COLFLAG_SORTERREF;
      }
    }
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
          }
        }
      }
    }
  }
  if( nTerm==1
   && pCol
   && pCol->eType==COLTYPE_INTEGER
   && sortOrder!=SQLITE_SO_DESC
  ){
    if( IN_RENAME_OBJECT && pList ){
      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
    }
    pTab->iPKey = iCol;







|







1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
          }
        }
      }
    }
  }
  if( nTerm==1
   && pCol
   && pCol->eCType==COLTYPE_INTEGER
   && sortOrder!=SQLITE_SO_DESC
  ){
    if( IN_RENAME_OBJECT && pList ){
      Expr *pCExpr = sqlite3ExprSkipCollate(pList->a[0].pExpr);
      sqlite3RenameTokenRemap(pParse, &pTab->iPKey, pCExpr);
    }
    pTab->iPKey = iCol;
2317
2318
2319
2320
2321
2322
2323
2324


2325
2326
2327
2328
2329
2330
2331
  sqlite3 *db = pParse->db;
  Vdbe *v = pParse->pVdbe;

  /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
  */
  if( !db->init.imposterTable ){
    for(i=0; i<pTab->nCol; i++){
      if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0 ){


        pTab->aCol[i].notNull = OE_Abort;
      }
    }
    pTab->tabFlags |= TF_HasNotNull;
  }

  /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY







|
>
>







2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
  sqlite3 *db = pParse->db;
  Vdbe *v = pParse->pVdbe;

  /* Mark every PRIMARY KEY column as NOT NULL (except for imposter tables)
  */
  if( !db->init.imposterTable ){
    for(i=0; i<pTab->nCol; i++){
      if( (pTab->aCol[i].colFlags & COLFLAG_PRIMKEY)!=0
       && (pTab->aCol[i].notNull==OE_None)
      ){
        pTab->aCol[i].notNull = OE_Abort;
      }
    }
    pTab->tabFlags |= TF_HasNotNull;
  }

  /* Convert the P3 operand of the OP_CreateBtree opcode from BTREE_INTKEY
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
** "CREATE TABLE ... AS SELECT ..." statement.  The column names of
** the new table will match the result set of the SELECT.
*/
void sqlite3EndTable(
  Parse *pParse,          /* Parse context */
  Token *pCons,           /* The ',' token after the last column defn. */
  Token *pEnd,            /* The ')' before options in the CREATE TABLE */
  u8 tabOpts,             /* Extra table options. Usually 0. */
  Select *pSelect         /* Select from a "CREATE ... AS SELECT" */
){
  Table *p;                 /* The new table */
  sqlite3 *db = pParse->db; /* The database connection */
  int iDb;                  /* Database in which the table lives */
  Index *pIdx;              /* An implied index of the table */








|







2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
** "CREATE TABLE ... AS SELECT ..." statement.  The column names of
** the new table will match the result set of the SELECT.
*/
void sqlite3EndTable(
  Parse *pParse,          /* Parse context */
  Token *pCons,           /* The ',' token after the last column defn. */
  Token *pEnd,            /* The ')' before options in the CREATE TABLE */
  u32 tabOpts,            /* Extra table options. Usually 0. */
  Select *pSelect         /* Select from a "CREATE ... AS SELECT" */
){
  Table *p;                 /* The new table */
  sqlite3 *db = pParse->db; /* The database connection */
  int iDb;                  /* Database in which the table lives */
  Index *pIdx;              /* An implied index of the table */

2585
2586
2587
2588
2589
2590
2591






































2592
2593
2594
2595
2596
2597
2598
    if( pSelect ){
      sqlite3ErrorMsg(pParse, "");
      return;
    }
    p->tnum = db->init.newTnum;
    if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
  }







































  assert( (p->tabFlags & TF_HasPrimaryKey)==0
       || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 );
  assert( (p->tabFlags & TF_HasPrimaryKey)!=0
       || (p->iPKey<0 && sqlite3PrimaryKeyIndex(p)==0) );

  /* Special processing for WITHOUT ROWID Tables */







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







2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
    if( pSelect ){
      sqlite3ErrorMsg(pParse, "");
      return;
    }
    p->tnum = db->init.newTnum;
    if( p->tnum==1 ) p->tabFlags |= TF_Readonly;
  }

  /* Special processing for tables that include the STRICT keyword:
  **
  **   *  Do not allow custom column datatypes.  Every column must have
  **      a datatype that is one of INT, INTEGER, REAL, TEXT, or BLOB.
  **
  **   *  If a PRIMARY KEY is defined, other than the INTEGER PRIMARY KEY,
  **      then all columns of the PRIMARY KEY must have a NOT NULL
  **      constraint.
  */
  if( tabOpts & TF_Strict ){
    int ii;
    p->tabFlags |= TF_Strict;
    for(ii=0; ii<p->nCol; ii++){
      Column *pCol = &p->aCol[ii];
      if( pCol->eCType==COLTYPE_CUSTOM ){
        if( pCol->colFlags & COLFLAG_HASTYPE ){
          sqlite3ErrorMsg(pParse,
            "unknown datatype for %s.%s: \"%s\"",
            p->zName, pCol->zCnName, sqlite3ColumnType(pCol, "")
          );
        }else{
          sqlite3ErrorMsg(pParse, "missing datatype for %s.%s",
                          p->zName, pCol->zCnName);
        }
        return;
      }else if( pCol->eCType==COLTYPE_ANY ){
        pCol->affinity = SQLITE_AFF_BLOB;
      }
      if( (pCol->colFlags & COLFLAG_PRIMKEY)!=0
       && p->iPKey!=ii
       && pCol->notNull == OE_None
      ){
        pCol->notNull = OE_Abort;
        p->tabFlags |= TF_HasNotNull;
      }
    }    
  }

  assert( (p->tabFlags & TF_HasPrimaryKey)==0
       || p->iPKey>=0 || sqlite3PrimaryKeyIndex(p)!=0 );
  assert( (p->tabFlags & TF_HasPrimaryKey)!=0
       || (p->iPKey<0 && sqlite3PrimaryKeyIndex(p)==0) );

  /* Special processing for WITHOUT ROWID Tables */
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
exit_create_index:
  if( pIndex ) sqlite3FreeIndex(db, pIndex);
  if( pTab ){
    /* Ensure all REPLACE indexes on pTab are at the end of the pIndex list.
    ** The list was already ordered when this routine was entered, so at this
    ** point at most a single index (the newly added index) will be out of
    ** order.  So we have to reorder at most one index. */
    Index **ppFrom = &pTab->pIndex;
    Index *pThis;
    for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){
      Index *pNext;
      if( pThis->onError!=OE_Replace ) continue;
      while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){
        *ppFrom = pNext;
        pThis->pNext = pNext->pNext;







|







4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
exit_create_index:
  if( pIndex ) sqlite3FreeIndex(db, pIndex);
  if( pTab ){
    /* Ensure all REPLACE indexes on pTab are at the end of the pIndex list.
    ** The list was already ordered when this routine was entered, so at this
    ** point at most a single index (the newly added index) will be out of
    ** order.  So we have to reorder at most one index. */
    Index **ppFrom;
    Index *pThis;
    for(ppFrom=&pTab->pIndex; (pThis = *ppFrom)!=0; ppFrom=&pThis->pNext){
      Index *pNext;
      if( pThis->onError!=OE_Replace ) continue;
      while( (pNext = pThis->pNext)!=0 && pNext->onError!=OE_Replace ){
        *ppFrom = pNext;
        pThis->pNext = pNext->pNext;
Changes to src/date.c.
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

1017

1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077

1078
1079



1080
1081
1082
1083
1084
1085
1086
1087



1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113



1114



1115
1116
1117
1118
1119
1120

1121


1122

1123
1124
1125
1126
1127
1128
1129




1130


1131
1132
1133
1134

1135
1136
1137
1138
1139
1140
1141
1142
1143
*/
static void strftimeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;
  u64 n;
  size_t i,j;
  char *z;
  sqlite3 *db;
  const char *zFmt;

  char zBuf[100];

  if( argc==0 ) return;
  zFmt = (const char*)sqlite3_value_text(argv[0]);
  if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
  db = sqlite3_context_db_handle(context);
  for(i=0, n=1; zFmt[i]; i++, n++){
    if( zFmt[i]=='%' ){
      switch( zFmt[i+1] ){
        case 'd':
        case 'H':
        case 'm':
        case 'M':
        case 'S':
        case 'W':
          n++;
          /* fall thru */
        case 'w':
        case '%':
          break;
        case 'f':
          n += 8;
          break;
        case 'j':
          n += 3;
          break;
        case 'Y':
          n += 8;
          break;
        case 's':
        case 'J':
          n += 50;
          break;
        default:
          return;  /* ERROR.  return a NULL */
      }
      i++;
    }
  }
  testcase( n==sizeof(zBuf)-1 );
  testcase( n==sizeof(zBuf) );
  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH]+1 );
  testcase( n==(u64)db->aLimit[SQLITE_LIMIT_LENGTH] );
  if( n<sizeof(zBuf) ){
    z = zBuf;
  }else if( n>(u64)db->aLimit[SQLITE_LIMIT_LENGTH] ){
    sqlite3_result_error_toobig(context);
    return;
  }else{
    z = sqlite3DbMallocRawNN(db, (int)n);
    if( z==0 ){
      sqlite3_result_error_nomem(context);
      return;
    }
  }
  computeJD(&x);
  computeYMD_HMS(&x);
  for(i=j=0; zFmt[i]; i++){
    if( zFmt[i]!='%' ){
      z[j++] = zFmt[i];
    }else{
      i++;

      switch( zFmt[i] ){
        case 'd':  sqlite3_snprintf(3, &z[j],"%02d",x.D); j+=2; break;



        case 'f': {
          double s = x.s;
          if( s>59.999 ) s = 59.999;
          sqlite3_snprintf(7, &z[j],"%06.3f", s);
          j += sqlite3Strlen30(&z[j]);
          break;
        }
        case 'H':  sqlite3_snprintf(3, &z[j],"%02d",x.h); j+=2; break;



        case 'W': /* Fall thru */
        case 'j': {
          int nDay;             /* Number of days since 1st day of year */
          DateTime y = x;
          y.validJD = 0;
          y.M = 1;
          y.D = 1;
          computeJD(&y);
          nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
          if( zFmt[i]=='W' ){
            int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
            wd = (int)(((x.iJD+43200000)/86400000)%7);
            sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
            j += 2;
          }else{
            sqlite3_snprintf(4, &z[j],"%03d",nDay+1);
            j += 3;
          }
          break;
        }
        case 'J': {
          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
          j+=sqlite3Strlen30(&z[j]);
          break;
        }
        case 'm':  sqlite3_snprintf(3, &z[j],"%02d",x.M); j+=2; break;



        case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;



        case 's': {
          i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
          sqlite3Int64ToText(iS, &z[j]);
          j += sqlite3Strlen30(&z[j]);
          break;
        }

        case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;


        case 'w': {

          z[j++] = (char)(((x.iJD+129600000)/86400000) % 7) + '0';
          break;
        }
        case 'Y': {
          sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=sqlite3Strlen30(&z[j]);
          break;
        }




        default:   z[j++] = '%'; break;


      }
    }
  }
  z[j] = 0;

  sqlite3_result_text(context, z, -1,
                      z==zBuf ? SQLITE_TRANSIENT : SQLITE_DYNAMIC);
}

/*
** current_time()
**
** This function returns the same value as time('now').
*/







<

<


>
|
>




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



|
|
<
|
>
|
|
>
>
>
|
|
|
|
<
|
|
|
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
<
|
|
|
|
|
<
|
|
|
>
>
>
|
>
>
>
|
|
|
<
|
|
>
|
>
>
|
>
|
|
|
|
|
|
|
>
>
>
>
|
>
>



<
>
|
<







1005
1006
1007
1008
1009
1010
1011

1012

1013
1014
1015
1016
1017
1018
1019
1020
1021




































1022










1023

1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039

1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058

1059
1060

1061
1062
1063
1064
1065

1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078

1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103

1104
1105

1106
1107
1108
1109
1110
1111
1112
*/
static void strftimeFunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  DateTime x;

  size_t i,j;

  sqlite3 *db;
  const char *zFmt;
  sqlite3_str sRes;


  if( argc==0 ) return;
  zFmt = (const char*)sqlite3_value_text(argv[0]);
  if( zFmt==0 || isDate(context, argc-1, argv+1, &x) ) return;
  db = sqlite3_context_db_handle(context);




































  sqlite3StrAccumInit(&sRes, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);












  computeJD(&x);
  computeYMD_HMS(&x);
  for(i=j=0; zFmt[i]; i++){
    if( zFmt[i]!='%' ) continue;
    if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j);

    i++;
    j = i + 1;
    switch( zFmt[i] ){
      case 'd': {
        sqlite3_str_appendf(&sRes, "%02d", x.D);
        break;
      }
      case 'f': {
        double s = x.s;
        if( s>59.999 ) s = 59.999;
        sqlite3_str_appendf(&sRes, "%06.3f", s);

        break;
      }
      case 'H': {
        sqlite3_str_appendf(&sRes, "%02d", x.h);
        break;
      }
      case 'W': /* Fall thru */
      case 'j': {
        int nDay;             /* Number of days since 1st day of year */
        DateTime y = x;
        y.validJD = 0;
        y.M = 1;
        y.D = 1;
        computeJD(&y);
        nDay = (int)((x.iJD-y.iJD+43200000)/86400000);
        if( zFmt[i]=='W' ){
          int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
          wd = (int)(((x.iJD+43200000)/86400000)%7);
          sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7);

        }else{
          sqlite3_str_appendf(&sRes,"%03d",nDay+1);

        }
        break;
      }
      case 'J': {
        sqlite3_str_appendf(&sRes,"%.16g",x.iJD/86400000.0);

        break;
      }
      case 'm': {
        sqlite3_str_appendf(&sRes,"%02d",x.M);
        break;
      }
      case 'M': {
        sqlite3_str_appendf(&sRes,"%02d",x.m);
        break;
      }
      case 's': {
        i64 iS = (i64)(x.iJD/1000 - 21086676*(i64)10000);
        sqlite3_str_appendf(&sRes,"%lld",iS);

        break;
      }
      case 'S': {
        sqlite3_str_appendf(&sRes,"%02d",(int)x.s);
        break;
      }
      case 'w': {
        sqlite3_str_appendchar(&sRes, 1,
                       (char)(((x.iJD+129600000)/86400000) % 7) + '0');
        break;
      }
      case 'Y': {
        sqlite3_str_appendf(&sRes,"%04d",x.Y);
        break;
      }
      case '%': {
        sqlite3_str_appendchar(&sRes, 1, '%');
        break;
      }
      default: {
        sqlite3_str_reset(&sRes);
        return;
      }
    }
  }

  if( j<i ) sqlite3_str_append(&sRes, zFmt+j, i-j);
  sqlite3ResultStrAccum(context, &sRes);

}

/*
** current_time()
**
** This function returns the same value as time('now').
*/
Changes to src/dbstat.c.
21
22
23
24
25
26
27









28
29
30
31
32
33
34
** official SQLite documentation.
*/

#include "sqliteInt.h"   /* Requires access to internal data structures */
#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
    && !defined(SQLITE_OMIT_VIRTUALTABLE)










/*
** Page paths:
** 
**   The value of the 'path' column describes the path taken from the 
**   root-node of the b-tree structure to each page. The value of the 
**   root-node path is '/'.
**







>
>
>
>
>
>
>
>
>







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
** official SQLite documentation.
*/

#include "sqliteInt.h"   /* Requires access to internal data structures */
#if (defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)) \
    && !defined(SQLITE_OMIT_VIRTUALTABLE)

/*
** The pager and btree modules arrange objects in memory so that there are
** always approximately 200 bytes of addressable memory following each page
** buffer. This way small buffer overreads caused by corrupt database pages
** do not cause undefined behaviour. This module pads each page buffer
** by the following number of bytes for the same purpose.
*/
#define DBSTAT_PAGE_PADDING_BYTES 256

/*
** Page paths:
** 
**   The value of the 'path' column describes the path taken from the 
**   root-node of the b-tree structure to each page. The value of the 
**   root-node path is '/'.
**
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
  int nLastOvfl;                  /* Bytes of payload on final overflow page */
  int iOvfl;                      /* Iterates through aOvfl[] */
};

/* Size information for a single btree page */
struct StatPage {
  u32 iPgno;                      /* Page number */
  DbPage *pPg;                    /* Page content */
  int iCell;                      /* Current cell */

  char *zPath;                    /* Path to this page */

  /* Variables populated by statDecodePage(): */
  u8 flags;                       /* Copy of flags byte */
  int nCell;                      /* Number of cells on page */
  int nUnused;                    /* Number of unused bytes on page */
  StatCell *aCell;                /* Array of parsed cells */







|

<







97
98
99
100
101
102
103
104
105

106
107
108
109
110
111
112
  int nLastOvfl;                  /* Bytes of payload on final overflow page */
  int iOvfl;                      /* Iterates through aOvfl[] */
};

/* Size information for a single btree page */
struct StatPage {
  u32 iPgno;                      /* Page number */
  u8 *aPg;                        /* Page buffer from sqlite3_malloc() */
  int iCell;                      /* Current cell */

  char *zPath;                    /* Path to this page */

  /* Variables populated by statDecodePage(): */
  u8 flags;                       /* Copy of flags byte */
  int nCell;                      /* Number of cells on page */
  int nUnused;                    /* Number of unused bytes on page */
  StatCell *aCell;                /* Array of parsed cells */
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
    sqlite3_free(p->aCell);
  }
  p->nCell = 0;
  p->aCell = 0;
}

static void statClearPage(StatPage *p){

  statClearCells(p);
  sqlite3PagerUnref(p->pPg);
  sqlite3_free(p->zPath);
  memset(p, 0, sizeof(StatPage));

}

static void statResetCsr(StatCursor *pCsr){
  int i;

  sqlite3_reset(pCsr->pStmt);


  for(i=0; i<ArraySize(pCsr->aPage); i++){
    statClearPage(&pCsr->aPage[i]);


  }

  pCsr->iPage = 0;
  sqlite3_free(pCsr->zPath);
  pCsr->zPath = 0;
  pCsr->isEof = 0;
}

/* Resize the space-used counters inside of the cursor */







>

<


>




>
|
>
>


>
>

>







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
    sqlite3_free(p->aCell);
  }
  p->nCell = 0;
  p->aCell = 0;
}

static void statClearPage(StatPage *p){
  u8 *aPg = p->aPg;
  statClearCells(p);

  sqlite3_free(p->zPath);
  memset(p, 0, sizeof(StatPage));
  p->aPg = aPg;
}

static void statResetCsr(StatCursor *pCsr){
  int i;
  /* In some circumstances, specifically if an OOM has occurred, the call
  ** to sqlite3_reset() may cause the pager to be reset (emptied). It is
  ** important that statClearPage() is called to free any page refs before
  ** this happens. dbsqlfuzz 9ed3e4e3816219d3509d711636c38542bf3f40b1. */
  for(i=0; i<ArraySize(pCsr->aPage); i++){
    statClearPage(&pCsr->aPage[i]);
    sqlite3_free(pCsr->aPage[i].aPg);
    pCsr->aPage[i].aPg = 0;
  }
  sqlite3_reset(pCsr->pStmt);
  pCsr->iPage = 0;
  sqlite3_free(pCsr->zPath);
  pCsr->zPath = 0;
  pCsr->isEof = 0;
}

/* Resize the space-used counters inside of the cursor */
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
static int statDecodePage(Btree *pBt, StatPage *p){
  int nUnused;
  int iOff;
  int nHdr;
  int isLeaf;
  int szPage;

  u8 *aData = sqlite3PagerGetData(p->pPg);
  u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];

  p->flags = aHdr[0];
  if( p->flags==0x0A || p->flags==0x0D ){
    isLeaf = 1;
    nHdr = 8;
  }else if( p->flags==0x05 || p->flags==0x02 ){







|







393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
static int statDecodePage(Btree *pBt, StatPage *p){
  int nUnused;
  int iOff;
  int nHdr;
  int isLeaf;
  int szPage;

  u8 *aData = p->aPg;
  u8 *aHdr = &aData[p->iPgno==1 ? 100 : 0];

  p->flags = aHdr[0];
  if( p->flags==0x0A || p->flags==0x0D ){
    isLeaf = 1;
    nHdr = 8;
  }else if( p->flags==0x05 || p->flags==0x02 ){
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
        if( nLocal<0 ) goto statPageIsCorrupt;
        pCell->nLocal = nLocal;
        assert( nPayload>=(u32)nLocal );
        assert( nLocal<=(nUsable-35) );
        if( nPayload>(u32)nLocal ){
          int j;
          int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
          if( iOff+nLocal>nUsable || nPayload>0x7fffffff ){
            goto statPageIsCorrupt;
          }
          pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
          pCell->nOvfl = nOvfl;
          pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
          if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
          pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);







|







464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
        if( nLocal<0 ) goto statPageIsCorrupt;
        pCell->nLocal = nLocal;
        assert( nPayload>=(u32)nLocal );
        assert( nLocal<=(nUsable-35) );
        if( nPayload>(u32)nLocal ){
          int j;
          int nOvfl = ((nPayload - nLocal) + nUsable-4 - 1) / (nUsable - 4);
          if( iOff+nLocal+4>nUsable || nPayload>0x7fffffff ){
            goto statPageIsCorrupt;
          }
          pCell->nLastOvfl = (nPayload-nLocal) - (nOvfl-1) * (nUsable-4);
          pCell->nOvfl = nOvfl;
          pCell->aOvfl = sqlite3_malloc64(sizeof(u32)*nOvfl);
          if( pCell->aOvfl==0 ) return SQLITE_NOMEM_BKPT;
          pCell->aOvfl[0] = sqlite3Get4byte(&aData[iOff+nLocal]);
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
550
551
552
    pCsr->szPage += x[1];
  }else{
    /* Not ZIPVFS: The default page size and offset */
    pCsr->szPage += sqlite3BtreeGetPageSize(pBt);
    pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
  }
}

































/*
** Move a DBSTAT cursor to the next entry.  Normally, the next
** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0),
** the next entry is the next btree.
*/
static int statNext(sqlite3_vtab_cursor *pCursor){
  int rc;
  int nPayload;
  char *z;
  StatCursor *pCsr = (StatCursor *)pCursor;
  StatTable *pTab = (StatTable *)pCursor->pVtab;
  Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
  Pager *pPager = sqlite3BtreePager(pBt);

  sqlite3_free(pCsr->zPath);
  pCsr->zPath = 0;

statNextRestart:
  if( pCsr->aPage[0].pPg==0 ){
    /* Start measuring space on the next btree */
    statResetCounts(pCsr);
    rc = sqlite3_step(pCsr->pStmt);
    if( rc==SQLITE_ROW ){
      int nPage;
      u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
      sqlite3PagerPagecount(pPager, &nPage);
      if( nPage==0 ){
        pCsr->isEof = 1;
        return sqlite3_reset(pCsr->pStmt);
      }
      rc = sqlite3PagerGet(pPager, iRoot, &pCsr->aPage[0].pPg, 0);
      pCsr->aPage[0].iPgno = iRoot;
      pCsr->aPage[0].iCell = 0;
      if( !pCsr->isAgg ){
        pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
        if( z==0 ) rc = SQLITE_NOMEM_BKPT;
      }
      pCsr->iPage = 0;







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



















|











|







522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
    pCsr->szPage += x[1];
  }else{
    /* Not ZIPVFS: The default page size and offset */
    pCsr->szPage += sqlite3BtreeGetPageSize(pBt);
    pCsr->iOffset = (i64)pCsr->szPage * (pCsr->iPageno - 1);
  }
}

/*
** Load a copy of the page data for page iPg into the buffer belonging
** to page object pPg. Allocate the buffer if necessary. Return SQLITE_OK
** if successful, or an SQLite error code otherwise.
*/
static int statGetPage(
  Btree *pBt,                     /* Load page from this b-tree */
  u32 iPg,                        /* Page number to load */
  StatPage *pPg                   /* Load page into this object */
){
  int pgsz = sqlite3BtreeGetPageSize(pBt);
  DbPage *pDbPage = 0;
  int rc;

  if( pPg->aPg==0 ){
    pPg->aPg = (u8*)sqlite3_malloc(pgsz + DBSTAT_PAGE_PADDING_BYTES);
    if( pPg->aPg==0 ){
      return SQLITE_NOMEM_BKPT;
    }
    memset(&pPg->aPg[pgsz], 0, DBSTAT_PAGE_PADDING_BYTES);
  }

  rc = sqlite3PagerGet(sqlite3BtreePager(pBt), iPg, &pDbPage, 0);
  if( rc==SQLITE_OK ){
    const u8 *a = sqlite3PagerGetData(pDbPage);
    memcpy(pPg->aPg, a, pgsz);
    sqlite3PagerUnref(pDbPage);
  }

  return rc;
}

/*
** Move a DBSTAT cursor to the next entry.  Normally, the next
** entry will be the next page, but in aggregated mode (pCsr->isAgg!=0),
** the next entry is the next btree.
*/
static int statNext(sqlite3_vtab_cursor *pCursor){
  int rc;
  int nPayload;
  char *z;
  StatCursor *pCsr = (StatCursor *)pCursor;
  StatTable *pTab = (StatTable *)pCursor->pVtab;
  Btree *pBt = pTab->db->aDb[pCsr->iDb].pBt;
  Pager *pPager = sqlite3BtreePager(pBt);

  sqlite3_free(pCsr->zPath);
  pCsr->zPath = 0;

statNextRestart:
  if( pCsr->iPage<0 ){
    /* Start measuring space on the next btree */
    statResetCounts(pCsr);
    rc = sqlite3_step(pCsr->pStmt);
    if( rc==SQLITE_ROW ){
      int nPage;
      u32 iRoot = (u32)sqlite3_column_int64(pCsr->pStmt, 1);
      sqlite3PagerPagecount(pPager, &nPage);
      if( nPage==0 ){
        pCsr->isEof = 1;
        return sqlite3_reset(pCsr->pStmt);
      }
      rc = statGetPage(pBt, iRoot, &pCsr->aPage[0]);
      pCsr->aPage[0].iPgno = iRoot;
      pCsr->aPage[0].iCell = 0;
      if( !pCsr->isAgg ){
        pCsr->aPage[0].zPath = z = sqlite3_mprintf("/");
        if( z==0 ) rc = SQLITE_NOMEM_BKPT;
      }
      pCsr->iPage = 0;
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
618
619
620
621
622
623
624
      }
      if( p->iRightChildPg ) break;
      p->iCell++;
    }

    if( !p->iRightChildPg || p->iCell>p->nCell ){
      statClearPage(p);
      if( pCsr->iPage>0 ){
        pCsr->iPage--;
      }else if( pCsr->isAgg ){
        /* label-statNext-done:  When computing aggregate space usage over
        ** an entire btree, this is the exit point from this function */
        return SQLITE_OK;
      }
      goto statNextRestart; /* Tail recursion */
    }
    pCsr->iPage++;
    if( pCsr->iPage>=ArraySize(pCsr->aPage) ){
      statResetCsr(pCsr);
      return SQLITE_CORRUPT_BKPT;
    }
    assert( p==&pCsr->aPage[pCsr->iPage-1] );

    if( p->iCell==p->nCell ){
      p[1].iPgno = p->iRightChildPg;
    }else{
      p[1].iPgno = p->aCell[p->iCell].iChildPg;
    }
    rc = sqlite3PagerGet(pPager, p[1].iPgno, &p[1].pPg, 0);
    pCsr->nPage++;
    p[1].iCell = 0;
    if( !pCsr->isAgg ){
      p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
    }
    p->iCell++;







<
|
|


















|







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
      }
      if( p->iRightChildPg ) break;
      p->iCell++;
    }

    if( !p->iRightChildPg || p->iCell>p->nCell ){
      statClearPage(p);

      pCsr->iPage--;
      if( pCsr->isAgg && pCsr->iPage<0 ){
        /* label-statNext-done:  When computing aggregate space usage over
        ** an entire btree, this is the exit point from this function */
        return SQLITE_OK;
      }
      goto statNextRestart; /* Tail recursion */
    }
    pCsr->iPage++;
    if( pCsr->iPage>=ArraySize(pCsr->aPage) ){
      statResetCsr(pCsr);
      return SQLITE_CORRUPT_BKPT;
    }
    assert( p==&pCsr->aPage[pCsr->iPage-1] );

    if( p->iCell==p->nCell ){
      p[1].iPgno = p->iRightChildPg;
    }else{
      p[1].iPgno = p->aCell[p->iCell].iChildPg;
    }
    rc = statGetPage(pBt, p[1].iPgno, &p[1]);
    pCsr->nPage++;
    p[1].iCell = 0;
    if( !pCsr->isAgg ){
      p[1].zPath = z = sqlite3_mprintf("%s%.3x/", p->zPath, p->iCell);
      if( z==0 ) rc = SQLITE_NOMEM_BKPT;
    }
    p->iCell++;
740
741
742
743
744
745
746

747
748
749
750
751
752
753
    return SQLITE_NOMEM_BKPT;
  }else{
    rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
    sqlite3_free(zSql);
  }

  if( rc==SQLITE_OK ){

    rc = statNext(pCursor);
  }
  return rc;
}

static int statColumn(
  sqlite3_vtab_cursor *pCursor, 







>







786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
    return SQLITE_NOMEM_BKPT;
  }else{
    rc = sqlite3_prepare_v2(pTab->db, zSql, -1, &pCsr->pStmt, 0);
    sqlite3_free(zSql);
  }

  if( rc==SQLITE_OK ){
    pCsr->iPage = -1;
    rc = statNext(pCursor);
  }
  return rc;
}

static int statColumn(
  sqlite3_vtab_cursor *pCursor, 
Changes to src/expr.c.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* Forward declarations */
static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);

/*
** Return the affinity character for a single column of a table.
*/
char sqlite3TableColumnAffinity(Table *pTab, int iCol){
  assert( iCol<pTab->nCol );
  return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
}

/*
** Return the 'affinity' of the expression pExpr if any.
**







|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* Forward declarations */
static void exprCodeBetween(Parse*,Expr*,int,void(*)(Parse*,Expr*,int,int),int);
static int exprCodeVector(Parse *pParse, Expr *p, int *piToFree);

/*
** Return the affinity character for a single column of a table.
*/
char sqlite3TableColumnAffinity(const Table *pTab, int iCol){
  assert( iCol<pTab->nCol );
  return iCol>=0 ? pTab->aCol[iCol].affinity : SQLITE_AFF_INTEGER;
}

/*
** Return the 'affinity' of the expression pExpr if any.
**
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
** sequence named by pToken.   Return a pointer to a new Expr node that
** implements the COLLATE operator.
**
** If a memory allocation error occurs, that fact is recorded in pParse->db
** and the pExpr parameter is returned unchanged.
*/
Expr *sqlite3ExprAddCollateToken(
  Parse *pParse,           /* Parsing context */
  Expr *pExpr,             /* Add the "COLLATE" clause to this expression */
  const Token *pCollName,  /* Name of collating sequence */
  int dequote              /* True to dequote pCollName */
){
  if( pCollName->n>0 ){
    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
    if( pNew ){
      pNew->pLeft = pExpr;
      pNew->flags |= EP_Collate|EP_Skip;
      pExpr = pNew;
    }
  }
  return pExpr;
}
Expr *sqlite3ExprAddCollateString(Parse *pParse, Expr *pExpr, const char *zC){




  Token s;
  assert( zC!=0 );
  sqlite3TokenInit(&s, (char*)zC);
  return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}

/*







|














|
>
>
>
>







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
** sequence named by pToken.   Return a pointer to a new Expr node that
** implements the COLLATE operator.
**
** If a memory allocation error occurs, that fact is recorded in pParse->db
** and the pExpr parameter is returned unchanged.
*/
Expr *sqlite3ExprAddCollateToken(
  const Parse *pParse,     /* Parsing context */
  Expr *pExpr,             /* Add the "COLLATE" clause to this expression */
  const Token *pCollName,  /* Name of collating sequence */
  int dequote              /* True to dequote pCollName */
){
  if( pCollName->n>0 ){
    Expr *pNew = sqlite3ExprAlloc(pParse->db, TK_COLLATE, pCollName, dequote);
    if( pNew ){
      pNew->pLeft = pExpr;
      pNew->flags |= EP_Collate|EP_Skip;
      pExpr = pNew;
    }
  }
  return pExpr;
}
Expr *sqlite3ExprAddCollateString(
  const Parse *pParse,  /* Parsing context */
  Expr *pExpr,          /* Add the "COLLATE" clause to this expression */
  const char *zC        /* The collating sequence name */
){
  Token s;
  assert( zC!=0 );
  sqlite3TokenInit(&s, (char*)zC);
  return sqlite3ExprAddCollateToken(pParse, pExpr, &s, 0);
}

/*
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
**
** A vector is defined as any expression that results in two or more
** columns of result.  Every TK_VECTOR node is an vector because the
** parser will not generate a TK_VECTOR with fewer than two entries.
** But a TK_SELECT might be either a vector or a scalar. It is only
** considered a vector if it has two or more result columns.
*/
int sqlite3ExprIsVector(Expr *pExpr){
  return sqlite3ExprVectorSize(pExpr)>1;
}

/*
** If the expression passed as the only argument is of type TK_VECTOR 
** return the number of expressions in the vector. Or, if the expression
** is a sub-select, return the number of columns in the sub-select. For
** any other type of expression, return 1.
*/
int sqlite3ExprVectorSize(Expr *pExpr){
  u8 op = pExpr->op;
  if( op==TK_REGISTER ) op = pExpr->op2;
  if( op==TK_VECTOR ){
    return pExpr->x.pList->nExpr;
  }else if( op==TK_SELECT ){
    return pExpr->x.pSelect->pEList->nExpr;
  }else{







|









|







409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
**
** A vector is defined as any expression that results in two or more
** columns of result.  Every TK_VECTOR node is an vector because the
** parser will not generate a TK_VECTOR with fewer than two entries.
** But a TK_SELECT might be either a vector or a scalar. It is only
** considered a vector if it has two or more result columns.
*/
int sqlite3ExprIsVector(const Expr *pExpr){
  return sqlite3ExprVectorSize(pExpr)>1;
}

/*
** If the expression passed as the only argument is of type TK_VECTOR 
** return the number of expressions in the vector. Or, if the expression
** is a sub-select, return the number of columns in the sub-select. For
** any other type of expression, return 1.
*/
int sqlite3ExprVectorSize(const Expr *pExpr){
  u8 op = pExpr->op;
  if( op==TK_REGISTER ) op = pExpr->op2;
  if( op==TK_VECTOR ){
    return pExpr->x.pList->nExpr;
  }else if( op==TK_SELECT ){
    return pExpr->x.pSelect->pEList->nExpr;
  }else{
508
509
510
511
512
513
514
515








516
517
518
519
520
521
522
523
524
    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0);
    if( pRet ){
      pRet->iTable = nField;
      pRet->iColumn = iField;
      pRet->pLeft = pVector;
    }
  }else{
    if( pVector->op==TK_VECTOR ) pVector = pVector->x.pList->a[iField].pExpr;








    pRet = sqlite3ExprDup(pParse->db, pVector, 0);
    sqlite3RenameTokenRemap(pParse, pRet, pVector);
  }
  return pRet;
}

/*
** If expression pExpr is of type TK_SELECT, generate code to evaluate
** it. Return the register in which the result is stored (or, if the 







|
>
>
>
>
>
>
>
>

<







512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528

529
530
531
532
533
534
535
    pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0);
    if( pRet ){
      pRet->iTable = nField;
      pRet->iColumn = iField;
      pRet->pLeft = pVector;
    }
  }else{
    if( pVector->op==TK_VECTOR ){
      Expr **ppVector = &pVector->x.pList->a[iField].pExpr;
      pVector = *ppVector;
      if( IN_RENAME_OBJECT ){
        /* This must be a vector UPDATE inside a trigger */
        *ppVector = 0;
        return pVector;
      }
    }
    pRet = sqlite3ExprDup(pParse->db, pVector, 0);

  }
  return pRet;
}

/*
** If expression pExpr is of type TK_SELECT, generate code to evaluate
** it. Return the register in which the result is stored (or, if the 
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
** of any expression tree referenced by the structure passed as the
** first argument.
**
** If this maximum height is greater than the current value pointed
** to by pnHeight, the second parameter, then set *pnHeight to that
** value.
*/
static void heightOfExpr(Expr *p, int *pnHeight){
  if( p ){
    if( p->nHeight>*pnHeight ){
      *pnHeight = p->nHeight;
    }
  }
}
static void heightOfExprList(ExprList *p, int *pnHeight){
  if( p ){
    int i;
    for(i=0; i<p->nExpr; i++){
      heightOfExpr(p->a[i].pExpr, pnHeight);
    }
  }
}
static void heightOfSelect(Select *pSelect, int *pnHeight){
  Select *p;
  for(p=pSelect; p; p=p->pPrior){
    heightOfExpr(p->pWhere, pnHeight);
    heightOfExpr(p->pHaving, pnHeight);
    heightOfExpr(p->pLimit, pnHeight);
    heightOfExprList(p->pEList, pnHeight);
    heightOfExprList(p->pGroupBy, pnHeight);
    heightOfExprList(p->pOrderBy, pnHeight);







|






|







|
|







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
** of any expression tree referenced by the structure passed as the
** first argument.
**
** If this maximum height is greater than the current value pointed
** to by pnHeight, the second parameter, then set *pnHeight to that
** value.
*/
static void heightOfExpr(const Expr *p, int *pnHeight){
  if( p ){
    if( p->nHeight>*pnHeight ){
      *pnHeight = p->nHeight;
    }
  }
}
static void heightOfExprList(const ExprList *p, int *pnHeight){
  if( p ){
    int i;
    for(i=0; i<p->nExpr; i++){
      heightOfExpr(p->a[i].pExpr, pnHeight);
    }
  }
}
static void heightOfSelect(const Select *pSelect, int *pnHeight){
  const Select *p;
  for(p=pSelect; p; p=p->pPrior){
    heightOfExpr(p->pWhere, pnHeight);
    heightOfExpr(p->pHaving, pnHeight);
    heightOfExpr(p->pLimit, pnHeight);
    heightOfExprList(p->pEList, pnHeight);
    heightOfExprList(p->pGroupBy, pnHeight);
    heightOfExprList(p->pOrderBy, pnHeight);
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
  sqlite3ExprCheckHeight(pParse, p->nHeight);
}

/*
** Return the maximum height of any expression tree referenced
** by the select statement passed as an argument.
*/
int sqlite3SelectExprHeight(Select *p){
  int nHeight = 0;
  heightOfSelect(p, &nHeight);
  return nHeight;
}
#else /* ABOVE:  Height enforcement enabled.  BELOW: Height enforcement off */
/*
** Propagate all EP_Propagate flags from the Expr.x.pList into







|







782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
  sqlite3ExprCheckHeight(pParse, p->nHeight);
}

/*
** Return the maximum height of any expression tree referenced
** by the select statement passed as an argument.
*/
int sqlite3SelectExprHeight(const Select *p){
  int nHeight = 0;
  heightOfSelect(p, &nHeight);
  return nHeight;
}
#else /* ABOVE:  Height enforcement enabled.  BELOW: Height enforcement off */
/*
** Propagate all EP_Propagate flags from the Expr.x.pList into
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(
  Parse *pParse,        /* Parsing context */
  ExprList *pList,      /* Argument list */
  Token *pToken,        /* Name of the function */
  int eDistinct         /* SF_Distinct or SF_ALL or 0 */
){
  Expr *pNew;
  sqlite3 *db = pParse->db;
  assert( pToken );
  pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
  if( pNew==0 ){







|







1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
/*
** Construct a new expression node for a function with multiple
** arguments.
*/
Expr *sqlite3ExprFunction(
  Parse *pParse,        /* Parsing context */
  ExprList *pList,      /* Argument list */
  const Token *pToken,  /* Name of the function */
  int eDistinct         /* SF_Distinct or SF_ALL or 0 */
){
  Expr *pNew;
  sqlite3 *db = pParse->db;
  assert( pToken );
  pNew = sqlite3ExprAlloc(db, TK_FUNCTION, pToken, 1);
  if( pNew==0 ){
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
**    SQLITE_FUNC_UNSAFE    -     Usable if TRUSTED_SCHEMA or from
**                                top-level SQL
**
** If the function is not usable, create an error.
*/
void sqlite3ExprFunctionUsable(
  Parse *pParse,         /* Parsing and code generating context */
  Expr *pExpr,           /* The function invocation */
  FuncDef *pDef          /* The function being invoked */
){
  assert( !IN_RENAME_OBJECT );
  assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 );
  if( ExprHasProperty(pExpr, EP_FromDDL) ){
    if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
     || (pParse->db->flags & SQLITE_TrustedSchema)==0
    ){







|
|







1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
**    SQLITE_FUNC_UNSAFE    -     Usable if TRUSTED_SCHEMA or from
**                                top-level SQL
**
** If the function is not usable, create an error.
*/
void sqlite3ExprFunctionUsable(
  Parse *pParse,         /* Parsing and code generating context */
  const Expr *pExpr,     /* The function invocation */
  const FuncDef *pDef    /* The function being invoked */
){
  assert( !IN_RENAME_OBJECT );
  assert( (pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE))!=0 );
  if( ExprHasProperty(pExpr, EP_FromDDL) ){
    if( (pDef->funcFlags & SQLITE_FUNC_DIRECT)!=0
     || (pParse->db->flags & SQLITE_TrustedSchema)==0
    ){
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
}

/*
** Return the number of bytes allocated for the expression structure 
** passed as the first argument. This is always one of EXPR_FULLSIZE,
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
*/
static int exprStructSize(Expr *p){
  if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
  if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
  return EXPR_FULLSIZE;
}

/*
** The dupedExpr*Size() routines each return the number of bytes required







|







1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
}

/*
** Return the number of bytes allocated for the expression structure 
** passed as the first argument. This is always one of EXPR_FULLSIZE,
** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE.
*/
static int exprStructSize(const Expr *p){
  if( ExprHasProperty(p, EP_TokenOnly) ) return EXPR_TOKENONLYSIZE;
  if( ExprHasProperty(p, EP_Reduced) ) return EXPR_REDUCEDSIZE;
  return EXPR_FULLSIZE;
}

/*
** The dupedExpr*Size() routines each return the number of bytes required
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
** later parts of the Expr object and that extra information might get chopped
** off if the expression is reduced.  Note also that it does not work to
** make an EXPRDUP_REDUCE copy of a reduced expression.  It is only legal
** to reduce a pristine expression tree from the parser.  The implementation
** of dupedExprStructSize() contain multiple assert() statements that attempt
** to enforce this constraint.
*/
static int dupedExprStructSize(Expr *p, int flags){
  int nSize;
  assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  assert( EXPR_FULLSIZE<=0xfff );
  assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  if( 0==flags || p->op==TK_SELECT_COLUMN 
#ifndef SQLITE_OMIT_WINDOWFUNC
   || ExprHasProperty(p, EP_WinFunc)







|







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
** later parts of the Expr object and that extra information might get chopped
** off if the expression is reduced.  Note also that it does not work to
** make an EXPRDUP_REDUCE copy of a reduced expression.  It is only legal
** to reduce a pristine expression tree from the parser.  The implementation
** of dupedExprStructSize() contain multiple assert() statements that attempt
** to enforce this constraint.
*/
static int dupedExprStructSize(const Expr *p, int flags){
  int nSize;
  assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */
  assert( EXPR_FULLSIZE<=0xfff );
  assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 );
  if( 0==flags || p->op==TK_SELECT_COLUMN 
#ifndef SQLITE_OMIT_WINDOWFUNC
   || ExprHasProperty(p, EP_WinFunc)
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
}

/*
** This function returns the space in bytes required to store the copy 
** of the Expr structure and a copy of the Expr.u.zToken string (if that
** string is defined.)
*/
static int dupedExprNodeSize(Expr *p, int flags){
  int nByte = dupedExprStructSize(p, flags) & 0xfff;
  if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
    nByte += sqlite3Strlen30NN(p->u.zToken)+1;
  }
  return ROUND8(nByte);
}

/*
** Return the number of bytes required to create a duplicate of the 
** expression passed as the first argument. The second argument is a
** mask containing EXPRDUP_XXX flags.
**
** The value returned includes space to create a copy of the Expr struct
** itself and the buffer referred to by Expr.u.zToken, if any.
**
** If the EXPRDUP_REDUCE flag is set, then the return value includes 
** space to duplicate all Expr nodes in the tree formed by Expr.pLeft 
** and Expr.pRight variables (but not for any structures pointed to or 
** descended from the Expr.x.pList or Expr.x.pSelect variables).
*/
static int dupedExprSize(Expr *p, int flags){
  int nByte = 0;
  if( p ){
    nByte = dupedExprNodeSize(p, flags);
    if( flags&EXPRDUP_REDUCE ){
      nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
    }
  }
  return nByte;
}

/*
** This function is similar to sqlite3ExprDup(), except that if pzBuffer 
** is not NULL then *pzBuffer is assumed to point to a buffer large enough 
** to store the copy of expression p, the copies of p->u.zToken
** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte past the
** portion of the buffer copied into by this function.
*/
static Expr *exprDup(sqlite3 *db, Expr *p, int dupFlags, u8 **pzBuffer){
  Expr *pNew;           /* Value to return */
  u8 *zAlloc;           /* Memory space from which to build Expr object */
  u32 staticFlag;       /* EP_Static if space not obtained from malloc */

  assert( db!=0 );
  assert( p );
  assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );







|




















|


















|







1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
}

/*
** This function returns the space in bytes required to store the copy 
** of the Expr structure and a copy of the Expr.u.zToken string (if that
** string is defined.)
*/
static int dupedExprNodeSize(const Expr *p, int flags){
  int nByte = dupedExprStructSize(p, flags) & 0xfff;
  if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){
    nByte += sqlite3Strlen30NN(p->u.zToken)+1;
  }
  return ROUND8(nByte);
}

/*
** Return the number of bytes required to create a duplicate of the 
** expression passed as the first argument. The second argument is a
** mask containing EXPRDUP_XXX flags.
**
** The value returned includes space to create a copy of the Expr struct
** itself and the buffer referred to by Expr.u.zToken, if any.
**
** If the EXPRDUP_REDUCE flag is set, then the return value includes 
** space to duplicate all Expr nodes in the tree formed by Expr.pLeft 
** and Expr.pRight variables (but not for any structures pointed to or 
** descended from the Expr.x.pList or Expr.x.pSelect variables).
*/
static int dupedExprSize(const Expr *p, int flags){
  int nByte = 0;
  if( p ){
    nByte = dupedExprNodeSize(p, flags);
    if( flags&EXPRDUP_REDUCE ){
      nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags);
    }
  }
  return nByte;
}

/*
** This function is similar to sqlite3ExprDup(), except that if pzBuffer 
** is not NULL then *pzBuffer is assumed to point to a buffer large enough 
** to store the copy of expression p, the copies of p->u.zToken
** (if applicable), and the copies of the p->pLeft and p->pRight expressions,
** if any. Before returning, *pzBuffer is set to the first byte past the
** portion of the buffer copied into by this function.
*/
static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){
  Expr *pNew;           /* Value to return */
  u8 *zAlloc;           /* Memory space from which to build Expr object */
  u32 staticFlag;       /* EP_Static if space not obtained from malloc */

  assert( db!=0 );
  assert( p );
  assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE );
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548

1549
1550
1551
1552
1553
1554
1555
** Any tables that the SrcList might point to are not duplicated.
**
** The flags parameter contains a combination of the EXPRDUP_XXX flags.
** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
** truncated version of the usual Expr structure that will be stored as
** part of the in-memory representation of the database schema.
*/
Expr *sqlite3ExprDup(sqlite3 *db, Expr *p, int flags){
  assert( flags==0 || flags==EXPRDUP_REDUCE );
  return p ? exprDup(db, p, flags, 0) : 0;
}
ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags){
  ExprList *pNew;
  struct ExprList_item *pItem, *pOldItem;

  int i;
  Expr *pPriorSelectColOld = 0;
  Expr *pPriorSelectColNew = 0;
  assert( db!=0 );
  if( p==0 ) return 0;
  pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
  if( pNew==0 ) return 0;







|



|

|
>







1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
** Any tables that the SrcList might point to are not duplicated.
**
** The flags parameter contains a combination of the EXPRDUP_XXX flags.
** If the EXPRDUP_REDUCE flag is set, then the structure returned is a
** truncated version of the usual Expr structure that will be stored as
** part of the in-memory representation of the database schema.
*/
Expr *sqlite3ExprDup(sqlite3 *db, const Expr *p, int flags){
  assert( flags==0 || flags==EXPRDUP_REDUCE );
  return p ? exprDup(db, p, flags, 0) : 0;
}
ExprList *sqlite3ExprListDup(sqlite3 *db, const ExprList *p, int flags){
  ExprList *pNew;
  struct ExprList_item *pItem;
  const struct ExprList_item *pOldItem;
  int i;
  Expr *pPriorSelectColOld = 0;
  Expr *pPriorSelectColNew = 0;
  assert( db!=0 );
  if( p==0 ) return 0;
  pNew = sqlite3DbMallocRawNN(db, sqlite3DbMallocSize(db, p));
  if( pNew==0 ) return 0;
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
** If cursors, triggers, views and subqueries are all omitted from
** the build, then none of the following routines, except for 
** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
** called with a NULL argument.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
 || !defined(SQLITE_OMIT_SUBQUERY)
SrcList *sqlite3SrcListDup(sqlite3 *db, SrcList *p, int flags){
  SrcList *pNew;
  int i;
  int nByte;
  assert( db!=0 );
  if( p==0 ) return 0;
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
  pNew = sqlite3DbMallocRawNN(db, nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    SrcItem *pNewItem = &pNew->a[i];
    SrcItem *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->pSchema = pOldItem->pSchema;
    pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
    pNewItem->fg = pOldItem->fg;
    pNewItem->iCursor = pOldItem->iCursor;







|











|







1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
** If cursors, triggers, views and subqueries are all omitted from
** the build, then none of the following routines, except for 
** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes
** called with a NULL argument.
*/
#if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_TRIGGER) \
 || !defined(SQLITE_OMIT_SUBQUERY)
SrcList *sqlite3SrcListDup(sqlite3 *db, const SrcList *p, int flags){
  SrcList *pNew;
  int i;
  int nByte;
  assert( db!=0 );
  if( p==0 ) return 0;
  nByte = sizeof(*p) + (p->nSrc>0 ? sizeof(p->a[0]) * (p->nSrc-1) : 0);
  pNew = sqlite3DbMallocRawNN(db, nByte );
  if( pNew==0 ) return 0;
  pNew->nSrc = pNew->nAlloc = p->nSrc;
  for(i=0; i<p->nSrc; i++){
    SrcItem *pNewItem = &pNew->a[i];
    const SrcItem *pOldItem = &p->a[i];
    Table *pTab;
    pNewItem->pSchema = pOldItem->pSchema;
    pNewItem->zDatabase = sqlite3DbStrDup(db, pOldItem->zDatabase);
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
    pNewItem->fg = pOldItem->fg;
    pNewItem->iCursor = pOldItem->iCursor;
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
    pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
    pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
    pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
    pNewItem->colUsed = pOldItem->colUsed;
  }
  return pNew;
}
IdList *sqlite3IdListDup(sqlite3 *db, IdList *p){
  IdList *pNew;
  int i;
  assert( db!=0 );
  if( p==0 ) return 0;
  pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
  if( pNew==0 ) return 0;
  pNew->nId = p->nId;







|







1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
    pNewItem->pSelect = sqlite3SelectDup(db, pOldItem->pSelect, flags);
    pNewItem->pOn = sqlite3ExprDup(db, pOldItem->pOn, flags);
    pNewItem->pUsing = sqlite3IdListDup(db, pOldItem->pUsing);
    pNewItem->colUsed = pOldItem->colUsed;
  }
  return pNew;
}
IdList *sqlite3IdListDup(sqlite3 *db, const IdList *p){
  IdList *pNew;
  int i;
  assert( db!=0 );
  if( p==0 ) return 0;
  pNew = sqlite3DbMallocRawNN(db, sizeof(*pNew) );
  if( pNew==0 ) return 0;
  pNew->nId = p->nId;
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
    struct IdList_item *pNewItem = &pNew->a[i];
    struct IdList_item *pOldItem = &p->a[i];
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->idx = pOldItem->idx;
  }
  return pNew;
}
Select *sqlite3SelectDup(sqlite3 *db, Select *pDup, int flags){
  Select *pRet = 0;
  Select *pNext = 0;
  Select **pp = &pRet;
  Select *p;

  assert( db!=0 );
  for(p=pDup; p; p=p->pPrior){
    Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
    if( pNew==0 ) break;
    pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
    pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);







|



|







1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
    struct IdList_item *pNewItem = &pNew->a[i];
    struct IdList_item *pOldItem = &p->a[i];
    pNewItem->zName = sqlite3DbStrDup(db, pOldItem->zName);
    pNewItem->idx = pOldItem->idx;
  }
  return pNew;
}
Select *sqlite3SelectDup(sqlite3 *db, const Select *pDup, int flags){
  Select *pRet = 0;
  Select *pNext = 0;
  Select **pp = &pRet;
  const Select *p;

  assert( db!=0 );
  for(p=pDup; p; p=p->pPrior){
    Select *pNew = sqlite3DbMallocRawNN(db, sizeof(*p) );
    if( pNew==0 ) break;
    pNew->pEList = sqlite3ExprListDup(db, p->pEList, flags);
    pNew->pSrc = sqlite3SrcListDup(db, p->pSrc, flags);
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
** pList might be NULL following an OOM error.  But pName should never be
** NULL.  If a memory allocation fails, the pParse->db->mallocFailed flag
** is set.
*/
void sqlite3ExprListSetName(
  Parse *pParse,          /* Parsing context */
  ExprList *pList,        /* List to which to add the span. */
  Token *pName,           /* Name to be added */
  int dequote             /* True to cause the name to be dequoted */
){
  assert( pList!=0 || pParse->db->mallocFailed!=0 );
  assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
  if( pList ){
    struct ExprList_item *pItem;
    assert( pList->nExpr>0 );
    pItem = &pList->a[pList->nExpr-1];
    assert( pItem->zEName==0 );
    assert( pItem->eEName==ENAME_NAME );
    pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
    if( dequote ){
      /* If dequote==0, then pName->z does not point to part of a DDL
      ** statement handled by the parser. And so no token need be added
      ** to the token-map.  */
      sqlite3Dequote(pItem->zEName);
      if( IN_RENAME_OBJECT ){
        sqlite3RenameTokenMap(pParse, (void*)pItem->zEName, pName);
      }
    }
  }
}

/*
** Set the ExprList.a[].zSpan element of the most recently added item







|

















|







1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
** pList might be NULL following an OOM error.  But pName should never be
** NULL.  If a memory allocation fails, the pParse->db->mallocFailed flag
** is set.
*/
void sqlite3ExprListSetName(
  Parse *pParse,          /* Parsing context */
  ExprList *pList,        /* List to which to add the span. */
  const Token *pName,     /* Name to be added */
  int dequote             /* True to cause the name to be dequoted */
){
  assert( pList!=0 || pParse->db->mallocFailed!=0 );
  assert( pParse->eParseMode!=PARSE_MODE_UNMAP || dequote==0 );
  if( pList ){
    struct ExprList_item *pItem;
    assert( pList->nExpr>0 );
    pItem = &pList->a[pList->nExpr-1];
    assert( pItem->zEName==0 );
    assert( pItem->eEName==ENAME_NAME );
    pItem->zEName = sqlite3DbStrNDup(pParse->db, pName->z, pName->n);
    if( dequote ){
      /* If dequote==0, then pName->z does not point to part of a DDL
      ** statement handled by the parser. And so no token need be added
      ** to the token-map.  */
      sqlite3Dequote(pItem->zEName);
      if( IN_RENAME_OBJECT ){
        sqlite3RenameTokenMap(pParse, (const void*)pItem->zEName, pName);
      }
    }
  }
}

/*
** Set the ExprList.a[].zSpan element of the most recently added item
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366

/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(Expr *p, int *pValue){
  int rc = 0;
  if( NEVER(p==0) ) return 0;  /* Used to only happen following on OOM */

  /* If an expression is an integer literal that fits in a signed 32-bit
  ** integer, then the EP_IntValue flag will have already been set */
  assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
           || sqlite3GetInt32(p->u.zToken, &rc)==0 );







|







2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378

/*
** If the expression p codes a constant integer that is small enough
** to fit in a 32-bit integer, return 1 and put the value of the integer
** in *pValue.  If the expression is not an integer or if it is too big
** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
*/
int sqlite3ExprIsInteger(const Expr *p, int *pValue){
  int rc = 0;
  if( NEVER(p==0) ) return 0;  /* Used to only happen following on OOM */

  /* If an expression is an integer literal that fits in a signed 32-bit
  ** integer, then the EP_IntValue flag will have already been set */
  assert( p->op!=TK_INTEGER || (p->flags & EP_IntValue)!=0
           || sqlite3GetInt32(p->u.zToken, &rc)==0 );
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
** pX is the RHS of an IN operator.  If pX is a SELECT statement 
** that can be simplified to a direct table access, then return
** a pointer to the SELECT statement.  If pX is not a SELECT statement,
** or if the SELECT statement needs to be manifested into a transient
** table, then return NULL.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static Select *isCandidateForInOpt(Expr *pX){
  Select *p;
  SrcList *pSrc;
  ExprList *pEList;
  Table *pTab;
  int i;
  if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0;  /* Not a subquery */
  if( ExprHasProperty(pX, EP_VarSelect)  ) return 0;  /* Correlated subq */







|







2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
** pX is the RHS of an IN operator.  If pX is a SELECT statement 
** that can be simplified to a direct table access, then return
** a pointer to the SELECT statement.  If pX is not a SELECT statement,
** or if the SELECT statement needs to be manifested into a transient
** table, then return NULL.
*/
#ifndef SQLITE_OMIT_SUBQUERY
static Select *isCandidateForInOpt(const Expr *pX){
  Select *p;
  SrcList *pSrc;
  ExprList *pEList;
  Table *pTab;
  int i;
  if( !ExprHasProperty(pX, EP_xIsSelect) ) return 0;  /* Not a subquery */
  if( ExprHasProperty(pX, EP_VarSelect)  ) return 0;  /* Correlated subq */
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
** Argument pExpr is an (?, ?...) IN(...) expression. This 
** function allocates and returns a nul-terminated string containing 
** the affinities to be used for each column of the comparison.
**
** It is the responsibility of the caller to ensure that the returned
** string is eventually freed using sqlite3DbFree().
*/
static char *exprINAffinity(Parse *pParse, Expr *pExpr){
  Expr *pLeft = pExpr->pLeft;
  int nVal = sqlite3ExprVectorSize(pLeft);
  Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0;
  char *zRet;

  assert( pExpr->op==TK_IN );
  zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);







|







2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
** Argument pExpr is an (?, ?...) IN(...) expression. This 
** function allocates and returns a nul-terminated string containing 
** the affinities to be used for each column of the comparison.
**
** It is the responsibility of the caller to ensure that the returned
** string is eventually freed using sqlite3DbFree().
*/
static char *exprINAffinity(Parse *pParse, const Expr *pExpr){
  Expr *pLeft = pExpr->pLeft;
  int nVal = sqlite3ExprVectorSize(pLeft);
  Select *pSelect = (pExpr->flags & EP_xIsSelect) ? pExpr->x.pSelect : 0;
  char *zRet;

  assert( pExpr->op==TK_IN );
  zRet = sqlite3DbMallocRaw(pParse->db, nVal+1);
3862
3863
3864
3865
3866
3867
3868

3869
3870
3871
3872
3873
3874
3875
      break;
    }

  /***********************************************************************
  ** Test-only SQL functions that are only usable if enabled
  ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
  */

    case INLINEFUNC_expr_compare: {
      /* Compare two expressions using sqlite3ExprCompare() */
      assert( nFarg==2 );
      sqlite3VdbeAddOp2(v, OP_Integer, 
         sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
         target);
      break;







>







3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
      break;
    }

  /***********************************************************************
  ** Test-only SQL functions that are only usable if enabled
  ** via SQLITE_TESTCTRL_INTERNAL_FUNCTIONS
  */
#if !defined(SQLITE_UNTESTABLE)
    case INLINEFUNC_expr_compare: {
      /* Compare two expressions using sqlite3ExprCompare() */
      assert( nFarg==2 );
      sqlite3VdbeAddOp2(v, OP_Integer, 
         sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1),
         target);
      break;
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
           target);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      }
      break;
    }

#ifdef SQLITE_DEBUG
    case INLINEFUNC_affinity: {
      /* The AFFINITY() function evaluates to a string that describes
      ** the type affinity of the argument.  This is used for testing of
      ** the SQLite type logic.
      */
      const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
      char aff;
      assert( nFarg==1 );
      aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
      sqlite3VdbeLoadString(v, target, 
              (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
      break;
    }
#endif
  }
  return target;
}


/*
** Generate code into the current Vdbe to evaluate the given







<













|







3908
3909
3910
3911
3912
3913
3914

3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
3926
3927
3928
3929
3930
3931
3932
3933
3934
3935
           target);
      }else{
        sqlite3VdbeAddOp2(v, OP_Null, 0, target);
      }
      break;
    }


    case INLINEFUNC_affinity: {
      /* The AFFINITY() function evaluates to a string that describes
      ** the type affinity of the argument.  This is used for testing of
      ** the SQLite type logic.
      */
      const char *azAff[] = { "blob", "text", "numeric", "integer", "real" };
      char aff;
      assert( nFarg==1 );
      aff = sqlite3ExprAffinity(pFarg->a[0].pExpr);
      sqlite3VdbeLoadString(v, target, 
              (aff<=SQLITE_AFF_NONE) ? "none" : azAff[aff-SQLITE_AFF_BLOB]);
      break;
    }
#endif /* !defined(SQLITE_UNTESTABLE) */
  }
  return target;
}


/*
** Generate code into the current Vdbe to evaluate the given
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
  assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
  assert( target>0 && target<=pParse->nMem );
  assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
  if( pParse->pVdbe==0 ) return;
  inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
  if( inReg!=target ){
    u8 op;
    if( ExprHasProperty(pExpr,EP_Subquery) ){
      op = OP_Copy;
    }else{
      op = OP_SCopy;
    }
    sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target);
  }
}







|







4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
  assert( pExpr==0 || !ExprHasVVAProperty(pExpr,EP_Immutable) );
  assert( target>0 && target<=pParse->nMem );
  assert( pParse->pVdbe!=0 || pParse->db->mallocFailed );
  if( pParse->pVdbe==0 ) return;
  inReg = sqlite3ExprCodeTarget(pParse, pExpr, target);
  if( inReg!=target ){
    u8 op;
    if( ALWAYS(pExpr) && ExprHasProperty(pExpr,EP_Subquery) ){
      op = OP_Copy;
    }else{
      op = OP_SCopy;
    }
    sqlite3VdbeAddOp2(pParse->pVdbe, op, inReg, target);
  }
}
5320
5321
5322
5323
5324
5325
5326
5327




5328
5329
5330
5331
5332
5333
5334
** to re-prepare each time a new value is bound to variable pVar.
**
** Additionally, if pExpr is a simple SQL value and the value is the
** same as that currently bound to variable pVar, non-zero is returned.
** Otherwise, if the values are not the same or if pExpr is not a simple
** SQL value, zero is returned.
*/
static int exprCompareVariable(Parse *pParse, Expr *pVar, Expr *pExpr){




  int res = 0;
  int iVar;
  sqlite3_value *pL, *pR = 0;
  
  sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
  if( pR ){
    iVar = pVar->iColumn;







|
>
>
>
>







5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
** to re-prepare each time a new value is bound to variable pVar.
**
** Additionally, if pExpr is a simple SQL value and the value is the
** same as that currently bound to variable pVar, non-zero is returned.
** Otherwise, if the values are not the same or if pExpr is not a simple
** SQL value, zero is returned.
*/
static int exprCompareVariable(
  const Parse *pParse,
  const Expr *pVar,
  const Expr *pExpr
){
  int res = 0;
  int iVar;
  sqlite3_value *pL, *pR = 0;
  
  sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR);
  if( pR ){
    iVar = pVar->iColumn;
5372
5373
5374
5375
5376
5377
5378
5379





5380
5381
5382
5383
5384
5385
5386
** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
** pParse->pReprepare can be matched against literals in pB.  The 
** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
** If pParse is NULL (the normal case) then any TK_VARIABLE term in 
** Argument pParse should normally be NULL. If it is not NULL and pA or
** pB causes a return value of 2.
*/
int sqlite3ExprCompare(Parse *pParse, Expr *pA, Expr *pB, int iTab){





  u32 combinedFlags;
  if( pA==0 || pB==0 ){
    return pB==pA ? 0 : 2;
  }
  if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
    return 0;
  }







|
>
>
>
>
>







5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in
** pParse->pReprepare can be matched against literals in pB.  The 
** pParse->pVdbe->expmask bitmask is updated for each variable referenced.
** If pParse is NULL (the normal case) then any TK_VARIABLE term in 
** Argument pParse should normally be NULL. If it is not NULL and pA or
** pB causes a return value of 2.
*/
int sqlite3ExprCompare(
  const Parse *pParse,
  const Expr *pA,
  const Expr *pB,
  int iTab
){
  u32 combinedFlags;
  if( pA==0 || pB==0 ){
    return pB==pA ? 0 : 2;
  }
  if( pParse && pA->op==TK_VARIABLE && exprCompareVariable(pParse, pA, pB) ){
    return 0;
  }
5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
** only consequence will be disabled optimizations.  But this routine
** must never return 0 if the two ExprList objects are different, or
** a malfunction will result.
**
** Two NULL pointers are considered to be the same.  But a NULL pointer
** always differs from a non-NULL pointer.
*/
int sqlite3ExprListCompare(ExprList *pA, ExprList *pB, int iTab){
  int i;
  if( pA==0 && pB==0 ) return 0;
  if( pA==0 || pB==0 ) return 1;
  if( pA->nExpr!=pB->nExpr ) return 1;
  for(i=0; i<pA->nExpr; i++){
    int res;
    Expr *pExprA = pA->a[i].pExpr;
    Expr *pExprB = pB->a[i].pExpr;
    if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
    if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
  }
  return 0;
}

/*
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
** are ignored.
*/
int sqlite3ExprCompareSkip(Expr *pA, Expr *pB, int iTab){
  return sqlite3ExprCompare(0,
             sqlite3ExprSkipCollateAndLikely(pA),
             sqlite3ExprSkipCollateAndLikely(pB),
             iTab);
}

/*
** Return non-zero if Expr p can only be true if pNN is not NULL.
**
** Or if seenNot is true, return non-zero if Expr p can only be
** non-NULL if pNN is not NULL
*/
static int exprImpliesNotNull(
  Parse *pParse,      /* Parsing context */
  Expr *p,            /* The expression to be checked */
  Expr *pNN,          /* The expression that is NOT NULL */
  int iTab,           /* Table being evaluated */
  int seenNot         /* Return true only if p can be any non-NULL value */
){
  assert( p );
  assert( pNN );
  if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
    return pNN->op!=TK_NULL;







|


















|













|
|
|







5477
5478
5479
5480
5481
5482
5483
5484
5485
5486
5487
5488
5489
5490
5491
5492
5493
5494
5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515
5516
5517
5518
5519
5520
5521
5522
5523
5524
5525
5526
** only consequence will be disabled optimizations.  But this routine
** must never return 0 if the two ExprList objects are different, or
** a malfunction will result.
**
** Two NULL pointers are considered to be the same.  But a NULL pointer
** always differs from a non-NULL pointer.
*/
int sqlite3ExprListCompare(const ExprList *pA, const ExprList *pB, int iTab){
  int i;
  if( pA==0 && pB==0 ) return 0;
  if( pA==0 || pB==0 ) return 1;
  if( pA->nExpr!=pB->nExpr ) return 1;
  for(i=0; i<pA->nExpr; i++){
    int res;
    Expr *pExprA = pA->a[i].pExpr;
    Expr *pExprB = pB->a[i].pExpr;
    if( pA->a[i].sortFlags!=pB->a[i].sortFlags ) return 1;
    if( (res = sqlite3ExprCompare(0, pExprA, pExprB, iTab)) ) return res;
  }
  return 0;
}

/*
** Like sqlite3ExprCompare() except COLLATE operators at the top-level
** are ignored.
*/
int sqlite3ExprCompareSkip(Expr *pA,Expr *pB, int iTab){
  return sqlite3ExprCompare(0,
             sqlite3ExprSkipCollateAndLikely(pA),
             sqlite3ExprSkipCollateAndLikely(pB),
             iTab);
}

/*
** Return non-zero if Expr p can only be true if pNN is not NULL.
**
** Or if seenNot is true, return non-zero if Expr p can only be
** non-NULL if pNN is not NULL
*/
static int exprImpliesNotNull(
  const Parse *pParse,/* Parsing context */
  const Expr *p,      /* The expression to be checked */
  const Expr *pNN,    /* The expression that is NOT NULL */
  int iTab,           /* Table being evaluated */
  int seenNot         /* Return true only if p can be any non-NULL value */
){
  assert( p );
  assert( pNN );
  if( sqlite3ExprCompare(pParse, p, pNN, iTab)==0 ){
    return pNN->op!=TK_NULL;
5584
5585
5586
5587
5588
5589
5590
5591





5592
5593
5594
5595
5596
5597
5598
** modified to record which bound variables are referenced.  If pParse 
** is NULL, then false will be returned if pE1 contains any bound variables.
**
** When in doubt, return false.  Returning true might give a performance
** improvement.  Returning false might cause a performance reduction, but
** it will always give the correct answer and is hence always safe.
*/
int sqlite3ExprImpliesExpr(Parse *pParse, Expr *pE1, Expr *pE2, int iTab){





  if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){
    return 1;
  }
  if( pE2->op==TK_OR
   && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
             || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
  ){







|
>
>
>
>
>







5605
5606
5607
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
** modified to record which bound variables are referenced.  If pParse 
** is NULL, then false will be returned if pE1 contains any bound variables.
**
** When in doubt, return false.  Returning true might give a performance
** improvement.  Returning false might cause a performance reduction, but
** it will always give the correct answer and is hence always safe.
*/
int sqlite3ExprImpliesExpr(
  const Parse *pParse,
  const Expr *pE1,
  const Expr *pE2,
  int iTab
){
  if( sqlite3ExprCompare(pParse, pE1, pE2, iTab)==0 ){
    return 1;
  }
  if( pE2->op==TK_OR
   && (sqlite3ExprImpliesExpr(pParse, pE1, pE2->pLeft, iTab)
             || sqlite3ExprImpliesExpr(pParse, pE1, pE2->pRight, iTab) )
  ){
Changes to src/func.c.
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  ** function. */
  sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
}

/*
** Implementation of the changes() SQL function.
**
** IMP: R-62073-11209 The changes() SQL function is a wrapper
** around the sqlite3_changes64() C/C++ function and hence follows the same
** rules for counting changes.
*/
static void changes(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);







|
|
|







567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
  ** function. */
  sqlite3_result_int64(context, sqlite3_last_insert_rowid(db));
}

/*
** Implementation of the changes() SQL function.
**
** IMP: R-32760-32347 The changes() SQL function is a wrapper
** around the sqlite3_changes64() C/C++ function and hence follows the
** same rules for counting changes.
*/
static void changes(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
static void total_changes(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  /* IMP: R-52756-41993 This function was a wrapper around the
  ** sqlite3_total_changes() C/C++ interface. */
  sqlite3_result_int64(context, sqlite3_total_changes64(db));
}

/*
** A structure defining how to do GLOB-style comparisons.
*/
struct compareInfo {







|
|







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
static void total_changes(
  sqlite3_context *context,
  int NotUsed,
  sqlite3_value **NotUsed2
){
  sqlite3 *db = sqlite3_context_db_handle(context);
  UNUSED_PARAMETER2(NotUsed, NotUsed2);
  /* IMP: R-11217-42568 This function is a wrapper around the
  ** sqlite3_total_changes64() C/C++ interface. */
  sqlite3_result_int64(context, sqlite3_total_changes64(db));
}

/*
** A structure defining how to do GLOB-style comparisons.
*/
struct compareInfo {
1711
1712
1713
1714
1715
1716
1717






1718














1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735

1736







1737
1738
1739




1740
1741

















1742


1743





1744
1745


1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758
1759

1760
1761
1762
1763
1764
1765



1766
1767



1768
1769


1770
1771
1772
1773
1774
1775
1776

1777



1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794

1795
1796
1797
1798
1799
1800
1801

1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
#endif /* SQLITE_OMIT_WINDOWFUNC */
static void minMaxFinalize(sqlite3_context *context){
  minMaxValueFinalize(context, 0);
}

/*
** group_concat(EXPR, ?SEPARATOR?)






*/














static void groupConcatStep(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zVal;
  StrAccum *pAccum;
  const char *zSep;
  int nVal, nSep;
  assert( argc==1 || argc==2 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));

  if( pAccum ){
    sqlite3 *db = sqlite3_context_db_handle(context);
    int firstTerm = pAccum->mxAlloc==0;
    pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];

    if( !firstTerm ){







      if( argc==2 ){
        zSep = (char*)sqlite3_value_text(argv[1]);
        nSep = sqlite3_value_bytes(argv[1]);




      }else{
        zSep = ",";

















        nSep = 1;


      }





      if( zSep ) sqlite3_str_append(pAccum, zSep, nSep);
    }


    zVal = (char*)sqlite3_value_text(argv[0]);
    nVal = sqlite3_value_bytes(argv[0]);
    if( zVal ) sqlite3_str_append(pAccum, zVal, nVal);
  }
}

#ifndef SQLITE_OMIT_WINDOWFUNC
static void groupConcatInverse(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  int n;
  StrAccum *pAccum;
  assert( argc==1 || argc==2 );

  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
  /* pAccum is always non-NULL since groupConcatStep() will have always
  ** run frist to initialize it */
  if( ALWAYS(pAccum) ){
    n = sqlite3_value_bytes(argv[0]);



    if( argc==2 ){
      n += sqlite3_value_bytes(argv[1]);



    }else{
      n++;


    }
    if( n>=(int)pAccum->nChar ){
      pAccum->nChar = 0;
    }else{
      pAccum->nChar -= n;
      memmove(pAccum->zText, &pAccum->zText[n], pAccum->nChar);
    }

    if( pAccum->nChar==0 ) pAccum->mxAlloc = 0;



  }
}
#else
# define groupConcatInverse 0
#endif /* SQLITE_OMIT_WINDOWFUNC */
static void groupConcatFinalize(sqlite3_context *context){
  StrAccum *pAccum;
  pAccum = sqlite3_aggregate_context(context, 0);
  if( pAccum ){
    if( pAccum->accError==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
      sqlite3_result_error_nomem(context);
    }else{    
      sqlite3_result_text(context, sqlite3StrAccumFinish(pAccum), -1, 
                          sqlite3_free);
    }

  }
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void groupConcatValue(sqlite3_context *context){
  sqlite3_str *pAccum;
  pAccum = (sqlite3_str*)sqlite3_aggregate_context(context, 0);
  if( pAccum ){

    if( pAccum->accError==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
      sqlite3_result_error_nomem(context);
    }else{    
      const char *zText = sqlite3_str_value(pAccum);
      sqlite3_result_text(context, zText, -1, SQLITE_TRANSIENT);
    }
  }
}
#else
# define groupConcatValue 0
#endif /* SQLITE_OMIT_WINDOWFUNC */








>
>
>
>
>
>

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






|




|
<
|

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

>
>


|


>






<
|

>

|
|

|
|
>
>
>
|
|
>
>
>

<
>
>

|
|

|
|

>
|
>
>
>






|
|
|
<
|
|
<
<
<
|
<
>




|
|
|
>






|







1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750

1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814

1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832

1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855

1856
1857



1858

1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
#endif /* SQLITE_OMIT_WINDOWFUNC */
static void minMaxFinalize(sqlite3_context *context){
  minMaxValueFinalize(context, 0);
}

/*
** group_concat(EXPR, ?SEPARATOR?)
**
** The SEPARATOR goes before the EXPR string.  This is tragic.  The
** groupConcatInverse() implementation would have been easier if the
** SEPARATOR were appended after EXPR.  And the order is undocumented,
** so we could change it, in theory.  But the old behavior has been
** around for so long that we dare not, for fear of breaking something.
*/
typedef struct {
  StrAccum str;          /* The accumulated concatenation */
#ifndef SQLITE_OMIT_WINDOWFUNC
  int nAccum;            /* Number of strings presently concatenated */
  int nFirstSepLength;   /* Used to detect separator length change */
  /* If pnSepLengths!=0, refs an array of inter-string separator lengths,
  ** stored as actually incorporated into presently accumulated result.
  ** (Hence, its slots in use number nAccum-1 between method calls.)
  ** If pnSepLengths==0, nFirstSepLength is the length used throughout.
  */
  int *pnSepLengths;
#endif
} GroupConcatCtx;

static void groupConcatStep(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  const char *zVal;
  GroupConcatCtx *pGCC;
  const char *zSep;
  int nVal, nSep;
  assert( argc==1 || argc==2 );
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));

  if( pGCC ){
    sqlite3 *db = sqlite3_context_db_handle(context);
    int firstTerm = pGCC->str.mxAlloc==0;
    pGCC->str.mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
    if( argc==1 ){
      if( !firstTerm ){
        sqlite3_str_appendchar(&pGCC->str, 1, ',');
      }
#ifndef SQLITE_OMIT_WINDOWFUNC
      else{
        pGCC->nFirstSepLength = 1;
      }
#endif
    }else if( !firstTerm ){
      zSep = (char*)sqlite3_value_text(argv[1]);
      nSep = sqlite3_value_bytes(argv[1]);
      if( zSep ){
        sqlite3_str_append(&pGCC->str, zSep, nSep);
      }
#ifndef SQLITE_OMIT_WINDOWFUNC
      else{
        nSep = 0;
      }
      if( nSep != pGCC->nFirstSepLength || pGCC->pnSepLengths != 0 ){
        int *pnsl = pGCC->pnSepLengths;
        if( pnsl == 0 ){
          /* First separator length variation seen, start tracking them. */
          pnsl = (int*)sqlite3_malloc64((pGCC->nAccum+1) * sizeof(int));
          if( pnsl!=0 ){
            int i = 0, nA = pGCC->nAccum-1;
            while( i<nA ) pnsl[i++] = pGCC->nFirstSepLength;
          }
        }else{
          pnsl = (int*)sqlite3_realloc64(pnsl, pGCC->nAccum * sizeof(int));
        }
        if( pnsl!=0 ){
          if( ALWAYS(pGCC->nAccum>0) ){
            pnsl[pGCC->nAccum-1] = nSep;
          }
          pGCC->pnSepLengths = pnsl;
        }else{
          sqlite3StrAccumSetError(&pGCC->str, SQLITE_NOMEM);
        }
      }
#endif
    }
#ifndef SQLITE_OMIT_WINDOWFUNC
    else{
      pGCC->nFirstSepLength = sqlite3_value_bytes(argv[1]);
    }
    pGCC->nAccum += 1;
#endif
    zVal = (char*)sqlite3_value_text(argv[0]);
    nVal = sqlite3_value_bytes(argv[0]);
    if( zVal ) sqlite3_str_append(&pGCC->str, zVal, nVal);
  }
}

#ifndef SQLITE_OMIT_WINDOWFUNC
static void groupConcatInverse(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){

  GroupConcatCtx *pGCC;
  assert( argc==1 || argc==2 );
  (void)argc;  /* Suppress unused parameter warning */
  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
  pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC));
  /* pGCC is always non-NULL since groupConcatStep() will have always
  ** run frist to initialize it */
  if( ALWAYS(pGCC) ){
    int nVS = sqlite3_value_bytes(argv[0]);
    pGCC->nAccum -= 1;
    if( pGCC->pnSepLengths!=0 ){
      assert(pGCC->nAccum >= 0);
      if( pGCC->nAccum>0 ){
        nVS += *pGCC->pnSepLengths;
        memmove(pGCC->pnSepLengths, pGCC->pnSepLengths+1,
               (pGCC->nAccum-1)*sizeof(int));
      }
    }else{

      /* If removing single accumulated string, harmlessly over-do. */
      nVS += pGCC->nFirstSepLength;
    }
    if( nVS>=(int)pGCC->str.nChar ){
      pGCC->str.nChar = 0;
    }else{
      pGCC->str.nChar -= nVS;
      memmove(pGCC->str.zText, &pGCC->str.zText[nVS], pGCC->str.nChar);
    }
    if( pGCC->str.nChar==0 ){
      pGCC->str.mxAlloc = 0;
      sqlite3_free(pGCC->pnSepLengths);
      pGCC->pnSepLengths = 0;
    }
  }
}
#else
# define groupConcatInverse 0
#endif /* SQLITE_OMIT_WINDOWFUNC */
static void groupConcatFinalize(sqlite3_context *context){
  GroupConcatCtx *pGCC
    = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0);
  if( pGCC ){

    sqlite3ResultStrAccum(context, &pGCC->str);
#ifndef SQLITE_OMIT_WINDOWFUNC



    sqlite3_free(pGCC->pnSepLengths);

#endif
  }
}
#ifndef SQLITE_OMIT_WINDOWFUNC
static void groupConcatValue(sqlite3_context *context){
  GroupConcatCtx *pGCC
    = (GroupConcatCtx*)sqlite3_aggregate_context(context, 0);
  if( pGCC ){
    StrAccum *pAccum = &pGCC->str;
    if( pAccum->accError==SQLITE_TOOBIG ){
      sqlite3_result_error_toobig(context);
    }else if( pAccum->accError==SQLITE_NOMEM ){
      sqlite3_result_error_nomem(context);
    }else{    
      const char *zText = sqlite3_str_value(pAccum);
      sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT);
    }
  }
}
#else
# define groupConcatValue 0
#endif /* SQLITE_OMIT_WINDOWFUNC */

2119
2120
2121
2122
2123
2124
2125

2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
  ** FuncDef.pHash elements at start-time.  The elements of this array
  ** are read-only after initialization is complete.
  **
  ** For peak efficiency, put the most frequently used function last.
  */
  static FuncDef aBuiltinFunc[] = {
/***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/

    TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0),
    TEST_FUNC(expr_compare,        2, INLINEFUNC_expr_compare,        0),
    TEST_FUNC(expr_implies_expr,   2, INLINEFUNC_expr_implies_expr,   0),
#ifdef SQLITE_DEBUG
    TEST_FUNC(affinity,          1, INLINEFUNC_affinity, 0),
#endif
/***** Regular functions *****/
#ifdef SQLITE_SOUNDEX
    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
    SFUNCTION(load_extension,    1, 0, 0, loadExt          ),
    SFUNCTION(load_extension,    2, 0, 0, loadExt          ),







>



<
|
|







2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195

2196
2197
2198
2199
2200
2201
2202
2203
2204
  ** FuncDef.pHash elements at start-time.  The elements of this array
  ** are read-only after initialization is complete.
  **
  ** For peak efficiency, put the most frequently used function last.
  */
  static FuncDef aBuiltinFunc[] = {
/***** Functions only available with SQLITE_TESTCTRL_INTERNAL_FUNCTIONS *****/
#if !defined(SQLITE_UNTESTABLE)
    TEST_FUNC(implies_nonnull_row, 2, INLINEFUNC_implies_nonnull_row, 0),
    TEST_FUNC(expr_compare,        2, INLINEFUNC_expr_compare,        0),
    TEST_FUNC(expr_implies_expr,   2, INLINEFUNC_expr_implies_expr,   0),

    TEST_FUNC(affinity,            1, INLINEFUNC_affinity,            0),
#endif /* !defined(SQLITE_UNTESTABLE) */
/***** Regular functions *****/
#ifdef SQLITE_SOUNDEX
    FUNCTION(soundex,            1, 0, 0, soundexFunc      ),
#endif
#ifndef SQLITE_OMIT_LOAD_EXTENSION
    SFUNCTION(load_extension,    1, 0, 0, loadExt          ),
    SFUNCTION(load_extension,    2, 0, 0, loadExt          ),
Changes to src/global.c.
347
348
349
350
351
352
353












354
355
356

357
358
359
360
361
362








363

364
365
366
367
368
369
** Name of the default collating sequence
*/
const char sqlite3StrBINARY[] = "BINARY";

/*
** Standard typenames.  These names must match the COLTYPE_* definitions.
** Adjust the SQLITE_N_STDTYPE value if adding or removing entries.












*/
const unsigned char sqlite3StdTypeLen[] = { 4, 3, 7, 4, 4 };
const char sqlite3StdTypeAffinity[] = {

  SQLITE_AFF_BLOB,
  SQLITE_AFF_INTEGER,
  SQLITE_AFF_INTEGER,
  SQLITE_AFF_REAL,
  SQLITE_AFF_TEXT
};








const char *sqlite3StdType[] = {

  "BLOB",
  "INT",
  "INTEGER",
  "REAL",
  "TEXT"
};







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

|

>






>
>
>
>
>
>
>
>

>






347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
** Name of the default collating sequence
*/
const char sqlite3StrBINARY[] = "BINARY";

/*
** Standard typenames.  These names must match the COLTYPE_* definitions.
** Adjust the SQLITE_N_STDTYPE value if adding or removing entries.
**
**    sqlite3StdType[]            The actual names of the datatypes.
**
**    sqlite3StdTypeLen[]         The length (in bytes) of each entry
**                                in sqlite3StdType[].
**
**    sqlite3StdTypeAffinity[]    The affinity associated with each entry
**                                in sqlite3StdType[].
**
**    sqlite3StdTypeMap[]         The type value (as returned from
**                                sqlite3_column_type() or sqlite3_value_type())
**                                for each entry in sqlite3StdType[].
*/
const unsigned char sqlite3StdTypeLen[] = { 3, 4, 3, 7, 4, 4 };
const char sqlite3StdTypeAffinity[] = {
  SQLITE_AFF_NUMERIC,
  SQLITE_AFF_BLOB,
  SQLITE_AFF_INTEGER,
  SQLITE_AFF_INTEGER,
  SQLITE_AFF_REAL,
  SQLITE_AFF_TEXT
};
const char sqlite3StdTypeMap[] = {
  0,
  SQLITE_BLOB,
  SQLITE_INTEGER,
  SQLITE_INTEGER,
  SQLITE_FLOAT,
  SQLITE_TEXT
};
const char *sqlite3StdType[] = {
  "ANY",
  "BLOB",
  "INT",
  "INTEGER",
  "REAL",
  "TEXT"
};
Changes to src/insert.c.
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
    pIdx->zColAff[n] = 0;
  }
 
  return pIdx->zColAff;
}

/*






** Compute the affinity string for table pTab, if it has not already been
** computed.  As an optimization, omit trailing SQLITE_AFF_BLOB affinities.
**
** If the affinity exists (if it is not entirely SQLITE_AFF_BLOB values) and


** if iReg>0 then code an OP_Affinity opcode that will set the affinities
** for register iReg and following.  Or if affinities exists and iReg==0,
** then just set the P4 operand of the previous opcode (which should  be
** an OP_MakeRecord) to the affinity string.
**
** A column affinity string has one character per column:
**
**  Character      Column affinity
**  ------------------------------
**  'A'            BLOB
**  'B'            TEXT
**  'C'            NUMERIC
**  'D'            INTEGER
**  'E'            REAL












*/
void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
  int i, j;




















  char *zColAff = pTab->zColAff;
  if( zColAff==0 ){
    sqlite3 *db = sqlite3VdbeDb(v);
    zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
    if( !zColAff ){
      sqlite3OomFault(db);
      return;
    }







>
>
>
>
>
>



|
>
>
|
|





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



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







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
    pIdx->zColAff[n] = 0;
  }
 
  return pIdx->zColAff;
}

/*
** Make changes to the evolving bytecode to do affinity transformations
** of values that are about to be gathered into a row for table pTab.
**
** For ordinary (legacy, non-strict) tables:
** -----------------------------------------
**
** Compute the affinity string for table pTab, if it has not already been
** computed.  As an optimization, omit trailing SQLITE_AFF_BLOB affinities.
**
** If the affinity string is empty (because it was all SQLITE_AFF_BLOB entries
** which were then optimized out) then this routine becomes a no-op.
**
** Otherwise if iReg>0 then code an OP_Affinity opcode that will set the
** affinities for register iReg and following.  Or if iReg==0,
** then just set the P4 operand of the previous opcode (which should  be
** an OP_MakeRecord) to the affinity string.
**
** A column affinity string has one character per column:
**
**    Character      Column affinity
**    ---------      ---------------
**    'A'            BLOB
**    'B'            TEXT
**    'C'            NUMERIC
**    'D'            INTEGER
**    'E'            REAL
**
** For STRICT tables:
** ------------------
**
** Generate an appropropriate OP_TypeCheck opcode that will verify the
** datatypes against the column definitions in pTab.  If iReg==0, that
** means an OP_MakeRecord opcode has already been generated and should be
** the last opcode generated.  The new OP_TypeCheck needs to be inserted
** before the OP_MakeRecord.  The new OP_TypeCheck should use the same
** register set as the OP_MakeRecord.  If iReg>0 then register iReg is
** the first of a series of registers that will form the new record.
** Apply the type checking to that array of registers.
*/
void sqlite3TableAffinity(Vdbe *v, Table *pTab, int iReg){
  int i, j;
  char *zColAff;
  if( pTab->tabFlags & TF_Strict ){
    if( iReg==0 ){
      /* Move the previous opcode (which should be OP_MakeRecord) forward
      ** by one slot and insert a new OP_TypeCheck where the current
      ** OP_MakeRecord is found */
      VdbeOp *pPrev;
      sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
      pPrev = sqlite3VdbeGetOp(v, -1);
      assert( pPrev!=0 );
      assert( pPrev->opcode==OP_MakeRecord || sqlite3VdbeDb(v)->mallocFailed );
      pPrev->opcode = OP_TypeCheck;
      sqlite3VdbeAddOp3(v, OP_MakeRecord, pPrev->p1, pPrev->p2, pPrev->p3);
    }else{
      /* Insert an isolated OP_Typecheck */
      sqlite3VdbeAddOp2(v, OP_TypeCheck, iReg, pTab->nNVCol);
      sqlite3VdbeAppendP4(v, pTab, P4_TABLE);
    }
    return;
  }
  zColAff = pTab->zColAff;
  if( zColAff==0 ){
    sqlite3 *db = sqlite3VdbeDb(v);
    zColAff = (char *)sqlite3DbMallocRaw(0, pTab->nCol+1);
    if( !zColAff ){
      sqlite3OomFault(db);
      return;
    }
153
154
155
156
157
158
159


160
161
162
163
164
165
166
  }
  assert( zColAff!=0 );
  i = sqlite3Strlen30NN(zColAff);
  if( i ){
    if( iReg ){
      sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
    }else{


      sqlite3VdbeChangeP4(v, -1, zColAff, i);
    }
  }
}

/*
** Return non-zero if the table pTab in database iDb or any of its indices







>
>







193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
  }
  assert( zColAff!=0 );
  i = sqlite3Strlen30NN(zColAff);
  if( i ){
    if( iReg ){
      sqlite3VdbeAddOp4(v, OP_Affinity, iReg, i, 0, zColAff, i);
    }else{
      assert( sqlite3VdbeGetOp(v, -1)->opcode==OP_MakeRecord
              || sqlite3VdbeDb(v)->mallocFailed );
      sqlite3VdbeChangeP4(v, -1, zColAff, i);
    }
  }
}

/*
** Return non-zero if the table pTab in database iDb or any of its indices
2790
2791
2792
2793
2794
2795
2796



2797
2798
2799
2800
2801
2802
2803
    return 0;   /* tab2 may not be a view or virtual table */
  }
  if( pDest->nCol!=pSrc->nCol ){
    return 0;   /* Number of columns must be the same in tab1 and tab2 */
  }
  if( pDest->iPKey!=pSrc->iPKey ){
    return 0;   /* Both tables must have the same INTEGER PRIMARY KEY */



  }
  for(i=0; i<pDest->nCol; i++){
    Column *pDestCol = &pDest->aCol[i];
    Column *pSrcCol = &pSrc->aCol[i];
#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
    if( (db->mDbFlags & DBFLAG_Vacuum)==0 
     && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN 







>
>
>







2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
    return 0;   /* tab2 may not be a view or virtual table */
  }
  if( pDest->nCol!=pSrc->nCol ){
    return 0;   /* Number of columns must be the same in tab1 and tab2 */
  }
  if( pDest->iPKey!=pSrc->iPKey ){
    return 0;   /* Both tables must have the same INTEGER PRIMARY KEY */
  }
  if( (pDest->tabFlags & TF_Strict)!=0 && (pSrc->tabFlags & TF_Strict)==0 ){
    return 0;   /* Cannot feed from a non-strict into a strict table */
  }
  for(i=0; i<pDest->nCol; i++){
    Column *pDestCol = &pDest->aCol[i];
    Column *pSrcCol = &pSrc->aCol[i];
#ifdef SQLITE_ENABLE_HIDDEN_COLUMNS
    if( (db->mDbFlags & DBFLAG_Vacuum)==0 
     && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN 
Changes to src/main.c.
3201
3202
3203
3204
3205
3206
3207







3208

3209
3210
3211
3212
3213
3214
3215
  assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
  db->autoCommit = 1;
  db->nextAutovac = -1;
  db->szMmap = sqlite3GlobalConfig.szMmap;
  db->nextPagesize = 0;







  db->nMaxSorterMmap = 0x7FFFFFFF;

  db->flags |= SQLITE_ShortColNames
                 | SQLITE_EnableTrigger
                 | SQLITE_EnableView
                 | SQLITE_CacheSpill
#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0
                 | SQLITE_TrustedSchema
#endif







>
>
>
>
>
>
>

>







3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
  assert( sizeof(db->aLimit)==sizeof(aHardLimit) );
  memcpy(db->aLimit, aHardLimit, sizeof(db->aLimit));
  db->aLimit[SQLITE_LIMIT_WORKER_THREADS] = SQLITE_DEFAULT_WORKER_THREADS;
  db->autoCommit = 1;
  db->nextAutovac = -1;
  db->szMmap = sqlite3GlobalConfig.szMmap;
  db->nextPagesize = 0;
  db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */
#ifdef SQLITE_ENABLE_SORTER_MMAP
  /* Beginning with version 3.37.0, using the VFS xFetch() API to memory-map 
  ** the temporary files used to do external sorts (see code in vdbesort.c)
  ** is disabled. It can still be used either by defining
  ** SQLITE_ENABLE_SORTER_MMAP at compile time or by using the
  ** SQLITE_TESTCTRL_SORTER_MMAP test-control at runtime. */
  db->nMaxSorterMmap = 0x7FFFFFFF;
#endif
  db->flags |= SQLITE_ShortColNames
                 | SQLITE_EnableTrigger
                 | SQLITE_EnableView
                 | SQLITE_CacheSpill
#if !defined(SQLITE_TRUSTED_SCHEMA) || SQLITE_TRUSTED_SCHEMA+0!=0
                 | SQLITE_TrustedSchema
#endif
4475
4476
4477
4478
4479
4480
4481

4482
4483
4484

4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
** It is an error to pass this routine a filename string that was not
** passed into the VFS from the SQLite core.  Doing so is similar to
** passing free() a pointer that was not obtained from malloc() - it is
** an error that we cannot easily detect but that will likely cause memory
** corruption.
*/
const char *sqlite3_filename_database(const char *zFilename){

  return databaseName(zFilename);
}
const char *sqlite3_filename_journal(const char *zFilename){

  zFilename = databaseName(zFilename);
  zFilename += sqlite3Strlen30(zFilename) + 1;
  while( zFilename[0] ){
    zFilename += sqlite3Strlen30(zFilename) + 1;
    zFilename += sqlite3Strlen30(zFilename) + 1;
  }
  return zFilename + 1;
}
const char *sqlite3_filename_wal(const char *zFilename){
#ifdef SQLITE_OMIT_WAL
  return 0;
#else
  zFilename = sqlite3_filename_journal(zFilename);
  zFilename += sqlite3Strlen30(zFilename) + 1;
  return zFilename;
#endif
}

/*
** Return the Btree pointer identified by zDbName.  Return NULL if not found.
*/







>



>













|







4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
** It is an error to pass this routine a filename string that was not
** passed into the VFS from the SQLite core.  Doing so is similar to
** passing free() a pointer that was not obtained from malloc() - it is
** an error that we cannot easily detect but that will likely cause memory
** corruption.
*/
const char *sqlite3_filename_database(const char *zFilename){
  if( zFilename==0 ) return 0;
  return databaseName(zFilename);
}
const char *sqlite3_filename_journal(const char *zFilename){
  if( zFilename==0 ) return 0;
  zFilename = databaseName(zFilename);
  zFilename += sqlite3Strlen30(zFilename) + 1;
  while( zFilename[0] ){
    zFilename += sqlite3Strlen30(zFilename) + 1;
    zFilename += sqlite3Strlen30(zFilename) + 1;
  }
  return zFilename + 1;
}
const char *sqlite3_filename_wal(const char *zFilename){
#ifdef SQLITE_OMIT_WAL
  return 0;
#else
  zFilename = sqlite3_filename_journal(zFilename);
  if( zFilename ) zFilename += sqlite3Strlen30(zFilename) + 1;
  return zFilename;
#endif
}

/*
** Return the Btree pointer identified by zDbName.  Return NULL if not found.
*/
Changes to src/malloc.c.
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
  return sqlite3Malloc(n);
}

/*
** TRUE if p is a lookaside memory allocation from db
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite3 *db, void *p){
  return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
}
#else
#define isLookaside(A,B) 0
#endif

/*
** Return the size of a memory allocation previously obtained from
** sqlite3Malloc() or sqlite3_malloc().
*/
int sqlite3MallocSize(void *p){
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  return sqlite3GlobalConfig.m.xSize(p);
}
static int lookasideMallocSize(sqlite3 *db, void *p){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE    
  return p<db->lookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL;
#else
  return db->lookaside.szTrue;
#endif  
}
int sqlite3DbMallocSize(sqlite3 *db, void *p){
  assert( p!=0 );
#ifdef SQLITE_DEBUG
  if( db==0 || !isLookaside(db,p) ){
    if( db==0 ){
      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
      assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
    }else{







|










|

|

|






|







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
  return sqlite3Malloc(n);
}

/*
** TRUE if p is a lookaside memory allocation from db
*/
#ifndef SQLITE_OMIT_LOOKASIDE
static int isLookaside(sqlite3 *db, const void *p){
  return SQLITE_WITHIN(p, db->lookaside.pStart, db->lookaside.pEnd);
}
#else
#define isLookaside(A,B) 0
#endif

/*
** Return the size of a memory allocation previously obtained from
** sqlite3Malloc() or sqlite3_malloc().
*/
int sqlite3MallocSize(const void *p){
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  return sqlite3GlobalConfig.m.xSize((void*)p);
}
static int lookasideMallocSize(sqlite3 *db, const void *p){
#ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE    
  return p<db->lookaside.pMiddle ? db->lookaside.szTrue : LOOKASIDE_SMALL;
#else
  return db->lookaside.szTrue;
#endif  
}
int sqlite3DbMallocSize(sqlite3 *db, const void *p){
  assert( p!=0 );
#ifdef SQLITE_DEBUG
  if( db==0 || !isLookaside(db,p) ){
    if( db==0 ){
      assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
      assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
    }else{
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#endif
      if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
        assert( sqlite3_mutex_held(db->mutex) );
        return db->lookaside.szTrue;
      }
    }
  }
  return sqlite3GlobalConfig.m.xSize(p);
}
sqlite3_uint64 sqlite3_msize(void *p){
  assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
}








|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#endif
      if( ((uptr)p)>=(uptr)(db->lookaside.pStart) ){
        assert( sqlite3_mutex_held(db->mutex) );
        return db->lookaside.szTrue;
      }
    }
  }
  return sqlite3GlobalConfig.m.xSize((void*)p);
}
sqlite3_uint64 sqlite3_msize(void *p){
  assert( sqlite3MemdebugNoType(p, (u8)~MEMTYPE_HEAP) );
  assert( sqlite3MemdebugHasType(p, MEMTYPE_HEAP) );
  return p ? sqlite3GlobalConfig.m.xSize(p) : 0;
}

Changes to src/memdb.c.
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
){
  MemFile *pFile = (MemFile*)pFd;
  MemStore *p = 0;
  int szName;
  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
    return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
  }
  memset(pFile, 0, sizeof(*p));
  szName = sqlite3Strlen30(zName);
  if( szName>1 && zName[0]=='/' ){
    int i;
#ifndef SQLITE_MUTEX_OMIT
    sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
    sqlite3_mutex_enter(pVfsMutex);







|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
){
  MemFile *pFile = (MemFile*)pFd;
  MemStore *p = 0;
  int szName;
  if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
    return ORIGVFS(pVfs)->xOpen(ORIGVFS(pVfs), zName, pFd, flags, pOutFlags);
  }
  memset(pFile, 0, sizeof(*pFile));
  szName = sqlite3Strlen30(zName);
  if( szName>1 && zName[0]=='/' ){
    int i;
#ifndef SQLITE_MUTEX_OMIT
    sqlite3_mutex *pVfsMutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_VFS1);
#endif
    sqlite3_mutex_enter(pVfsMutex);
Changes to src/os.c.
157
158
159
160
161
162
163

164
165
166
167
168
169
170
}

int sqlite3OsSectorSize(sqlite3_file *id){
  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
}
int sqlite3OsDeviceCharacteristics(sqlite3_file *id){

  return id->pMethods->xDeviceCharacteristics(id);
}
#ifndef SQLITE_OMIT_WAL
int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
  return id->pMethods->xShmLock(id, offset, n, flags);
}
void sqlite3OsShmBarrier(sqlite3_file *id){







>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
}

int sqlite3OsSectorSize(sqlite3_file *id){
  int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
  return (xSectorSize ? xSectorSize(id) : SQLITE_DEFAULT_SECTOR_SIZE);
}
int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
  if( NEVER(id->pMethods==0) ) return 0;
  return id->pMethods->xDeviceCharacteristics(id);
}
#ifndef SQLITE_OMIT_WAL
int sqlite3OsShmLock(sqlite3_file *id, int offset, int n, int flags){
  return id->pMethods->xShmLock(id, offset, n, flags);
}
void sqlite3OsShmBarrier(sqlite3_file *id){
Changes to src/pager.c.
675
676
677
678
679
680
681
682
683

684
685
686
687
688
689
690
  ** End of the routinely-changing class members
  ***************************************************************************/

  u16 nExtra;                 /* Add this many bytes to each in-memory page */
  i16 nReserve;               /* Number of unused bytes at end of each page */
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  u32 sectorSize;             /* Assumed sector size during rollback */
  int pageSize;               /* Number of bytes in a page */
  Pgno mxPgno;                /* Maximum allowed size of the database */

  i64 journalSizeLimit;       /* Size limit for persistent journal files */
  char *zFilename;            /* Name of the database file */
  char *zJournal;             /* Name of the journal file */
  int (*xBusyHandler)(void*); /* Function to call when busy */
  void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
  int aStat[4];               /* Total cache hits, misses, writes, spills */
#ifdef SQLITE_TEST







<

>







675
676
677
678
679
680
681

682
683
684
685
686
687
688
689
690
  ** End of the routinely-changing class members
  ***************************************************************************/

  u16 nExtra;                 /* Add this many bytes to each in-memory page */
  i16 nReserve;               /* Number of unused bytes at end of each page */
  u32 vfsFlags;               /* Flags for sqlite3_vfs.xOpen() */
  u32 sectorSize;             /* Assumed sector size during rollback */

  Pgno mxPgno;                /* Maximum allowed size of the database */
  i64 pageSize;               /* Number of bytes in a page */
  i64 journalSizeLimit;       /* Size limit for persistent journal files */
  char *zFilename;            /* Name of the database file */
  char *zJournal;             /* Name of the journal file */
  int (*xBusyHandler)(void*); /* Function to call when busy */
  void *pBusyHandlerArg;      /* Context argument for xBusyHandler */
  int aStat[4];               /* Total cache hits, misses, writes, spills */
#ifdef SQLITE_TEST
4851
4852
4853
4854
4855
4856
4857

4858
4859
4860
4861
4862
4863
4864
#endif
    memcpy(pPtr, zPathname, nPathname);   pPtr += nPathname;
    memcpy(pPtr, "-wal2", 5);             pPtr += 5 + 1;
  }else{
    pPager->zWal = 0;
  }
#endif


  if( nPathname ) sqlite3DbFree(0, zPathname);
  pPager->pVfs = pVfs;
  pPager->vfsFlags = vfsFlags;

  /* Open the pager file.
  */







>







4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
#endif
    memcpy(pPtr, zPathname, nPathname);   pPtr += nPathname;
    memcpy(pPtr, "-wal2", 5);             pPtr += 5 + 1;
  }else{
    pPager->zWal = 0;
  }
#endif
  (void)pPtr;  /* Suppress warning about unused pPtr value */

  if( nPathname ) sqlite3DbFree(0, zPathname);
  pPager->pVfs = pVfs;
  pPager->vfsFlags = vfsFlags;

  /* Open the pager file.
  */
6730
6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
#endif

/*
** Return the approximate number of bytes of memory currently
** used by the pager and its associated cache.
*/
int sqlite3PagerMemUsed(Pager *pPager){
  int perPageSize = pPager->pageSize + pPager->nExtra + sizeof(PgHdr)
                                     + 5*sizeof(void*);
  return perPageSize*sqlite3PcachePagecount(pPager->pPCache)
           + sqlite3MallocSize(pPager)
           + pPager->pageSize;
}

/*
** Return the number of references to the specified page.







|
|







6731
6732
6733
6734
6735
6736
6737
6738
6739
6740
6741
6742
6743
6744
6745
6746
#endif

/*
** Return the approximate number of bytes of memory currently
** used by the pager and its associated cache.
*/
int sqlite3PagerMemUsed(Pager *pPager){
  int perPageSize = pPager->pageSize + pPager->nExtra
    + (int)(sizeof(PgHdr) + 5*sizeof(void*));
  return perPageSize*sqlite3PcachePagecount(pPager->pPCache)
           + sqlite3MallocSize(pPager)
           + pPager->pageSize;
}

/*
** Return the number of references to the specified page.
6925
6926
6927
6928
6929
6930
6931
6932
6933

6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
    */
    nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
    for(ii=nNew; ii<pPager->nSavepoint; ii++){
      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
    }
    pPager->nSavepoint = nNew;

    /* If this is a release of the outermost savepoint, truncate 
    ** the sub-journal to zero bytes in size. */

    if( op==SAVEPOINT_RELEASE ){
      PagerSavepoint *pRel = &pPager->aSavepoint[nNew];
      if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){
        /* Only truncate if it is an in-memory sub-journal. */
        if( sqlite3JournalIsInMemory(pPager->sjfd) ){
          i64 sz = (pPager->pageSize+4)*pRel->iSubRec;
          rc = sqlite3OsTruncate(pPager->sjfd, sz);
          assert( rc==SQLITE_OK );
        }
        pPager->nSubRec = pRel->iSubRec;
      }
    }
    /* Else this is a rollback operation, playback the specified savepoint.







<
|
>





|







6926
6927
6928
6929
6930
6931
6932

6933
6934
6935
6936
6937
6938
6939
6940
6941
6942
6943
6944
6945
6946
6947
    */
    nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1);
    for(ii=nNew; ii<pPager->nSavepoint; ii++){
      sqlite3BitvecDestroy(pPager->aSavepoint[ii].pInSavepoint);
    }
    pPager->nSavepoint = nNew;


    /* Truncate the sub-journal so that it only includes the parts
    ** that are still in use. */
    if( op==SAVEPOINT_RELEASE ){
      PagerSavepoint *pRel = &pPager->aSavepoint[nNew];
      if( pRel->bTruncateOnRelease && isOpen(pPager->sjfd) ){
        /* Only truncate if it is an in-memory sub-journal. */
        if( sqlite3JournalIsInMemory(pPager->sjfd) ){
          i64 sz = (pPager->pageSize+4)*(i64)pRel->iSubRec;
          rc = sqlite3OsTruncate(pPager->sjfd, sz);
          assert( rc==SQLITE_OK );
        }
        pPager->nSubRec = pRel->iSubRec;
      }
    }
    /* Else this is a rollback operation, playback the specified savepoint.
Changes to src/parse.y.
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
ifnotexists(A) ::= .              {A = 0;}
ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
%type temp {int}
%ifndef SQLITE_OMIT_TEMPDB
temp(A) ::= TEMP.  {A = pParse->db->init.busy==0;}
%endif  SQLITE_OMIT_TEMPDB
temp(A) ::= .      {A = 0;}
create_table_args ::= LP columnlist conslist_opt(X) RP(E) table_options(F). {
  sqlite3EndTable(pParse,&X,&E,F,0);
}
create_table_args ::= AS select(S). {
  sqlite3EndTable(pParse,0,0,0,S);
  sqlite3SelectDelete(pParse->db, S);
}
%type table_options {int}

table_options(A) ::= .    {A = 0;}


table_options(A) ::= WITHOUT nm(X). {
  if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){
    A = TF_WithoutRowid | TF_NoVisibleRowid;
  }else{








    A = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
  }
}
columnlist ::= columnlist COMMA columnname carglist.
columnlist ::= columnname carglist.
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}







|






|
>
|
>
>
|



>
>
>
>
>
>
>
>







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
ifnotexists(A) ::= .              {A = 0;}
ifnotexists(A) ::= IF NOT EXISTS. {A = 1;}
%type temp {int}
%ifndef SQLITE_OMIT_TEMPDB
temp(A) ::= TEMP.  {A = pParse->db->init.busy==0;}
%endif  SQLITE_OMIT_TEMPDB
temp(A) ::= .      {A = 0;}
create_table_args ::= LP columnlist conslist_opt(X) RP(E) table_option_set(F). {
  sqlite3EndTable(pParse,&X,&E,F,0);
}
create_table_args ::= AS select(S). {
  sqlite3EndTable(pParse,0,0,0,S);
  sqlite3SelectDelete(pParse->db, S);
}
%type table_option_set {u32}
%type table_option {u32}
table_option_set(A) ::= .    {A = 0;}
table_option_set(A) ::= table_option(A).
table_option_set(A) ::= table_option_set(X) COMMA table_option(Y). {A = X|Y;}
table_option(A) ::= WITHOUT nm(X). {
  if( X.n==5 && sqlite3_strnicmp(X.z,"rowid",5)==0 ){
    A = TF_WithoutRowid | TF_NoVisibleRowid;
  }else{
    A = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
  }
}
table_option(A) ::= nm(X). {
  if( X.n==6 && sqlite3_strnicmp(X.z,"strict",6)==0 ){
    A = TF_Strict;
  }else{
    A = 0;
    sqlite3ErrorMsg(pParse, "unknown table option: %.*s", X.n, X.z);
  }
}
columnlist ::= columnlist COMMA columnname carglist.
columnlist ::= columnname carglist.
columnname(A) ::= nm(A) typetoken(Y). {sqlite3AddColumn(pParse,A,Y);}
1623
1624
1625
1626
1627
1628
1629
1630

1631
1632
1633
1634
1635
1636
1637
/////////////////////////////////// ANALYZE ///////////////////////////////////
%ifndef SQLITE_OMIT_ANALYZE
cmd ::= ANALYZE.                {sqlite3Analyze(pParse, 0, 0);}
cmd ::= ANALYZE nm(X) dbnm(Y).  {sqlite3Analyze(pParse, &X, &Y);}
%endif

//////////////////////// ALTER TABLE table ... ////////////////////////////////
%ifndef SQLITE_OMIT_ALTERTABLE

cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). {
  sqlite3AlterRenameTable(pParse,X,&Z);
}
cmd ::= ALTER TABLE add_column_fullname
        ADD kwcolumn_opt columnname(Y) carglist. {
  Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n;
  sqlite3AlterFinishAddColumn(pParse, &Y);







|
>







1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
/////////////////////////////////// ANALYZE ///////////////////////////////////
%ifndef SQLITE_OMIT_ANALYZE
cmd ::= ANALYZE.                {sqlite3Analyze(pParse, 0, 0);}
cmd ::= ANALYZE nm(X) dbnm(Y).  {sqlite3Analyze(pParse, &X, &Y);}
%endif

//////////////////////// ALTER TABLE table ... ////////////////////////////////
%ifndef SQLITE_OMIT_ALTERTABLE 
%ifndef SQLITE_OMIT_VIRTUALTABLE
cmd ::= ALTER TABLE fullname(X) RENAME TO nm(Z). {
  sqlite3AlterRenameTable(pParse,X,&Z);
}
cmd ::= ALTER TABLE add_column_fullname
        ADD kwcolumn_opt columnname(Y) carglist. {
  Y.n = (int)(pParse->sLastToken.z-Y.z) + pParse->sLastToken.n;
  sqlite3AlterFinishAddColumn(pParse, &Y);
1647
1648
1649
1650
1651
1652
1653

1654
1655
1656
1657
1658
1659
1660
1661
cmd ::= ALTER TABLE fullname(X) RENAME kwcolumn_opt nm(Y) TO nm(Z). {
  sqlite3AlterRenameColumn(pParse, X, &Y, &Z);
}

kwcolumn_opt ::= .
kwcolumn_opt ::= COLUMNKW.


%endif  SQLITE_OMIT_ALTERTABLE

//////////////////////// CREATE VIRTUAL TABLE ... /////////////////////////////
%ifndef SQLITE_OMIT_VIRTUALTABLE
cmd ::= create_vtab.                       {sqlite3VtabFinishParse(pParse,0);}
cmd ::= create_vtab LP vtabarglist RP(X).  {sqlite3VtabFinishParse(pParse,&X);}
create_vtab ::= createkw VIRTUAL TABLE ifnotexists(E)
                nm(X) dbnm(Y) USING nm(Z). {







>
|







1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
cmd ::= ALTER TABLE fullname(X) RENAME kwcolumn_opt nm(Y) TO nm(Z). {
  sqlite3AlterRenameColumn(pParse, X, &Y, &Z);
}

kwcolumn_opt ::= .
kwcolumn_opt ::= COLUMNKW.

%endif SQLITE_OMIT_VIRTUALTABLE
%endif SQLITE_OMIT_ALTERTABLE

//////////////////////// CREATE VIRTUAL TABLE ... /////////////////////////////
%ifndef SQLITE_OMIT_VIRTUALTABLE
cmd ::= create_vtab.                       {sqlite3VtabFinishParse(pParse,0);}
cmd ::= create_vtab LP vtabarglist RP(X).  {sqlite3VtabFinishParse(pParse,&X);}
create_vtab ::= createkw VIRTUAL TABLE ifnotexists(E)
                nm(X) dbnm(Y) USING nm(Z). {
Changes to src/pcache.c.
239
240
241
242
243
244
245

246
247
248
249
250


251
252
253
254
255
256
257
*/
static int numberOfCachePages(PCache *p){
  if( p->szCache>=0 ){
    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
    ** suggested cache size is set to N. */
    return p->szCache;
  }else{

    /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
    ** number of cache pages is adjusted to be a number of pages that would
    ** use approximately abs(N*1024) bytes of memory based on the current
    ** page size. */
    return (int)((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));


  }
}

/*************************************************** General Interfaces ******
**
** Initialize and shutdown the page cache subsystem. Neither of these 
** functions are threadsafe.







>




|
>
>







239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
*/
static int numberOfCachePages(PCache *p){
  if( p->szCache>=0 ){
    /* IMPLEMENTATION-OF: R-42059-47211 If the argument N is positive then the
    ** suggested cache size is set to N. */
    return p->szCache;
  }else{
    i64 n;
    /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the
    ** number of cache pages is adjusted to be a number of pages that would
    ** use approximately abs(N*1024) bytes of memory based on the current
    ** page size. */
    n = ((-1024*(i64)p->szCache)/(p->szPage+p->szExtra));
    if( n>1000000000 ) n = 1000000000;
    return (int)n;
  }
}

/*************************************************** General Interfaces ******
**
** Initialize and shutdown the page cache subsystem. Neither of these 
** functions are threadsafe.
Changes to src/pcache1.c.
813
814
815
816
817
818
819


820
821
822

823
824
825
826
827
828
829
830
831
832
833
834
835
/*
** Implementation of the sqlite3_pcache.xCachesize method. 
**
** Configure the cache_size limit for a cache.
*/
static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
  PCache1 *pCache = (PCache1 *)p;


  if( pCache->bPurgeable ){
    PGroup *pGroup = pCache->pGroup;
    pcache1EnterMutex(pGroup);

    if( nMax > 0xffff0000 - pGroup->nMaxPage + pCache->nMax ){
      nMax = 0xffff0000 - pGroup->nMaxPage + pCache->nMax;
    }
    pGroup->nMaxPage += (nMax - pCache->nMax);
    pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
    pCache->nMax = nMax;
    pCache->n90pct = pCache->nMax*9/10;
    pcache1EnforceMaxPage(pCache);
    pcache1LeaveMutex(pGroup);
  }
}

/*







>
>



>
|
|

|

|







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
/*
** Implementation of the sqlite3_pcache.xCachesize method. 
**
** Configure the cache_size limit for a cache.
*/
static void pcache1Cachesize(sqlite3_pcache *p, int nMax){
  PCache1 *pCache = (PCache1 *)p;
  u32 n;
  assert( nMax>=0 );
  if( pCache->bPurgeable ){
    PGroup *pGroup = pCache->pGroup;
    pcache1EnterMutex(pGroup);
    n = (u32)nMax;
    if( n > 0x7fff0000 - pGroup->nMaxPage + pCache->nMax ){
      n = 0x7fff0000 - pGroup->nMaxPage + pCache->nMax;
    }
    pGroup->nMaxPage += (n - pCache->nMax);
    pGroup->mxPinned = pGroup->nMaxPage + 10 - pGroup->nMinPage;
    pCache->nMax = n;
    pCache->n90pct = pCache->nMax*9/10;
    pcache1EnforceMaxPage(pCache);
    pcache1LeaveMutex(pGroup);
  }
}

/*
Changes to src/pragma.c.
1191
1192
1193
1194
1195
1196
1197
















































1198
1199
1200
1201
1202
1203
1204
               k,
               isHidden);
      }
    }
  }
  break;

















































#ifdef SQLITE_DEBUG
  case PragTyp_STATS: {
    Index *pIdx;
    HashElem *i;
    pParse->nMem = 5;
    sqlite3CodeVerifySchema(pParse, iDb);
    for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){







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







1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
               k,
               isHidden);
      }
    }
  }
  break;

  /*
  **   PRAGMA table_list
  **
  ** Return a single row for each table, virtual table, or view in the
  ** entire schema.
  **
  ** schema:     Name of attached database hold this table
  ** name:       Name of the table itself
  ** type:       "table", "view", "virtual", "shadow"
  ** ncol:       Number of columns
  ** wr:         True for a WITHOUT ROWID table
  ** strict:     True for a STRICT table
  */
  case PragTyp_TABLE_LIST: {
    int ii;
    pParse->nMem = 6;
    sqlite3CodeVerifyNamedSchema(pParse, zDb);
    for(ii=0; ii<db->nDb; ii++){
      HashElem *k;
      Hash *pHash;
      if( zDb && sqlite3_stricmp(zDb, db->aDb[ii].zDbSName)!=0 ) continue;
      pHash = &db->aDb[ii].pSchema->tblHash;
      for(k=sqliteHashFirst(pHash); k; k=sqliteHashNext(k) ){
        Table *pTab = sqliteHashData(k);
        const char *zType;
        if( zRight && sqlite3_stricmp(zRight, pTab->zName)!=0 ) continue;
        if( IsView(pTab) ){
          zType = "view";
        }else if( IsVirtual(pTab) ){
          zType = "virtual";
        }else if( pTab->tabFlags & TF_Shadow ){
          zType = "shadow";
        }else{
          zType = "table";
        }
        sqlite3VdbeMultiLoad(v, 1, "sssiii",
           db->aDb[ii].zDbSName,
           pTab->zName,
           zType,
           pTab->nCol,
           (pTab->tabFlags & TF_WithoutRowid)!=0,
           (pTab->tabFlags & TF_Strict)!=0
        );
      }
    }
  }
  break;

#ifdef SQLITE_DEBUG
  case PragTyp_STATS: {
    Index *pIdx;
    HashElem *i;
    pParse->nMem = 5;
    sqlite3CodeVerifySchema(pParse, iDb);
    for(i=sqliteHashFirst(&pDb->pSchema->tblHash); i; i=sqliteHashNext(i)){
1650
1651
1652
1653
1654
1655
1656

1657
1658
1659
1660
1661
1662
1663
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx, *pPk;
        Index *pPrior = 0;
        int loopTop;
        int iDataCur, iIdxCur;
        int r1 = -1;


        if( pTab->tnum<1 ) continue;  /* Skip VIEWs or VIRTUAL TABLEs */
        if( pObjTab && pObjTab!=pTab ) continue;
        pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
                                   1, 0, &iDataCur, &iIdxCur);
        /* reg[7] counts the number of entries in the table.







>







1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
      for(x=sqliteHashFirst(pTbls); x; x=sqliteHashNext(x)){
        Table *pTab = sqliteHashData(x);
        Index *pIdx, *pPk;
        Index *pPrior = 0;
        int loopTop;
        int iDataCur, iIdxCur;
        int r1 = -1;
        int bStrict;

        if( pTab->tnum<1 ) continue;  /* Skip VIEWs or VIRTUAL TABLEs */
        if( pObjTab && pObjTab!=pTab ) continue;
        pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
        sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0,
                                   1, 0, &iDataCur, &iIdxCur);
        /* reg[7] counts the number of entries in the table.
1671
1672
1673
1674
1675
1676
1677

1678
1679


1680
1681

1682
1683
1684

1685
1686
1687
1688

1689
1690

















1691
1692

1693
1694

1695
1696
1697
1698
1699
1700
1701
        assert( sqlite3NoTempsInRange(pParse,1,7+j) );
        sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
        loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
        if( !isQuick ){
          /* Sanity check on record header decoding */
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3);
          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);

        }
        /* Verify that all NOT NULL columns really are NOT NULL */


        for(j=0; j<pTab->nCol; j++){
          char *zErr;

          int jmp2;
          if( j==pTab->iPKey ) continue;
          if( pTab->aCol[j].notNull==0 ) continue;

          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
          if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){
            sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
          }

          jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
          zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,

















                              pTab->aCol[j].zCnName);
          sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);

          integrityCheckResultRow(v);
          sqlite3VdbeJumpHere(v, jmp2);

        }
        /* Verify CHECK constraints */
        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
          if( db->mallocFailed==0 ){
            int addrCkFault = sqlite3VdbeMakeLabel(pParse);
            int addrCkOk = sqlite3VdbeMakeLabel(pParse);







>

|
>
>


>
|

|
>




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







1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
        assert( sqlite3NoTempsInRange(pParse,1,7+j) );
        sqlite3VdbeAddOp2(v, OP_Rewind, iDataCur, 0); VdbeCoverage(v);
        loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
        if( !isQuick ){
          /* Sanity check on record header decoding */
          sqlite3VdbeAddOp3(v, OP_Column, iDataCur, pTab->nNVCol-1,3);
          sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
          VdbeComment((v, "(right-most column)"));
        }
        /* Verify that all NOT NULL columns really are NOT NULL.  At the
        ** same time verify the type of the content of STRICT tables */
        bStrict = (pTab->tabFlags & TF_Strict)!=0;
        for(j=0; j<pTab->nCol; j++){
          char *zErr;
          Column *pCol = pTab->aCol + j;
          int doError, jmp2;
          if( j==pTab->iPKey ) continue;
          if( pCol->notNull==0 && !bStrict ) continue;
          doError = bStrict ? sqlite3VdbeMakeLabel(pParse) : 0;
          sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, j, 3);
          if( sqlite3VdbeGetOp(v,-1)->opcode==OP_Column ){
            sqlite3VdbeChangeP5(v, OPFLAG_TYPEOFARG);
          }
          if( pCol->notNull ){
            jmp2 = sqlite3VdbeAddOp1(v, OP_NotNull, 3); VdbeCoverage(v);
            zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName,
                                pCol->zCnName);
            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
            if( bStrict ){
              sqlite3VdbeGoto(v, doError);
            }else{
              integrityCheckResultRow(v);
            }
            sqlite3VdbeJumpHere(v, jmp2);
          }
          if( (pTab->tabFlags & TF_Strict)!=0
           && pCol->eCType!=COLTYPE_ANY
          ){
            jmp2 = sqlite3VdbeAddOp3(v, OP_IsNullOrType, 3, 0, 
                                     sqlite3StdTypeMap[pCol->eCType-1]);
            VdbeCoverage(v);
            zErr = sqlite3MPrintf(db, "non-%s value in %s.%s",
                                  sqlite3StdType[pCol->eCType-1],
                                  pTab->zName, pTab->aCol[j].zCnName);
            sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC);
            sqlite3VdbeResolveLabel(v, doError);
            integrityCheckResultRow(v);
            sqlite3VdbeJumpHere(v, jmp2);
          }
        }
        /* Verify CHECK constraints */
        if( pTab->pCheck && (db->flags & SQLITE_IgnoreChecks)==0 ){
          ExprList *pCheck = sqlite3ExprListDup(db, pTab->pCheck, 0);
          if( db->mallocFailed==0 ){
            int addrCkFault = sqlite3VdbeMakeLabel(pParse);
            int addrCkOk = sqlite3VdbeMakeLabel(pParse);
Changes to src/pragma.h.
39
40
41
42
43
44
45

46
47
48
49
50
51
52
53
54
55
56
57
58
59
#define PragTyp_PAGE_SIZE                     31
#define PragTyp_PRAGMA_LIST                   32
#define PragTyp_SECURE_DELETE                 33
#define PragTyp_SHRINK_MEMORY                 34
#define PragTyp_SOFT_HEAP_LIMIT               35
#define PragTyp_SYNCHRONOUS                   36
#define PragTyp_TABLE_INFO                    37

#define PragTyp_TEMP_STORE                    38
#define PragTyp_TEMP_STORE_DIRECTORY          39
#define PragTyp_THREADS                       40
#define PragTyp_WAL_AUTOCHECKPOINT            41
#define PragTyp_WAL_CHECKPOINT                42
#define PragTyp_LOCK_STATUS                   43
#define PragTyp_STATS                         44

/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
#define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
#define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
#define PragFlg_Result0    0x10 /* Acts as query when no argument */







>
|
|
|
|
|
|
|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#define PragTyp_PAGE_SIZE                     31
#define PragTyp_PRAGMA_LIST                   32
#define PragTyp_SECURE_DELETE                 33
#define PragTyp_SHRINK_MEMORY                 34
#define PragTyp_SOFT_HEAP_LIMIT               35
#define PragTyp_SYNCHRONOUS                   36
#define PragTyp_TABLE_INFO                    37
#define PragTyp_TABLE_LIST                    38
#define PragTyp_TEMP_STORE                    39
#define PragTyp_TEMP_STORE_DIRECTORY          40
#define PragTyp_THREADS                       41
#define PragTyp_WAL_AUTOCHECKPOINT            42
#define PragTyp_WAL_CHECKPOINT                43
#define PragTyp_LOCK_STATUS                   44
#define PragTyp_STATS                         45

/* Property flags associated with various pragma. */
#define PragFlg_NeedSchema 0x01 /* Force schema load before running */
#define PragFlg_NoColumns  0x02 /* OP_ResultRow called with zero columns */
#define PragFlg_NoColumns1 0x04 /* zero columns if RHS argument is present */
#define PragFlg_ReadOnly   0x08 /* Read-only HEADER_VALUE */
#define PragFlg_Result0    0x10 /* Acts as query when no argument */
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
  /*   9 */ "name",       
  /*  10 */ "type",       
  /*  11 */ "notnull",    
  /*  12 */ "dflt_value", 
  /*  13 */ "pk",         
  /*  14 */ "hidden",     
                           /* table_info reuses 8 */
  /*  15 */ "seqno",       /* Used by: index_xinfo */
  /*  16 */ "cid",        
  /*  17 */ "name",       
  /*  18 */ "desc",       
  /*  19 */ "coll",       
  /*  20 */ "key",        
  /*  21 */ "name",        /* Used by: function_list */
  /*  22 */ "builtin",    
  /*  23 */ "type",       
  /*  24 */ "enc",        
  /*  25 */ "narg",       
  /*  26 */ "flags",      
  /*  27 */ "tbl",         /* Used by: stats */
  /*  28 */ "idx",        
  /*  29 */ "wdth",       
  /*  30 */ "hght",       
  /*  31 */ "flgs",       
  /*  32 */ "seq",         /* Used by: index_list */
  /*  33 */ "name",       
  /*  34 */ "unique",     
  /*  35 */ "origin",     
  /*  36 */ "partial",    
  /*  37 */ "table",       /* Used by: foreign_key_check */
  /*  38 */ "rowid",      
  /*  39 */ "parent",     
  /*  40 */ "fkid",       






                           /* index_info reuses 15 */
  /*  41 */ "seq",         /* Used by: database_list */
  /*  42 */ "name",       
  /*  43 */ "file",       
  /*  44 */ "busy",        /* Used by: wal_checkpoint */
  /*  45 */ "log",        
  /*  46 */ "checkpointed",
                           /* collation_list reuses 32 */
  /*  47 */ "database",    /* Used by: lock_status */
  /*  48 */ "status",     
  /*  49 */ "cache_size",  /* Used by: default_cache_size */
                           /* module_list pragma_list reuses 9 */
  /*  50 */ "timeout",     /* Used by: busy_timeout */
};

/* Definitions of all built-in pragmas */
typedef struct PragmaName {
  const char *const zName; /* Name of pragma */
  u8 ePragTyp;             /* PragTyp_XXX value */
  u8 mPragFlg;             /* Zero or more PragFlg_XXX values */







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

|







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
  /*   9 */ "name",       
  /*  10 */ "type",       
  /*  11 */ "notnull",    
  /*  12 */ "dflt_value", 
  /*  13 */ "pk",         
  /*  14 */ "hidden",     
                           /* table_info reuses 8 */
  /*  15 */ "schema",      /* Used by: table_list */
  /*  16 */ "name",       
  /*  17 */ "type",       
  /*  18 */ "ncol",       
  /*  19 */ "wr",         
  /*  20 */ "strict",     
  /*  21 */ "seqno",       /* Used by: index_xinfo */
  /*  22 */ "cid",        
  /*  23 */ "name",       
  /*  24 */ "desc",       
  /*  25 */ "coll",       
  /*  26 */ "key",        
  /*  27 */ "name",        /* Used by: function_list */
  /*  28 */ "builtin",    
  /*  29 */ "type",       
  /*  30 */ "enc",        
  /*  31 */ "narg",       
  /*  32 */ "flags",      
  /*  33 */ "tbl",         /* Used by: stats */
  /*  34 */ "idx",        
  /*  35 */ "wdth",       
  /*  36 */ "hght",       
  /*  37 */ "flgs",       
  /*  38 */ "seq",         /* Used by: index_list */
  /*  39 */ "name",       
  /*  40 */ "unique",     
  /*  41 */ "origin",     
  /*  42 */ "partial",    
  /*  43 */ "table",       /* Used by: foreign_key_check */
  /*  44 */ "rowid",      
  /*  45 */ "parent",     
  /*  46 */ "fkid",       
                           /* index_info reuses 21 */
  /*  47 */ "seq",         /* Used by: database_list */
  /*  48 */ "name",       
  /*  49 */ "file",       
  /*  50 */ "busy",        /* Used by: wal_checkpoint */
  /*  51 */ "log",        
  /*  52 */ "checkpointed",
                           /* collation_list reuses 38 */
  /*  53 */ "database",    /* Used by: lock_status */
  /*  54 */ "status",     
  /*  55 */ "cache_size",  /* Used by: default_cache_size */
                           /* module_list pragma_list reuses 9 */
  /*  56 */ "timeout",     /* Used by: busy_timeout */
};

/* Definitions of all built-in pragmas */
typedef struct PragmaName {
  const char *const zName; /* Name of pragma */
  u8 ePragTyp;             /* PragTyp_XXX value */
  u8 mPragFlg;             /* Zero or more PragFlg_XXX values */
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_AutoIndex },
#endif
#endif
 {/* zName:     */ "busy_timeout",
  /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 50, 1,
  /* iArg:      */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "cache_size",
  /* ePragTyp:  */ PragTyp_CACHE_SIZE,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },







|







174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_AutoIndex },
#endif
#endif
 {/* zName:     */ "busy_timeout",
  /* ePragTyp:  */ PragTyp_BUSY_TIMEOUT,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 56, 1,
  /* iArg:      */ 0 },
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "cache_size",
  /* ePragTyp:  */ PragTyp_CACHE_SIZE,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_CkptFullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "collation_list",
  /* ePragTyp:  */ PragTyp_COLLATION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 32, 2,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
 {/* zName:     */ "compile_options",
  /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 0, 0,







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_CkptFullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "collation_list",
  /* ePragTyp:  */ PragTyp_COLLATION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 38, 2,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_COMPILEOPTION_DIAGS)
 {/* zName:     */ "compile_options",
  /* ePragTyp:  */ PragTyp_COMPILE_OPTIONS,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 0, 0,
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
  /* ColNames:  */ 0, 0,
  /* iArg:      */ BTREE_DATA_VERSION },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "database_list",
  /* ePragTyp:  */ PragTyp_DATABASE_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
  /* ColNames:  */ 41, 3,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
 {/* zName:     */ "default_cache_size",
  /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 49, 1,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
 {/* zName:     */ "defer_foreign_keys",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,







|






|







248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
  /* ColNames:  */ 0, 0,
  /* iArg:      */ BTREE_DATA_VERSION },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "database_list",
  /* ePragTyp:  */ PragTyp_DATABASE_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0,
  /* ColNames:  */ 47, 3,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED)
 {/* zName:     */ "default_cache_size",
  /* ePragTyp:  */ PragTyp_DEFAULT_CACHE_SIZE,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 55, 1,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
 {/* zName:     */ "defer_foreign_keys",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
 {/* zName:     */ "foreign_key_check",
  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 37, 4,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
 {/* zName:     */ "foreign_key_list",
  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 0, 8,







|







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER)
 {/* zName:     */ "foreign_key_check",
  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_CHECK,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 43, 4,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FOREIGN_KEY)
 {/* zName:     */ "foreign_key_list",
  /* ePragTyp:  */ PragTyp_FOREIGN_KEY_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 0, 8,
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
  /* iArg:      */ SQLITE_FullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "function_list",
  /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 21, 6,
  /* iArg:      */ 0 },
#endif
#endif
 {/* zName:     */ "hard_heap_limit",
  /* ePragTyp:  */ PragTyp_HARD_HEAP_LIMIT,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 0, 0,







|







328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
  /* iArg:      */ SQLITE_FullFSync },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
#if !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS)
 {/* zName:     */ "function_list",
  /* ePragTyp:  */ PragTyp_FUNCTION_LIST,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 27, 6,
  /* iArg:      */ 0 },
#endif
#endif
 {/* zName:     */ "hard_heap_limit",
  /* ePragTyp:  */ PragTyp_HARD_HEAP_LIMIT,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 0, 0,
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "index_info",
  /* ePragTyp:  */ PragTyp_INDEX_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 15, 3,
  /* iArg:      */ 0 },
 {/* zName:     */ "index_list",
  /* ePragTyp:  */ PragTyp_INDEX_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 32, 5,
  /* iArg:      */ 0 },
 {/* zName:     */ "index_xinfo",
  /* ePragTyp:  */ PragTyp_INDEX_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 15, 6,
  /* iArg:      */ 1 },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
 {/* zName:     */ "integrity_check",
  /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 0, 0,







|




|




|







357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "index_info",
  /* ePragTyp:  */ PragTyp_INDEX_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 21, 3,
  /* iArg:      */ 0 },
 {/* zName:     */ "index_list",
  /* ePragTyp:  */ PragTyp_INDEX_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 38, 5,
  /* iArg:      */ 0 },
 {/* zName:     */ "index_xinfo",
  /* ePragTyp:  */ PragTyp_INDEX_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 21, 6,
  /* iArg:      */ 1 },
#endif
#if !defined(SQLITE_OMIT_INTEGRITY_CHECK)
 {/* zName:     */ "integrity_check",
  /* ePragTyp:  */ PragTyp_INTEGRITY_CHECK,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 0, 0,
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
 {/* zName:     */ "lock_status",
  /* ePragTyp:  */ PragTyp_LOCK_STATUS,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 47, 2,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "locking_mode",
  /* ePragTyp:  */ PragTyp_LOCKING_MODE,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 0, 0,







|







407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST)
 {/* zName:     */ "lock_status",
  /* ePragTyp:  */ PragTyp_LOCK_STATUS,
  /* ePragFlg:  */ PragFlg_Result0,
  /* ColNames:  */ 53, 2,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "locking_mode",
  /* ePragTyp:  */ PragTyp_LOCKING_MODE,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 0, 0,
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561





562
563
564
565
566
567
568
  /* iArg:      */ SQLITE_SqlTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
 {/* zName:     */ "stats",
  /* ePragTyp:  */ PragTyp_STATS,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 27, 5,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "synchronous",
  /* ePragTyp:  */ PragTyp_SYNCHRONOUS,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "table_info",
  /* ePragTyp:  */ PragTyp_TABLE_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 8, 6,
  /* iArg:      */ 0 },





 {/* zName:     */ "table_xinfo",
  /* ePragTyp:  */ PragTyp_TABLE_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 8, 7,
  /* iArg:      */ 1 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)







|















>
>
>
>
>







546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
  /* iArg:      */ SQLITE_SqlTrace },
#endif
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)
 {/* zName:     */ "stats",
  /* ePragTyp:  */ PragTyp_STATS,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq,
  /* ColNames:  */ 33, 5,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
 {/* zName:     */ "synchronous",
  /* ePragTyp:  */ PragTyp_SYNCHRONOUS,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result0|PragFlg_SchemaReq|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)
 {/* zName:     */ "table_info",
  /* ePragTyp:  */ PragTyp_TABLE_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 8, 6,
  /* iArg:      */ 0 },
 {/* zName:     */ "table_list",
  /* ePragTyp:  */ PragTyp_TABLE_LIST,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1,
  /* ColNames:  */ 15, 6,
  /* iArg:      */ 1 },
 {/* zName:     */ "table_xinfo",
  /* ePragTyp:  */ PragTyp_TABLE_INFO,
  /* ePragFlg:  */ PragFlg_NeedSchema|PragFlg_Result1|PragFlg_SchemaOpt,
  /* ColNames:  */ 8, 7,
  /* iArg:      */ 1 },
#endif
#if !defined(SQLITE_OMIT_PAGER_PRAGMAS)
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
  /* ePragTyp:  */ PragTyp_WAL_AUTOCHECKPOINT,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
 {/* zName:     */ "wal_checkpoint",
  /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
  /* ePragFlg:  */ PragFlg_NeedSchema,
  /* ColNames:  */ 44, 3,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 67 on by default, 77 total. */







|










|
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
  /* ePragTyp:  */ PragTyp_WAL_AUTOCHECKPOINT,
  /* ePragFlg:  */ 0,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ 0 },
 {/* zName:     */ "wal_checkpoint",
  /* ePragTyp:  */ PragTyp_WAL_CHECKPOINT,
  /* ePragFlg:  */ PragFlg_NeedSchema,
  /* ColNames:  */ 50, 3,
  /* iArg:      */ 0 },
#endif
#if !defined(SQLITE_OMIT_FLAG_PRAGMAS)
 {/* zName:     */ "writable_schema",
  /* ePragTyp:  */ PragTyp_FLAG,
  /* ePragFlg:  */ PragFlg_Result0|PragFlg_NoColumns1,
  /* ColNames:  */ 0, 0,
  /* iArg:      */ SQLITE_WriteSchema|SQLITE_NoSchemaError },
#endif
};
/* Number of pragmas: 68 on by default, 78 total. */
Changes to src/prepare.c.
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
     || (db->init.newTnum>pData->mxPage && pData->mxPage>0)
    ){
      if( sqlite3Config.bExtraSchemaChecks ){
        corruptSchema(pData, argv, "invalid rootpage");
      }
    }
    db->init.orphanTrigger = 0;
    db->init.azInit = argv;
    pStmt = 0;
    TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0);
    rc = db->errCode;
    assert( (rc&0xFF)==(rcp&0xFF) );
    db->init.iDb = saved_iDb;
    /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
        if( rc > pData->rc ) pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          sqlite3OomFault(db);
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv, sqlite3_errmsg(db));
        }
      }
    }

    sqlite3_finalize(pStmt);
  }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){
    corruptSchema(pData, argv, 0);
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already







|


















>







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
     || (db->init.newTnum>pData->mxPage && pData->mxPage>0)
    ){
      if( sqlite3Config.bExtraSchemaChecks ){
        corruptSchema(pData, argv, "invalid rootpage");
      }
    }
    db->init.orphanTrigger = 0;
    db->init.azInit = (const char**)argv;
    pStmt = 0;
    TESTONLY(rcp = ) sqlite3Prepare(db, argv[4], -1, 0, 0, &pStmt, 0);
    rc = db->errCode;
    assert( (rc&0xFF)==(rcp&0xFF) );
    db->init.iDb = saved_iDb;
    /* assert( saved_iDb==0 || (db->mDbFlags & DBFLAG_Vacuum)!=0 ); */
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
        if( rc > pData->rc ) pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          sqlite3OomFault(db);
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv, sqlite3_errmsg(db));
        }
      }
    }
    db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */
    sqlite3_finalize(pStmt);
  }else if( argv[1]==0 || (argv[4]!=0 && argv[4][0]!=0) ){
    corruptSchema(pData, argv, 0);
  }else{
    /* If the SQL column is blank it means this is an index that
    ** was created to be the PRIMARY KEY or to fulfill a UNIQUE
    ** constraint for a CREATE TABLE.  The index should have already
Changes to src/printf.c.
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  return (char)digit;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */

/*
** Set the StrAccum object to an error mode.
*/
static void setStrAccumError(StrAccum *p, u8 eError){
  assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
  p->accError = eError;
  if( p->mxAlloc ) sqlite3_str_reset(p);
  if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError);
}

/*







|







141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
  return (char)digit;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */

/*
** Set the StrAccum object to an error mode.
*/
void sqlite3StrAccumSetError(StrAccum *p, u8 eError){
  assert( eError==SQLITE_NOMEM || eError==SQLITE_TOOBIG );
  p->accError = eError;
  if( p->mxAlloc ) sqlite3_str_reset(p);
  if( eError==SQLITE_TOOBIG ) sqlite3ErrorToParser(p->db, eError);
}

/*
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
** SQL from requesting large allocations using the precision or width
** field of the printf() function.
*/
static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
  char *z;
  if( pAccum->accError ) return 0;
  if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){
    setStrAccumError(pAccum, SQLITE_TOOBIG);
    return 0;
  }
  z = sqlite3DbMallocRaw(pAccum->db, n);
  if( z==0 ){
    setStrAccumError(pAccum, SQLITE_NOMEM);
  }
  return z;
}

/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.







|




|







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
** SQL from requesting large allocations using the precision or width
** field of the printf() function.
*/
static char *printfTempBuf(sqlite3_str *pAccum, sqlite3_int64 n){
  char *z;
  if( pAccum->accError ) return 0;
  if( n>pAccum->nAlloc && n>pAccum->mxAlloc ){
    sqlite3StrAccumSetError(pAccum, SQLITE_TOOBIG);
    return 0;
  }
  z = sqlite3DbMallocRaw(pAccum->db, n);
  if( z==0 ){
    sqlite3StrAccumSetError(pAccum, SQLITE_NOMEM);
  }
  return z;
}

/*
** On machines with a small stack size, you can redefine the
** SQLITE_PRINT_BUF_SIZE to be something smaller, if desired.
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
  assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
  if( p->accError ){
    testcase(p->accError==SQLITE_TOOBIG);
    testcase(p->accError==SQLITE_NOMEM);
    return 0;
  }
  if( p->mxAlloc==0 ){
    setStrAccumError(p, SQLITE_TOOBIG);
    return p->nAlloc - p->nChar - 1;
  }else{
    char *zOld = isMalloced(p) ? p->zText : 0;
    i64 szNew = p->nChar;
    szNew += (sqlite3_int64)N + 1;
    if( szNew+p->nChar<=p->mxAlloc ){
      /* Force exponential buffer size growth as long as it does not overflow,
      ** to avoid having to call this routine too often */
      szNew += p->nChar;
    }
    if( szNew > p->mxAlloc ){
      sqlite3_str_reset(p);
      setStrAccumError(p, SQLITE_TOOBIG);
      return 0;
    }else{
      p->nAlloc = (int)szNew;
    }
    if( p->db ){
      zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
    }else{
      zNew = sqlite3Realloc(zOld, p->nAlloc);
    }
    if( zNew ){
      assert( p->zText!=0 || p->nChar==0 );
      if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
      p->zText = zNew;
      p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
      p->printfFlags |= SQLITE_PRINTF_MALLOCED;
    }else{
      sqlite3_str_reset(p);
      setStrAccumError(p, SQLITE_NOMEM);
      return 0;
    }
  }
  return N;
}

/*







|












|

















|







921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
  assert( p->nChar+(i64)N >= p->nAlloc ); /* Only called if really needed */
  if( p->accError ){
    testcase(p->accError==SQLITE_TOOBIG);
    testcase(p->accError==SQLITE_NOMEM);
    return 0;
  }
  if( p->mxAlloc==0 ){
    sqlite3StrAccumSetError(p, SQLITE_TOOBIG);
    return p->nAlloc - p->nChar - 1;
  }else{
    char *zOld = isMalloced(p) ? p->zText : 0;
    i64 szNew = p->nChar;
    szNew += (sqlite3_int64)N + 1;
    if( szNew+p->nChar<=p->mxAlloc ){
      /* Force exponential buffer size growth as long as it does not overflow,
      ** to avoid having to call this routine too often */
      szNew += p->nChar;
    }
    if( szNew > p->mxAlloc ){
      sqlite3_str_reset(p);
      sqlite3StrAccumSetError(p, SQLITE_TOOBIG);
      return 0;
    }else{
      p->nAlloc = (int)szNew;
    }
    if( p->db ){
      zNew = sqlite3DbRealloc(p->db, zOld, p->nAlloc);
    }else{
      zNew = sqlite3Realloc(zOld, p->nAlloc);
    }
    if( zNew ){
      assert( p->zText!=0 || p->nChar==0 );
      if( !isMalloced(p) && p->nChar>0 ) memcpy(zNew, p->zText, p->nChar);
      p->zText = zNew;
      p->nAlloc = sqlite3DbMallocSize(p->db, zNew);
      p->printfFlags |= SQLITE_PRINTF_MALLOCED;
    }else{
      sqlite3_str_reset(p);
      sqlite3StrAccumSetError(p, SQLITE_NOMEM);
      return 0;
    }
  }
  return N;
}

/*
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
















1046
1047
1048
1049
1050
1051
1052
  char *zText;
  assert( p->mxAlloc>0 && !isMalloced(p) );
  zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
  if( zText ){
    memcpy(zText, p->zText, p->nChar+1);
    p->printfFlags |= SQLITE_PRINTF_MALLOCED;
  }else{
    setStrAccumError(p, SQLITE_NOMEM);
  }
  p->zText = zText;
  return zText;
}
char *sqlite3StrAccumFinish(StrAccum *p){
  if( p->zText ){
    p->zText[p->nChar] = 0;
    if( p->mxAlloc>0 && !isMalloced(p) ){
      return strAccumFinishRealloc(p);
    }
  }
  return p->zText;
}

















/*
** This singleton is an sqlite3_str object that is returned if
** sqlite3_malloc() fails to provide space for a real one.  This
** sqlite3_str object accepts no new text and always returns
** an SQLITE_NOMEM error.
*/







|













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







1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
  char *zText;
  assert( p->mxAlloc>0 && !isMalloced(p) );
  zText = sqlite3DbMallocRaw(p->db, p->nChar+1 );
  if( zText ){
    memcpy(zText, p->zText, p->nChar+1);
    p->printfFlags |= SQLITE_PRINTF_MALLOCED;
  }else{
    sqlite3StrAccumSetError(p, SQLITE_NOMEM);
  }
  p->zText = zText;
  return zText;
}
char *sqlite3StrAccumFinish(StrAccum *p){
  if( p->zText ){
    p->zText[p->nChar] = 0;
    if( p->mxAlloc>0 && !isMalloced(p) ){
      return strAccumFinishRealloc(p);
    }
  }
  return p->zText;
}

/*
** Use the content of the StrAccum passed as the second argument
** as the result of an SQL function.
*/
void sqlite3ResultStrAccum(sqlite3_context *pCtx, StrAccum *p){
  if( p->accError ){
    sqlite3_result_error_code(pCtx, p->accError);
    sqlite3_str_reset(p);
  }else if( isMalloced(p) ){
    sqlite3_result_text(pCtx, p->zText, p->nChar, SQLITE_DYNAMIC);
  }else{
    sqlite3_result_text(pCtx, "", 0, SQLITE_STATIC);
    sqlite3_str_reset(p);
  }
}

/*
** This singleton is an sqlite3_str object that is returned if
** sqlite3_malloc() fails to provide space for a real one.  This
** sqlite3_str object accepts no new text and always returns
** an SQLITE_NOMEM error.
*/
Changes to src/resolve.c.
1115
1116
1117
1118
1119
1120
1121

1122
1123

1124

1125
1126
1127
1128
1129
1130
1131
      testcase( pExpr->op==TK_IN );
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        int nRef = pNC->nRef;
        testcase( pNC->ncFlags & NC_IsCheck );
        testcase( pNC->ncFlags & NC_PartIdx );
        testcase( pNC->ncFlags & NC_IdxExpr );
        testcase( pNC->ncFlags & NC_GenCol );

        sqlite3ResolveNotValid(pParse, pNC, "subqueries",
                 NC_IsCheck|NC_PartIdx|NC_IdxExpr|NC_GenCol, pExpr);

        sqlite3WalkSelect(pWalker, pExpr->x.pSelect);

        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
          pNC->ncFlags |= NC_VarSelect;
        }
      }
      break;







>
|
<
>
|
>







1115
1116
1117
1118
1119
1120
1121
1122
1123

1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
      testcase( pExpr->op==TK_IN );
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        int nRef = pNC->nRef;
        testcase( pNC->ncFlags & NC_IsCheck );
        testcase( pNC->ncFlags & NC_PartIdx );
        testcase( pNC->ncFlags & NC_IdxExpr );
        testcase( pNC->ncFlags & NC_GenCol );
        if( pNC->ncFlags & NC_SelfRef ){
          notValidImpl(pParse, pNC, "subqueries", pExpr);

        }else{
          sqlite3WalkSelect(pWalker, pExpr->x.pSelect);
        }
        assert( pNC->nRef>=nRef );
        if( nRef!=pNC->nRef ){
          ExprSetProperty(pExpr, EP_VarSelect);
          pNC->ncFlags |= NC_VarSelect;
        }
      }
      break;
Changes to src/select.c.
343
344
345
346
347
348
349



350
351
352
353
354
355
356
  assert( pSrc->a[iLeft].pTab );
  assert( pSrc->a[iRight].pTab );

  pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
  pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);

  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);



  if( pEq && isOuterJoin ){
    ExprSetProperty(pEq, EP_FromJoin);
    assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(pEq, EP_NoReduce);
    pEq->iRightJoinTable = pE2->iTable;
  }
  *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);







>
>
>







343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
  assert( pSrc->a[iLeft].pTab );
  assert( pSrc->a[iRight].pTab );

  pE1 = sqlite3CreateColumnExpr(db, pSrc, iLeft, iColLeft);
  pE2 = sqlite3CreateColumnExpr(db, pSrc, iRight, iColRight);

  pEq = sqlite3PExpr(pParse, TK_EQ, pE1, pE2);
  assert( pE2!=0 || pEq==0 );  /* Due to db->mallocFailed test
                               ** in sqlite3DbMallocRawNN() called from
                               ** sqlite3PExpr(). */
  if( pEq && isOuterJoin ){
    ExprSetProperty(pEq, EP_FromJoin);
    assert( !ExprHasProperty(pEq, EP_TokenOnly|EP_Reduced) );
    ExprSetVVAProperty(pEq, EP_NoReduce);
    pEq->iRightJoinTable = pE2->iTable;
  }
  *ppWhere = sqlite3ExprAnd(pParse, *ppWhere, pEq);
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
      if( pCol->zCnName ){
        memcpy(&pCol->zCnName[n+1], zType, m+1);
        pCol->colFlags |= COLFLAG_HASTYPE;
      }
    }
    if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
    pColl = sqlite3ExprCollSeq(pParse, p);
    if( pColl && (pCol->colFlags & COLFLAG_HASCOLL)==0 ){
      assert( pTab->pIndex==0 );
      sqlite3ColumnSetColl(db, pCol, pColl->zName);
    }
  }
  pTab->szTabRow = 1; /* Any non-zero value works */
}








|







2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
      if( pCol->zCnName ){
        memcpy(&pCol->zCnName[n+1], zType, m+1);
        pCol->colFlags |= COLFLAG_HASTYPE;
      }
    }
    if( pCol->affinity<=SQLITE_AFF_NONE ) pCol->affinity = aff;
    pColl = sqlite3ExprCollSeq(pParse, p);
    if( pColl ){
      assert( pTab->pIndex==0 );
      sqlite3ColumnSetColl(db, pCol, pColl->zName);
    }
  }
  pTab->szTabRow = 1; /* Any non-zero value works */
}

2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
  Parse *pParse,        /* Parsing context */
  Select *p,            /* The recursive SELECT to be coded */
  SelectDest *pDest     /* What to do with query results */
){
  SrcList *pSrc = p->pSrc;      /* The FROM clause of the recursive query */
  int nCol = p->pEList->nExpr;  /* Number of columns in the recursive table */
  Vdbe *v = pParse->pVdbe;      /* The prepared statement under construction */
  Select *pSetup = p->pPrior;   /* The setup query */
  Select *pFirstRec;            /* Left-most recursive term */
  int addrTop;                  /* Top of the loop */
  int addrCont, addrBreak;      /* CONTINUE and BREAK addresses */
  int iCurrent = 0;             /* The Current table */
  int regCurrent;               /* Register holding Current table */
  int iQueue;                   /* The Queue table */
  int iDistinct = 0;            /* To ensure unique results if UNION */







|







2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
  Parse *pParse,        /* Parsing context */
  Select *p,            /* The recursive SELECT to be coded */
  SelectDest *pDest     /* What to do with query results */
){
  SrcList *pSrc = p->pSrc;      /* The FROM clause of the recursive query */
  int nCol = p->pEList->nExpr;  /* Number of columns in the recursive table */
  Vdbe *v = pParse->pVdbe;      /* The prepared statement under construction */
  Select *pSetup;               /* The setup query */
  Select *pFirstRec;            /* Left-most recursive term */
  int addrTop;                  /* Top of the loop */
  int addrCont, addrBreak;      /* CONTINUE and BREAK addresses */
  int iCurrent = 0;             /* The Current table */
  int regCurrent;               /* Register holding Current table */
  int iQueue;                   /* The Queue table */
  int iDistinct = 0;            /* To ensure unique results if UNION */
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
  /* Figure out how many elements of the compound SELECT are part of the
  ** recursive query.  Make sure no recursive elements use aggregate
  ** functions.  Mark the recursive elements as UNION ALL even if they
  ** are really UNION because the distinctness will be enforced by the
  ** iDistinct table.  pFirstRec is left pointing to the left-most
  ** recursive term of the CTE.
  */
  pFirstRec = p;
  for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){
    if( pFirstRec->selFlags & SF_Aggregate ){
      sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
      goto end_of_recursive_query;
    }
    pFirstRec->op = TK_ALL;
    if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break;







<







2514
2515
2516
2517
2518
2519
2520

2521
2522
2523
2524
2525
2526
2527
  /* Figure out how many elements of the compound SELECT are part of the
  ** recursive query.  Make sure no recursive elements use aggregate
  ** functions.  Mark the recursive elements as UNION ALL even if they
  ** are really UNION because the distinctness will be enforced by the
  ** iDistinct table.  pFirstRec is left pointing to the left-most
  ** recursive term of the CTE.
  */

  for(pFirstRec=p; ALWAYS(pFirstRec!=0); pFirstRec=pFirstRec->pPrior){
    if( pFirstRec->selFlags & SF_Aggregate ){
      sqlite3ErrorMsg(pParse, "recursive aggregate queries not supported");
      goto end_of_recursive_query;
    }
    pFirstRec->op = TK_ALL;
    if( (pFirstRec->pPrior->selFlags & SF_Recursive)==0 ) break;
3011
3012
3013
3014
3015
3016
3017


3018


3019
3020
3021
3022
3023
3024
3025
    }
    sqlite3KeyInfoUnref(pKeyInfo);
  }

multi_select_end:
  pDest->iSdst = dest.iSdst;
  pDest->nSdst = dest.nSdst;


  sqlite3SelectDelete(db, pDelete);


  return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

/*
** Error message for when two or more terms of a compound select have different
** size result sets.







>
>
|
>
>







3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
    }
    sqlite3KeyInfoUnref(pKeyInfo);
  }

multi_select_end:
  pDest->iSdst = dest.iSdst;
  pDest->nSdst = dest.nSdst;
  if( pDelete ){
    sqlite3ParserAddCleanup(pParse,
        (void(*)(sqlite3*,void*))sqlite3SelectDelete,
        pDelete);
  }
  return rc;
}
#endif /* SQLITE_OMIT_COMPOUND_SELECT */

/*
** Error message for when two or more terms of a compound select have different
** size result sets.
5488
5489
5490
5491
5492
5493
5494
5495

5496
5497
5498
5499
5500
5501
5502
5503
5504
          if( (db->flags & SQLITE_EnableView)==0
           && pTab->pSchema!=db->aDb[1].pSchema
          ){
            sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
              pTab->zName);
          }
          pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0);
        }else

#ifndef SQLITE_OMIT_VIRTUALTABLE
        if( ALWAYS(IsVirtual(pTab))
         && pFrom->fg.fromDDL
         && ALWAYS(pTab->u.vtab.p!=0)
         && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0)
        ){
          sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"",
                                  pTab->zName);
        }







<
>

|







5494
5495
5496
5497
5498
5499
5500

5501
5502
5503
5504
5505
5506
5507
5508
5509
5510
          if( (db->flags & SQLITE_EnableView)==0
           && pTab->pSchema!=db->aDb[1].pSchema
          ){
            sqlite3ErrorMsg(pParse, "access to view \"%s\" prohibited",
              pTab->zName);
          }
          pFrom->pSelect = sqlite3SelectDup(db, pTab->u.view.pSelect, 0);

        }
#ifndef SQLITE_OMIT_VIRTUALTABLE
        else if( ALWAYS(IsVirtual(pTab))
         && pFrom->fg.fromDDL
         && ALWAYS(pTab->u.vtab.p!=0)
         && pTab->u.vtab.p->eVtabRisk > ((db->flags & SQLITE_TrustedSchema)!=0)
        ){
          sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"",
                                  pTab->zName);
        }
6579
6580
6581
6582
6583
6584
6585
6586

6587
6588
6589
6590
6591
6592
6593
    */
    pParse->nHeight += sqlite3SelectExprHeight(p);

    /* Make copies of constant WHERE-clause terms in the outer query down
    ** inside the subquery.  This can help the subquery to run more efficiently.
    */
    if( OptimizationEnabled(db, SQLITE_PushDown)
     && (pItem->fg.isCte==0 || pItem->u2.pCteUse->eM10d!=M10d_Yes)

     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
                           (pItem->fg.jointype & JT_OUTER)!=0)
    ){
#if SELECTTRACE_ENABLED
      if( sqlite3SelectTrace & 0x100 ){
        SELECTTRACE(0x100,pParse,p,
            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));







|
>







6585
6586
6587
6588
6589
6590
6591
6592
6593
6594
6595
6596
6597
6598
6599
6600
    */
    pParse->nHeight += sqlite3SelectExprHeight(p);

    /* Make copies of constant WHERE-clause terms in the outer query down
    ** inside the subquery.  This can help the subquery to run more efficiently.
    */
    if( OptimizationEnabled(db, SQLITE_PushDown)
     && (pItem->fg.isCte==0 
         || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2))
     && pushDownWhereTerms(pParse, pSub, p->pWhere, pItem->iCursor,
                           (pItem->fg.jointype & JT_OUTER)!=0)
    ){
#if SELECTTRACE_ENABLED
      if( sqlite3SelectTrace & 0x100 ){
        SELECTTRACE(0x100,pParse,p,
            ("After WHERE-clause push-down into subquery %d:\n", pSub->selId));
6640
6641
6642
6643
6644
6645
6646

6647
6648
6649
6650
6651
6652
6653
      ** generated.  Invoke the subroutine to compute the materialization,
      ** the make the pItem->iCursor be a copy of the ephemerial table that
      ** holds the result of the materialization. */
      CteUse *pCteUse = pItem->u2.pCteUse;
      sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e);
      if( pItem->iCursor!=pCteUse->iCur ){
        sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur);

      }
      pSub->nSelectRow = pCteUse->nRowEst;
    }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){
      /* This view has already been materialized by a prior entry in
      ** this same FROM clause.  Reuse it. */
      if( pPrior->addrFillSub ){
        sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub);







>







6647
6648
6649
6650
6651
6652
6653
6654
6655
6656
6657
6658
6659
6660
6661
      ** generated.  Invoke the subroutine to compute the materialization,
      ** the make the pItem->iCursor be a copy of the ephemerial table that
      ** holds the result of the materialization. */
      CteUse *pCteUse = pItem->u2.pCteUse;
      sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e);
      if( pItem->iCursor!=pCteUse->iCur ){
        sqlite3VdbeAddOp2(v, OP_OpenDup, pItem->iCursor, pCteUse->iCur);
        VdbeComment((v, "%!S", pItem));
      }
      pSub->nSelectRow = pCteUse->nRowEst;
    }else if( (pPrior = isSelfJoinView(pTabList, pItem))!=0 ){
      /* This view has already been materialized by a prior entry in
      ** this same FROM clause.  Reuse it. */
      if( pPrior->addrFillSub ){
        sqlite3VdbeAddOp2(v, OP_Gosub, pPrior->regReturn, pPrior->addrFillSub);
Changes to src/shell.c.in.
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
  while( *z ){
    if( (0xc0&*(z++))!=0x80 ) n++;
  }
  return n;
}

/*

** Return true if zFile does not exist or if it is not an ordinary file.

*/

#ifdef _WIN32

# define notNormalFile(X) 0











#else
static int notNormalFile(const char *zFile){
  struct stat x;
  int rc;
  memset(&x, 0, sizeof(x));



  rc = stat(zFile, &x);

  return rc || !S_ISREG(x.st_mode);
}
#endif



/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**







>
|
>

>

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

<
|
|
<
>
>
>
|
>
|
|

>
>







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
  while( *z ){
    if( (0xc0&*(z++))!=0x80 ) n++;
  }
  return n;
}

/*
** Return open FILE * if zFile exists, can be opened for read
** and is an ordinary file or a character stream source.
** Otherwise return 0.
*/
static FILE * openChrSource(const char *zFile){
#ifdef _WIN32
  struct _stat x = {0};
# define STAT_CHR_SRC(mode) ((mode & (_S_IFCHR|_S_IFIFO|_S_IFREG))!=0)
  /* On Windows, open first, then check the stream nature. This order
  ** is necessary because _stat() and sibs, when checking a named pipe,
  ** effectively break the pipe as its supplier sees it. */
  FILE *rv = fopen(zFile, "rb");
  if( rv==0 ) return 0;
  if( _fstat(_fileno(rv), &x) != 0
      || !STAT_CHR_SRC(x.st_mode)){
    fclose(rv);
    rv = 0;
  }
  return rv;
#else

  struct stat x = {0};
  int rc = stat(zFile, &x);

# define STAT_CHR_SRC(mode) (S_ISREG(mode)||S_ISFIFO(mode)||S_ISCHR(mode))
  if( rc!=0 ) return 0;
  if( STAT_CHR_SRC(x.st_mode) ){
    return fopen(zFile, "rb");
  }else{
    return 0;
  }
#endif
#undef STAT_CHR_SRC
}

/*
** This routine reads a line of text from FILE in, stores
** the text in memory obtained from malloc() and returns a pointer
** to the text.  NULL is returned at end of file, or if malloc()
** fails.
**
1100
1101
1102
1103
1104
1105
1106


1107
1108
1109
1110
1111
1112
1113
  u8 autoEQPtest;        /* autoEQP is in test mode */
  u8 autoEQPtrace;       /* autoEQP is in trace mode */
  u8 scanstatsOn;        /* True to display scan stats before each finalize */
  u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
  u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
  u8 nEqpLevel;          /* Depth of the EQP output graph */
  u8 eTraceType;         /* SHELL_TRACE_* value for type of trace */


  unsigned statsOn;      /* True to display memory stats before each finalize */
  unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
  int outCount;          /* Revert to stdout when reaching zero */
  int cnt;               /* Number of records displayed so far */
  int lineno;            /* Line number of last line read from in */
  int openFlags;         /* Additional flags to open.  (SQLITE_OPEN_NOFOLLOW) */
  FILE *in;              /* Read commands from this stream */







>
>







1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
  u8 autoEQPtest;        /* autoEQP is in test mode */
  u8 autoEQPtrace;       /* autoEQP is in trace mode */
  u8 scanstatsOn;        /* True to display scan stats before each finalize */
  u8 openMode;           /* SHELL_OPEN_NORMAL, _APPENDVFS, or _ZIPFILE */
  u8 doXdgOpen;          /* Invoke start/open/xdg-open in output_reset() */
  u8 nEqpLevel;          /* Depth of the EQP output graph */
  u8 eTraceType;         /* SHELL_TRACE_* value for type of trace */
  u8 bSafeMode;          /* True to prohibit unsafe operations */
  u8 bSafeModePersist;   /* The long-term value of bSafeMode */
  unsigned statsOn;      /* True to display memory stats before each finalize */
  unsigned mEqpLines;    /* Mask of veritical lines in the EQP output graph */
  int outCount;          /* Revert to stdout when reaching zero */
  int cnt;               /* Number of records displayed so far */
  int lineno;            /* Line number of last line read from in */
  int openFlags;         /* Additional flags to open.  (SQLITE_OPEN_NOFOLLOW) */
  FILE *in;              /* Read commands from this stream */
1151
1152
1153
1154
1155
1156
1157

1158
1159
1160
1161
1162
1163
1164
1165
1166
    OpenSession aSession[4];   /* Array of sessions.  [0] is in focus. */
#endif
  } aAuxDb[5],           /* Array of all database connections */
    *pAuxDb;             /* Currently active database connection */
  int *aiIndent;         /* Array of indents used in MODE_Explain */
  int nIndent;           /* Size of array aiIndent[] */
  int iIndent;           /* Index of current op in aiIndent[] */

  EQPGraph sGraph;       /* Information for the graphical EXPLAIN QUERY PLAN */
  ExpertInfo expert;        /* Valid if previous command was ".expert OPT..." */
};


/* Allowed values for ShellState.autoEQP
*/
#define AUTOEQP_off      0           /* Automatic EXPLAIN QUERY PLAN is off */
#define AUTOEQP_on       1           /* Automatic EQP is on */







>

|







1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
    OpenSession aSession[4];   /* Array of sessions.  [0] is in focus. */
#endif
  } aAuxDb[5],           /* Array of all database connections */
    *pAuxDb;             /* Currently active database connection */
  int *aiIndent;         /* Array of indents used in MODE_Explain */
  int nIndent;           /* Size of array aiIndent[] */
  int iIndent;           /* Index of current op in aiIndent[] */
  char *zNonce;          /* Nonce for temporary safe-mode excapes */
  EQPGraph sGraph;       /* Information for the graphical EXPLAIN QUERY PLAN */
  ExpertInfo expert;     /* Valid if previous command was ".expert OPT..." */
};


/* Allowed values for ShellState.autoEQP
*/
#define AUTOEQP_off      0           /* Automatic EXPLAIN QUERY PLAN is off */
#define AUTOEQP_on       1           /* Automatic EQP is on */
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
#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 */
#define SHFLG_PreserveRowid  0x00000008 /* .dump preserves rowid values */
#define SHFLG_Newlines       0x00000010 /* .dump --newline flag */
#define SHFLG_CountChanges   0x00000020 /* .changes setting */
#define SHFLG_Echo           0x00000040 /* .echo or --echo setting */
#define SHFLG_HeaderSet      0x00000080 /* .header has been used */
#define SHFLG_DumpDataOnly   0x00000100 /* .dump show data only */
#define SHFLG_DumpNoSys      0x00000200 /* .dump omits system tables */

/*
** Macros for testing and setting shellFlgs
*/
#define ShellHasFlag(P,X)    (((P)->shellFlgs & (X))!=0)







|







1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
#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 */
#define SHFLG_PreserveRowid  0x00000008 /* .dump preserves rowid values */
#define SHFLG_Newlines       0x00000010 /* .dump --newline flag */
#define SHFLG_CountChanges   0x00000020 /* .changes setting */
#define SHFLG_Echo           0x00000040 /* .echo or --echo setting */
#define SHFLG_HeaderSet      0x00000080 /* showHeader has been specified */
#define SHFLG_DumpDataOnly   0x00000100 /* .dump show data only */
#define SHFLG_DumpNoSys      0x00000200 /* .dump omits system tables */

/*
** Macros for testing and setting shellFlgs
*/
#define ShellHasFlag(P,X)    (((P)->shellFlgs & (X))!=0)
1287
1288
1289
1290
1291
1292
1293





















1294
1295
1296
1297
1298
1299
1300
  sqlite3_value **apVal
){
  ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
  (void)nVal;
  utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
  sqlite3_result_value(pCtx, apVal[0]);
}






















/*
** SQL function:   edit(VALUE)
**                 edit(VALUE,EDITOR)
**
** These steps:
**







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







1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
  sqlite3_value **apVal
){
  ShellState *p = (ShellState*)sqlite3_user_data(pCtx);
  (void)nVal;
  utf8_printf(p->out, "%s\n", sqlite3_value_text(apVal[0]));
  sqlite3_result_value(pCtx, apVal[0]);
}

/*
** If in safe mode, print an error message described by the arguments
** and exit immediately.
*/
static void failIfSafeMode(
  ShellState *p,
  const char *zErrMsg,
  ...
){
  if( p->bSafeMode ){
    va_list ap;
    char *zMsg;
    va_start(ap, zErrMsg);
    zMsg = sqlite3_vmprintf(zErrMsg, ap);
    va_end(ap);
    raw_printf(stderr, "line %d: ", p->lineno);
    utf8_printf(stderr, "%s\n", zMsg);
    exit(1);
  }
}

/*
** SQL function:   edit(VALUE)
**                 edit(VALUE,EDITOR)
**
** These steps:
**
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
  }
  if( bBin ){
    sqlite3_result_blob64(context, p, sz, sqlite3_free);
  }else{
    sqlite3_int64 i, j;
    if( hasCRNL ){
      /* If the original contains \r\n then do no conversions back to \n */
      j = sz;
    }else{
      /* If the file did not originally contain \r\n then convert any new
      ** \r\n back into \n */
      for(i=j=0; i<sz; i++){
        if( p[i]=='\r' && p[i+1]=='\n' ) i++;
        p[j++] = p[i];
      }







<







1451
1452
1453
1454
1455
1456
1457

1458
1459
1460
1461
1462
1463
1464
  }
  if( bBin ){
    sqlite3_result_blob64(context, p, sz, sqlite3_free);
  }else{
    sqlite3_int64 i, j;
    if( hasCRNL ){
      /* If the original contains \r\n then do no conversions back to \n */

    }else{
      /* If the file did not originally contain \r\n then convert any new
      ** \r\n back into \n */
      for(i=j=0; i<sz; i++){
        if( p[i]=='\r' && p[i+1]=='\n' ) i++;
        p[j++] = p[i];
      }
1765
1766
1767
1768
1769
1770
1771











































1772
1773
1774
1775
1776
1777
1778
    return TRUE;
  }
  return FALSE;
}
#endif

#ifndef SQLITE_OMIT_AUTHORIZATION











































/*
** When the ".auth ON" is set, the following authorizer callback is
** invoked.  It always returns SQLITE_OK.
*/
static int shellAuth(
  void *pClientData,
  int op,







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







1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
    return TRUE;
  }
  return FALSE;
}
#endif

#ifndef SQLITE_OMIT_AUTHORIZATION
/*
** This authorizer runs in safe mode.
*/
static int safeModeAuth(
  void *pClientData,
  int op,
  const char *zA1,
  const char *zA2,
  const char *zA3,
  const char *zA4
){
  ShellState *p = (ShellState*)pClientData;
  static const char *azProhibitedFunctions[] = {
    "edit",
    "fts3_tokenizer",
    "load_extension",
    "readfile",
    "writefile",
    "zipfile",
    "zipfile_cds",
  };
  UNUSED_PARAMETER(zA2);
  UNUSED_PARAMETER(zA3);
  UNUSED_PARAMETER(zA4);
  switch( op ){
    case SQLITE_ATTACH: {
      failIfSafeMode(p, "cannot run ATTACH in safe mode");
      break;
    }
    case SQLITE_FUNCTION: {
      int i;
      for(i=0; i<ArraySize(azProhibitedFunctions); i++){
        if( sqlite3_stricmp(zA1, azProhibitedFunctions[i])==0 ){
          failIfSafeMode(p, "cannot use the %s() function in safe mode",
                         azProhibitedFunctions[i]);
        }
      }
      break;
    }
  }
  return SQLITE_OK;
}

/*
** When the ".auth ON" is set, the following authorizer callback is
** invoked.  It always returns SQLITE_OK.
*/
static int shellAuth(
  void *pClientData,
  int op,
1807
1808
1809
1810
1811
1812
1813

1814
1815
1816
1817
1818
1819
1820
    if( az[i] ){
      output_c_string(p->out, az[i]);
    }else{
      raw_printf(p->out, "NULL");
    }
  }
  raw_printf(p->out, "\n");

  return SQLITE_OK;
}
#endif

/*
** Print a schema statement.  Part of MODE_Semi and MODE_Pretty output.
**







>







1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
    if( az[i] ){
      output_c_string(p->out, az[i]);
    }else{
      raw_printf(p->out, "NULL");
    }
  }
  raw_printf(p->out, "\n");
  if( p->bSafeMode ) (void)safeModeAuth(pClientData, op, zA1, zA2, zA3, zA4);
  return SQLITE_OK;
}
#endif

/*
** Print a schema statement.  Part of MODE_Semi and MODE_Pretty output.
**
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
      if( azData==0 ) shell_out_of_memory();
    }
    nRow++;
    for(i=0; i<nColumn; i++){
      z = (const char*)sqlite3_column_text(pStmt,i);
      azData[nRow*nColumn + i] = z ? strdup(z) : 0;
    }
  }while( (rc = sqlite3_step(pStmt))==SQLITE_ROW );
  if( nColumn>p->nWidth ){
    p->colWidth = realloc(p->colWidth, nColumn*2*sizeof(int));
    if( p->colWidth==0 ) shell_out_of_memory();
    for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
    p->nWidth = nColumn;
    p->actualWidth = &p->colWidth[nColumn];
  }
  memset(p->actualWidth, 0, nColumn*sizeof(int));
  for(i=0; i<nColumn; i++){







|

|







3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
      if( azData==0 ) shell_out_of_memory();
    }
    nRow++;
    for(i=0; i<nColumn; i++){
      z = (const char*)sqlite3_column_text(pStmt,i);
      azData[nRow*nColumn + i] = z ? strdup(z) : 0;
    }
  }while( sqlite3_step(pStmt)==SQLITE_ROW );
  if( nColumn>p->nWidth ){
    p->colWidth = realloc(p->colWidth, (nColumn+1)*2*sizeof(int));
    if( p->colWidth==0 ) shell_out_of_memory();
    for(i=p->nWidth; i<nColumn; i++) p->colWidth[i] = 0;
    p->nWidth = nColumn;
    p->actualWidth = &p->colWidth[nColumn];
  }
  memset(p->actualWidth, 0, nColumn*sizeof(int));
  for(i=0; i<nColumn; i++){
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
  rc = sqlite3_step(pStmt);
  /* if we have a result set... */
  if( SQLITE_ROW == rc ){
    /* allocate space for col name ptr, value ptr, and type */
    int nCol = sqlite3_column_count(pStmt);
    void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
    if( !pData ){
      rc = SQLITE_NOMEM;
    }else{
      char **azCols = (char **)pData;      /* Names of result columns */
      char **azVals = &azCols[nCol];       /* Results */
      int *aiTypes = (int *)&azVals[nCol]; /* Result types */
      int i, x;
      assert(sizeof(int) <= sizeof(char *));
      /* save off ptrs to column names */







|







3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
  rc = sqlite3_step(pStmt);
  /* if we have a result set... */
  if( SQLITE_ROW == rc ){
    /* allocate space for col name ptr, value ptr, and type */
    int nCol = sqlite3_column_count(pStmt);
    void *pData = sqlite3_malloc64(3*nCol*sizeof(const char*) + 1);
    if( !pData ){
      shell_out_of_memory();
    }else{
      char **azCols = (char **)pData;      /* Names of result columns */
      char **azVals = &azCols[nCol];       /* Results */
      int *aiTypes = (int *)&azVals[nCol]; /* Result types */
      int i, x;
      assert(sizeof(int) <= sizeof(char *));
      /* save off ptrs to column names */
3980
3981
3982
3983
3984
3985
3986

3987
3988
3989
3990
3991
3992
3993
  "     line      One value per line",
  "     list      Values delimited by \"|\"",
  "     markdown  Markdown table format",
  "     quote     Escape answers as for SQL",
  "     table     ASCII-art table",
  "     tabs      Tab-separated values",
  "     tcl       TCL list elements",

  ".nullvalue STRING        Use STRING in place of NULL values",
  ".once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE",
  "     If FILE begins with '|' then open as a pipe",
  "       --bom  Put a UTF8 byte-order mark at the beginning",
  "       -e     Send output to the system text editor",
  "       -x     Send output as CSV to a spreadsheet (same as \".excel\")",
#ifdef SQLITE_DEBUG







>







4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
  "     line      One value per line",
  "     list      Values delimited by \"|\"",
  "     markdown  Markdown table format",
  "     quote     Escape answers as for SQL",
  "     table     ASCII-art table",
  "     tabs      Tab-separated values",
  "     tcl       TCL list elements",
  ".nonce STRING            Disable safe mode for one command if the nonce matches",
  ".nullvalue STRING        Use STRING in place of NULL values",
  ".once ?OPTIONS? ?FILE?   Output for the next SQL command only to FILE",
  "     If FILE begins with '|' then open as a pipe",
  "       --bom  Put a UTF8 byte-order mark at the beginning",
  "       -e     Send output to the system text editor",
  "       -x     Send output as CSV to a spreadsheet (same as \".excel\")",
#ifdef SQLITE_DEBUG
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
      break;
    }
    rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
    if( rc==17 ){
      k = iOffset+j;
      if( k+16<=n ){
        int ii;
        for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
      }
    }
  }
  *pnData = n;
  if( in!=p->in ){







|







4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
      break;
    }
    rc = sscanf(zLine,"| %d: %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x",
                &j, &x[0], &x[1], &x[2], &x[3], &x[4], &x[5], &x[6], &x[7],
                &x[8], &x[9], &x[10], &x[11], &x[12], &x[13], &x[14], &x[15]);
    if( rc==17 ){
      k = iOffset+j;
      if( k+16<=n && k>=0 ){
        int ii;
        for(ii=0; ii<16; ii++) a[k+ii] = x[ii]&0xff;
      }
    }
  }
  *pnData = n;
  if( in!=p->in ){
4694
4695
4696
4697
4698
4699
4700



4701
4702
4703
4704
4705
4706
4707
      }
      if( p->szMax>0 ){
        sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
      }
    }
#endif
  }



}

/*
** Attempt to close the databaes connection.  Report errors.
*/
void close_db(sqlite3 *db){
  int rc = sqlite3_close(db);







>
>
>







4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
      }
      if( p->szMax>0 ){
        sqlite3_file_control(p->db, "main", SQLITE_FCNTL_SIZE_LIMIT, &p->szMax);
      }
    }
#endif
  }
  if( p->bSafeModePersist && p->db!=0 ){
    sqlite3_set_authorizer(p->db, safeModeAuth, p);
  }
}

/*
** Attempt to close the databaes connection.  Report errors.
*/
void close_db(sqlite3 *db){
  int rc = sqlite3_close(db);
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
5305
    rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
    if( rc ){
      utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
                      sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
                      zQuery);
      goto end_schema_xfer;
    }
    while( (rc = sqlite3_step(pQuery))==SQLITE_ROW ){
      zName = sqlite3_column_text(pQuery, 0);
      zSql = sqlite3_column_text(pQuery, 1);
      printf("%s... ", zName); fflush(stdout);
      sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
      if( zErrMsg ){
        utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
        sqlite3_free(zErrMsg);







|







5381
5382
5383
5384
5385
5386
5387
5388
5389
5390
5391
5392
5393
5394
5395
    rc = sqlite3_prepare_v2(p->db, zQuery, -1, &pQuery, 0);
    if( rc ){
      utf8_printf(stderr, "Error: (%d) %s on [%s]\n",
                      sqlite3_extended_errcode(p->db), sqlite3_errmsg(p->db),
                      zQuery);
      goto end_schema_xfer;
    }
    while( sqlite3_step(pQuery)==SQLITE_ROW ){
      zName = sqlite3_column_text(pQuery, 0);
      zSql = sqlite3_column_text(pQuery, 1);
      printf("%s... ", zName); fflush(stdout);
      sqlite3_exec(newDb, (const char*)zSql, 0, 0, &zErrMsg);
      if( zErrMsg ){
        utf8_printf(stderr, "Error: %s\nSQL: [%s]\n", zErrMsg, zSql);
        sqlite3_free(zErrMsg);
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
#endif
    }
    p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
  }else{
    p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
  }
  if( p->zTempFile==0 ){
    raw_printf(stderr, "out of memory\n");
    exit(1);
  }
}


/*
** The implementation of SQL scalar function fkey_collate_clause(), used
** by the ".lint fkey-indexes" command. This scalar function is always







|
<







5769
5770
5771
5772
5773
5774
5775
5776

5777
5778
5779
5780
5781
5782
5783
#endif
    }
    p->zTempFile = sqlite3_mprintf("%s/temp%llx.%s", zTemp, r, zSuffix);
  }else{
    p->zTempFile = sqlite3_mprintf("%z.%s", p->zTempFile, zSuffix);
  }
  if( p->zTempFile==0 ){
    shell_out_of_memory();

  }
}


/*
** The implementation of SQL scalar function fkey_collate_clause(), used
** by the ".lint fkey-indexes" command. This scalar function is always
7457
7458
7459
7460
7461
7462
7463


7464
7465
7466
7467
7468
7469
7470
7471
7472

7473
7474
7475
7476
7477
7478
7479
7480
7481
7482
7483
7484
7485
7486

7487
7488
7489
7490
7491
7492
7493
      raw_printf(stderr, "Usage: .auth ON|OFF\n");
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);
    if( booleanValue(azArg[1]) ){
      sqlite3_set_authorizer(p->db, shellAuth, p);


    }else{
      sqlite3_set_authorizer(p->db, 0, 0);
    }
  }else
#endif

#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
  if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
    open_db(p, 0);

    rc = arDotCommand(p, 0, azArg, nArg);
  }else
#endif

  if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
   || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
  ){
    const char *zDestFile = 0;
    const char *zDb = 0;
    sqlite3 *pDest;
    sqlite3_backup *pBackup;
    int j;
    int bAsync = 0;
    const char *zVfs = 0;

    for(j=1; j<nArg; j++){
      const char *z = azArg[j];
      if( z[0]=='-' ){
        if( z[1]=='-' ) z++;
        if( strcmp(z, "-append")==0 ){
          zVfs = "apndvfs";
        }else







>
>









>














>







7546
7547
7548
7549
7550
7551
7552
7553
7554
7555
7556
7557
7558
7559
7560
7561
7562
7563
7564
7565
7566
7567
7568
7569
7570
7571
7572
7573
7574
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7586
      raw_printf(stderr, "Usage: .auth ON|OFF\n");
      rc = 1;
      goto meta_command_exit;
    }
    open_db(p, 0);
    if( booleanValue(azArg[1]) ){
      sqlite3_set_authorizer(p->db, shellAuth, p);
    }else if( p->bSafeModePersist ){
      sqlite3_set_authorizer(p->db, safeModeAuth, p);
    }else{
      sqlite3_set_authorizer(p->db, 0, 0);
    }
  }else
#endif

#if !defined(SQLITE_OMIT_VIRTUALTABLE) && defined(SQLITE_HAVE_ZLIB)
  if( c=='a' && strncmp(azArg[0], "archive", n)==0 ){
    open_db(p, 0);
    failIfSafeMode(p, "cannot run .archive in safe mode");
    rc = arDotCommand(p, 0, azArg, nArg);
  }else
#endif

  if( (c=='b' && n>=3 && strncmp(azArg[0], "backup", n)==0)
   || (c=='s' && n>=3 && strncmp(azArg[0], "save", n)==0)
  ){
    const char *zDestFile = 0;
    const char *zDb = 0;
    sqlite3 *pDest;
    sqlite3_backup *pBackup;
    int j;
    int bAsync = 0;
    const char *zVfs = 0;
    failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
    for(j=1; j<nArg; j++){
      const char *z = azArg[j];
      if( z[0]=='-' ){
        if( z[1]=='-' ) z++;
        if( strcmp(z, "-append")==0 ){
          zVfs = "apndvfs";
        }else
7568
7569
7570
7571
7572
7573
7574

7575
7576
7577
7578
7579
7580
7581
  ** routine named test_breakpoint().
  */
  if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
    test_breakpoint();
  }else

  if( c=='c' && strcmp(azArg[0],"cd")==0 ){

    if( nArg==2 ){
#if defined(_WIN32) || defined(WIN32)
      wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
      rc = !SetCurrentDirectoryW(z);
      sqlite3_free(z);
#else
      rc = chdir(azArg[1]);







>







7661
7662
7663
7664
7665
7666
7667
7668
7669
7670
7671
7672
7673
7674
7675
  ** routine named test_breakpoint().
  */
  if( c=='b' && n>=3 && strncmp(azArg[0], "breakpoint", n)==0 ){
    test_breakpoint();
  }else

  if( c=='c' && strcmp(azArg[0],"cd")==0 ){
    failIfSafeMode(p, "cannot run .cd in safe mode");
    if( nArg==2 ){
#if defined(_WIN32) || defined(WIN32)
      wchar_t *z = sqlite3_win32_utf8_to_unicode(azArg[1]);
      rc = !SetCurrentDirectoryW(z);
      sqlite3_free(z);
#else
      rc = chdir(azArg[1]);
7621
7622
7623
7624
7625
7626
7627

7628
7629
7630
7631
7632
7633
7634
      utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
      p->nCheck++;
    }
    sqlite3_free(zRes);
  }else

  if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){

    if( nArg==2 ){
      tryToClone(p, azArg[1]);
    }else{
      raw_printf(stderr, "Usage: .clone FILENAME\n");
      rc = 1;
    }
  }else







>







7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
      utf8_printf(stdout, "testcase-%s ok\n", p->zTestcase);
      p->nCheck++;
    }
    sqlite3_free(zRes);
  }else

  if( c=='c' && strncmp(azArg[0], "clone", n)==0 ){
    failIfSafeMode(p, "cannot run .clone in safe mode");
    if( nArg==2 ){
      tryToClone(p, azArg[1]);
    }else{
      raw_printf(stderr, "Usage: .clone FILENAME\n");
      rc = 1;
    }
  }else
8182
8183
8184
8185
8186
8187
8188

8189
8190
8191
8192
8193
8194
8195
    char *zSql;                 /* An SQL statement */
    ImportCtx sCtx;             /* Reader context */
    char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
    int eVerbose = 0;           /* Larger for more console output */
    int nSkip = 0;              /* Initial lines to skip */
    int useOutputMode = 1;      /* Use output mode to determine separators */


    memset(&sCtx, 0, sizeof(sCtx));
    if( p->mode==MODE_Ascii ){
      xRead = ascii_read_one_field;
    }else{
      xRead = csv_read_one_field;
    }
    for(i=1; i<nArg; i++){







>







8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
    char *zSql;                 /* An SQL statement */
    ImportCtx sCtx;             /* Reader context */
    char *(SQLITE_CDECL *xRead)(ImportCtx*); /* Func to read one value */
    int eVerbose = 0;           /* Larger for more console output */
    int nSkip = 0;              /* Initial lines to skip */
    int useOutputMode = 1;      /* Use output mode to determine separators */

    failIfSafeMode(p, "cannot run .import in safe mode");
    memset(&sCtx, 0, sizeof(sCtx));
    if( p->mode==MODE_Ascii ){
      xRead = ascii_read_one_field;
    }else{
      xRead = csv_read_one_field;
    }
    for(i=1; i<nArg; i++){
8488
8489
8490
8491
8492
8493
8494
8495
8496
8497
8498
8499
8500
8501
8502
      isWO = sqlite3_column_int(pStmt, 1);
    }
    sqlite3_finalize(pStmt);
    zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
    i = 0;
    while( sqlite3_step(pStmt)==SQLITE_ROW ){
      char zLabel[20];
      const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
      i++;
      if( zCol==0 ){
        if( sqlite3_column_int(pStmt,1)==-1 ){
          zCol = "_ROWID_";
        }else{







|







8584
8585
8586
8587
8588
8589
8590
8591
8592
8593
8594
8595
8596
8597
8598
      isWO = sqlite3_column_int(pStmt, 1);
    }
    sqlite3_finalize(pStmt);
    zSql = sqlite3_mprintf("PRAGMA index_xinfo='%q'", azArg[1]);
    rc = sqlite3_prepare_v2(p->db, zSql, -1, &pStmt, 0);
    sqlite3_free(zSql);
    i = 0;
    while( rc==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
      char zLabel[20];
      const char *zCol = (const char*)sqlite3_column_text(pStmt,2);
      i++;
      if( zCol==0 ){
        if( sqlite3_column_int(pStmt,1)==-1 ){
          zCol = "_ROWID_";
        }else{
8633
8634
8635
8636
8637
8638
8639

8640
8641
8642
8643
8644
8645
8646
8647
8648
8649
8650
8651
8652
8653
8654
8655
8656
8657

8658
8659
8660
8661
8662
8663
8664
    lintDotCommand(p, azArg, nArg);
  }else

#ifndef SQLITE_OMIT_LOAD_EXTENSION
  if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
    const char *zFile, *zProc;
    char *zErrMsg = 0;

    if( nArg<2 ){
      raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
      rc = 1;
      goto meta_command_exit;
    }
    zFile = azArg[1];
    zProc = nArg>=3 ? azArg[2] : 0;
    open_db(p, 0);
    rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
    if( rc!=SQLITE_OK ){
      utf8_printf(stderr, "Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }
  }else
#endif

  if( c=='l' && strncmp(azArg[0], "log", n)==0 ){

    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .log FILENAME\n");
      rc = 1;
    }else{
      const char *zFile = azArg[1];
      output_file_close(p->pLog);
      p->pLog = output_file_open(zFile, 0);







>


















>







8729
8730
8731
8732
8733
8734
8735
8736
8737
8738
8739
8740
8741
8742
8743
8744
8745
8746
8747
8748
8749
8750
8751
8752
8753
8754
8755
8756
8757
8758
8759
8760
8761
8762
    lintDotCommand(p, azArg, nArg);
  }else

#ifndef SQLITE_OMIT_LOAD_EXTENSION
  if( c=='l' && strncmp(azArg[0], "load", n)==0 ){
    const char *zFile, *zProc;
    char *zErrMsg = 0;
    failIfSafeMode(p, "cannot run .load in safe mode");
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .load FILE ?ENTRYPOINT?\n");
      rc = 1;
      goto meta_command_exit;
    }
    zFile = azArg[1];
    zProc = nArg>=3 ? azArg[2] : 0;
    open_db(p, 0);
    rc = sqlite3_load_extension(p->db, zFile, zProc, &zErrMsg);
    if( rc!=SQLITE_OK ){
      utf8_printf(stderr, "Error: %s\n", zErrMsg);
      sqlite3_free(zErrMsg);
      rc = 1;
    }
  }else
#endif

  if( c=='l' && strncmp(azArg[0], "log", n)==0 ){
    failIfSafeMode(p, "cannot run .log in safe mode");
    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .log FILENAME\n");
      rc = 1;
    }else{
      const char *zFile = azArg[1];
      output_file_close(p->pLog);
      p->pLog = output_file_open(zFile, 0);
8720
8721
8722
8723
8724
8725
8726














8727
8728
8729
8730
8731
8732
8733
      raw_printf(stderr, "Error: mode should be one of: "
         "ascii box column csv html insert json line list markdown "
         "quote table tabs tcl\n");
      rc = 1;
    }
    p->cMode = p->mode;
  }else















  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
    if( nArg==2 ){
      sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
                       "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
    }else{
      raw_printf(stderr, "Usage: .nullvalue STRING\n");







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







8818
8819
8820
8821
8822
8823
8824
8825
8826
8827
8828
8829
8830
8831
8832
8833
8834
8835
8836
8837
8838
8839
8840
8841
8842
8843
8844
8845
      raw_printf(stderr, "Error: mode should be one of: "
         "ascii box column csv html insert json line list markdown "
         "quote table tabs tcl\n");
      rc = 1;
    }
    p->cMode = p->mode;
  }else

  if( c=='n' && strcmp(azArg[0], "nonce")==0 ){
    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .nonce NONCE\n");
      rc = 1;
    }else if( p->zNonce==0 || strcmp(azArg[1],p->zNonce)!=0 ){
      raw_printf(stderr, "line %d: incorrect nonce: \"%s\"\n", p->lineno, azArg[1]);
      exit(1);
    }else{
      p->bSafeMode = 0;
      return 0;  /* Return immediately to bypass the safe mode reset
                 ** at the end of this procedure */
    }
  }else

  if( c=='n' && strncmp(azArg[0], "nullvalue", n)==0 ){
    if( nArg==2 ){
      sqlite3_snprintf(sizeof(p->nullValue), p->nullValue,
                       "%.*s", (int)ArraySize(p->nullValue)-1, azArg[1]);
    }else{
      raw_printf(stderr, "Usage: .nullvalue STRING\n");
8812
8813
8814
8815
8816
8817
8818
8819







8820
8821
8822
8823
8824
8825
8826
        goto meta_command_exit;
      }else{
        zNewFilename = sqlite3_mprintf("%s", z);
      }
    }
    /* If a filename is specified, try to open it first */
    if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
      if( newFlag ) shellDeleteFile(zNewFilename);







      p->pAuxDb->zDbFilename = zNewFilename;
      open_db(p, OPEN_DB_KEEPALIVE);
      if( p->db==0 ){
        utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
        sqlite3_free(zNewFilename);
      }else{
        p->pAuxDb->zFreeOnClose = zNewFilename;







|
>
>
>
>
>
>
>







8924
8925
8926
8927
8928
8929
8930
8931
8932
8933
8934
8935
8936
8937
8938
8939
8940
8941
8942
8943
8944
8945
        goto meta_command_exit;
      }else{
        zNewFilename = sqlite3_mprintf("%s", z);
      }
    }
    /* If a filename is specified, try to open it first */
    if( zNewFilename || p->openMode==SHELL_OPEN_HEXDB ){
      if( newFlag && !p->bSafeMode ) shellDeleteFile(zNewFilename);
      if( p->bSafeMode
       && p->openMode!=SHELL_OPEN_HEXDB
       && zNewFilename
       && strcmp(zNewFilename,":memory:")!=0
      ){
        failIfSafeMode(p, "cannot open disk-based database files in safe mode");
      }
      p->pAuxDb->zDbFilename = zNewFilename;
      open_db(p, OPEN_DB_KEEPALIVE);
      if( p->db==0 ){
        utf8_printf(stderr, "Error: cannot open '%s'\n", zNewFilename);
        sqlite3_free(zNewFilename);
      }else{
        p->pAuxDb->zFreeOnClose = zNewFilename;
8840
8841
8842
8843
8844
8845
8846

8847
8848
8849
8850
8851
8852
8853
    char *zFile = 0;
    int bTxtMode = 0;
    int i;
    int eMode = 0;
    int bBOM = 0;
    int bOnce = 0;  /* 0: .output, 1: .once, 2: .excel */


    if( c=='e' ){
      eMode = 'x';
      bOnce = 2;
    }else if( strncmp(azArg[0],"once",n)==0 ){
      bOnce = 1;
    }
    for(i=1; i<nArg; i++){







>







8959
8960
8961
8962
8963
8964
8965
8966
8967
8968
8969
8970
8971
8972
8973
    char *zFile = 0;
    int bTxtMode = 0;
    int i;
    int eMode = 0;
    int bBOM = 0;
    int bOnce = 0;  /* 0: .output, 1: .once, 2: .excel */

    failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
    if( c=='e' ){
      eMode = 'x';
      bOnce = 2;
    }else if( strncmp(azArg[0],"once",n)==0 ){
      bOnce = 1;
    }
    for(i=1; i<nArg; i++){
8969
8970
8971
8972
8973
8974
8975
8976
8977
8978
8979
8980
8981
8982
8983
      }
      sqlite3_finalize(pStmt);
      pStmt = 0;
      if( len ){
        rx = sqlite3_prepare_v2(p->db,
             "SELECT key, quote(value) "
             "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
        while( sqlite3_step(pStmt)==SQLITE_ROW ){
          utf8_printf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
                      sqlite3_column_text(pStmt,1));
        }
        sqlite3_finalize(pStmt);
      }
    }else








|







9089
9090
9091
9092
9093
9094
9095
9096
9097
9098
9099
9100
9101
9102
9103
      }
      sqlite3_finalize(pStmt);
      pStmt = 0;
      if( len ){
        rx = sqlite3_prepare_v2(p->db,
             "SELECT key, quote(value) "
             "FROM temp.sqlite_parameters;", -1, &pStmt, 0);
        while( rx==SQLITE_OK && sqlite3_step(pStmt)==SQLITE_ROW ){
          utf8_printf(p->out, "%-*s %s\n", len, sqlite3_column_text(pStmt,0),
                      sqlite3_column_text(pStmt,1));
        }
        sqlite3_finalize(pStmt);
      }
    }else

9112
9113
9114
9115
9116
9117
9118

9119
9120
9121
9122
9123
9124
9125
9126
9127
9128
9129
9130
9131
9132
9133
9134
9135
9136
9137
9138
9139
9140
9141
9142
9143
9144
9145
9146
9147
9148
9149
9150
9151
9152
9153
9154
9155
9156

9157
9158
9159
9160
9161
9162
9163
  if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
    rc = 2;
  }else

  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
    FILE *inSaved = p->in;
    int savedLineno = p->lineno;

    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .read FILE\n");
      rc = 1;
      goto meta_command_exit;
    }
    if( azArg[1][0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
      rc = 1;
      p->out = stdout;
#else
      p->in = popen(azArg[1]+1, "r");
      if( p->in==0 ){
        utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
        rc = 1;
      }else{
        rc = process_input(p);
        pclose(p->in);
      }
#endif
    }else if( notNormalFile(azArg[1]) || (p->in = fopen(azArg[1], "rb"))==0 ){
      utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
      rc = 1;
    }else{
      rc = process_input(p);
      fclose(p->in);
    }
    p->in = inSaved;
    p->lineno = savedLineno;
  }else

  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
    const char *zSrcFile;
    const char *zDb;
    sqlite3 *pSrc;
    sqlite3_backup *pBackup;
    int nTimeout = 0;


    if( nArg==2 ){
      zSrcFile = azArg[1];
      zDb = "main";
    }else if( nArg==3 ){
      zSrcFile = azArg[2];
      zDb = azArg[1];
    }else{







>




















|

















>







9232
9233
9234
9235
9236
9237
9238
9239
9240
9241
9242
9243
9244
9245
9246
9247
9248
9249
9250
9251
9252
9253
9254
9255
9256
9257
9258
9259
9260
9261
9262
9263
9264
9265
9266
9267
9268
9269
9270
9271
9272
9273
9274
9275
9276
9277
9278
9279
9280
9281
9282
9283
9284
9285
  if( c=='q' && strncmp(azArg[0], "quit", n)==0 ){
    rc = 2;
  }else

  if( c=='r' && n>=3 && strncmp(azArg[0], "read", n)==0 ){
    FILE *inSaved = p->in;
    int savedLineno = p->lineno;
    failIfSafeMode(p, "cannot run .read in safe mode");
    if( nArg!=2 ){
      raw_printf(stderr, "Usage: .read FILE\n");
      rc = 1;
      goto meta_command_exit;
    }
    if( azArg[1][0]=='|' ){
#ifdef SQLITE_OMIT_POPEN
      raw_printf(stderr, "Error: pipes are not supported in this OS\n");
      rc = 1;
      p->out = stdout;
#else
      p->in = popen(azArg[1]+1, "r");
      if( p->in==0 ){
        utf8_printf(stderr, "Error: cannot open \"%s\"\n", azArg[1]);
        rc = 1;
      }else{
        rc = process_input(p);
        pclose(p->in);
      }
#endif
    }else if( (p->in = openChrSource(azArg[1]))==0 ){
      utf8_printf(stderr,"Error: cannot open \"%s\"\n", azArg[1]);
      rc = 1;
    }else{
      rc = process_input(p);
      fclose(p->in);
    }
    p->in = inSaved;
    p->lineno = savedLineno;
  }else

  if( c=='r' && n>=3 && strncmp(azArg[0], "restore", n)==0 ){
    const char *zSrcFile;
    const char *zDb;
    sqlite3 *pSrc;
    sqlite3_backup *pBackup;
    int nTimeout = 0;

    failIfSafeMode(p, "cannot run .restore in safe mode");
    if( nArg==2 ){
      zSrcFile = azArg[1];
      zDb = "main";
    }else if( nArg==3 ){
      zSrcFile = azArg[2];
      zDb = azArg[1];
    }else{
9399
9400
9401
9402
9403
9404
9405

9406
9407
9408
9409
9410
9411
9412

    /* .session changeset FILE
    ** .session patchset FILE
    ** Write a changeset or patchset into a file.  The file is overwritten.
    */
    if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
      FILE *out = 0;

      if( nCmd!=2 ) goto session_syntax_error;
      if( pSession->p==0 ) goto session_not_open;
      out = fopen(azCmd[1], "wb");
      if( out==0 ){
        utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
                    azCmd[1]);
      }else{







>







9521
9522
9523
9524
9525
9526
9527
9528
9529
9530
9531
9532
9533
9534
9535

    /* .session changeset FILE
    ** .session patchset FILE
    ** Write a changeset or patchset into a file.  The file is overwritten.
    */
    if( strcmp(azCmd[0],"changeset")==0 || strcmp(azCmd[0],"patchset")==0 ){
      FILE *out = 0;
      failIfSafeMode(p, "cannot run \".session %s\" in safe mode", azCmd[0]);
      if( nCmd!=2 ) goto session_syntax_error;
      if( pSession->p==0 ) goto session_not_open;
      out = fopen(azCmd[1], "wb");
      if( out==0 ){
        utf8_printf(stderr, "ERROR: cannot open \"%s\" for writing\n",
                    azCmd[1]);
      }else{
9813
9814
9815
9816
9817
9818
9819

9820
9821
9822
9823
9824
9825
9826

#ifndef SQLITE_NOHAVE_SYSTEM
  if( c=='s'
   && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
  ){
    char *zCmd;
    int i, x;

    if( nArg<2 ){
      raw_printf(stderr, "Usage: .system COMMAND\n");
      rc = 1;
      goto meta_command_exit;
    }
    zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
    for(i=2; i<nArg; i++){







>







9936
9937
9938
9939
9940
9941
9942
9943
9944
9945
9946
9947
9948
9949
9950

#ifndef SQLITE_NOHAVE_SYSTEM
  if( c=='s'
   && (strncmp(azArg[0], "shell", n)==0 || strncmp(azArg[0],"system",n)==0)
  ){
    char *zCmd;
    int i, x;
    failIfSafeMode(p, "cannot run .%s in safe mode", azArg[0]);
    if( nArg<2 ){
      raw_printf(stderr, "Usage: .system COMMAND\n");
      rc = 1;
      goto meta_command_exit;
    }
    zCmd = sqlite3_mprintf(strchr(azArg[1],' ')==0?"%s":"\"%s\"", azArg[1]);
    for(i=2; i<nArg; i++){
9938
9939
9940
9941
9942
9943
9944

9945
9946

9947
9948
9949
9950
9951
9952
9953
                      "   AND name LIKE ?1", 0);
      }else{
        appendText(&s," WHERE type='index'"
                      "   AND tbl_name LIKE ?1", 0);
      }
    }
    rc = sqlite3_finalize(pStmt);

    appendText(&s, " ORDER BY 1", 0);
    rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);

    freeText(&s);
    if( rc ) return shellDatabaseError(p->db);

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







>
|
|
>







10062
10063
10064
10065
10066
10067
10068
10069
10070
10071
10072
10073
10074
10075
10076
10077
10078
10079
                      "   AND name LIKE ?1", 0);
      }else{
        appendText(&s," WHERE type='index'"
                      "   AND tbl_name LIKE ?1", 0);
      }
    }
    rc = sqlite3_finalize(pStmt);
    if( rc==SQLITE_OK ){
      appendText(&s, " ORDER BY 1", 0);
      rc = sqlite3_prepare_v2(p->db, s.z, -1, &pStmt, 0);
    }
    freeText(&s);
    if( rc ) return shellDatabaseError(p->db);

    /* Run the SQL statement prepared by the above block. Store the results
    ** as an array of nul-terminated strings in azResult[].  */
    nRow = nAlloc = 0;
    azResult = 0;
10465
10466
10467
10468
10469
10470
10471
10472
10473
10474
10475
10476
10477
10478
10479
10480
10481
10482
10483
10484
10485
10486
10487
10488
10489
10490

10491
10492
10493
10494
10495
10496
10497
10498

10499
10500
10501




10502





10503
10504
10505



10506

10507




10508
10509













10510

10511
10512


10513
10514

10515







10516








10517


10518
10519



10520

10521
10522


10523



10524



10525
10526
10527
10528
10529
10530
10531
10532
10533
10534
10535
10536
10537
10538
10539
10540
10541

10542

10543
10544
10545
10546
10547
10548
10549
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
  }else

  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
    int j;
    assert( nArg<=ArraySize(azArg) );
    p->nWidth = nArg-1;
    p->colWidth = realloc(p->colWidth, p->nWidth*sizeof(int)*2);
    if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
    if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
    for(j=1; j<nArg; j++){
      p->colWidth[j-1] = (int)integerValue(azArg[j]);
    }
  }else

  {
    utf8_printf(stderr, "Error: unknown command or invalid arguments: "
      " \"%s\". Enter \".help\" for help\n", azArg[0]);
    rc = 1;
  }

meta_command_exit:
  if( p->outCount ){
    p->outCount--;
    if( p->outCount==0 ) output_reset(p);
  }

  return rc;
}

/*
** Return TRUE if a semicolon occurs anywhere in the first N characters
** of string z[].
*/
static int line_contains_semicolon(const char *z, int N){

  int i;
  for(i=0; i<N; i++){  if( z[i]==';' ) return 1; }
  return 0;




}






/*
** Test to see if a line consists entirely of whitespace.



*/

static int _all_whitespace(const char *z){




  for(; *z; z++){
    if( IsSpace(z[0]) ) continue;













    if( *z=='/' && z[1]=='*' ){

      z += 2;
      while( *z && (*z!='*' || z[1]!='/') ){ z++; }


      if( *z==0 ) return 0;
      z++;

      continue;







    }








    if( *z=='-' && z[1]=='-' ){


      z += 2;
      while( *z && *z!='\n' ){ z++; }



      if( *z==0 ) return 1;

      continue;
    }


    return 0;



  }



  return 1;
}

/*
** Return TRUE if the line typed in is an SQL command terminator other
** than a semi-colon.  The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
static int line_is_command_terminator(const char *zLine){
  while( IsSpace(zLine[0]) ){ zLine++; };
  if( zLine[0]=='/' && _all_whitespace(&zLine[1]) ){
    return 1;  /* Oracle */
  }
  if( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o'
         && _all_whitespace(&zLine[2]) ){
    return 1;  /* SQL Server */
  }

  return 0;

}

/*
** We need a default sqlite3_complete() implementation to use in case
** the shell is compiled with SQLITE_OMIT_COMPLETE.  The default assumes
** any arbitrary text is a complete SQL statement.  This is not very
** user-friendly, but it does seem to work.







|


















>



|
<
<

<
>
|
<
|
>
>
>
>
|
>
>
>
>
>


<
>
>
>

>
|
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
|
>
>
|
<
>
|
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
|
>
>
|
<
>
>
>
|
>
|
|
>
>
|
>
>
>
|
>
>
>
|







|

|
|
<
|
<
|
<
>
|
>







10591
10592
10593
10594
10595
10596
10597
10598
10599
10600
10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621


10622

10623
10624

10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637

10638
10639
10640
10641
10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653
10654
10655
10656
10657
10658
10659
10660
10661
10662
10663
10664
10665
10666
10667
10668
10669

10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687
10688
10689
10690
10691

10692
10693
10694
10695
10696
10697
10698
10699
10700
10701
10702
10703
10704
10705
10706
10707
10708
10709
10710
10711
10712
10713
10714
10715
10716
10717
10718
10719
10720

10721

10722

10723
10724
10725
10726
10727
10728
10729
10730
10731
10732
    sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 3, &x);
  }else

  if( c=='w' && strncmp(azArg[0], "width", n)==0 ){
    int j;
    assert( nArg<=ArraySize(azArg) );
    p->nWidth = nArg-1;
    p->colWidth = realloc(p->colWidth, (p->nWidth+1)*sizeof(int)*2);
    if( p->colWidth==0 && p->nWidth>0 ) shell_out_of_memory();
    if( p->nWidth ) p->actualWidth = &p->colWidth[p->nWidth];
    for(j=1; j<nArg; j++){
      p->colWidth[j-1] = (int)integerValue(azArg[j]);
    }
  }else

  {
    utf8_printf(stderr, "Error: unknown command or invalid arguments: "
      " \"%s\". Enter \".help\" for help\n", azArg[0]);
    rc = 1;
  }

meta_command_exit:
  if( p->outCount ){
    p->outCount--;
    if( p->outCount==0 ) output_reset(p);
  }
  p->bSafeMode = p->bSafeModePersist;
  return rc;
}

/* Line scan result and intermediate states (supporting scan resumption)


*/

#ifndef CHAR_BIT
# define CHAR_BIT 8

#endif
typedef enum {
  QSS_HasDark = 1<<CHAR_BIT, QSS_EndingSemi = 2<<CHAR_BIT,
  QSS_CharMask = (1<<CHAR_BIT)-1, QSS_ScanMask = 3<<CHAR_BIT,
  QSS_Start = 0
} QuickScanState;
#define QSS_SETV(qss, newst) ((newst) | ((qss) & QSS_ScanMask))
#define QSS_INPLAIN(qss) (((qss)&QSS_CharMask)==QSS_Start)
#define QSS_PLAINWHITE(qss) (((qss)&~QSS_EndingSemi)==QSS_Start)
#define QSS_PLAINDARK(qss) (((qss)&~QSS_EndingSemi)==QSS_HasDark)
#define QSS_SEMITERM(qss) (((qss)&~QSS_HasDark)==QSS_EndingSemi)

/*

** Scan line for classification to guide shell's handling.
** The scan is resumable for subsequent lines when prior
** return values are passed as the 2nd argument.
*/
static QuickScanState quickscan(char *zLine, QuickScanState qss){
  char cin;
  char cWait = (char)qss; /* intentional narrowing loss */
  if( cWait==0 ){
  PlainScan:
    assert( cWait==0 );
    while( (cin = *zLine++)!=0 ){
      if( IsSpace(cin) )
        continue;
      switch (cin){
      case '-':
        if( *zLine!='-' )
          break;
        while((cin = *++zLine)!=0 )
          if( cin=='\n')
            goto PlainScan;
        return qss;
      case ';':
        qss |= QSS_EndingSemi;
        continue;
      case '/':
        if( *zLine=='*' ){
          ++zLine;
          cWait = '*';
          qss = QSS_SETV(qss, cWait);
          goto TermScan;
        }
        break;

      case '[':
        cin = ']';
        /* fall thru */
      case '`': case '\'': case '"':
        cWait = cin;
        qss = QSS_HasDark | cWait;
        goto TermScan;
      default:
        break;
      }
      qss = (qss & ~QSS_EndingSemi) | QSS_HasDark;
    }
  }else{
  TermScan:
    while( (cin = *zLine++)!=0 ){
      if( cin==cWait ){
        switch( cWait ){
        case '*':
          if( *zLine != '/' )
            continue;
          ++zLine;
          cWait = 0;

          qss = QSS_SETV(qss, 0);
          goto PlainScan;
        case '`': case '\'': case '"':
          if(*zLine==cWait){
            ++zLine;
            continue;
          }
          /* fall thru */
        case ']':
          cWait = 0;
          qss = QSS_SETV(qss, 0);
          goto PlainScan;
        default: assert(0); 
        }
      }
    }
  }
  return qss;
}

/*
** Return TRUE if the line typed in is an SQL command terminator other
** than a semi-colon.  The SQL Server style "go" command is understood
** as is the Oracle "/".
*/
static int line_is_command_terminator(char *zLine){
  while( IsSpace(zLine[0]) ){ zLine++; };
  if( zLine[0]=='/' )
    zLine += 1; /* Oracle */

  else if ( ToLower(zLine[0])=='g' && ToLower(zLine[1])=='o' )

    zLine += 2; /* SQL Server */

  else
    return 0;
  return quickscan(zLine,QSS_Start)==QSS_Start;
}

/*
** We need a default sqlite3_complete() implementation to use in case
** the shell is compiled with SQLITE_OMIT_COMPLETE.  The default assumes
** any arbitrary text is a complete SQL statement.  This is not very
** user-friendly, but it does seem to work.
10592
10593
10594
10595
10596
10597
10598


10599
10600

10601
10602
10603
10604
10605
10606
10607
10608
10609
10610
10611
10612
10613
10614
10615
10616
10617
10618
10619
10620
10621
10622
10623
10624

10625
10626
10627
10628
10629
10630
10631
10632
10633
10634
10635
10636
10637
10638
10639






10640
10641



10642
10643
10644
10645
10646
10647
10648
10649
10650
10651
10652
10653

10654
10655
10656
10657
10658
10659
10660

10661
10662
10663
10664
10665
10666
10667
10668
10669
10670
10671
10672
10673
10674
10675
10676
10677
10678
10679
10680
10681
10682
10683
10684
10685
10686
10687


10688
10689
10690

10691
10692
10693
10694
10695
10696
10697
10698
10699
10700
      sqlite3_free(zErrMsg);
      zErrMsg = 0;
    }else{
      utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
    }
    return 1;
  }else if( ShellHasFlag(p, SHFLG_CountChanges) ){


    raw_printf(p->out, "changes: %3lld   total_changes: %lld\n",
            sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));

  }
  return 0;
}


/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**
** Return the number of errors.
*/
static int process_input(ShellState *p){
  char *zLine = 0;          /* A single input line */
  char *zSql = 0;           /* Accumulated SQL text */
  int nLine;                /* Length of current line */
  int nSql = 0;             /* Bytes of zSql[] used */
  int nAlloc = 0;           /* Allocated zSql[] space */
  int nSqlPrior = 0;        /* Bytes of zSql[] used by prior line */
  int rc;                   /* Error code */
  int errCnt = 0;           /* Number of errors seen */
  int startline = 0;        /* Line number for start of current input */


  p->lineno = 0;
  while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
    fflush(p->out);
    zLine = one_input_line(p->in, zLine, nSql>0);
    if( zLine==0 ){
      /* End of input */
      if( p->in==0 && stdin_is_interactive ) printf("\n");
      break;
    }
    if( seenInterrupt ){
      if( p->in!=0 ) break;
      seenInterrupt = 0;
    }
    p->lineno++;






    if( nSql==0 && _all_whitespace(zLine) ){
      if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);



      continue;
    }
    if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
      if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
      if( zLine[0]=='.' ){
        rc = do_meta_command(zLine, p);
        if( rc==2 ){ /* exit requested */
          break;
        }else if( rc ){
          errCnt++;
        }
      }

      continue;
    }
    if( line_is_command_terminator(zLine) && line_is_complete(zSql, nSql) ){
      memcpy(zLine,";",2);
    }
    nLine = strlen30(zLine);
    if( nSql+nLine+2>=nAlloc ){

      nAlloc = nSql+nLine+100;
      zSql = realloc(zSql, nAlloc);
      if( zSql==0 ) shell_out_of_memory();
    }
    nSqlPrior = nSql;
    if( nSql==0 ){
      int i;
      for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
      assert( nAlloc>0 && zSql!=0 );
      memcpy(zSql, zLine+i, nLine+1-i);
      startline = p->lineno;
      nSql = nLine-i;
    }else{
      zSql[nSql++] = '\n';
      memcpy(zSql+nSql, zLine, nLine+1);
      nSql += nLine;
    }
    if( nSql && line_contains_semicolon(&zSql[nSqlPrior], nSql-nSqlPrior)
                && sqlite3_complete(zSql) ){
      errCnt += runOneSqlLine(p, zSql, p->in, startline);
      nSql = 0;
      if( p->outCount ){
        output_reset(p);
        p->outCount = 0;
      }else{
        clearTempFile(p);
      }


    }else if( nSql && _all_whitespace(zSql) ){
      if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
      nSql = 0;

    }
  }
  if( nSql && !_all_whitespace(zSql) ){
    errCnt += runOneSqlLine(p, zSql, p->in, startline);
  }
  free(zSql);
  free(zLine);
  return errCnt>0;
}








>
>
|

>




















<



>















>
>
>
>
>
>
|
|
>
>
>












>


<
|
<


>
|



<












<
|








>
>
|


>


|







10775
10776
10777
10778
10779
10780
10781
10782
10783
10784
10785
10786
10787
10788
10789
10790
10791
10792
10793
10794
10795
10796
10797
10798
10799
10800
10801
10802
10803
10804
10805
10806

10807
10808
10809
10810
10811
10812
10813
10814
10815
10816
10817
10818
10819
10820
10821
10822
10823
10824
10825
10826
10827
10828
10829
10830
10831
10832
10833
10834
10835
10836
10837
10838
10839
10840
10841
10842
10843
10844
10845
10846
10847
10848
10849
10850
10851

10852

10853
10854
10855
10856
10857
10858
10859

10860
10861
10862
10863
10864
10865
10866
10867
10868
10869
10870
10871

10872
10873
10874
10875
10876
10877
10878
10879
10880
10881
10882
10883
10884
10885
10886
10887
10888
10889
10890
10891
10892
10893
10894
10895
10896
      sqlite3_free(zErrMsg);
      zErrMsg = 0;
    }else{
      utf8_printf(stderr, "%s %s\n", zPrefix, sqlite3_errmsg(p->db));
    }
    return 1;
  }else if( ShellHasFlag(p, SHFLG_CountChanges) ){
    char zLineBuf[2000];
    sqlite3_snprintf(sizeof(zLineBuf), zLineBuf,
            "changes: %lld   total_changes: %lld",
            sqlite3_changes64(p->db), sqlite3_total_changes64(p->db));
    raw_printf(p->out, "%s\n", zLineBuf);
  }
  return 0;
}


/*
** Read input from *in and process it.  If *in==0 then input
** is interactive - the user is typing it it.  Otherwise, input
** is coming from a file or device.  A prompt is issued and history
** is saved only if input is interactive.  An interrupt signal will
** cause this routine to exit immediately, unless input is interactive.
**
** Return the number of errors.
*/
static int process_input(ShellState *p){
  char *zLine = 0;          /* A single input line */
  char *zSql = 0;           /* Accumulated SQL text */
  int nLine;                /* Length of current line */
  int nSql = 0;             /* Bytes of zSql[] used */
  int nAlloc = 0;           /* Allocated zSql[] space */

  int rc;                   /* Error code */
  int errCnt = 0;           /* Number of errors seen */
  int startline = 0;        /* Line number for start of current input */
  QuickScanState qss = QSS_Start; /* Accumulated line status (so far) */

  p->lineno = 0;
  while( errCnt==0 || !bail_on_error || (p->in==0 && stdin_is_interactive) ){
    fflush(p->out);
    zLine = one_input_line(p->in, zLine, nSql>0);
    if( zLine==0 ){
      /* End of input */
      if( p->in==0 && stdin_is_interactive ) printf("\n");
      break;
    }
    if( seenInterrupt ){
      if( p->in!=0 ) break;
      seenInterrupt = 0;
    }
    p->lineno++;
    if( QSS_INPLAIN(qss)
        && line_is_command_terminator(zLine)
        && line_is_complete(zSql, nSql) ){
      memcpy(zLine,";",2);
    }
    qss = quickscan(zLine, qss);
    if( QSS_PLAINWHITE(qss) && nSql==0 ){
      if( ShellHasFlag(p, SHFLG_Echo) )
        printf("%s\n", zLine);
      /* Just swallow single-line whitespace */
      qss = QSS_Start;
      continue;
    }
    if( zLine && (zLine[0]=='.' || zLine[0]=='#') && nSql==0 ){
      if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zLine);
      if( zLine[0]=='.' ){
        rc = do_meta_command(zLine, p);
        if( rc==2 ){ /* exit requested */
          break;
        }else if( rc ){
          errCnt++;
        }
      }
      qss = QSS_Start;
      continue;
    }

    /* No single-line dispositions remain; accumulate line(s). */

    nLine = strlen30(zLine);
    if( nSql+nLine+2>=nAlloc ){
      /* Grow buffer by half-again increments when big. */
      nAlloc = nSql+(nSql>>1)+nLine+100;
      zSql = realloc(zSql, nAlloc);
      if( zSql==0 ) shell_out_of_memory();
    }

    if( nSql==0 ){
      int i;
      for(i=0; zLine[i] && IsSpace(zLine[i]); i++){}
      assert( nAlloc>0 && zSql!=0 );
      memcpy(zSql, zLine+i, nLine+1-i);
      startline = p->lineno;
      nSql = nLine-i;
    }else{
      zSql[nSql++] = '\n';
      memcpy(zSql+nSql, zLine, nLine+1);
      nSql += nLine;
    }

    if( nSql && QSS_SEMITERM(qss) && sqlite3_complete(zSql) ){
      errCnt += runOneSqlLine(p, zSql, p->in, startline);
      nSql = 0;
      if( p->outCount ){
        output_reset(p);
        p->outCount = 0;
      }else{
        clearTempFile(p);
      }
      p->bSafeMode = p->bSafeModePersist;
      qss = QSS_Start;
    }else if( nSql && QSS_PLAINWHITE(qss) ){
      if( ShellHasFlag(p, SHFLG_Echo) ) printf("%s\n", zSql);
      nSql = 0;
      qss = QSS_Start;
    }
  }
  if( nSql && QSS_PLAINDARK(qss) ){
    errCnt += runOneSqlLine(p, zSql, p->in, startline);
  }
  free(zSql);
  free(zLine);
  return errCnt>0;
}

10847
10848
10849
10850
10851
10852
10853

10854
10855
10856
10857

10858
10859
10860
10861
10862
10863
10864
  "   -memtrace            trace all memory allocations and deallocations\n"
  "   -mmap N              default mmap size set to N\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
  "   -newline SEP         set output row separator. Default: '\\n'\n"
  "   -nofollow            refuse to open symbolic links to database files\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"
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
  "   -sorterref SIZE      sorter references threshold size\n"
#endif
  "   -stats               print memory stats before each finalize\n"
  "   -table               set output mode to 'table'\n"
  "   -tabs                set output mode to 'tabs'\n"







>




>







11043
11044
11045
11046
11047
11048
11049
11050
11051
11052
11053
11054
11055
11056
11057
11058
11059
11060
11061
11062
  "   -memtrace            trace all memory allocations and deallocations\n"
  "   -mmap N              default mmap size set to N\n"
#ifdef SQLITE_ENABLE_MULTIPLEX
  "   -multiplex           enable the multiplexor VFS\n"
#endif
  "   -newline SEP         set output row separator. Default: '\\n'\n"
  "   -nofollow            refuse to open symbolic links to database files\n"
  "   -nonce STRING        set the safe-mode escape nonce\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"
  "   -safe                enable safe-mode\n"
  "   -separator SEP       set output column separator. Default: '|'\n"
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
  "   -sorterref SIZE      sorter references threshold size\n"
#endif
  "   -stats               print memory stats before each finalize\n"
  "   -table               set output mode to 'table'\n"
  "   -tabs                set output mode to 'tabs'\n"
11196
11197
11198
11199
11200
11201
11202





11203
11204
11205
11206
11207
11208
11209
      ** command, so ignore them */
      break;
#endif
    }else if( strcmp(z, "-memtrace")==0 ){
      sqlite3MemTraceActivate(stderr);
    }else if( strcmp(z,"-bail")==0 ){
      bail_on_error = 1;





    }
  }
  verify_uninitialized();


#ifdef SQLITE_SHELL_INIT_PROC
  {







>
>
>
>
>







11394
11395
11396
11397
11398
11399
11400
11401
11402
11403
11404
11405
11406
11407
11408
11409
11410
11411
11412
      ** command, so ignore them */
      break;
#endif
    }else if( strcmp(z, "-memtrace")==0 ){
      sqlite3MemTraceActivate(stderr);
    }else if( strcmp(z,"-bail")==0 ){
      bail_on_error = 1;
    }else if( strcmp(z,"-nonce")==0 ){
      free(data.zNonce);
      data.zNonce = strdup(argv[++i]);
    }else if( strcmp(z,"-safe")==0 ){
      /* no-op - catch this on the second pass */
    }
  }
  verify_uninitialized();


#ifdef SQLITE_SHELL_INIT_PROC
  {
11322
11323
11324
11325
11326
11327
11328

11329
11330

11331
11332
11333
11334
11335
11336
11337
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-nullvalue")==0 ){
      sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-header")==0 ){
      data.showHeader = 1;

    }else if( strcmp(z,"-noheader")==0 ){
      data.showHeader = 0;

    }else if( strcmp(z,"-echo")==0 ){
      ShellSetFlag(&data, SHFLG_Echo);
    }else if( strcmp(z,"-eqp")==0 ){
      data.autoEQP = AUTOEQP_on;
    }else if( strcmp(z,"-eqpfull")==0 ){
      data.autoEQP = AUTOEQP_full;
    }else if( strcmp(z,"-stats")==0 ){







>
|

>







11525
11526
11527
11528
11529
11530
11531
11532
11533
11534
11535
11536
11537
11538
11539
11540
11541
11542
      sqlite3_snprintf(sizeof(data.rowSeparator), data.rowSeparator,
                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-nullvalue")==0 ){
      sqlite3_snprintf(sizeof(data.nullValue), data.nullValue,
                       "%s",cmdline_option_value(argc,argv,++i));
    }else if( strcmp(z,"-header")==0 ){
      data.showHeader = 1;
      ShellSetFlag(&data, SHFLG_HeaderSet);
     }else if( strcmp(z,"-noheader")==0 ){
      data.showHeader = 0;
      ShellSetFlag(&data, SHFLG_HeaderSet);
    }else if( strcmp(z,"-echo")==0 ){
      ShellSetFlag(&data, SHFLG_Echo);
    }else if( strcmp(z,"-eqp")==0 ){
      data.autoEQP = AUTOEQP_on;
    }else if( strcmp(z,"-eqpfull")==0 ){
      data.autoEQP = AUTOEQP_full;
    }else if( strcmp(z,"-stats")==0 ){
11358
11359
11360
11361
11362
11363
11364


11365
11366
11367
11368
11369
11370
11371
      i++;
    }else if( strcmp(z,"-pagecache")==0 ){
      i+=2;
    }else if( strcmp(z,"-lookaside")==0 ){
      i+=2;
    }else if( strcmp(z,"-threadsafe")==0 ){
      i+=2;


    }else if( strcmp(z,"-mmap")==0 ){
      i++;
    }else if( strcmp(z,"-memtrace")==0 ){
      i++;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
    }else if( strcmp(z,"-sorterref")==0 ){
      i++;







>
>







11563
11564
11565
11566
11567
11568
11569
11570
11571
11572
11573
11574
11575
11576
11577
11578
      i++;
    }else if( strcmp(z,"-pagecache")==0 ){
      i+=2;
    }else if( strcmp(z,"-lookaside")==0 ){
      i+=2;
    }else if( strcmp(z,"-threadsafe")==0 ){
      i+=2;
    }else if( strcmp(z,"-nonce")==0 ){
      i += 2;
    }else if( strcmp(z,"-mmap")==0 ){
      i++;
    }else if( strcmp(z,"-memtrace")==0 ){
      i++;
#ifdef SQLITE_ENABLE_SORTER_REFERENCES
    }else if( strcmp(z,"-sorterref")==0 ){
      i++;
11416
11417
11418
11419
11420
11421
11422


11423
11424
11425
11426
11427
11428
11429
        arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
      }else{
        arDotCommand(&data, 1, argv+i, argc-i);
      }
      readStdin = 0;
      break;
#endif


    }else{
      utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
      raw_printf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
    data.cMode = data.mode;
  }







>
>







11623
11624
11625
11626
11627
11628
11629
11630
11631
11632
11633
11634
11635
11636
11637
11638
        arDotCommand(&data, 1, argv+(i-1), argc-(i-1));
      }else{
        arDotCommand(&data, 1, argv+i, argc-i);
      }
      readStdin = 0;
      break;
#endif
    }else if( strcmp(z,"-safe")==0 ){
      data.bSafeMode = data.bSafeModePersist = 1;
    }else{
      utf8_printf(stderr,"%s: Error: unknown option: %s\n", Argv0, z);
      raw_printf(stderr,"Use -help for a list of options.\n");
      return 1;
    }
    data.cMode = data.mode;
  }
11518
11519
11520
11521
11522
11523
11524

11525
11526
11527
11528
11529
  data.doXdgOpen = 0;
  clearTempFile(&data);
#if !SQLITE_SHELL_IS_UTF8
  for(i=0; i<argcToFree; i++) free(argvToFree[i]);
  free(argvToFree);
#endif
  free(data.colWidth);

  /* Clear the global data structure so that valgrind will detect memory
  ** leaks */
  memset(&data, 0, sizeof(data));
  return rc;
}







>





11727
11728
11729
11730
11731
11732
11733
11734
11735
11736
11737
11738
11739
  data.doXdgOpen = 0;
  clearTempFile(&data);
#if !SQLITE_SHELL_IS_UTF8
  for(i=0; i<argcToFree; i++) free(argvToFree[i]);
  free(argvToFree);
#endif
  free(data.colWidth);
  free(data.zNonce);
  /* Clear the global data structure so that valgrind will detect memory
  ** leaks */
  memset(&data, 0, sizeof(data));
  return rc;
}
Changes to src/sqlite.h.in.
557
558
559
560
561
562
563

564
565
566
567
568
569
570
#define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (5<<8))
#define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (6<<8))
#define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
#define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))

#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8))








>







557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
#define SQLITE_CONSTRAINT_NOTNULL      (SQLITE_CONSTRAINT | (5<<8))
#define SQLITE_CONSTRAINT_PRIMARYKEY   (SQLITE_CONSTRAINT | (6<<8))
#define SQLITE_CONSTRAINT_TRIGGER      (SQLITE_CONSTRAINT | (7<<8))
#define SQLITE_CONSTRAINT_UNIQUE       (SQLITE_CONSTRAINT | (8<<8))
#define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
#define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
#define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))
#define SQLITE_CONSTRAINT_DATATYPE     (SQLITE_CONSTRAINT |(12<<8))
#define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
#define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
#define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
#define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8))

Changes to src/sqliteInt.h.
574
575
576
577
578
579
580







581
582
583
584
585
586
587
/*
** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN
*/
#ifdef SQLITE_OMIT_EXPLAIN
# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
#endif








/*
** Return true (non-zero) if the input is an integer that is too large
** to fit in 32-bits.  This macro is used inside of various testcase()
** macros to verify that we have tested SQLite for large-file support.
*/
#define IS_BIG_INT(X)  (((X)&~(i64)0xffffffff)!=0)








>
>
>
>
>
>
>







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
/*
** SQLITE_ENABLE_EXPLAIN_COMMENTS is incompatible with SQLITE_OMIT_EXPLAIN
*/
#ifdef SQLITE_OMIT_EXPLAIN
# undef SQLITE_ENABLE_EXPLAIN_COMMENTS
#endif

/*
** SQLITE_OMIT_VIRTUALTABLE implies SQLITE_OMIT_ALTERTABLE
*/
#if defined(SQLITE_OMIT_VIRTUALTABLE) && !defined(SQLITE_OMIT_ALTERTABLE)
# define SQLITE_OMIT_ALTERTABLE
#endif

/*
** Return true (non-zero) if the input is an integer that is too large
** to fit in 32-bits.  This macro is used inside of various testcase()
** macros to verify that we have tested SQLite for large-file support.
*/
#define IS_BIG_INT(X)  (((X)&~(i64)0xffffffff)!=0)

1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
  struct sqlite3InitInfo {      /* Information used during initialization */
    Pgno newTnum;               /* Rootpage of table being initialized */
    u8 iDb;                     /* Which db file is being initialized */
    u8 busy;                    /* TRUE if currently initializing */
    unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
    unsigned imposterTable : 1; /* Building an imposter table */
    unsigned reopenMemdb : 1;   /* ATTACH is really a reopen using MemDB */
    char **azInit;              /* "type", "name", and "tbl_name" columns */
  } init;
  int nVdbeActive;              /* Number of VDBEs currently running */
  int nVdbeRead;                /* Number of active VDBEs that read or write */
  int nVdbeWrite;               /* Number of active VDBEs that read and write */
  int nVdbeExec;                /* Number of nested calls to VdbeExec() */
  int nVDestroy;                /* Number of active OP_VDestroy operations */
  int nExtension;               /* Number of loaded extensions */







|







1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
  struct sqlite3InitInfo {      /* Information used during initialization */
    Pgno newTnum;               /* Rootpage of table being initialized */
    u8 iDb;                     /* Which db file is being initialized */
    u8 busy;                    /* TRUE if currently initializing */
    unsigned orphanTrigger : 1; /* Last statement is orphaned TEMP trigger */
    unsigned imposterTable : 1; /* Building an imposter table */
    unsigned reopenMemdb : 1;   /* ATTACH is really a reopen using MemDB */
    const char **azInit;        /* "type", "name", and "tbl_name" columns */
  } init;
  int nVdbeActive;              /* Number of VDBEs currently running */
  int nVdbeRead;                /* Number of active VDBEs that read or write */
  int nVdbeWrite;               /* Number of active VDBEs that read and write */
  int nVdbeExec;                /* Number of nested calls to VdbeExec() */
  int nVDestroy;                /* Number of active OP_VDestroy operations */
  int nExtension;               /* Number of loaded extensions */
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057

2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
** is only included if the COLFLAG_HASTYPE bit of colFlags is set and the
** collating sequence name is only included if the COLFLAG_HASCOLL bit is
** set.
*/
struct Column {
  char *zCnName;        /* Name of this column */
  unsigned notNull :4;  /* An OE_ code for handling a NOT NULL constraint */
  unsigned eType :4;    /* One of the standard types */
  char affinity;        /* One of the SQLITE_AFF_... values */
  u8 szEst;             /* Est size of value in this column. sizeof(INT)==1 */
  u8 hName;             /* Column name hash for faster lookup */
  u16 iDflt;            /* 1-based index of DEFAULT.  0 means "none" */
  u16 colFlags;         /* Boolean properties.  See COLFLAG_ defines below */
};

/* Allowed values for Column.eType.
**
** Values must match entries in the global constant arrays
** sqlite3StdTypeLen[] and sqlite3StdType[].  Each value is one more
** than the offset into these arrays for the corresponding name.
** Adjust the SQLITE_N_STDTYPE value if adding or removing entries.
*/
#define COLTYPE_CUSTOM      0   /* Type appended to zName */

#define COLTYPE_BLOB        1
#define COLTYPE_INT         2
#define COLTYPE_INTEGER     3
#define COLTYPE_REAL        4
#define COLTYPE_TEXT        5
#define SQLITE_N_STDTYPE    5  /* Number of standard types */

/* Allowed values for Column.colFlags.
**
** Constraints:
**         TF_HasVirtual == COLFLAG_VIRTUAL
**         TF_HasStored  == COLFLAG_STORED
**         TF_HasHidden  == COLFLAG_HIDDEN







|







|







>
|
|
|
|
|
|







2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
** is only included if the COLFLAG_HASTYPE bit of colFlags is set and the
** collating sequence name is only included if the COLFLAG_HASCOLL bit is
** set.
*/
struct Column {
  char *zCnName;        /* Name of this column */
  unsigned notNull :4;  /* An OE_ code for handling a NOT NULL constraint */
  unsigned eCType :4;   /* One of the standard types */
  char affinity;        /* One of the SQLITE_AFF_... values */
  u8 szEst;             /* Est size of value in this column. sizeof(INT)==1 */
  u8 hName;             /* Column name hash for faster lookup */
  u16 iDflt;            /* 1-based index of DEFAULT.  0 means "none" */
  u16 colFlags;         /* Boolean properties.  See COLFLAG_ defines below */
};

/* Allowed values for Column.eCType.
**
** Values must match entries in the global constant arrays
** sqlite3StdTypeLen[] and sqlite3StdType[].  Each value is one more
** than the offset into these arrays for the corresponding name.
** Adjust the SQLITE_N_STDTYPE value if adding or removing entries.
*/
#define COLTYPE_CUSTOM      0   /* Type appended to zName */
#define COLTYPE_ANY         1
#define COLTYPE_BLOB        2
#define COLTYPE_INT         3
#define COLTYPE_INTEGER     4
#define COLTYPE_REAL        5
#define COLTYPE_TEXT        6
#define SQLITE_N_STDTYPE    6  /* Number of standard types */

/* Allowed values for Column.colFlags.
**
** Constraints:
**         TF_HasVirtual == COLFLAG_VIRTUAL
**         TF_HasStored  == COLFLAG_STORED
**         TF_HasHidden  == COLFLAG_HIDDEN
2280
2281
2282
2283
2284
2285
2286

2287
2288
2289
2290
2291
2292
2293
#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */
#define TF_OOOHidden      0x00000400 /* Out-of-Order hidden columns */
#define TF_HasNotNull     0x00000800 /* Contains NOT NULL constraints */
#define TF_Shadow         0x00001000 /* True for a shadow table */
#define TF_HasStat4       0x00002000 /* STAT4 info available for this table */
#define TF_Ephemeral      0x00004000 /* An ephemeral table */
#define TF_Eponymous      0x00008000 /* An eponymous virtual table */


/*
** Allowed values for Table.eTabType
*/
#define TABTYP_NORM      0     /* Ordinary table */
#define TABTYP_VTAB      1     /* Virtual table */
#define TABTYP_VIEW      2     /* A view */







>







2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
#define TF_NoVisibleRowid 0x00000200 /* No user-visible "rowid" column */
#define TF_OOOHidden      0x00000400 /* Out-of-Order hidden columns */
#define TF_HasNotNull     0x00000800 /* Contains NOT NULL constraints */
#define TF_Shadow         0x00001000 /* True for a shadow table */
#define TF_HasStat4       0x00002000 /* STAT4 info available for this table */
#define TF_Ephemeral      0x00004000 /* An ephemeral table */
#define TF_Eponymous      0x00008000 /* An eponymous virtual table */
#define TF_Strict         0x00010000 /* STRICT mode */

/*
** Allowed values for Table.eTabType
*/
#define TABTYP_NORM      0     /* Ordinary table */
#define TABTYP_VTAB      1     /* Virtual table */
#define TABTYP_VIEW      2     /* A view */
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowUnlinkFromSelect(Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
void sqlite3WindowLink(Select *pSel, Window *pWin);
int sqlite3WindowCompare(Parse*, Window*, Window*, int);
void sqlite3WindowCodeInit(Parse*, Select*);
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
int sqlite3WindowRewrite(Parse*, Select*);
void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
void sqlite3WindowFunctions(void);







|







4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowUnlinkFromSelect(Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
void sqlite3WindowAttach(Parse*, Expr*, Window*);
void sqlite3WindowLink(Select *pSel, Window *pWin);
int sqlite3WindowCompare(const Parse*, const Window*, const Window*, int);
void sqlite3WindowCodeInit(Parse*, Select*);
void sqlite3WindowCodeStep(Parse*, Select*, WhereInfo*, int, int);
int sqlite3WindowRewrite(Parse*, Select*);
void sqlite3WindowUpdate(Parse*, Window*, Window*, FuncDef*);
Window *sqlite3WindowDup(sqlite3 *db, Expr *pOwner, Window *p);
Window *sqlite3WindowListDup(sqlite3 *db, Window *p);
void sqlite3WindowFunctions(void);
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
void *sqlite3Realloc(void*, u64);
void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
void *sqlite3DbRealloc(sqlite3 *, void *, u64);
void sqlite3DbFree(sqlite3*, void*);
void sqlite3DbFreeNN(sqlite3*, void*);
int sqlite3MallocSize(void*);
int sqlite3DbMallocSize(sqlite3*, void*);
void *sqlite3PageMalloc(int);
void sqlite3PageFree(void*);
void sqlite3MemSetDefault(void);
#ifndef SQLITE_UNTESTABLE
void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
#endif
int sqlite3HeapNearlyFull(void);







|
|







4245
4246
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
char *sqlite3DbStrNDup(sqlite3*,const char*, u64);
char *sqlite3DbSpanDup(sqlite3*,const char*,const char*);
void *sqlite3Realloc(void*, u64);
void *sqlite3DbReallocOrFree(sqlite3 *, void *, u64);
void *sqlite3DbRealloc(sqlite3 *, void *, u64);
void sqlite3DbFree(sqlite3*, void*);
void sqlite3DbFreeNN(sqlite3*, void*);
int sqlite3MallocSize(const void*);
int sqlite3DbMallocSize(sqlite3*, const void*);
void *sqlite3PageMalloc(int);
void sqlite3PageFree(void*);
void sqlite3MemSetDefault(void);
#ifndef SQLITE_UNTESTABLE
void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
#endif
int sqlite3HeapNearlyFull(void);
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
Expr *sqlite3ExprSimplifiedAndOr(Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, Token*, int);
void sqlite3ExprFunctionUsable(Parse*,Expr*,FuncDef*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
void sqlite3ExprDeferredDelete(Parse*, Expr*);
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
void sqlite3ExprListSetSortOrder(ExprList*,int,int);
void sqlite3ExprListSetName(Parse*,ExprList*,Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
void sqlite3ExprListDelete(sqlite3*, ExprList*);
u32 sqlite3ExprListFlags(const ExprList*);
int sqlite3IndexHasDuplicateRootPage(Index*);
int sqlite3Init(sqlite3*, char**);
int sqlite3InitCallback(void*, int, char**, char**);
int sqlite3InitOne(sqlite3*, int, char**, u32);







|
|








|







4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
Expr *sqlite3ExprAlloc(sqlite3*,int,const Token*,int);
Expr *sqlite3Expr(sqlite3*,int,const char*);
void sqlite3ExprAttachSubtrees(sqlite3*,Expr*,Expr*,Expr*);
Expr *sqlite3PExpr(Parse*, int, Expr*, Expr*);
void sqlite3PExprAddSelect(Parse*, Expr*, Select*);
Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*);
Expr *sqlite3ExprSimplifiedAndOr(Expr*);
Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int);
void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*);
void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32);
void sqlite3ExprDelete(sqlite3*, Expr*);
void sqlite3ExprDeferredDelete(Parse*, Expr*);
void sqlite3ExprUnmapAndDelete(Parse*, Expr*);
ExprList *sqlite3ExprListAppend(Parse*,ExprList*,Expr*);
ExprList *sqlite3ExprListAppendVector(Parse*,ExprList*,IdList*,Expr*);
Select *sqlite3ExprListToValues(Parse*, int, ExprList*);
void sqlite3ExprListSetSortOrder(ExprList*,int,int);
void sqlite3ExprListSetName(Parse*,ExprList*,const Token*,int);
void sqlite3ExprListSetSpan(Parse*,ExprList*,const char*,const char*);
void sqlite3ExprListDelete(sqlite3*, ExprList*);
u32 sqlite3ExprListFlags(const ExprList*);
int sqlite3IndexHasDuplicateRootPage(Index*);
int sqlite3Init(sqlite3*, char**);
int sqlite3InitCallback(void*, int, char**, char**);
int sqlite3InitOne(sqlite3*, int, char**, u32);
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
void sqlite3AddColumn(Parse*,Token,Token);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
void sqlite3AddCollateType(Parse*, Token*);
void sqlite3AddGenerated(Parse*,Expr*,Token*);
void sqlite3EndTable(Parse*,Token*,Token*,u8,Select*);
void sqlite3AddReturning(Parse*,ExprList*);
int sqlite3ParseUri(const char*,const char*,unsigned int*,
                    sqlite3_vfs**,char**,char **);
#define sqlite3CodecQueryParameters(A,B,C) 0
Btree *sqlite3DbNameToBtree(sqlite3*,const char*);

#ifdef SQLITE_UNTESTABLE







|







4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
void sqlite3AddColumn(Parse*,Token,Token);
void sqlite3AddNotNull(Parse*, int);
void sqlite3AddPrimaryKey(Parse*, ExprList*, int, int, int);
void sqlite3AddCheckConstraint(Parse*, Expr*, const char*, const char*);
void sqlite3AddDefaultValue(Parse*,Expr*,const char*,const char*);
void sqlite3AddCollateType(Parse*, Token*);
void sqlite3AddGenerated(Parse*,Expr*,Token*);
void sqlite3EndTable(Parse*,Token*,Token*,u32,Select*);
void sqlite3AddReturning(Parse*,ExprList*);
int sqlite3ParseUri(const char*,const char*,unsigned int*,
                    sqlite3_vfs**,char**,char **);
#define sqlite3CodecQueryParameters(A,B,C) 0
Btree *sqlite3DbNameToBtree(sqlite3*,const char*);

#ifdef SQLITE_UNTESTABLE
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*,Token*,Expr*);
int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
char *sqlite3NameFromToken(sqlite3*, Token*);
int sqlite3ExprCompare(Parse*,Expr*, Expr*, int);
int sqlite3ExprCompareSkip(Expr*, Expr*, int);
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
int sqlite3ExprImpliesNonNullRow(Expr*,int);
void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
Vdbe *sqlite3GetVdbe(Parse*);







|
|
|
|
|







4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
Table *sqlite3LocateTable(Parse*,u32 flags,const char*, const char*);
Table *sqlite3LocateTableItem(Parse*,u32 flags,SrcItem *);
Index *sqlite3FindIndex(sqlite3*,const char*, const char*);
void sqlite3UnlinkAndDeleteTable(sqlite3*,int,const char*);
void sqlite3UnlinkAndDeleteIndex(sqlite3*,int,const char*);
void sqlite3Vacuum(Parse*,Token*,Expr*);
int sqlite3RunVacuum(char**, sqlite3*, int, sqlite3_value*);
char *sqlite3NameFromToken(sqlite3*, const Token*);
int sqlite3ExprCompare(const Parse*,const Expr*,const Expr*, int);
int sqlite3ExprCompareSkip(Expr*,Expr*,int);
int sqlite3ExprListCompare(const ExprList*,const ExprList*, int);
int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int);
int sqlite3ExprImpliesNonNullRow(Expr*,int);
void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
Vdbe *sqlite3GetVdbe(Parse*);
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr*);
#endif
int sqlite3ExprIsInteger(Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(
    Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);







|







4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
int sqlite3ExprIsTableConstant(Expr*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
int sqlite3ExprContainsSubquery(Expr*);
#endif
int sqlite3ExprIsInteger(const Expr*, int*);
int sqlite3ExprCanBeNull(const Expr*);
int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(
    Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int);
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int);
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
void sqlite3BeginWriteOperation(Parse*, int, int);
void sqlite3MultiWrite(Parse*);
void sqlite3MayAbort(Parse*);
void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8);
void sqlite3UniqueConstraint(Parse*, int, Index*);
void sqlite3RowidConstraint(Parse*, int, Table*);
Expr *sqlite3ExprDup(sqlite3*,Expr*,int);
ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int);
SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int);
IdList *sqlite3IdListDup(sqlite3*,IdList*);
Select *sqlite3SelectDup(sqlite3*,Select*,int);
FuncDef *sqlite3FunctionSearch(int,const char*);
void sqlite3InsertBuiltinFuncs(FuncDef*,int);
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
void sqlite3RegisterBuiltinFunctions(void);
void sqlite3RegisterDateTimeFunctions(void);
void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
int sqlite3SafetyCheckOk(sqlite3*);







|
|
|
|
|







4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
int sqlite3OpenTableAndIndices(Parse*, Table*, int, u8, int, u8*, int*, int*);
void sqlite3BeginWriteOperation(Parse*, int, int);
void sqlite3MultiWrite(Parse*);
void sqlite3MayAbort(Parse*);
void sqlite3HaltConstraint(Parse*, int, int, char*, i8, u8);
void sqlite3UniqueConstraint(Parse*, int, Index*);
void sqlite3RowidConstraint(Parse*, int, Table*);
Expr *sqlite3ExprDup(sqlite3*,const Expr*,int);
ExprList *sqlite3ExprListDup(sqlite3*,const ExprList*,int);
SrcList *sqlite3SrcListDup(sqlite3*,const SrcList*,int);
IdList *sqlite3IdListDup(sqlite3*,const IdList*);
Select *sqlite3SelectDup(sqlite3*,const Select*,int);
FuncDef *sqlite3FunctionSearch(int,const char*);
void sqlite3InsertBuiltinFuncs(FuncDef*,int);
FuncDef *sqlite3FindFunction(sqlite3*,const char*,int,u8,u8);
void sqlite3RegisterBuiltinFunctions(void);
void sqlite3RegisterDateTimeFunctions(void);
void sqlite3RegisterPerConnectionBuiltinFunctions(sqlite3*);
int sqlite3SafetyCheckOk(sqlite3*);
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
#define putVarint    sqlite3PutVarint


const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
void sqlite3TableAffinity(Vdbe*, Table*, int);
char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
char sqlite3TableColumnAffinity(Table*,int);
char sqlite3ExprAffinity(const Expr *pExpr);
int sqlite3Atoi64(const char*, i64*, int, u8);
int sqlite3DecOrHexToI64(const char*, i64*);
void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
void sqlite3Error(sqlite3*,int);
void sqlite3ErrorClear(sqlite3*);
void sqlite3SystemError(sqlite3*,int);







|







4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
#define putVarint    sqlite3PutVarint


const char *sqlite3IndexAffinityStr(sqlite3*, Index*);
void sqlite3TableAffinity(Vdbe*, Table*, int);
char sqlite3CompareAffinity(const Expr *pExpr, char aff2);
int sqlite3IndexAffinityOk(const Expr *pExpr, char idx_affinity);
char sqlite3TableColumnAffinity(const Table*,int);
char sqlite3ExprAffinity(const Expr *pExpr);
int sqlite3Atoi64(const char*, i64*, int, u8);
int sqlite3DecOrHexToI64(const char*, i64*);
void sqlite3ErrorWithMsg(sqlite3*, int, const char*,...);
void sqlite3Error(sqlite3*,int);
void sqlite3ErrorClear(sqlite3*);
void sqlite3SystemError(sqlite3*,int);
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
int sqlite3IsBinary(const CollSeq*);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
void sqlite3SetTextEncoding(sqlite3 *db, u8);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr);
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr);
int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*);
Expr *sqlite3ExprAddCollateToken(Parse *pParse, Expr*, const Token*, int);
Expr *sqlite3ExprAddCollateString(Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
Expr *sqlite3ExprSkipCollateAndLikely(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3WritableSchema(sqlite3*);
int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*);
void sqlite3VdbeSetChanges(sqlite3 *, i64);
int sqlite3AddInt64(i64*,i64);







|
|







4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
CollSeq *sqlite3FindCollSeq(sqlite3*,u8 enc, const char*,int);
int sqlite3IsBinary(const CollSeq*);
CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char*zName);
void sqlite3SetTextEncoding(sqlite3 *db, u8);
CollSeq *sqlite3ExprCollSeq(Parse *pParse, const Expr *pExpr);
CollSeq *sqlite3ExprNNCollSeq(Parse *pParse, const Expr *pExpr);
int sqlite3ExprCollSeqMatch(Parse*,const Expr*,const Expr*);
Expr *sqlite3ExprAddCollateToken(const Parse *pParse, Expr*, const Token*, int);
Expr *sqlite3ExprAddCollateString(const Parse*,Expr*,const char*);
Expr *sqlite3ExprSkipCollate(Expr*);
Expr *sqlite3ExprSkipCollateAndLikely(Expr*);
int sqlite3CheckCollSeq(Parse *, CollSeq *);
int sqlite3WritableSchema(sqlite3*);
int sqlite3CheckObjectName(Parse*, const char*,const char*,const char*);
void sqlite3VdbeSetChanges(sqlite3 *, i64);
int sqlite3AddInt64(i64*,i64);
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842

4843
4844
4845
4846
4847
4848
4849
#ifndef SQLITE_UNTESTABLE
void sqlite3ResultIntReal(sqlite3_context*);
#endif
sqlite3_value *sqlite3ValueNew(sqlite3 *);
#ifndef SQLITE_OMIT_UTF16
char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
#endif
int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3OpcodeProperty[];
extern const char sqlite3StrBINARY[];
extern const unsigned char sqlite3StdTypeLen[];
extern const char sqlite3StdTypeAffinity[];

extern const char *sqlite3StdType[];
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char *sqlite3aLTb;
extern const unsigned char *sqlite3aEQb;
extern const unsigned char *sqlite3aGTb;
extern const unsigned char sqlite3CtypeMap[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;







|






>







4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
#ifndef SQLITE_UNTESTABLE
void sqlite3ResultIntReal(sqlite3_context*);
#endif
sqlite3_value *sqlite3ValueNew(sqlite3 *);
#ifndef SQLITE_OMIT_UTF16
char *sqlite3Utf16to8(sqlite3 *, const void*, int, u8);
#endif
int sqlite3ValueFromExpr(sqlite3 *, const Expr *, u8, u8, sqlite3_value **);
void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
#ifndef SQLITE_AMALGAMATION
extern const unsigned char sqlite3OpcodeProperty[];
extern const char sqlite3StrBINARY[];
extern const unsigned char sqlite3StdTypeLen[];
extern const char sqlite3StdTypeAffinity[];
extern const char sqlite3StdTypeMap[];
extern const char *sqlite3StdType[];
extern const unsigned char sqlite3UpperToLower[];
extern const unsigned char *sqlite3aLTb;
extern const unsigned char *sqlite3aEQb;
extern const unsigned char *sqlite3aGTb;
extern const unsigned char sqlite3CtypeMap[];
extern SQLITE_WSD struct Sqlite3Config sqlite3Config;
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
void sqlite3AlterDropColumn(Parse*, SrcList*, Token*);
void *sqlite3RenameTokenMap(Parse*, void*, Token*);
void sqlite3RenameTokenRemap(Parse*, void *pTo, void *pFrom);
void sqlite3RenameExprUnmap(Parse*, Expr*);
void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*, Column*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3FindDb(sqlite3*, Token*);







|
|
|







4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
int sqlite3ResolveExprListNames(NameContext*, ExprList*);
void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*);
int sqlite3ResolveSelfReference(Parse*,Table*,int,Expr*,ExprList*);
int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*);
void sqlite3ColumnDefault(Vdbe *, Table *, int, int);
void sqlite3AlterFinishAddColumn(Parse *, Token *);
void sqlite3AlterBeginAddColumn(Parse *, SrcList *);
void sqlite3AlterDropColumn(Parse*, SrcList*, const Token*);
const void *sqlite3RenameTokenMap(Parse*, const void*, const Token*);
void sqlite3RenameTokenRemap(Parse*, const void *pTo, const void *pFrom);
void sqlite3RenameExprUnmap(Parse*, Expr*);
void sqlite3RenameExprlistUnmap(Parse*, ExprList*);
CollSeq *sqlite3GetCollSeq(Parse*, u8, CollSeq *, const char*);
char sqlite3AffinityType(const char*, Column*);
void sqlite3Analyze(Parse*, Token*, Token*);
int sqlite3InvokeBusyHandler(BusyHandler*);
int sqlite3FindDb(sqlite3*, Token*);
4926
4927
4928
4929
4930
4931
4932


4933
4934
4935
4936
4937
4938
4939
void sqlite3OomFault(sqlite3*);
void sqlite3OomClear(sqlite3*);
int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *);

void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
char *sqlite3StrAccumFinish(StrAccum*);


void sqlite3SelectDestInit(SelectDest*,int,int);
Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

void sqlite3BackupRestart(sqlite3_backup *);
void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);

#ifndef SQLITE_OMIT_SUBQUERY







>
>







4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
void sqlite3OomFault(sqlite3*);
void sqlite3OomClear(sqlite3*);
int sqlite3ApiExit(sqlite3 *db, int);
int sqlite3OpenTempDatabase(Parse *);

void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int);
char *sqlite3StrAccumFinish(StrAccum*);
void sqlite3StrAccumSetError(StrAccum*, u8);
void sqlite3ResultStrAccum(sqlite3_context*,StrAccum*);
void sqlite3SelectDestInit(SelectDest*,int,int);
Expr *sqlite3CreateColumnExpr(sqlite3 *, SrcList *, int, int);

void sqlite3BackupRestart(sqlite3_backup *);
void sqlite3BackupUpdate(sqlite3_backup *, Pgno, const u8 *);

#ifndef SQLITE_OMIT_SUBQUERY
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
#endif

#ifdef SQLITE_TEST
  int sqlite3Utf8To8(unsigned char*);
#endif

#ifdef SQLITE_OMIT_VIRTUALTABLE
#  define sqlite3VtabClear(Y)
#  define sqlite3VtabSync(X,Y) SQLITE_OK
#  define sqlite3VtabRollback(X)
#  define sqlite3VtabCommit(X)
#  define sqlite3VtabInSync(db) 0
#  define sqlite3VtabLock(X)
#  define sqlite3VtabUnlock(X)
#  define sqlite3VtabModuleUnref(D,X)







|







4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
5000
5001
5002
5003
5004
#endif

#ifdef SQLITE_TEST
  int sqlite3Utf8To8(unsigned char*);
#endif

#ifdef SQLITE_OMIT_VIRTUALTABLE
#  define sqlite3VtabClear(D,T)
#  define sqlite3VtabSync(X,Y) SQLITE_OK
#  define sqlite3VtabRollback(X)
#  define sqlite3VtabCommit(X)
#  define sqlite3VtabInSync(db) 0
#  define sqlite3VtabLock(X)
#  define sqlite3VtabUnlock(X)
#  define sqlite3VtabModuleUnref(D,X)
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
#endif

int sqlite3JournalIsInMemory(sqlite3_file *p);
void sqlite3MemJournalOpen(sqlite3_file *);

void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
#if SQLITE_MAX_EXPR_DEPTH>0
  int sqlite3SelectExprHeight(Select *);
  int sqlite3ExprCheckHeight(Parse*, int);
#else
  #define sqlite3SelectExprHeight(x) 0
  #define sqlite3ExprCheckHeight(x,y)
#endif

u32 sqlite3Get4byte(const u8*);







|







5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
#endif

int sqlite3JournalIsInMemory(sqlite3_file *p);
void sqlite3MemJournalOpen(sqlite3_file *);

void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p);
#if SQLITE_MAX_EXPR_DEPTH>0
  int sqlite3SelectExprHeight(const Select *);
  int sqlite3ExprCheckHeight(Parse*, int);
#else
  #define sqlite3SelectExprHeight(x) 0
  #define sqlite3ExprCheckHeight(x,y)
#endif

u32 sqlite3Get4byte(const u8*);
5254
5255
5256
5257
5258
5259
5260
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
int sqlite3DbpageRegister(sqlite3*);
#endif
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
int sqlite3DbstatRegister(sqlite3*);
#endif

int sqlite3ExprVectorSize(Expr *pExpr);
int sqlite3ExprIsVector(Expr *pExpr);
Expr *sqlite3VectorFieldSubexpr(Expr*, int);
Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int);
void sqlite3VectorErrorMsg(Parse*, Expr*);

#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
const char **sqlite3CompileOptions(int *pnOpt);
#endif

#endif /* SQLITEINT_H */







|
|









5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
5281
5282
5283
#if defined(SQLITE_ENABLE_DBPAGE_VTAB) || defined(SQLITE_TEST)
int sqlite3DbpageRegister(sqlite3*);
#endif
#if defined(SQLITE_ENABLE_DBSTAT_VTAB) || defined(SQLITE_TEST)
int sqlite3DbstatRegister(sqlite3*);
#endif

int sqlite3ExprVectorSize(const Expr *pExpr);
int sqlite3ExprIsVector(const Expr *pExpr);
Expr *sqlite3VectorFieldSubexpr(Expr*, int);
Expr *sqlite3ExprForVectorField(Parse*,Expr*,int,int);
void sqlite3VectorErrorMsg(Parse*, Expr*);

#ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS
const char **sqlite3CompileOptions(int *pnOpt);
#endif

#endif /* SQLITEINT_H */
Changes to src/tclsqlite.c.
177
178
179
180
181
182
183

184
185
186
187
188
189
190
  int maxStmt;               /* The next maximum number of stmtList */
  int nStmt;                 /* Number of statements in stmtList */
  IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
  int nStep, nSort, nIndex;  /* Statistics for most recent operation */
  int nVMStep;               /* Another statistic for most recent operation */
  int nTransaction;          /* Number of nested [transaction] methods */
  int openFlags;             /* Flags used to open.  (SQLITE_OPEN_URI) */

#ifdef SQLITE_TEST
  int bLegacyPrepare;        /* True to use sqlite3_prepare() */
#endif
};

struct IncrblobChannel {
  sqlite3_blob *pBlob;      /* sqlite3 blob handle */







>







177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
  int maxStmt;               /* The next maximum number of stmtList */
  int nStmt;                 /* Number of statements in stmtList */
  IncrblobChannel *pIncrblob;/* Linked list of open incrblob channels */
  int nStep, nSort, nIndex;  /* Statistics for most recent operation */
  int nVMStep;               /* Another statistic for most recent operation */
  int nTransaction;          /* Number of nested [transaction] methods */
  int openFlags;             /* Flags used to open.  (SQLITE_OPEN_URI) */
  int nRef;                  /* Delete object when this reaches 0 */
#ifdef SQLITE_TEST
  int bLegacyPrepare;        /* True to use sqlite3_prepare() */
#endif
};

struct IncrblobChannel {
  sqlite3_blob *pBlob;      /* sqlite3 blob handle */
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
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
    pNext = pPreStmt->pNext;
    dbFreeStmt(pPreStmt);
  }
  pDb->nStmt = 0;
  pDb->stmtLast = 0;
  pDb->stmtList = 0;
}








































































/*
** TCL calls this procedure when an sqlite3 database command is
** deleted.
*/
static void SQLITE_TCLAPI DbDeleteCmd(void *db){
  SqliteDb *pDb = (SqliteDb*)db;
  flushStmtCache(pDb);
  closeIncrblobChannels(pDb);
  sqlite3_close(pDb->db);
  while( pDb->pFunc ){
    SqlFunc *pFunc = pDb->pFunc;
    pDb->pFunc = pFunc->pNext;
    assert( pFunc->pDb==pDb );
    Tcl_DecrRefCount(pFunc->pScript);
    Tcl_Free((char*)pFunc);
  }
  while( pDb->pCollate ){
    SqlCollate *pCollate = pDb->pCollate;
    pDb->pCollate = pCollate->pNext;
    Tcl_Free((char*)pCollate);
  }
  if( pDb->zBusy ){
    Tcl_Free(pDb->zBusy);
  }
  if( pDb->zTrace ){
    Tcl_Free(pDb->zTrace);
  }
  if( pDb->zTraceV2 ){
    Tcl_Free(pDb->zTraceV2);
  }
  if( pDb->zProfile ){
    Tcl_Free(pDb->zProfile);
  }
  if( pDb->zBindFallback ){
    Tcl_Free(pDb->zBindFallback);
  }
  if( pDb->zAuth ){
    Tcl_Free(pDb->zAuth);
  }
  if( pDb->zNull ){
    Tcl_Free(pDb->zNull);
  }
  if( pDb->pUpdateHook ){
    Tcl_DecrRefCount(pDb->pUpdateHook);
  }
  if( pDb->pPreUpdateHook ){
    Tcl_DecrRefCount(pDb->pPreUpdateHook);
  }
  if( pDb->pRollbackHook ){
    Tcl_DecrRefCount(pDb->pRollbackHook);
  }
  if( pDb->pWalHook ){
    Tcl_DecrRefCount(pDb->pWalHook);
  }
  if( pDb->pCollateNeeded ){
    Tcl_DecrRefCount(pDb->pCollateNeeded);
  }
  Tcl_Free((char*)pDb);
}

/*
** This routine is called when a database file is locked while trying
** to execute SQL.
*/
static int DbBusyHandler(void *cd, int nTries){







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







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







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
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598



















































599
600
601
602
603
604
605
    pNext = pPreStmt->pNext;
    dbFreeStmt(pPreStmt);
  }
  pDb->nStmt = 0;
  pDb->stmtLast = 0;
  pDb->stmtList = 0;
}

/*
** Increment the reference counter on the SqliteDb object. The reference
** should be released by calling delDatabaseRef().
*/
static void addDatabaseRef(SqliteDb *pDb){
  pDb->nRef++;
}

/*
** Decrement the reference counter associated with the SqliteDb object.
** If it reaches zero, delete the object.
*/
static void delDatabaseRef(SqliteDb *pDb){
  assert( pDb->nRef>0 );
  pDb->nRef--;
  if( pDb->nRef==0 ){
    flushStmtCache(pDb);
    closeIncrblobChannels(pDb);
    sqlite3_close(pDb->db);
    while( pDb->pFunc ){
      SqlFunc *pFunc = pDb->pFunc;
      pDb->pFunc = pFunc->pNext;
      assert( pFunc->pDb==pDb );
      Tcl_DecrRefCount(pFunc->pScript);
      Tcl_Free((char*)pFunc);
    }
    while( pDb->pCollate ){
      SqlCollate *pCollate = pDb->pCollate;
      pDb->pCollate = pCollate->pNext;
      Tcl_Free((char*)pCollate);
    }
    if( pDb->zBusy ){
      Tcl_Free(pDb->zBusy);
    }
    if( pDb->zTrace ){
      Tcl_Free(pDb->zTrace);
    }
    if( pDb->zTraceV2 ){
      Tcl_Free(pDb->zTraceV2);
    }
    if( pDb->zProfile ){
      Tcl_Free(pDb->zProfile);
    }
    if( pDb->zBindFallback ){
      Tcl_Free(pDb->zBindFallback);
    }
    if( pDb->zAuth ){
      Tcl_Free(pDb->zAuth);
    }
    if( pDb->zNull ){
      Tcl_Free(pDb->zNull);
    }
    if( pDb->pUpdateHook ){
      Tcl_DecrRefCount(pDb->pUpdateHook);
    }
    if( pDb->pPreUpdateHook ){
      Tcl_DecrRefCount(pDb->pPreUpdateHook);
    }
    if( pDb->pRollbackHook ){
      Tcl_DecrRefCount(pDb->pRollbackHook);
    }
    if( pDb->pWalHook ){
      Tcl_DecrRefCount(pDb->pWalHook);
    }
    if( pDb->pCollateNeeded ){
      Tcl_DecrRefCount(pDb->pCollateNeeded);
    }
    Tcl_Free((char*)pDb);
  }
}

/*
** TCL calls this procedure when an sqlite3 database command is
** deleted.
*/
static void SQLITE_TCLAPI DbDeleteCmd(void *db){
  SqliteDb *pDb = (SqliteDb*)db;
  delDatabaseRef(pDb);



















































}

/*
** This routine is called when a database file is locked while trying
** to execute SQL.
*/
static int DbBusyHandler(void *cd, int nTries){
1242
1243
1244
1245
1246
1247
1248

1249
1250
1251
1252
1253
1254
1255
      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
      rc = TCL_ERROR;
    }
    sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
  }
  pDb->disableAuth--;


  return rc;
}

/*
** Unless SQLITE_TEST is defined, this function is a simple wrapper around
** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending







>







1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
      Tcl_AppendResult(interp, sqlite3_errmsg(pDb->db), (char*)0);
      rc = TCL_ERROR;
    }
    sqlite3_exec(pDb->db, "ROLLBACK", 0, 0, 0);
  }
  pDb->disableAuth--;

  delDatabaseRef(pDb);
  return rc;
}

/*
** Unless SQLITE_TEST is defined, this function is a simple wrapper around
** sqlite3_prepare_v2(). If SQLITE_TEST is defined, then it uses either
** sqlite3_prepare_v2() or legacy interface sqlite3_prepare(), depending
1575
1576
1577
1578
1579
1580
1581

1582
1583
1584
1585
1586
1587
1588
  p->pSql = pSql;
  Tcl_IncrRefCount(pSql);
  if( pArray ){
    p->pArray = pArray;
    Tcl_IncrRefCount(pArray);
  }
  p->evalFlags = evalFlags;

}

/*
** Obtain information about the row that the DbEvalContext passed as the
** first argument currently points to.
*/
static void dbEvalRowInfo(







>







1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
  p->pSql = pSql;
  Tcl_IncrRefCount(pSql);
  if( pArray ){
    p->pArray = pArray;
    Tcl_IncrRefCount(pArray);
  }
  p->evalFlags = evalFlags;
  addDatabaseRef(p->pDb);
}

/*
** Obtain information about the row that the DbEvalContext passed as the
** first argument currently points to.
*/
static void dbEvalRowInfo(
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
  }
  if( p->pArray ){
    Tcl_DecrRefCount(p->pArray);
    p->pArray = 0;
  }
  Tcl_DecrRefCount(p->pSql);
  dbReleaseColumnNames(p);

}

/*
** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
** the value for the iCol'th column of the row currently pointed to by
** the DbEvalContext structure passed as the first argument.
*/







>







1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
  }
  if( p->pArray ){
    Tcl_DecrRefCount(p->pArray);
    p->pArray = 0;
  }
  Tcl_DecrRefCount(p->pSql);
  dbReleaseColumnNames(p);
  delDatabaseRef(p->pDb);
}

/*
** Return a pointer to a Tcl_Obj structure with ref-count 0 that contains
** the value for the iCol'th column of the row currently pointed to by
** the DbEvalContext structure passed as the first argument.
*/
3431
3432
3433
3434
3435
3436
3437

3438
3439
3440
3441
3442
3443
3444
    pDb->nTransaction++;

    /* If using NRE, schedule a callback to invoke the script pScript, then
    ** a second callback to commit (or rollback) the transaction or savepoint
    ** opened above. If not using NRE, evaluate the script directly, then
    ** call function DbTransPostCmd() to commit (or rollback) the transaction
    ** or savepoint.  */

    if( DbUseNre() ){
      Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
      (void)Tcl_NREvalObj(interp, pScript, 0);
    }else{
      rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
    }
    break;







>







3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
    pDb->nTransaction++;

    /* If using NRE, schedule a callback to invoke the script pScript, then
    ** a second callback to commit (or rollback) the transaction or savepoint
    ** opened above. If not using NRE, evaluate the script directly, then
    ** call function DbTransPostCmd() to commit (or rollback) the transaction
    ** or savepoint.  */
    addDatabaseRef(pDb);          /* DbTransPostCmd() calls delDatabaseRef() */
    if( DbUseNre() ){
      Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
      (void)Tcl_NREvalObj(interp, pScript, 0);
    }else{
      rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
    }
    break;
3838
3839
3840
3841
3842
3843
3844

3845
3846
3847
3848
3849
3850
3851
  zArg = Tcl_GetStringFromObj(objv[1], 0);
  if( DbUseNre() ){
    Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
                        (char*)p, DbDeleteCmd);
  }else{
    Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
  }

  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static
** library.
*/







>







3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
  zArg = Tcl_GetStringFromObj(objv[1], 0);
  if( DbUseNre() ){
    Tcl_NRCreateCommand(interp, zArg, DbObjCmdAdaptor, DbObjCmd,
                        (char*)p, DbDeleteCmd);
  }else{
    Tcl_CreateObjCommand(interp, zArg, DbObjCmd, (char*)p, DbDeleteCmd);
  }
  p->nRef = 1;
  return TCL_OK;
}

/*
** Provide a dummy Tcl_InitStubs if we are using this as a static
** library.
*/
Changes to src/test_tclsh.c.
83
84
85
86
87
88
89

90
91
92
93
94
95
96
  extern int SqlitetestThread_Init(Tcl_Interp*);
  extern int SqlitetestOnefile_Init();
  extern int SqlitetestOsinst_Init(Tcl_Interp*);
  extern int Sqlitetestbackup_Init(Tcl_Interp*);
  extern int Sqlitetestintarray_Init(Tcl_Interp*);
  extern int Sqlitetestvfs_Init(Tcl_Interp *);
  extern int Sqlitetestrtree_Init(Tcl_Interp*);

  extern int Sqlitequota_Init(Tcl_Interp*);
  extern int Sqlitemultiplex_Init(Tcl_Interp*);
  extern int SqliteSuperlock_Init(Tcl_Interp*);
  extern int SqlitetestSyscall_Init(Tcl_Interp*);
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  extern int TestSession_Init(Tcl_Interp*);
#endif







>







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
  extern int SqlitetestThread_Init(Tcl_Interp*);
  extern int SqlitetestOnefile_Init();
  extern int SqlitetestOsinst_Init(Tcl_Interp*);
  extern int Sqlitetestbackup_Init(Tcl_Interp*);
  extern int Sqlitetestintarray_Init(Tcl_Interp*);
  extern int Sqlitetestvfs_Init(Tcl_Interp *);
  extern int Sqlitetestrtree_Init(Tcl_Interp*);
  extern int Sqlitetestrtreedoc_Init(Tcl_Interp*);
  extern int Sqlitequota_Init(Tcl_Interp*);
  extern int Sqlitemultiplex_Init(Tcl_Interp*);
  extern int SqliteSuperlock_Init(Tcl_Interp*);
  extern int SqlitetestSyscall_Init(Tcl_Interp*);
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  extern int TestSession_Init(Tcl_Interp*);
#endif
153
154
155
156
157
158
159

160
161
162
163
164
165
166
  SqlitetestThread_Init(interp);
  SqlitetestOnefile_Init();
  SqlitetestOsinst_Init(interp);
  Sqlitetestbackup_Init(interp);
  Sqlitetestintarray_Init(interp);
  Sqlitetestvfs_Init(interp);
  Sqlitetestrtree_Init(interp);

  Sqlitequota_Init(interp);
  Sqlitemultiplex_Init(interp);
  SqliteSuperlock_Init(interp);
  SqlitetestSyscall_Init(interp);
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  TestSession_Init(interp);
#endif







>







154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  SqlitetestThread_Init(interp);
  SqlitetestOnefile_Init();
  SqlitetestOsinst_Init(interp);
  Sqlitetestbackup_Init(interp);
  Sqlitetestintarray_Init(interp);
  Sqlitetestvfs_Init(interp);
  Sqlitetestrtree_Init(interp);
  Sqlitetestrtreedoc_Init(interp);
  Sqlitequota_Init(interp);
  Sqlitemultiplex_Init(interp);
  SqliteSuperlock_Init(interp);
  SqlitetestSyscall_Init(interp);
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
  TestSession_Init(interp);
#endif
Changes to src/util.c.
56
57
58
59
60
61
62



63
64


65
66





67
68
69
70
71
72
73
74
  return xCallback ? xCallback(iTest) : SQLITE_OK;
}
#endif

#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).



*/
int sqlite3IsNaN(double x){


  u64 y;
  memcpy(&y,&x,sizeof(y));





  return IsNaN(y);
}
#endif /* SQLITE_OMIT_FLOATING_POINT */

/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
**







>
>
>


>
>


>
>
>
>
>
|







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
  return xCallback ? xCallback(iTest) : SQLITE_OK;
}
#endif

#ifndef SQLITE_OMIT_FLOATING_POINT
/*
** Return true if the floating point value is Not a Number (NaN).
**
** Use the math library isnan() function if compiled with SQLITE_HAVE_ISNAN.
** Otherwise, we have our own implementation that works on most systems.
*/
int sqlite3IsNaN(double x){
  int rc;   /* The value return */
#if !SQLITE_HAVE_ISNAN && !HAVE_ISNAN
  u64 y;
  memcpy(&y,&x,sizeof(y));
  rc = IsNaN(y);
#else
  rc = isnan(x);
#endif /* HAVE_ISNAN */
  testcase( rc );
  return rc;
}
#endif /* SQLITE_OMIT_FLOATING_POINT */

/*
** Compute a string length that is limited to what can be stored in
** lower 30 bits of a 32-bit signed integer.
**
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
**
** The column type is an extra string stored after the zero-terminator on
** the column name if and only if the COLFLAG_HASTYPE flag is set.
*/
char *sqlite3ColumnType(Column *pCol, char *zDflt){
  if( pCol->colFlags & COLFLAG_HASTYPE ){
    return pCol->zCnName + strlen(pCol->zCnName) + 1;
  }else if( pCol->eType ){
    assert( pCol->eType<=SQLITE_N_STDTYPE );
    return (char*)sqlite3StdType[pCol->eType-1];
  }else{
    return zDflt;
  }
}

/*
** Helper function for sqlite3Error() - called rarely.  Broken out into







|
|
|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
**
** The column type is an extra string stored after the zero-terminator on
** the column name if and only if the COLFLAG_HASTYPE flag is set.
*/
char *sqlite3ColumnType(Column *pCol, char *zDflt){
  if( pCol->colFlags & COLFLAG_HASTYPE ){
    return pCol->zCnName + strlen(pCol->zCnName) + 1;
  }else if( pCol->eCType ){
    assert( pCol->eCType<=SQLITE_N_STDTYPE );
    return (char*)sqlite3StdType[pCol->eCType-1];
  }else{
    return zDflt;
  }
}

/*
** Helper function for sqlite3Error() - called rarely.  Broken out into
Changes to src/vdbe.c.
667
668
669
670
671
672
673













674
675
676
677
678
679
680
    return out2PrereleaseWithClear(pOut);
  }else{
    pOut->flags = MEM_Int;
    return pOut;
  }
}















/*
** Execute as much of a VDBE program as we can.
** This is the core of sqlite3_step().  
*/
int sqlite3VdbeExec(
  Vdbe *p                    /* The VDBE */







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







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
    return out2PrereleaseWithClear(pOut);
  }else{
    pOut->flags = MEM_Int;
    return pOut;
  }
}

/*
** Return the symbolic name for the data type of a pMem
*/
static const char *vdbeMemTypeName(Mem *pMem){
  static const char *azTypes[] = {
      /* SQLITE_INTEGER */ "INT",
      /* SQLITE_FLOAT   */ "REAL",
      /* SQLITE_TEXT    */ "TEXT",
      /* SQLITE_BLOB    */ "BLOB",
      /* SQLITE_NULL    */ "NULL"
  };
  return azTypes[sqlite3_value_type(pMem)-1];
}

/*
** Execute as much of a VDBE program as we can.
** This is the core of sqlite3_step().  
*/
int sqlite3VdbeExec(
  Vdbe *p                    /* The VDBE */
2497
2498
2499
2500
2501
2502
2503
















2504
2505
2506
2507
2508
2509
2510
  pIn1 = &aMem[pOp->p1];
  VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
  if( (pIn1->flags & MEM_Null)!=0 ){
    goto jump_to_p2;
  }
  break;
}

















/* Opcode: ZeroOrNull P1 P2 P3 * *
** Synopsis: r[P2] = 0 OR NULL
**
** If all both registers P1 and P3 are NOT NULL, then store a zero in
** register P2.  If either registers P1 or P3 are NULL then put
** a NULL in register P2.







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







2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
  pIn1 = &aMem[pOp->p1];
  VdbeBranchTaken( (pIn1->flags & MEM_Null)!=0, 2);
  if( (pIn1->flags & MEM_Null)!=0 ){
    goto jump_to_p2;
  }
  break;
}

/* Opcode: IsNullOrType P1 P2 P3 * *
** Synopsis: if typeof(r[P1]) IN (P3,5) goto P2
**
** Jump to P2 if the value in register P1 is NULL or has a datatype P3.
** P3 is an integer which should be one of SQLITE_INTEGER, SQLITE_FLOAT,
** SQLITE_BLOB, SQLITE_NULL, or SQLITE_TEXT.
*/
case OP_IsNullOrType: {      /* jump, in1 */
  int doTheJump;
  pIn1 = &aMem[pOp->p1];
  doTheJump = (pIn1->flags & MEM_Null)!=0 || sqlite3_value_type(pIn1)==pOp->p3;
  VdbeBranchTaken( doTheJump, 2);
  if( doTheJump ) goto jump_to_p2;
  break;
}

/* Opcode: ZeroOrNull P1 P2 P3 * *
** Synopsis: r[P2] = 0 OR NULL
**
** If all both registers P1 and P3 are NOT NULL, then store a zero in
** register P2.  If either registers P1 or P3 are NULL then put
** a NULL in register P2.
2865
2866
2867
2868
2869
2870
2871






























































































2872
2873
2874
2875
2876
2877
2878
    pOp = &aOp[aOp[0].p3-1];
    break;
  }else{
    rc = SQLITE_CORRUPT_BKPT;
    goto abort_due_to_error;
  }
}































































































/* Opcode: Affinity P1 P2 * P4 *
** Synopsis: affinity(r[P1@P2])
**
** Apply affinities to a range of P2 registers starting with P1.
**
** P4 is a string that is P2 characters long. The N-th character of the







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







2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
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
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
    pOp = &aOp[aOp[0].p3-1];
    break;
  }else{
    rc = SQLITE_CORRUPT_BKPT;
    goto abort_due_to_error;
  }
}

/* Opcode: TypeCheck P1 P2 * P4 *
** Synopsis: typecheck(r[P1@P2])
**
** Apply affinities to the range of P2 registers beginning with P1.
** Take the affinities from the Table object in P4.  If any value
** cannot be coerced into the correct type, then raise an error.
**
** This opcode is similar to OP_Affinity except that this opcode
** forces the register type to the Table column type.  This is used
** to implement "strict affinity".
**
** Preconditions:
**
** <ul>
** <li> P2 should be the number of non-virtual columns in the
**      table of P4.
** <li> Table P4 should be a STRICT table.
** </ul>
**
** If any precondition is false, an assertion fault occurs.
*/
case OP_TypeCheck: {
  Table *pTab;
  Column *aCol;
  int i;

  assert( pOp->p4type==P4_TABLE );
  pTab = pOp->p4.pTab;
  assert( pTab->tabFlags & TF_Strict );
  assert( pTab->nNVCol==pOp->p2 );
  aCol = pTab->aCol;
  pIn1 = &aMem[pOp->p1];
  for(i=0; i<pTab->nCol; i++){
    if( aCol[i].colFlags & COLFLAG_VIRTUAL ) continue;
    assert( pIn1 < &aMem[pOp->p1+pOp->p2] );
    applyAffinity(pIn1, aCol[i].affinity, encoding);
    if( (pIn1->flags & MEM_Null)==0 ){
      switch( aCol[i].eCType ){
        case COLTYPE_BLOB: {
          if( (pIn1->flags & MEM_Blob)==0 ) goto vdbe_type_error;
          break;
        }
        case COLTYPE_INTEGER:
        case COLTYPE_INT: {
          if( (pIn1->flags & MEM_Int)==0 ) goto vdbe_type_error;
          break;
        }
        case COLTYPE_TEXT: {
          if( (pIn1->flags & MEM_Str)==0 ) goto vdbe_type_error;
          break;
        }
        case COLTYPE_REAL: {
          if( pIn1->flags & MEM_Int ){
            /* When applying REAL affinity, if the result is still an MEM_Int
            ** that will fit in 6 bytes, then change the type to MEM_IntReal
            ** so that we keep the high-resolution integer value but know that
            ** the type really wants to be REAL. */
            testcase( pIn1->u.i==140737488355328LL );
            testcase( pIn1->u.i==140737488355327LL );
            testcase( pIn1->u.i==-140737488355328LL );
            testcase( pIn1->u.i==-140737488355329LL );
            if( pIn1->u.i<=140737488355327LL && pIn1->u.i>=-140737488355328LL){
              pIn1->flags |= MEM_IntReal;
              pIn1->flags &= ~MEM_Int;
            }else{
              pIn1->u.r = (double)pIn1->u.i;
              pIn1->flags |= MEM_Real;
              pIn1->flags &= ~MEM_Int;
            }
          }else if( (pIn1->flags & MEM_Real)==0 ){
            goto vdbe_type_error;
          }
          break;
        }
        default: {
          /* COLTYPE_ANY.  Accept anything. */
          break;
        }
      }
    }
    REGISTER_TRACE((int)(pIn1-aMem), pIn1);
    pIn1++;
  }
  assert( pIn1 == &aMem[pOp->p1+pOp->p2] );
  break;

vdbe_type_error:
  sqlite3VdbeError(p, "cannot store %s value in %s column %s.%s",
     vdbeMemTypeName(pIn1), sqlite3StdType[aCol[i].eCType-1],
     pTab->zName, aCol[i].zCnName);
  rc = SQLITE_CONSTRAINT_DATATYPE;
  goto abort_due_to_error;
}

/* Opcode: Affinity P1 P2 * P4 *
** Synopsis: affinity(r[P1@P2])
**
** Apply affinities to a range of P2 registers starting with P1.
**
** P4 is a string that is P2 characters long. The N-th character of the
5916
5917
5918
5919
5920
5921
5922
5923

5924
5925
5926
5927
5928
5929
5930
** index opened by cursor P1.
**
** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
** if no matching index entry is found.  This happens when running
** an UPDATE or DELETE statement and the index entry to be updated
** or deleted is not found.  For some uses of IdxDelete
** (example:  the EXCEPT operator) it does not matter that no matching
** entry is found.  For those cases, P5 is zero.

*/
case OP_IdxDelete: {
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;








|
>







6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
** index opened by cursor P1.
**
** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error
** if no matching index entry is found.  This happens when running
** an UPDATE or DELETE statement and the index entry to be updated
** or deleted is not found.  For some uses of IdxDelete
** (example:  the EXCEPT operator) it does not matter that no matching
** entry is found.  For those cases, P5 is zero.  Also, do not raise
** this (self-correcting and non-critical) error if in writable_schema mode.
*/
case OP_IdxDelete: {
  VdbeCursor *pC;
  BtCursor *pCrsr;
  int res;
  UnpackedRecord r;

5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
  r.default_rc = 0;
  r.aMem = &aMem[pOp->p2];
  rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res);
  if( rc ) goto abort_due_to_error;
  if( res==0 ){
    rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
    if( rc ) goto abort_due_to_error;
  }else if( pOp->p5 ){
    rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption");
    goto abort_due_to_error;
  }
  assert( pC->deferredMoveto==0 );
  pC->cacheStatus = CACHE_STALE;
  pC->seekResult = 0;
  break;







|







6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
  r.default_rc = 0;
  r.aMem = &aMem[pOp->p2];
  rc = sqlite3BtreeIndexMoveto(pCrsr, &r, &res);
  if( rc ) goto abort_due_to_error;
  if( res==0 ){
    rc = sqlite3BtreeDelete(pCrsr, BTREE_AUXDELETE);
    if( rc ) goto abort_due_to_error;
  }else if( pOp->p5 && !sqlite3WritableSchema(db) ){
    rc = sqlite3ReportError(SQLITE_CORRUPT_INDEX, __LINE__, "index corruption");
    goto abort_due_to_error;
  }
  assert( pC->deferredMoveto==0 );
  pC->cacheStatus = CACHE_STALE;
  pC->seekResult = 0;
  break;
7619
7620
7621
7622
7623
7624
7625
7626
7627
7628
7629
7630
7631
7632
7633

  /* Grab the index number and argc parameters */
  assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
  nArg = (int)pArgc->u.i;
  iQuery = (int)pQuery->u.i;

  /* Invoke the xFilter method */
  res = 0;
  apArg = p->apArg;
  for(i = 0; i<nArg; i++){
    apArg[i] = &pArgc[i+1];
  }
  rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
  sqlite3VtabImportErrmsg(p, pVtab);
  if( rc ) goto abort_due_to_error;







<







7743
7744
7745
7746
7747
7748
7749

7750
7751
7752
7753
7754
7755
7756

  /* Grab the index number and argc parameters */
  assert( (pQuery->flags&MEM_Int)!=0 && pArgc->flags==MEM_Int );
  nArg = (int)pArgc->u.i;
  iQuery = (int)pQuery->u.i;

  /* Invoke the xFilter method */

  apArg = p->apArg;
  for(i = 0; i<nArg; i++){
    apArg[i] = &pArgc[i+1];
  }
  rc = pModule->xFilter(pVCur, iQuery, pOp->p4.z, nArg, apArg);
  sqlite3VtabImportErrmsg(p, pVtab);
  if( rc ) goto abort_due_to_error;
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
*/
case OP_VNext: {   /* jump */
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
  int res;
  VdbeCursor *pCur;

  res = 0;
  pCur = p->apCsr[pOp->p1];
  assert( pCur->eCurType==CURTYPE_VTAB );
  if( pCur->nullRow ){
    break;
  }
  pVtab = pCur->uc.pVCur->pVtab;
  pModule = pVtab->pModule;







<







7832
7833
7834
7835
7836
7837
7838

7839
7840
7841
7842
7843
7844
7845
*/
case OP_VNext: {   /* jump */
  sqlite3_vtab *pVtab;
  const sqlite3_module *pModule;
  int res;
  VdbeCursor *pCur;


  pCur = p->apCsr[pOp->p1];
  assert( pCur->eCurType==CURTYPE_VTAB );
  if( pCur->nullRow ){
    break;
  }
  pVtab = pCur->uc.pVCur->pVtab;
  pModule = pVtab->pModule;
8251
8252
8253
8254
8255
8256
8257





8258
8259
8260
8261
8262
8263
8264
abort_due_to_error:
  if( db->mallocFailed ){
    rc = SQLITE_NOMEM_BKPT;
  }else if( rc==SQLITE_IOERR_CORRUPTFS ){
    rc = SQLITE_CORRUPT_BKPT;
  }
  assert( rc );





  if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
    sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
  }
  p->rc = rc;
  sqlite3SystemError(db, rc);
  testcase( sqlite3GlobalConfig.xLog!=0 );
  sqlite3_log(rc, "statement aborts at %d: [%s] %s", 







>
>
>
>
>







8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
abort_due_to_error:
  if( db->mallocFailed ){
    rc = SQLITE_NOMEM_BKPT;
  }else if( rc==SQLITE_IOERR_CORRUPTFS ){
    rc = SQLITE_CORRUPT_BKPT;
  }
  assert( rc );
#ifdef SQLITE_DEBUG
  if( db->flags & SQLITE_VdbeTrace ){
     printf("ABORT-due-to-error.  rc=%d\n", rc);
  }
#endif
  if( p->zErrMsg==0 && rc!=SQLITE_IOERR_NOMEM ){
    sqlite3VdbeError(p, "%s", sqlite3ErrStr(rc));
  }
  p->rc = rc;
  sqlite3SystemError(db, rc);
  testcase( sqlite3GlobalConfig.xLog!=0 );
  sqlite3_log(rc, "statement aborts at %d: [%s] %s", 
Changes to src/vdbemem.c.
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
** If the conditions above are not met, this function returns SQLITE_OK
** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
** NULL and an SQLite error code returned.
*/
#ifdef SQLITE_ENABLE_STAT4
static int valueFromFunction(
  sqlite3 *db,                    /* The database connection */
  Expr *p,                        /* The expression to evaluate */
  u8 enc,                         /* Encoding to use */
  u8 aff,                         /* Affinity to use */
  sqlite3_value **ppVal,          /* Write the new value here */
  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
){
  sqlite3_context ctx;            /* Context object for function invocation */
  sqlite3_value **apVal = 0;      /* Function arguments */







|







1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
** If the conditions above are not met, this function returns SQLITE_OK
** and sets (*ppVal) to NULL. Or, if an error occurs, (*ppVal) is set to
** NULL and an SQLite error code returned.
*/
#ifdef SQLITE_ENABLE_STAT4
static int valueFromFunction(
  sqlite3 *db,                    /* The database connection */
  const Expr *p,                  /* The expression to evaluate */
  u8 enc,                         /* Encoding to use */
  u8 aff,                         /* Affinity to use */
  sqlite3_value **ppVal,          /* Write the new value here */
  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
){
  sqlite3_context ctx;            /* Context object for function invocation */
  sqlite3_value **apVal = 0;      /* Function arguments */
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
** If pCtx is NULL and an error occurs after the sqlite3_value object
** has been allocated, it is freed before returning. Or, if pCtx is not
** NULL, it is assumed that the caller will free any allocated object
** in all cases.
*/
static int valueFromExpr(
  sqlite3 *db,                    /* The database connection */
  Expr *pExpr,                    /* The expression to evaluate */
  u8 enc,                         /* Encoding to use */
  u8 affinity,                    /* Affinity to use */
  sqlite3_value **ppVal,          /* Write the new value here */
  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
){
  int op;
  char *zVal = 0;







|







1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
** If pCtx is NULL and an error occurs after the sqlite3_value object
** has been allocated, it is freed before returning. Or, if pCtx is not
** NULL, it is assumed that the caller will free any allocated object
** in all cases.
*/
static int valueFromExpr(
  sqlite3 *db,                    /* The database connection */
  const Expr *pExpr,              /* The expression to evaluate */
  u8 enc,                         /* Encoding to use */
  u8 affinity,                    /* Affinity to use */
  sqlite3_value **ppVal,          /* Write the new value here */
  struct ValueNewStat4Ctx *pCtx   /* Second argument for valueNew() */
){
  int op;
  char *zVal = 0;
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
** be converted directly into a value, then the value is allocated and
** a pointer written to *ppVal. The caller is responsible for deallocating
** the value by passing it to sqlite3ValueFree() later on. If the expression
** cannot be converted to a value, then *ppVal is set to NULL.
*/
int sqlite3ValueFromExpr(
  sqlite3 *db,              /* The database connection */
  Expr *pExpr,              /* The expression to evaluate */
  u8 enc,                   /* Encoding to use */
  u8 affinity,              /* Affinity to use */
  sqlite3_value **ppVal     /* Write the new value here */
){
  return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
}








|







1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
** be converted directly into a value, then the value is allocated and
** a pointer written to *ppVal. The caller is responsible for deallocating
** the value by passing it to sqlite3ValueFree() later on. If the expression
** cannot be converted to a value, then *ppVal is set to NULL.
*/
int sqlite3ValueFromExpr(
  sqlite3 *db,              /* The database connection */
  const Expr *pExpr,        /* The expression to evaluate */
  u8 enc,                   /* Encoding to use */
  u8 affinity,              /* Affinity to use */
  sqlite3_value **ppVal     /* Write the new value here */
){
  return pExpr ? valueFromExpr(db, pExpr, enc, affinity, ppVal, 0) : 0;
}

Changes to src/vdbetrace.c.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  int nToken;              /* Length of the parameter token */
  int i;                   /* Loop counter */
  Mem *pVar;               /* Value of a host parameter */
  StrAccum out;            /* Accumulate the output here */
#ifndef SQLITE_OMIT_UTF16
  Mem utf8;                /* Used to convert UTF16 into UTF8 for display */
#endif
  char zBase[100];         /* Initial working space */

  db = p->db;
  sqlite3StrAccumInit(&out, 0, zBase, sizeof(zBase), 
                      db->aLimit[SQLITE_LIMIT_LENGTH]);
  if( db->nVdbeExec>1 ){
    while( *zRawSql ){
      const char *zStart = zRawSql;
      while( *(zRawSql++)!='\n' && *zRawSql );
      sqlite3_str_append(&out, "-- ", 3);
      assert( (zRawSql - zStart) > 0 );
      sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));







<


|
<







80
81
82
83
84
85
86

87
88
89

90
91
92
93
94
95
96
  int nToken;              /* Length of the parameter token */
  int i;                   /* Loop counter */
  Mem *pVar;               /* Value of a host parameter */
  StrAccum out;            /* Accumulate the output here */
#ifndef SQLITE_OMIT_UTF16
  Mem utf8;                /* Used to convert UTF16 into UTF8 for display */
#endif


  db = p->db;
  sqlite3StrAccumInit(&out, 0, 0, 0, db->aLimit[SQLITE_LIMIT_LENGTH]);

  if( db->nVdbeExec>1 ){
    while( *zRawSql ){
      const char *zStart = zRawSql;
      while( *(zRawSql++)!='\n' && *zRawSql );
      sqlite3_str_append(&out, "-- ", 3);
      assert( (zRawSql - zStart) > 0 );
      sqlite3_str_append(&out, zStart, (int)(zRawSql-zStart));
Changes to src/vtab.c.
797
798
799
800
801
802
803

804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822






823
824
825
826
827
828
829
*/
int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
  VtabCtx *pCtx;
  int rc = SQLITE_OK;
  Table *pTab;
  char *zErr = 0;
  Parse sParse;


#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
    return SQLITE_MISUSE_BKPT;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pCtx = db->pVtabCtx;
  if( !pCtx || pCtx->bDeclared ){
    sqlite3Error(db, SQLITE_MISUSE);
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_MISUSE_BKPT;
  }
  pTab = pCtx->pTab;
  assert( IsVirtual(pTab) );

  memset(&sParse, 0, sizeof(sParse));
  sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
  sParse.db = db;






  sParse.nQueryLoop = 1;
  if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) 
   && sParse.pNewTable
   && !db->mallocFailed
   && IsOrdinaryTable(sParse.pNewTable)
  ){
    if( !pTab->aCol ){







>



















>
>
>
>
>
>







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
*/
int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){
  VtabCtx *pCtx;
  int rc = SQLITE_OK;
  Table *pTab;
  char *zErr = 0;
  Parse sParse;
  int initBusy;

#ifdef SQLITE_ENABLE_API_ARMOR
  if( !sqlite3SafetyCheckOk(db) || zCreateTable==0 ){
    return SQLITE_MISUSE_BKPT;
  }
#endif
  sqlite3_mutex_enter(db->mutex);
  pCtx = db->pVtabCtx;
  if( !pCtx || pCtx->bDeclared ){
    sqlite3Error(db, SQLITE_MISUSE);
    sqlite3_mutex_leave(db->mutex);
    return SQLITE_MISUSE_BKPT;
  }
  pTab = pCtx->pTab;
  assert( IsVirtual(pTab) );

  memset(&sParse, 0, sizeof(sParse));
  sParse.eParseMode = PARSE_MODE_DECLARE_VTAB;
  sParse.db = db;
  /* We should never be able to reach this point while loading the
  ** schema.  Nevertheless, defend against that (turn off db->init.busy)
  ** in case a bug arises. */
  assert( db->init.busy==0 );
  initBusy = db->init.busy;
  db->init.busy = 0;
  sParse.nQueryLoop = 1;
  if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable, &zErr) 
   && sParse.pNewTable
   && !db->mallocFailed
   && IsOrdinaryTable(sParse.pNewTable)
  ){
    if( !pTab->aCol ){
862
863
864
865
866
867
868

869
870
871
872
873
874
875
  sParse.eParseMode = PARSE_MODE_NORMAL;

  if( sParse.pVdbe ){
    sqlite3VdbeFinalize(sParse.pVdbe);
  }
  sqlite3DeleteTable(db, sParse.pNewTable);
  sqlite3ParserReset(&sParse);


  assert( (rc&0xff)==rc );
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}








>







869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
  sParse.eParseMode = PARSE_MODE_NORMAL;

  if( sParse.pVdbe ){
    sqlite3VdbeFinalize(sParse.pVdbe);
  }
  sqlite3DeleteTable(db, sParse.pNewTable);
  sqlite3ParserReset(&sParse);
  db->init.busy = initBusy;

  assert( (rc&0xff)==rc );
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}

Changes to src/where.c.
2007
2008
2009
2010
2011
2012
2013
2014

2015
2016
2017
2018
2019
2020
2021
    sqlite3DbFree(pWInfo->pParse->db, p);
  }
}

/*
** Return TRUE if all of the following are true:
**
**   (1)  X has the same or lower cost that Y

**   (2)  X uses fewer WHERE clause terms than Y
**   (3)  Every WHERE clause term used by X is also used by Y
**   (4)  X skips at least as many columns as Y
**   (5)  If X is a covering index, than Y is too
**
** Conditions (2) and (3) mean that X is a "proper subset" of Y.
** If X is a proper subset of Y then Y is a better choice and ought







|
>







2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
    sqlite3DbFree(pWInfo->pParse->db, p);
  }
}

/*
** Return TRUE if all of the following are true:
**
**   (1)  X has the same or lower cost, or returns the same or fewer rows, 
**        than Y.
**   (2)  X uses fewer WHERE clause terms than Y
**   (3)  Every WHERE clause term used by X is also used by Y
**   (4)  X skips at least as many columns as Y
**   (5)  If X is a covering index, than Y is too
**
** Conditions (2) and (3) mean that X is a "proper subset" of Y.
** If X is a proper subset of Y then Y is a better choice and ought
2030
2031
2032
2033
2034
2035
2036

2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079


2080
2081
2082
2083
2084
2085
2086


2087
2088
2089
2090
2091
2092
2093
2094
2095
  const WhereLoop *pX,       /* First WhereLoop to compare */
  const WhereLoop *pY        /* Compare against this WhereLoop */
){
  int i, j;
  if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
    return 0; /* X is not a subset of Y */
  }

  if( pY->nSkip > pX->nSkip ) return 0;
  if( pX->rRun >= pY->rRun ){
    if( pX->rRun > pY->rRun ) return 0;    /* X costs more than Y */
    if( pX->nOut > pY->nOut ) return 0;    /* X costs more than Y */
  }
  for(i=pX->nLTerm-1; i>=0; i--){
    if( pX->aLTerm[i]==0 ) continue;
    for(j=pY->nLTerm-1; j>=0; j--){
      if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
    }
    if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
  }
  if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 
   && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
    return 0;  /* Constraint (5) */
  }
  return 1;  /* All conditions meet */
}

/*
** Try to adjust the cost of WhereLoop pTemplate upwards or downwards so
** that:
**
**   (1) pTemplate costs less than any other WhereLoops that are a proper
**       subset of pTemplate
**
**   (2) pTemplate costs more than any other WhereLoops for which pTemplate
**       is a proper subset.
**
** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
** WHERE clause terms than Y and that every WHERE clause term used by X is
** also used by Y.
*/
static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
  if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return;
  for(; p; p=p->pNextLoop){
    if( p->iTab!=pTemplate->iTab ) continue;
    if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
    if( whereLoopCheaperProperSubset(p, pTemplate) ){
      /* Adjust pTemplate cost downward so that it is cheaper than its 
      ** subset p. */
      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
                       pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut-1));


      pTemplate->rRun = p->rRun;
      pTemplate->nOut = p->nOut - 1;
    }else if( whereLoopCheaperProperSubset(pTemplate, p) ){
      /* Adjust pTemplate cost upward so that it is costlier than p since
      ** pTemplate is a proper subset of p */
      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
                       pTemplate->rRun, pTemplate->nOut, p->rRun, p->nOut+1));


      pTemplate->rRun = p->rRun;
      pTemplate->nOut = p->nOut + 1;
    }
  }
}

/*
** Search the list of WhereLoops in *ppPrev looking for one that can be
** replaced by pTemplate.







>

<
<
<
<















|
|




















|
>
>
|
|




|
>
>
|
|







2031
2032
2033
2034
2035
2036
2037
2038
2039




2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
  const WhereLoop *pX,       /* First WhereLoop to compare */
  const WhereLoop *pY        /* Compare against this WhereLoop */
){
  int i, j;
  if( pX->nLTerm-pX->nSkip >= pY->nLTerm-pY->nSkip ){
    return 0; /* X is not a subset of Y */
  }
  if( pX->rRun>pY->rRun && pX->nOut>pY->nOut ) return 0;
  if( pY->nSkip > pX->nSkip ) return 0;




  for(i=pX->nLTerm-1; i>=0; i--){
    if( pX->aLTerm[i]==0 ) continue;
    for(j=pY->nLTerm-1; j>=0; j--){
      if( pY->aLTerm[j]==pX->aLTerm[i] ) break;
    }
    if( j<0 ) return 0;  /* X not a subset of Y since term X[i] not used by Y */
  }
  if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 
   && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){
    return 0;  /* Constraint (5) */
  }
  return 1;  /* All conditions meet */
}

/*
** Try to adjust the cost and number of output rows of WhereLoop pTemplate
** upwards or downwards so that:
**
**   (1) pTemplate costs less than any other WhereLoops that are a proper
**       subset of pTemplate
**
**   (2) pTemplate costs more than any other WhereLoops for which pTemplate
**       is a proper subset.
**
** To say "WhereLoop X is a proper subset of Y" means that X uses fewer
** WHERE clause terms than Y and that every WHERE clause term used by X is
** also used by Y.
*/
static void whereLoopAdjustCost(const WhereLoop *p, WhereLoop *pTemplate){
  if( (pTemplate->wsFlags & WHERE_INDEXED)==0 ) return;
  for(; p; p=p->pNextLoop){
    if( p->iTab!=pTemplate->iTab ) continue;
    if( (p->wsFlags & WHERE_INDEXED)==0 ) continue;
    if( whereLoopCheaperProperSubset(p, pTemplate) ){
      /* Adjust pTemplate cost downward so that it is cheaper than its 
      ** subset p. */
      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
                       pTemplate->rRun, pTemplate->nOut, 
                       MIN(p->rRun, pTemplate->rRun),
                       MIN(p->nOut - 1, pTemplate->nOut)));
      pTemplate->rRun = MIN(p->rRun, pTemplate->rRun);
      pTemplate->nOut = MIN(p->nOut - 1, pTemplate->nOut);
    }else if( whereLoopCheaperProperSubset(pTemplate, p) ){
      /* Adjust pTemplate cost upward so that it is costlier than p since
      ** pTemplate is a proper subset of p */
      WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n",
                       pTemplate->rRun, pTemplate->nOut, 
                       MAX(p->rRun, pTemplate->rRun),
                       MAX(p->nOut + 1, pTemplate->nOut)));
      pTemplate->rRun = MAX(p->rRun, pTemplate->rRun);
      pTemplate->nOut = MAX(p->nOut + 1, pTemplate->nOut);
    }
  }
}

/*
** Search the list of WhereLoops in *ppPrev looking for one that can be
** replaced by pTemplate.
4588
4589
4590
4591
4592
4593
4594

4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610

4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627

4628
4629
4630
4631
4632
4633
4634
  WhereClause *pWC;
  WhereTerm *pTerm;
  WhereLoop *pLoop;
  int iCur;
  int j;
  Table *pTab;
  Index *pIdx;


  pWInfo = pBuilder->pWInfo;
  if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
  assert( pWInfo->pTabList->nSrc>=1 );
  pItem = pWInfo->pTabList->a;
  pTab = pItem->pTab;
  if( IsVirtual(pTab) ) return 0;
  if( pItem->fg.isIndexedBy ) return 0;
  iCur = pItem->iCursor;
  pWC = &pWInfo->sWC;
  pLoop = pBuilder->pNew;
  pLoop->wsFlags = 0;
  pLoop->nSkip = 0;
  pTerm = sqlite3WhereFindTerm(pWC, iCur, -1, 0, WO_EQ|WO_IS, 0);
  if( pTerm ){
    testcase( pTerm->eOperator & WO_IS );

    pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
    pLoop->aLTerm[0] = pTerm;
    pLoop->nLTerm = 1;
    pLoop->u.btree.nEq = 1;
    /* TUNING: Cost of a rowid lookup is 10 */
    pLoop->rRun = 33;  /* 33==sqlite3LogEst(10) */
  }else{
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int opMask;
      assert( pLoop->aLTermSpace==pLoop->aLTerm );
      if( !IsUniqueIndex(pIdx)
       || pIdx->pPartIdxWhere!=0 
       || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) 
      ) continue;
      opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ;
      for(j=0; j<pIdx->nKeyCol; j++){
        pTerm = sqlite3WhereFindTerm(pWC, iCur, j, 0, opMask, pIdx);

        if( pTerm==0 ) break;
        testcase( pTerm->eOperator & WO_IS );
        pLoop->aLTerm[j] = pTerm;
      }
      if( j!=pIdx->nKeyCol ) continue;
      pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
      if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){







>













|


>
















|
>







4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
  WhereClause *pWC;
  WhereTerm *pTerm;
  WhereLoop *pLoop;
  int iCur;
  int j;
  Table *pTab;
  Index *pIdx;
  WhereScan scan;

  pWInfo = pBuilder->pWInfo;
  if( pWInfo->wctrlFlags & WHERE_OR_SUBCLAUSE ) return 0;
  assert( pWInfo->pTabList->nSrc>=1 );
  pItem = pWInfo->pTabList->a;
  pTab = pItem->pTab;
  if( IsVirtual(pTab) ) return 0;
  if( pItem->fg.isIndexedBy ) return 0;
  iCur = pItem->iCursor;
  pWC = &pWInfo->sWC;
  pLoop = pBuilder->pNew;
  pLoop->wsFlags = 0;
  pLoop->nSkip = 0;
  pTerm = whereScanInit(&scan, pWC, iCur, -1, WO_EQ|WO_IS, 0);
  if( pTerm ){
    testcase( pTerm->eOperator & WO_IS );
    assert( pTerm->prereqRight==0 );
    pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_IPK|WHERE_ONEROW;
    pLoop->aLTerm[0] = pTerm;
    pLoop->nLTerm = 1;
    pLoop->u.btree.nEq = 1;
    /* TUNING: Cost of a rowid lookup is 10 */
    pLoop->rRun = 33;  /* 33==sqlite3LogEst(10) */
  }else{
    for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){
      int opMask;
      assert( pLoop->aLTermSpace==pLoop->aLTerm );
      if( !IsUniqueIndex(pIdx)
       || pIdx->pPartIdxWhere!=0 
       || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) 
      ) continue;
      opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ;
      for(j=0; j<pIdx->nKeyCol; j++){
        pTerm = whereScanInit(&scan, pWC, iCur, j, opMask, pIdx);
        while( pTerm && pTerm->prereqRight ) pTerm = whereScanNext(&scan);
        if( pTerm==0 ) break;
        testcase( pTerm->eOperator & WO_IS );
        pLoop->aLTerm[j] = pTerm;
      }
      if( j!=pIdx->nKeyCol ) continue;
      pLoop->wsFlags = WHERE_COLUMN_EQ|WHERE_ONEROW|WHERE_INDEXED;
      if( pIdx->isCovering || (pItem->colUsed & pIdx->colNotIdxed)==0 ){
4649
4650
4651
4652
4653
4654
4655

4656
4657





4658
4659
4660
4661
4662
4663
4664
    pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
    pWInfo->a[0].iTabCur = iCur;
    pWInfo->nRowOut = 1;
    if( pWInfo->pOrderBy ) pWInfo->nOBSat =  pWInfo->pOrderBy->nExpr;
    if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
    }

#ifdef SQLITE_DEBUG
    pLoop->cId = '0';





#endif
    return 1;
  }
  return 0;
}

/*







>


>
>
>
>
>







4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
    pLoop->maskSelf = 1; /* sqlite3WhereGetMask(&pWInfo->sMaskSet, iCur); */
    pWInfo->a[0].iTabCur = iCur;
    pWInfo->nRowOut = 1;
    if( pWInfo->pOrderBy ) pWInfo->nOBSat =  pWInfo->pOrderBy->nExpr;
    if( pWInfo->wctrlFlags & WHERE_WANT_DISTINCT ){
      pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
    }
    if( scan.iEquiv>1 ) pLoop->wsFlags |= WHERE_TRANSCONS;
#ifdef SQLITE_DEBUG
    pLoop->cId = '0';
#endif
#ifdef WHERETRACE_ENABLED
    if( sqlite3WhereTrace ){
      sqlite3DebugPrintf("whereShortCut() used to compute solution\n");
    }
#endif
    return 1;
  }
  return 0;
}

/*
Changes to src/wherecode.c.
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
    iReleaseReg = ++pParse->nMem;
    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
    if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
    addrNxt = pLevel->addrNxt;
    sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
    VdbeCoverage(v);
    pLevel->op = OP_Noop;
    if( (pTerm->prereqAll & pLevel->notReady)==0 ){
      pTerm->wtFlags |= TERM_CODED;
    }
  }else if( (pLoop->wsFlags & WHERE_IPK)!=0
         && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
  ){
    /* Case 3:  We have an inequality comparison against the ROWID field.
    */
    int testOp = OP_Noop;
    int start;







<
<
<







1496
1497
1498
1499
1500
1501
1502



1503
1504
1505
1506
1507
1508
1509
    iReleaseReg = ++pParse->nMem;
    iRowidReg = codeEqualityTerm(pParse, pTerm, pLevel, 0, bRev, iReleaseReg);
    if( iRowidReg!=iReleaseReg ) sqlite3ReleaseTempReg(pParse, iReleaseReg);
    addrNxt = pLevel->addrNxt;
    sqlite3VdbeAddOp3(v, OP_SeekRowid, iCur, addrNxt, iRowidReg);
    VdbeCoverage(v);
    pLevel->op = OP_Noop;



  }else if( (pLoop->wsFlags & WHERE_IPK)!=0
         && (pLoop->wsFlags & WHERE_COLUMN_RANGE)!=0
  ){
    /* Case 3:  We have an inequality comparison against the ROWID field.
    */
    int testOp = OP_Noop;
    int start;
Changes to src/whereexpr.c.
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
        **    2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
        **    2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
        **    2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
        **    2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
        */
        if( pLeft->op!=TK_COLUMN 
         || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
         || IsVirtual(pLeft->y.pTab)  /* Value might be numeric */
        ){
          int isNum;
          double rDummy;
          isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
          if( isNum<=0 ){
            if( iTo==1 && zNew[0]=='-' ){
              isNum = +1;







|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
        **    2019-05-02 https://sqlite.org/src/info/b043a54c3de54b28
        **    2019-06-10 https://sqlite.org/src/info/fd76310a5e843e07
        **    2019-06-14 https://sqlite.org/src/info/ce8717f0885af975
        **    2019-09-03 https://sqlite.org/src/info/0f0428096f17252a
        */
        if( pLeft->op!=TK_COLUMN 
         || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT 
         || (pLeft->y.pTab && IsVirtual(pLeft->y.pTab))  /* Might be numeric */
        ){
          int isNum;
          double rDummy;
          isNum = sqlite3AtoF(zNew, &rDummy, iTo, SQLITE_UTF8);
          if( isNum<=0 ){
            if( iTo==1 && zNew[0]=='-' ){
              isNum = +1;
Changes to src/window.c.
1062
1063
1064
1065
1066
1067
1068



1069
1070
1071
1072
1073
1074
1075
    pSub = sqlite3SelectNew(
        pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
    );
    SELECTTRACE(1,pParse,pSub,
       ("New window-function subquery in FROM clause of (%u/%p)\n",
       p->selId, p));
    p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);



    if( p->pSrc ){
      Table *pTab2;
      p->pSrc->a[0].pSelect = pSub;
      sqlite3SrcListAssignCursors(pParse, p->pSrc);
      pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
      pSub->selFlags |= (selFlags & SF_Aggregate);







>
>
>







1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
    pSub = sqlite3SelectNew(
        pParse, pSublist, pSrc, pWhere, pGroupBy, pHaving, pSort, 0, 0
    );
    SELECTTRACE(1,pParse,pSub,
       ("New window-function subquery in FROM clause of (%u/%p)\n",
       p->selId, p));
    p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
    assert( pSub!=0 || p->pSrc==0 ); /* Due to db->mallocFailed test inside
                                     ** of sqlite3DbMallocRawNN() called from
                                     ** sqlite3SrcListAppend() */
    if( p->pSrc ){
      Table *pTab2;
      p->pSrc->a[0].pSelect = pSub;
      sqlite3SrcListAssignCursors(pParse, p->pSrc);
      pSub->selFlags |= SF_Expanded|SF_OrderByReqd;
      pTab2 = sqlite3ResultSetOfSelect(pParse, pSub, SQLITE_AFF_NONE);
      pSub->selFlags |= (selFlags & SF_Aggregate);
1338
1339
1340
1341
1342
1343
1344
1345





1346
1347
1348
1349
1350
1351
1352
}

/*
** Return 0 if the two window objects are identical, 1 if they are
** different, or 2 if it cannot be determined if the objects are identical
** or not. Identical window objects can be processed in a single scan.
*/
int sqlite3WindowCompare(Parse *pParse, Window *p1, Window *p2, int bFilter){





  int res;
  if( NEVER(p1==0) || NEVER(p2==0) ) return 1;
  if( p1->eFrmType!=p2->eFrmType ) return 1;
  if( p1->eStart!=p2->eStart ) return 1;
  if( p1->eEnd!=p2->eEnd ) return 1;
  if( p1->eExclude!=p2->eExclude ) return 1;
  if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;







|
>
>
>
>
>







1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
}

/*
** Return 0 if the two window objects are identical, 1 if they are
** different, or 2 if it cannot be determined if the objects are identical
** or not. Identical window objects can be processed in a single scan.
*/
int sqlite3WindowCompare(
  const Parse *pParse,
  const Window *p1,
  const Window *p2,
  int bFilter
){
  int res;
  if( NEVER(p1==0) || NEVER(p2==0) ) return 1;
  if( p1->eFrmType!=p2->eFrmType ) return 1;
  if( p1->eStart!=p2->eStart ) return 1;
  if( p1->eEnd!=p2->eEnd ) return 1;
  if( p1->eExclude!=p2->eExclude ) return 1;
  if( sqlite3ExprCompare(pParse, p1->pStart, p2->pStart, -1) ) return 1;
Changes to test/altercorrupt.test.
9
10
11
12
13
14
15






16
17
18
19
20
21
22
#
#***********************************************************************
#

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







database_may_be_corrupt

#--------------------------------------------------------------------------
reset_db
do_test 1.0 {
  sqlite3 db {}







>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#
#***********************************************************************
#

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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

database_may_be_corrupt

#--------------------------------------------------------------------------
reset_db
do_test 1.0 {
  sqlite3 db {}
Changes to test/altermalloc3.test.
39
40
41
42
43
44
45































46
47
  faultsim_restore_and_reopen
} -body {
  execsql { ALTER TABLE t1 DROP COLUMN c }
} -test {
  faultsim_test_result {0 {}}
}

































finish_test







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


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
  faultsim_restore_and_reopen
} -body {
  execsql { ALTER TABLE t1 DROP COLUMN c }
} -test {
  faultsim_test_result {0 {}}
}

#-------------------------------------------------------------------------
# dbsqlfuzz e3dd84cda3848016a6a6024c7249d09bc2ef2615
#
reset_db
do_execsql_test 2.0 {
  CREATE TABLE t2(k,v);
  CREATE TRIGGER r2 AFTER INSERT ON t2 BEGIN
    UPDATE t2 SET (k,v)= (
       (WITH cte1(a) AS ( SELECT 1 FROM ( SELECT * FROM t2 ) )
       SELECT a FROM cte1
    ), 1);
  END;
}

faultsim_save_and_close
faultsim_restore_and_reopen

do_execsql_test 2.1 {
  ALTER TABLE t2 RENAME TO t2x;
}

do_faultsim_test 2.2 -prep {
  faultsim_restore_and_reopen
  db eval { SELECT * FROM sqlite_master } 
} -body {
  execsql {
    ALTER TABLE t2 RENAME TO t2x;
  }
} -test {
  faultsim_test_result {0 {}}
}

finish_test
Changes to test/alterqf.test.
12
13
14
15
16
17
18







19
20
21
22
23
24
25
# script focuses on testing internal function sqlite_rename_quotefix().
#


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








sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
}








>
>
>
>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# script focuses on testing internal function sqlite_rename_quotefix().
#


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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}


sqlite3_test_control SQLITE_TESTCTRL_INTERNAL_FUNCTIONS db

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
}

Changes to test/altertab3.test.
643
644
645
646
647
648
649






































650
651
     UPDATE t1 SET xx=xx FROM(SELECT xx);
  END;
} {}
do_catchsql_test 26.6 {
  ALTER TABLE t1 RENAME TO t2;
} {1 {error in trigger xx: ambiguous column name: xx}}








































finish_test







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


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
     UPDATE t1 SET xx=xx FROM(SELECT xx);
  END;
} {}
do_catchsql_test 26.6 {
  ALTER TABLE t1 RENAME TO t2;
} {1 {error in trigger xx: ambiguous column name: xx}}


#-------------------------------------------------------------------------
reset_db

do_execsql_test 27.1 {
  CREATE TABLE t1(a, b AS ((WITH w1 (xyz) AS  ( SELECT t1.b FROM t1 )  SELECT 123) IN ()), c);
}

do_execsql_test 27.2 {
  ALTER TABLE t1 DROP COLUMN c;
  SELECT sql FROM sqlite_schema WHERE name = 't1';
} {
  {CREATE TABLE t1(a, b AS ((WITH w1 (xyz) AS  ( SELECT t1.b FROM t1 )  SELECT 123) IN ()))}
}

do_execsql_test 27.3 {
  CREATE TABLE t0(c0 , c1 AS (CASE TRUE   NOT IN () WHEN NULL   THEN CASE + 0xa     ISNULL  WHEN NOT + 0x9     THEN t0.c1  ELSE CURRENT_TIME   LIKE CAST (t0.c1 REGEXP '-([1-9]\d*.\d*|0\.\d*[1-9]\d*)'ESCAPE (c1) COLLATE BINARY  BETWEEN c1  AND c1   NOT IN (WITH t4 (c0) AS  (WITH t3 (c0) AS NOT MATERIALIZED  (WITH RECURSIVE t2 (c0) AS  (WITH RECURSIVE t1 AS  (VALUES (x'717171ff71717171' )  )  SELECT DISTINCT t0.c0  FROM t0 NOT INDEXED  WHERE t0.c0 =t0.c0 GROUP BY 0x9      )  SELECT DISTINCT t0.c0  FROM t0 NOT INDEXED  WHERE t0.c0 =t0.c1   )  SELECT DISTINCT t0.c0  FROM t0 NOT INDEXED  WHERE t0.c0 =t0.c0 GROUP BY typeof(0x9   )    )  SELECT DISTINCT t0.c0  FROM t0 NOT INDEXED  WHERE t0.c0 =t0.c0 GROUP BY typeof(typeof(0x9    )  )    ) IN t0   BETWEEN typeof(typeof(typeof(hex(*) FILTER (WHERE + x'5ccd1e68'   )  )  )  )  AND 1   >0xa      AS BLOB (+4.4E4 , -0xe  ) )  END  <> c1  IN ()  END  ) VIRTUAL   , c35 PRIMARY KEY   ,  c60 , c64 NUMERIC (-6.8 , -0xE  )  ) WITHOUT ROWID ;
} {}

do_execsql_test 27.4 {
  ALTER TABLE t0 DROP COLUMN c60;
} {}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 28.1 {
  CREATE TABLE t1(a,b,c,d);
  CREATE TRIGGER AFTER INSERT ON t1 BEGIN
    UPDATE t1 SET (c,d)=(a,b);
  END;
  ALTER TABLE t1 RENAME TO t2;
}

do_execsql_test 28.2 {
  SELECT sql FROM sqlite_schema WHERE type='trigger'
} {{CREATE TRIGGER AFTER INSERT ON "t2" BEGIN
    UPDATE "t2" SET (c,d)=(a,b);
  END}}

finish_test
Changes to test/analyze4.test.
15
16
17
18
19
20
21






22
23
24
25
26
27
28
# statistics.
#
# Also include test cases for collating sequences on indices.
#

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







do_test analyze4-1.0 {
  db eval {
    CREATE TABLE t1(a,b);
    CREATE INDEX t1a ON t1(a);
    CREATE INDEX t1b ON t1(b);
    INSERT INTO t1 VALUES(1,NULL);







>
>
>
>
>
>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# statistics.
#
# Also include test cases for collating sequences on indices.
#

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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

do_test analyze4-1.0 {
  db eval {
    CREATE TABLE t1(a,b);
    CREATE INDEX t1a ON t1(a);
    CREATE INDEX t1b ON t1(b);
    INSERT INTO t1 VALUES(1,NULL);
Changes to test/auth3.test.
111
112
113
114
115
116
117

118
119
120
121
122
123
124
125
126
127
128
129
130

131
132
  set sqlite_search_count
} {1}

# 2016-07-28.  A problem report from a private client complaining about
# an authorizer failure during an ALTER TABLE.  The solution (I think) is
# to disable the authorizer during schema parsing.
#

proc auth {code args} {
  if {$code=="SQLITE_READ" && [regexp {DoNotRead} $args]} {
    return SQLITE_DENY
  }
  return SQLITE_OK
}
do_execsql_test auth3-3.0 {
  CREATE TEMPORARY TABLE TempTable (
      key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,
      value TEXT NOT NULL ON CONFLICT FAIL);
  ALTER TABLE TempTable RENAME TO DoNotRead;
  SELECT name FROM temp.sqlite_master;
} {DoNotRead sqlite_autoindex_DoNotRead_1}


finish_test







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


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  set sqlite_search_count
} {1}

# 2016-07-28.  A problem report from a private client complaining about
# an authorizer failure during an ALTER TABLE.  The solution (I think) is
# to disable the authorizer during schema parsing.
#
ifcapable altertable {
  proc auth {code args} {
    if {$code=="SQLITE_READ" && [regexp {DoNotRead} $args]} {
      return SQLITE_DENY
    }
    return SQLITE_OK
  }
  do_execsql_test auth3-3.0 {
    CREATE TEMPORARY TABLE TempTable (
        key TEXT NOT NULL ON CONFLICT FAIL UNIQUE ON CONFLICT REPLACE,
        value TEXT NOT NULL ON CONFLICT FAIL);
    ALTER TABLE TempTable RENAME TO DoNotRead;
    SELECT name FROM temp.sqlite_master;
  } {DoNotRead sqlite_autoindex_DoNotRead_1}
}

finish_test
Changes to test/columncount.test.
11
12
13
14
15
16
17






18
19
20
21
22
23
24
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite3_column_count() API.
#

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







proc do_ccsql_test {tn sql res} {

  uplevel [list do_test $tn [subst -nocommands {
    set stmt [sqlite3_prepare_v2 db {$sql} -1 dummy]
    set res [sqlite3_column_count [set stmt]]
    while {[sqlite3_step [set stmt]]=="SQLITE_ROW"} {







>
>
>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# This file implements regression tests for SQLite library.  The
# focus of this file is testing the sqlite3_column_count() API.
#

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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

proc do_ccsql_test {tn sql res} {

  uplevel [list do_test $tn [subst -nocommands {
    set stmt [sqlite3_prepare_v2 db {$sql} -1 dummy]
    set res [sqlite3_column_count [set stmt]]
    while {[sqlite3_step [set stmt]]=="SQLITE_ROW"} {
Changes to test/corruptL.test.
1175
1176
1177
1178
1179
1180
1181


1182
1183
1184

1185
1186
1187
1188
1189
1190
1191
}]} {}

extra_schema_checks 0
do_catchsql_test 14.1 {
  PRAGMA integrity_check;
} {1 {database disk image is malformed}}



do_catchsql_test 14.2 {
  ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s; 
} {1 {database disk image is malformed}}

extra_schema_checks 1

#-------------------------------------------------------------------------
reset_db
do_test 15.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {







>
>
|
|
|
>







1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
}]} {}

extra_schema_checks 0
do_catchsql_test 14.1 {
  PRAGMA integrity_check;
} {1 {database disk image is malformed}}

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable altertable {
  do_catchsql_test 14.2 {
    ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s; 
  } {1 {database disk image is malformed}}
}
extra_schema_checks 1

#-------------------------------------------------------------------------
reset_db
do_test 15.0 {
  sqlite3 db {}
  db deserialize [decode_hexdb {
Changes to test/e_changes.test.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  uplevel [list \
    do_test $tn "concat \[execsql {$sql}\] \[db changes\]" $res
  ]
}


#--------------------------------------------------------------------------
# EVIDENCE-OF: R-15996-49369 This function returns the number of rows
# modified, inserted or deleted by the most recently completed INSERT,
# UPDATE or DELETE statement on the database connection specified by the
# only parameter.
#
do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
  CREATE INDEX i1 ON t1(a);
  CREATE INDEX i2 ON t2(y);
}







|
|
|
|







21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
  uplevel [list \
    do_test $tn "concat \[execsql {$sql}\] \[db changes\]" $res
  ]
}


#--------------------------------------------------------------------------
# EVIDENCE-OF: R-58361-29089 The changes() function returns the number
# of database rows that were changed or inserted or deleted by the most
# recently completed INSERT, DELETE, or UPDATE statement, exclusive of
# statements in lower-level triggers.
#
do_execsql_test 1.0 {
  CREATE TABLE t1(a, b);
  CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
  CREATE INDEX i1 ON t1(a);
  CREATE INDEX i2 ON t2(y);
}
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
  do_test 1.$tn.11 { db changes } 0
  do_changes_test 1.$tn.12 COMMIT 0

}


#--------------------------------------------------------------------------
# EVIDENCE-OF: R-44877-05564 Executing any other type of SQL statement
# does not modify the value returned by this function.
#
reset_db
do_changes_test 2.1 { CREATE TABLE t1(x)          } 0
do_changes_test 2.2 { 
  WITH d(y) AS (SELECT 1 UNION ALL SELECT y+1 FROM d WHERE y<47)
  INSERT INTO t1 SELECT y FROM d;
} 47

# The statement above set changes() to 47. Check that none of the following
# modify this.
do_changes_test 2.3 { SELECT count(x) FROM t1 } {47 47}
do_changes_test 2.4 { DROP TABLE t1               } 47
do_changes_test 2.5 { CREATE TABLE t1(x)          } 47

do_changes_test 2.6 { ALTER TABLE t1 ADD COLUMN b } 47



#--------------------------------------------------------------------------
# EVIDENCE-OF: R-53938-27527 Only changes made directly by the INSERT,
# UPDATE or DELETE statement are considered - auxiliary changes caused
# by triggers, foreign key actions or REPLACE constraint resolution are
# not counted.







|














>
|
>







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
  do_test 1.$tn.11 { db changes } 0
  do_changes_test 1.$tn.12 COMMIT 0

}


#--------------------------------------------------------------------------
# X-EVIDENCE-OF: R-44877-05564 Executing any other type of SQL statement
# does not modify the value returned by this function.
#
reset_db
do_changes_test 2.1 { CREATE TABLE t1(x)          } 0
do_changes_test 2.2 { 
  WITH d(y) AS (SELECT 1 UNION ALL SELECT y+1 FROM d WHERE y<47)
  INSERT INTO t1 SELECT y FROM d;
} 47

# The statement above set changes() to 47. Check that none of the following
# modify this.
do_changes_test 2.3 { SELECT count(x) FROM t1 } {47 47}
do_changes_test 2.4 { DROP TABLE t1               } 47
do_changes_test 2.5 { CREATE TABLE t1(x)          } 47
ifcapable altertable {
  do_changes_test 2.6 { ALTER TABLE t1 ADD COLUMN b } 47
}


#--------------------------------------------------------------------------
# EVIDENCE-OF: R-53938-27527 Only changes made directly by the INSERT,
# UPDATE or DELETE statement are considered - auxiliary changes caused
# by triggers, foreign key actions or REPLACE constraint resolution are
# not counted.
Changes to test/e_expr.test.
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
db func regexp -argcount 2 regexfunc

#-------------------------------------------------------------------------
# Test cases e_expr-1.* attempt to verify that all binary operators listed
# in the documentation exist and that the relative precedences of the
# operators are also as the documentation suggests.
#
# EVIDENCE-OF: R-15514-65163 SQLite understands the following binary
# operators, in order from highest to lowest precedence: || * / % + -
# << >> & | < <= > >= = == != <> IS IS
# NOT IN LIKE GLOB MATCH REGEXP AND OR
#
# EVIDENCE-OF: R-38759-38789 Operators IS and IS NOT have the same
# precedence as =.
#

unset -nocomplain untested
foreach op1 $oplist {
  foreach op2 $oplist {
    set untested($op1,$op2) 1







|




|







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
db func regexp -argcount 2 regexfunc

#-------------------------------------------------------------------------
# Test cases e_expr-1.* attempt to verify that all binary operators listed
# in the documentation exist and that the relative precedences of the
# operators are also as the documentation suggests.
#
# X-EVIDENCE-OF: R-15514-65163 SQLite understands the following binary
# operators, in order from highest to lowest precedence: || * / % + -
# << >> & | < <= > >= = == != <> IS IS
# NOT IN LIKE GLOB MATCH REGEXP AND OR
#
# X-EVIDENCE-OF: R-38759-38789 Operators IS and IS NOT have the same
# precedence as =.
#

unset -nocomplain untested
foreach op1 $oplist {
  foreach op2 $oplist {
    set untested($op1,$op2) 1
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  SELECT 0 == 0 < 2,   (0 == 0) < 2,   0 == (0 < 2)
} {0 1 0}

#-------------------------------------------------------------------------
# Check that the four unary prefix operators mentioned in the 
# documentation exist.
#
# EVIDENCE-OF: R-13958-53419 Supported unary prefix operators are these:
# - + ~ NOT
#
do_execsql_test e_expr-2.1 { SELECT -   10   } {-10}
do_execsql_test e_expr-2.2 { SELECT +   10   } {10}
do_execsql_test e_expr-2.3 { SELECT ~   10   } {-11}
do_execsql_test e_expr-2.4 { SELECT NOT 10   } {0}








|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
  SELECT 0 == 0 < 2,   (0 == 0) < 2,   0 == (0 < 2)
} {0 1 0}

#-------------------------------------------------------------------------
# Check that the four unary prefix operators mentioned in the 
# documentation exist.
#
# X-EVIDENCE-OF: R-13958-53419 Supported unary prefix operators are these:
# - + ~ NOT
#
do_execsql_test e_expr-2.1 { SELECT -   10   } {-10}
do_execsql_test e_expr-2.2 { SELECT +   10   } {10}
do_execsql_test e_expr-2.3 { SELECT ~   10   } {-11}
do_execsql_test e_expr-2.4 { SELECT NOT 10   } {0}

364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  string compare [reverse_str $zLeft] [reverse_str $zRight]
}
db collate reverse reverse_collate

# EVIDENCE-OF: R-59577-33471 The COLLATE operator is a unary postfix
# operator that assigns a collating sequence to an expression.
#
# EVIDENCE-OF: R-36231-30731 The COLLATE operator has a higher
# precedence (binds more tightly) than any binary operator and any unary
# prefix operator except "~".
#
do_execsql_test e_expr-9.1 { SELECT  'abcd' < 'bbbb'    COLLATE reverse } 0
do_execsql_test e_expr-9.2 { SELECT ('abcd' < 'bbbb')   COLLATE reverse } 1
do_execsql_test e_expr-9.3 { SELECT  'abcd' <= 'bbbb'   COLLATE reverse } 0
do_execsql_test e_expr-9.4 { SELECT ('abcd' <= 'bbbb')  COLLATE reverse } 1







|







364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
  string compare [reverse_str $zLeft] [reverse_str $zRight]
}
db collate reverse reverse_collate

# EVIDENCE-OF: R-59577-33471 The COLLATE operator is a unary postfix
# operator that assigns a collating sequence to an expression.
#
# X-EVIDENCE-OF: R-36231-30731 The COLLATE operator has a higher
# precedence (binds more tightly) than any binary operator and any unary
# prefix operator except "~".
#
do_execsql_test e_expr-9.1 { SELECT  'abcd' < 'bbbb'    COLLATE reverse } 0
do_execsql_test e_expr-9.2 { SELECT ('abcd' < 'bbbb')   COLLATE reverse } 1
do_execsql_test e_expr-9.3 { SELECT  'abcd' <= 'bbbb'   COLLATE reverse } 0
do_execsql_test e_expr-9.4 { SELECT ('abcd' <= 'bbbb')  COLLATE reverse } 1
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
  do_test e_expr-13.1.$tn {
    set ::xcount 0
    set a [execsql "SELECT $expr"]
    list $::xcount $a
  } [list $nEval $res]
}

# EVIDENCE-OF: R-05155-34454 The precedence of the BETWEEN operator is
# the same as the precedence as operators == and != and LIKE and groups
# left to right.
# 
# Therefore, BETWEEN groups more tightly than operator "AND", but less
# so than "<".
#
do_execsql_test e_expr-13.2.1  { SELECT 1 == 10 BETWEEN 0 AND 2   }  1







|







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
  do_test e_expr-13.1.$tn {
    set ::xcount 0
    set a [execsql "SELECT $expr"]
    list $::xcount $a
  } [list $nEval $res]
}

# X-EVIDENCE-OF: R-05155-34454 The precedence of the BETWEEN operator is
# the same as the precedence as operators == and != and LIKE and groups
# left to right.
# 
# Therefore, BETWEEN groups more tightly than operator "AND", but less
# so than "<".
#
do_execsql_test e_expr-13.2.1  { SELECT 1 == 10 BETWEEN 0 AND 2   }  1
Changes to test/e_totalchanges.test.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
  CREATE INDEX t1_b ON t1(b);
  CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
  CREATE INDEX t2_y ON t2(y);
}


#--------------------------------------------------------------------------
# EVIDENCE-OF: R-65438-26258 This function returns the total number of
# rows inserted, modified or deleted by all INSERT, UPDATE or DELETE
# statements completed since the database connection was opened,
# including those executed as part of trigger programs.
#
#   1.1.*: different types of I/U/D statements,
#   1.2.*: trigger programs.
#
do_tc_test 1.1.1 {
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);







|
|
|
<







28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
  CREATE INDEX t1_b ON t1(b);
  CREATE TABLE t2(x, y, PRIMARY KEY(x, y)) WITHOUT ROWID;
  CREATE INDEX t2_y ON t2(y);
}


#--------------------------------------------------------------------------
# EVIDENCE-OF: R-38914-26427 The total_changes() function returns the
# number of row changes caused by INSERT, UPDATE or DELETE statements
# since the current database connection was opened.

#
#   1.1.*: different types of I/U/D statements,
#   1.2.*: trigger programs.
#
do_tc_test 1.1.1 {
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(3, 4);
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
  UPDATE t1 SET b='c';               -- 1 + 1 + 2
  DELETE FROM t1;                    -- 1 + 1 + 1
} {9}

#--------------------------------------------------------------------------
# EVIDENCE-OF: R-61766-15253 Executing any other type of SQL statement
# does not affect the value returned by sqlite3_total_changes().

do_tc_test 2.1 {
  INSERT INTO t1 VALUES(1, 2), (3, 4);
  INSERT INTO t2 VALUES(1, 2), (3, 4);
} {15}
do_tc_test 2.2 {
  SELECT count(*) FROM t1;
} {2 15}
do_tc_test 2.3 {
  CREATE TABLE t4(a, b);
  ALTER TABLE t4 ADD COLUMN c;
  CREATE INDEX i4 ON t4(c);
  ALTER TABLE t4 RENAME TO t5;
  ANALYZE;
  BEGIN;
  DROP TABLE t2;
  ROLLBACK;
  VACUUM;
} {15}



#--------------------------------------------------------------------------
# EVIDENCE-OF: R-36043-10590 Changes made as part of foreign key
# actions are included in the count, but those made as part of REPLACE
# constraint resolution are not.
#







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







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
  UPDATE t1 SET b='c';               -- 1 + 1 + 2
  DELETE FROM t1;                    -- 1 + 1 + 1
} {9}

#--------------------------------------------------------------------------
# EVIDENCE-OF: R-61766-15253 Executing any other type of SQL statement
# does not affect the value returned by sqlite3_total_changes().
ifcapable altertable {
  do_tc_test 2.1 {
    INSERT INTO t1 VALUES(1, 2), (3, 4);
    INSERT INTO t2 VALUES(1, 2), (3, 4);
  } {15}
  do_tc_test 2.2 {
    SELECT count(*) FROM t1;
  } {2 15}
  do_tc_test 2.3 {
    CREATE TABLE t4(a, b);
    ALTER TABLE t4 ADD COLUMN c;
    CREATE INDEX i4 ON t4(c);
    ALTER TABLE t4 RENAME TO t5;
    ANALYZE;
    BEGIN;
    DROP TABLE t2;
    ROLLBACK;
    VACUUM;
  } {15}
}


#--------------------------------------------------------------------------
# EVIDENCE-OF: R-36043-10590 Changes made as part of foreign key
# actions are included in the count, but those made as part of REPLACE
# constraint resolution are not.
#
Changes to test/func.test.
1455
1456
1457
1458
1459
1460
1461


1462
1463
1464
1465
1466
1467

1468
1469
1470
1471
1472
1473
1474
  CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
    INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b);
  END;
} {}
do_catchsql_test func-33.11 {
  INSERT INTO t33a VALUES(1,2);
} {1 {unsafe use of testdirectonly()}}


do_execsql_test func-33.20 {
  ALTER TABLE t33a RENAME COLUMN a TO aaa;
  SELECT sql FROM sqlite_master WHERE name='r1';
} {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
    INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b);
  END}}


# 2020-01-09 Yongheng fuzzer find
# The bug is in the register-validity debug logic, not in the SQLite core
# and as such it only impacts debug builds.  Release builds work fine.
#
reset_db
do_execsql_test func-34.10 {







>
>






>







1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
  CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
    INSERT INTO t33b(x,y) VALUES(testdirectonly(new.a),new.b);
  END;
} {}
do_catchsql_test func-33.11 {
  INSERT INTO t33a VALUES(1,2);
} {1 {unsafe use of testdirectonly()}}

ifcapable altertable {
do_execsql_test func-33.20 {
  ALTER TABLE t33a RENAME COLUMN a TO aaa;
  SELECT sql FROM sqlite_master WHERE name='r1';
} {{CREATE TRIGGER r1 AFTER INSERT ON t33a BEGIN
    INSERT INTO t33b(x,y) VALUES(testdirectonly(new.aaa),new.b);
  END}}
}

# 2020-01-09 Yongheng fuzzer find
# The bug is in the register-validity debug logic, not in the SQLite core
# and as such it only impacts debug builds.  Release builds work fine.
#
reset_db
do_execsql_test func-34.10 {
Changes to test/fuzzdata8.db.

cannot compute difference between binary files

Changes to test/gencol1.test.
583
584
585
586
587
588
589

590
591
592
593
594
595
596
597
598
599
600
601
602
603












604
605
      ON CONFLICT(prim) DO UPDATE SET  b=excluded.b;
  -- Now b is NULL rather than 5
  SELECT * FROM tab;
} {2001-01-01 0 0 5 {}}

# 2021-07-30 forum https://sqlite.org/forum/forumpost/ff3ffe09251c105b?t=h
#

reset_db
do_execsql_test gencol1-21.1 {
  CREATE TABLE t1(
    a integer primary key,
    b int generated always as (a+5),
    c text    GENERATED   ALWAYS as (printf('%08x',a)),
    d Generated
      Always
      AS ('xyzzy'),
    e int                         Always default(5)
  );
  INSERT INTO t1(a) VALUES(5);
  SELECT name, type FROM pragma_table_xinfo('t1');
} {a INTEGER b INT c TEXT d {} e INT}













finish_test







>

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


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
618
      ON CONFLICT(prim) DO UPDATE SET  b=excluded.b;
  -- Now b is NULL rather than 5
  SELECT * FROM tab;
} {2001-01-01 0 0 5 {}}

# 2021-07-30 forum https://sqlite.org/forum/forumpost/ff3ffe09251c105b?t=h
#
ifcapable vtab {
reset_db
  do_execsql_test gencol1-21.1 {
    CREATE TABLE t1(
      a integer primary key,
      b int generated always as (a+5),
      c text    GENERATED   ALWAYS as (printf('%08x',a)),
      d Generated
        Always
        AS ('xyzzy'),
      e int                         Always default(5)
    );
    INSERT INTO t1(a) VALUES(5);
    SELECT name, type FROM pragma_table_xinfo('t1');
  } {a INTEGER b INT c TEXT d {} e INT}
}

# 2021-09-07 forum https://sqlite.org/forum/forumpost/699b44b3ee
#
reset_db
do_execsql_test gencol1-22.1 {
  CREATE TABLE t0(a PRIMARY KEY,b TEXT AS ('2') UNIQUE);
  INSERT INTO t0(a) VALUES(2);
  SELECT * FROM t0 AS x JOIN t0 AS y
   WHERE x.b='2'
     AND (y.a=2 OR (x.b LIKE '2*' AND y.a=x.b));
} {2 2 2 2}

finish_test
Changes to test/hook.test.
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

do_preupdate_test 7.4.2.3 {
  UPDATE t5 SET b = 5 WHERE a = 'a'
} {
  DELETE main t5 1 1   a 1
}


do_execsql_test 7.5.1.0 {
  CREATE TABLE t7(a, b);
  INSERT INTO t7 VALUES('one', 'two');
  INSERT INTO t7 VALUES('three', 'four');
  ALTER TABLE t7 ADD COLUMN c DEFAULT NULL;
}

do_preupdate_test 7.5.1.1 {
  DELETE FROM t7 WHERE a = 'one'
} {
  DELETE main t7 1 1   one two {}
}

do_preupdate_test 7.5.1.2 {
  UPDATE t7 SET b = 'five'
} {
  UPDATE main t7 2 2   three four {}  three five {}
}

do_execsql_test 7.5.2.0 {
  CREATE TABLE t8(a, b);
  INSERT INTO t8 VALUES('one', 'two');
  INSERT INTO t8 VALUES('three', 'four');
  ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';

}

if 0 {
  # At time of writing, these two are broken. They demonstrate that the
  # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
  # has been used to add a column with a default value other than NULL.
  #







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







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

do_preupdate_test 7.4.2.3 {
  UPDATE t5 SET b = 5 WHERE a = 'a'
} {
  DELETE main t5 1 1   a 1
}

ifcapable altertable {
  do_execsql_test 7.5.1.0 {
    CREATE TABLE t7(a, b);
    INSERT INTO t7 VALUES('one', 'two');
    INSERT INTO t7 VALUES('three', 'four');
    ALTER TABLE t7 ADD COLUMN c DEFAULT NULL;
  }
  
  do_preupdate_test 7.5.1.1 {
    DELETE FROM t7 WHERE a = 'one'
  } {
    DELETE main t7 1 1   one two {}
  }
  
  do_preupdate_test 7.5.1.2 {
    UPDATE t7 SET b = 'five'
  } {
    UPDATE main t7 2 2   three four {}  three five {}
  }
  
  do_execsql_test 7.5.2.0 {
    CREATE TABLE t8(a, b);
    INSERT INTO t8 VALUES('one', 'two');
    INSERT INTO t8 VALUES('three', 'four');
    ALTER TABLE t8 ADD COLUMN c DEFAULT 'xxx';
  }
}

if 0 {
  # At time of writing, these two are broken. They demonstrate that the
  # sqlite3_preupdate_old() method does not handle the case where ALTER TABLE
  # has been used to add a column with a default value other than NULL.
  #
844
845
846
847
848
849
850

851
852
853
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
883
884
885
886
887
888
889
890
891
892

893
894
895
896
897
898
899
  DELETE main t4 1 1   3      abc
  DELETE main t3 1 1   2      abc
  DELETE main t2 1 1   1      abc
  DELETE main t1 1 1   0      abc
}

# No preupdate callbacks for modifying sqlite_master.

do_preupdate_test 8.1 { CREATE TABLE x1(x, y); } { }
do_preupdate_test 8.2 { ALTER TABLE x1 ADD COLUMN z } { }
do_preupdate_test 8.3 { ALTER TABLE x1 RENAME TO y1 } { }
do_preupdate_test 8.4 { CREATE INDEX y1x ON y1(x) } { }
do_preupdate_test 8.5 { CREATE VIEW v1 AS SELECT * FROM y1 } { }
do_preupdate_test 8.6 { DROP TABLE y1 } { }


#-------------------------------------------------------------------------
reset_db
db preupdate hook preupdate_hook


do_execsql_test 9.0 {
  CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
  CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
}
do_preupdate_test 9.1 {
  INSERT INTO t1 VALUES(456, NULL, NULL);
} {
  INSERT main t1 456 456  0  456 {} {}
}
do_execsql_test 9.2 {
  ALTER TABLE t1 ADD COLUMN d;
}
do_preupdate_test 9.3 {
  INSERT INTO t1(a, b, c) VALUES(457, NULL, NULL);
} {
  INSERT main t1 457 457  0  457 {} {} {}
}
do_preupdate_test 9.4 {
  DELETE FROM t1 WHERE a=456
} {
  DELETE main t1 456 456  0  456 {} {} {}
}
do_preupdate_test 9.5 {
  INSERT INTO t2 DEFAULT VALUES;
} {
  INSERT main t2 1 1  0  {} 1
} 
do_preupdate_test 9.6 {
  INSERT INTO t1 DEFAULT VALUES;
} {
  INSERT main t1 458 458  0  458 {} {} {}
} 



do_execsql_test 10.0 {
  CREATE TABLE t3(a, b INTEGER PRIMARY KEY);
}
do_preupdate_test 10.1 {
  INSERT INTO t3 DEFAULT VALUES







>
|
|
|
|
|
|
>




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







846
847
848
849
850
851
852
853
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
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
  DELETE main t4 1 1   3      abc
  DELETE main t3 1 1   2      abc
  DELETE main t2 1 1   1      abc
  DELETE main t1 1 1   0      abc
}

# No preupdate callbacks for modifying sqlite_master.
ifcapable altertable {
  do_preupdate_test 8.1 { CREATE TABLE x1(x, y); } { }
  do_preupdate_test 8.2 { ALTER TABLE x1 ADD COLUMN z } { }
  do_preupdate_test 8.3 { ALTER TABLE x1 RENAME TO y1 } { }
  do_preupdate_test 8.4 { CREATE INDEX y1x ON y1(x) } { }
  do_preupdate_test 8.5 { CREATE VIEW v1 AS SELECT * FROM y1 } { }
  do_preupdate_test 8.6 { DROP TABLE y1 } { }
}

#-------------------------------------------------------------------------
reset_db
db preupdate hook preupdate_hook

ifcapable altertable {
  do_execsql_test 9.0 {
    CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c);
    CREATE TABLE t2(a, b INTEGER PRIMARY KEY);
  }
  do_preupdate_test 9.1 {
    INSERT INTO t1 VALUES(456, NULL, NULL);
  } {
    INSERT main t1 456 456  0  456 {} {}
  }
  do_execsql_test 9.2 {
    ALTER TABLE t1 ADD COLUMN d;
  }
  do_preupdate_test 9.3 {
    INSERT INTO t1(a, b, c) VALUES(457, NULL, NULL);
  } {
    INSERT main t1 457 457  0  457 {} {} {}
  }
  do_preupdate_test 9.4 {
    DELETE FROM t1 WHERE a=456
  } {
    DELETE main t1 456 456  0  456 {} {} {}
  }
  do_preupdate_test 9.5 {
    INSERT INTO t2 DEFAULT VALUES;
  } {
    INSERT main t2 1 1  0  {} 1
  } 
  do_preupdate_test 9.6 {
    INSERT INTO t1 DEFAULT VALUES;
  } {
    INSERT main t1 458 458  0  458 {} {} {}
  } 
}


do_execsql_test 10.0 {
  CREATE TABLE t3(a, b INTEGER PRIMARY KEY);
}
do_preupdate_test 10.1 {
  INSERT INTO t3 DEFAULT VALUES
Changes to test/indexexpr1.test.
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
} {2 3 5}
do_execsql_test indexexpr1-150eqp {
  EXPLAIN QUERY PLAN
  SELECT rowid FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
   ORDER BY +rowid;
} {/USING INDEX t1abx/}


do_execsql_test indexexpr1-160 {
  ALTER TABLE t1 ADD COLUMN d;
  UPDATE t1 SET d=length(a);
  CREATE INDEX t1a2 ON t1(SUBSTR(a, 27, 3)) WHERE d>=29;
  SELECT rowid, b, c FROM t1
   WHERE substr(a,27,3)=='ord' AND d>=29;
} {1 1 1}
do_execsql_test indexexpr1-160eqp {
  EXPLAIN QUERY PLAN
  SELECT rowid, b, c FROM t1
   WHERE substr(a,27,3)=='ord' AND d>=29;
} {/USING INDEX t1a2/}


# ORDER BY using an indexed expression
#
do_execsql_test indexexpr1-170 {
  CREATE INDEX t1alen ON t1(length(a));
  SELECT length(a) FROM t1 ORDER BY length(a);
} {20 25 27 29 38 52}







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







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
} {2 3 5}
do_execsql_test indexexpr1-150eqp {
  EXPLAIN QUERY PLAN
  SELECT rowid FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
   ORDER BY +rowid;
} {/USING INDEX t1abx/}

ifcapable altertable {
  do_execsql_test indexexpr1-160 {
    ALTER TABLE t1 ADD COLUMN d;
    UPDATE t1 SET d=length(a);
    CREATE INDEX t1a2 ON t1(SUBSTR(a, 27, 3)) WHERE d>=29;
    SELECT rowid, b, c FROM t1
      WHERE substr(a,27,3)=='ord' AND d>=29;
  } {1 1 1}
  do_execsql_test indexexpr1-160eqp {
    EXPLAIN QUERY PLAN
      SELECT rowid, b, c FROM t1
      WHERE substr(a,27,3)=='ord' AND d>=29;
  } {/USING INDEX t1a2/}
}

# ORDER BY using an indexed expression
#
do_execsql_test indexexpr1-170 {
  CREATE INDEX t1alen ON t1(length(a));
  SELECT length(a) FROM t1 ORDER BY length(a);
} {20 25 27 29 38 52}
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
} {2 3 5}
do_execsql_test indexexpr1-250eqp {
  EXPLAIN QUERY PLAN
  SELECT id FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
   ORDER BY +id;
} {/USING INDEX t1abx/}


do_execsql_test indexexpr1-260 {
  ALTER TABLE t1 ADD COLUMN d;
  UPDATE t1 SET d=length(a);
  CREATE INDEX t1a2 ON t1(SUBSTR(a, 27, 3)) WHERE d>=29;
  SELECT id, b, c FROM t1
   WHERE substr(a,27,3)=='ord' AND d>=29;
} {1 1 1}
do_execsql_test indexexpr1-260eqp {
  EXPLAIN QUERY PLAN
  SELECT id, b, c FROM t1
   WHERE substr(a,27,3)=='ord' AND d>=29;
} {/USING INDEX t1a2/}



do_catchsql_test indexexpr1-300 {
  CREATE TABLE t2(a,b,c); INSERT INTO t2 VALUES(1,2,3);
  CREATE INDEX t2x1 ON t2(a,b+random());
} {1 {non-deterministic functions prohibited in index expressions}}
do_catchsql_test indexexpr1-301 {







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







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
} {2 3 5}
do_execsql_test indexexpr1-250eqp {
  EXPLAIN QUERY PLAN
  SELECT id FROM t1 WHERE substr(a,b,3) IN ('and','l_t','xyz')
   ORDER BY +id;
} {/USING INDEX t1abx/}

ifcapable altertable {
  do_execsql_test indexexpr1-260 {
    ALTER TABLE t1 ADD COLUMN d;
    UPDATE t1 SET d=length(a);
    CREATE INDEX t1a2 ON t1(SUBSTR(a, 27, 3)) WHERE d>=29;
    SELECT id, b, c FROM t1
      WHERE substr(a,27,3)=='ord' AND d>=29;
  } {1 1 1}
  do_execsql_test indexexpr1-260eqp {
    EXPLAIN QUERY PLAN
      SELECT id, b, c FROM t1
      WHERE substr(a,27,3)=='ord' AND d>=29;
  } {/USING INDEX t1a2/}
}


do_catchsql_test indexexpr1-300 {
  CREATE TABLE t2(a,b,c); INSERT INTO t2 VALUES(1,2,3);
  CREATE INDEX t2x1 ON t2(a,b+random());
} {1 {non-deterministic functions prohibited in index expressions}}
do_catchsql_test indexexpr1-301 {
Changes to test/istrue.test.
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
    SELECT x IS TRUE FROM t1;
  } [expr {$tn in [list 5 6] ? {1} : {0}}]
  do_execsql_test istrue-600.$tn.4 {
    SELECT x IS FALSE FROM t1;
  } {0}
}


do_execsql_test istrue-700 {
  CREATE TABLE t7(
    a INTEGER PRIMARY KEY,
    b BOOLEAN DEFAULT false,
    c BOOLEAN DEFAULT true
  );
  INSERT INTO t7(a) VALUES(1);
  INSERT INTO t7(a,b,c) VALUES(2,true,false);
  ALTER TABLE t7 ADD COLUMN d BOOLEAN DEFAULT false;
  ALTER TABLE t7 ADD COLUMN e BOOLEAN DEFAULT true;
  INSERT INTO t7(a,b,c) VALUES(3,true,false);
  INSERT INTO t7 VALUES(4,false,true,true,false);
  SELECT *,'x' FROM t7 ORDER BY a;
} {1 0 1 0 1 x 2 1 0 0 1 x 3 1 0 0 1 x 4 0 1 1 0 x}


do_execsql_test istrue-710 {
  SELECT 0.5 IS TRUE COLLATE NOCASE;
  SELECT 0.5 IS TRUE COLLATE RTRIM;
  SELECT 0.5 IS TRUE COLLATE BINARY;

  SELECT 0.5 IS TRUE;







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







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
    SELECT x IS TRUE FROM t1;
  } [expr {$tn in [list 5 6] ? {1} : {0}}]
  do_execsql_test istrue-600.$tn.4 {
    SELECT x IS FALSE FROM t1;
  } {0}
}

ifcapable altertable {
  do_execsql_test istrue-700 {
    CREATE TABLE t7(
      a INTEGER PRIMARY KEY,
      b BOOLEAN DEFAULT false,
      c BOOLEAN DEFAULT true
    );
    INSERT INTO t7(a) VALUES(1);
    INSERT INTO t7(a,b,c) VALUES(2,true,false);
    ALTER TABLE t7 ADD COLUMN d BOOLEAN DEFAULT false;
    ALTER TABLE t7 ADD COLUMN e BOOLEAN DEFAULT true;
    INSERT INTO t7(a,b,c) VALUES(3,true,false);
    INSERT INTO t7 VALUES(4,false,true,true,false);
    SELECT *,'x' FROM t7 ORDER BY a;
  } {1 0 1 0 1 x 2 1 0 0 1 x 3 1 0 0 1 x 4 0 1 1 0 x}
}

do_execsql_test istrue-710 {
  SELECT 0.5 IS TRUE COLLATE NOCASE;
  SELECT 0.5 IS TRUE COLLATE RTRIM;
  SELECT 0.5 IS TRUE COLLATE BINARY;

  SELECT 0.5 IS TRUE;
Changes to test/minmax.test.
642
643
644
645
646
647
648

649









650
651
  SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
} {100}
do_execsql_test 14.2 {
  CREATE INDEX t14ba ON t14(b,a);
  SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
} {100}













finish_test







>
|
>
>
>
>
>
>
>
>
>


642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
  SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
} {100}
do_execsql_test 14.2 {
  CREATE INDEX t14ba ON t14(b,a);
  SELECT min(a) FROM t14 WHERE b='2' AND a>'50';
} {100}

# 2021-08-21.  https://sqlite.org/forum/forumpost/cfcb4b461d
# 
reset_db
do_execsql_test 15.1 {
  CREATE TABLE t1(a);
  CREATE TABLE t2(b);
  CREATE TABLE t3(c);
  INSERT INTO t1 VALUES(0);
  INSERT INTO t2 VALUES(5);
  SELECT MIN((SELECT b FROM t2 UNION SELECT x FROM (SELECT x FROM (SELECT 1 AS x WHERE t1.a=1) UNION ALL SELECT c FROM t3))) FROM t1;
} {5}

finish_test
Changes to test/pager1.test.
1936
1937
1938
1939
1940
1941
1942

1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956

1957
1958
1959
1960
1961
1962
1963
do_test pager1-18.4 {
  hexio_write test.db [expr ($pgno-1)*1024] 90000000
  sqlite3 db2 test.db
  catchsql { SELECT length(x||'') FROM t2 } db2
} {1 {database disk image is malformed}}
db2 close
extra_schema_checks 0

do_test pager1-18.5 {
  sqlite3 db ""
  sqlite3_db_config db DEFENSIVE 0
  execsql {
    CREATE TABLE t1(a, b);
    CREATE TABLE t2(a, b);
    PRAGMA writable_schema = 1;
    UPDATE sqlite_master SET rootpage=5 WHERE tbl_name = 't1';
    PRAGMA writable_schema = 0;
    ALTER TABLE t1 RENAME TO x1;
  }
  catchsql { SELECT * FROM x1 }
} {1 {database disk image is malformed}}
db close

extra_schema_checks 1

do_test pager1-18.6 {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
    PRAGMA page_size = 1024;







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







1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
do_test pager1-18.4 {
  hexio_write test.db [expr ($pgno-1)*1024] 90000000
  sqlite3 db2 test.db
  catchsql { SELECT length(x||'') FROM t2 } db2
} {1 {database disk image is malformed}}
db2 close
extra_schema_checks 0
ifcapable altertable {
  do_test pager1-18.5 {
    sqlite3 db ""
      sqlite3_db_config db DEFENSIVE 0
      execsql {
        CREATE TABLE t1(a, b);
        CREATE TABLE t2(a, b);
        PRAGMA writable_schema = 1;
        UPDATE sqlite_master SET rootpage=5 WHERE tbl_name = 't1';
        PRAGMA writable_schema = 0;
        ALTER TABLE t1 RENAME TO x1;
      }
    catchsql { SELECT * FROM x1 }
  } {1 {database disk image is malformed}}
  db close
}
extra_schema_checks 1

do_test pager1-18.6 {
  faultsim_delete_and_reopen
  db func a_string a_string
  execsql {
    PRAGMA page_size = 1024;
Changes to test/permutations.test.
1252
1253
1254
1255
1256
1257
1258

1259
1260
        set extra [list -files $files]
      }

      eval run_tests $suite $S $extra
    }
  }
  main $argv

  finish_test
}







>


1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
        set extra [list -files $files]
      }

      eval run_tests $suite $S $extra
    }
  }
  main $argv
  set argv {}
  finish_test
}
Changes to test/pragma.test.
528
529
530
531
532
533
534

535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557

558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
    db eval {PRAGMA integrity_check}
  } {ok}
}

# Verify that PRAGMA integrity_check catches UNIQUE and NOT NULL
# constraint violations.
#

sqlite3_db_config db DEFENSIVE 0
do_execsql_test pragma-3.20 {
  CREATE TABLE t1(a,b);
  CREATE INDEX t1a ON t1(a);
  INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(2,4),(NULL,5),(NULL,6);
  PRAGMA writable_schema=ON;
  UPDATE sqlite_master SET sql='CREATE UNIQUE INDEX t1a ON t1(a)'
   WHERE name='t1a';
  UPDATE sqlite_master SET sql='CREATE TABLE t1(a NOT NULL,b)'
   WHERE name='t1';
  PRAGMA writable_schema=OFF;
  ALTER TABLE t1 RENAME TO t1x;
  PRAGMA integrity_check;
} {{non-unique entry in index t1a} {NULL value in t1x.a} {non-unique entry in index t1a} {NULL value in t1x.a}}
do_execsql_test pragma-3.21 {
  PRAGMA integrity_check(3);
} {{non-unique entry in index t1a} {NULL value in t1x.a} {non-unique entry in index t1a}}
do_execsql_test pragma-3.22 {
  PRAGMA integrity_check(2);
} {{non-unique entry in index t1a} {NULL value in t1x.a}}
do_execsql_test pragma-3.23 {
  PRAGMA integrity_check(1);
} {{non-unique entry in index t1a}}


# PRAGMA integrity check (or more specifically the sqlite3BtreeCount()
# interface) used to leave index cursors in an inconsistent state
# which could result in an assertion fault in sqlite3BtreeKey()
# called from saveCursorPosition() if content is removed from the
# index while the integrity_check is still running.  This test verifies
# that problem has been fixed.
#
do_test pragma-3.30 {
  db close
  delete_file test.db
  sqlite3 db test.db
  db eval {
    CREATE TABLE t1(a,b,c);
    WITH RECURSIVE
      c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<100)
    INSERT INTO t1(a,b,c) SELECT i, printf('xyz%08x',i), 2000-i FROM c;







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









|







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
    db eval {PRAGMA integrity_check}
  } {ok}
}

# Verify that PRAGMA integrity_check catches UNIQUE and NOT NULL
# constraint violations.
#
ifcapable altertable {
  sqlite3_db_config db DEFENSIVE 0
    do_execsql_test pragma-3.20 {
      CREATE TABLE t1(a,b);
      CREATE INDEX t1a ON t1(a);
      INSERT INTO t1 VALUES(1,1),(2,2),(3,3),(2,4),(NULL,5),(NULL,6);
      PRAGMA writable_schema=ON;
      UPDATE sqlite_master SET sql='CREATE UNIQUE INDEX t1a ON t1(a)'
        WHERE name='t1a';
      UPDATE sqlite_master SET sql='CREATE TABLE t1(a NOT NULL,b)'
        WHERE name='t1';
      PRAGMA writable_schema=OFF;
      ALTER TABLE t1 RENAME TO t1x;
      PRAGMA integrity_check;
    } {{non-unique entry in index t1a} {NULL value in t1x.a} {non-unique entry in index t1a} {NULL value in t1x.a}}
  do_execsql_test pragma-3.21 {
    PRAGMA integrity_check(3);
  } {{non-unique entry in index t1a} {NULL value in t1x.a} {non-unique entry in index t1a}}
  do_execsql_test pragma-3.22 {
    PRAGMA integrity_check(2);
  } {{non-unique entry in index t1a} {NULL value in t1x.a}}
  do_execsql_test pragma-3.23 {
    PRAGMA integrity_check(1);
  } {{non-unique entry in index t1a}}
}

# PRAGMA integrity check (or more specifically the sqlite3BtreeCount()
# interface) used to leave index cursors in an inconsistent state
# which could result in an assertion fault in sqlite3BtreeKey()
# called from saveCursorPosition() if content is removed from the
# index while the integrity_check is still running.  This test verifies
# that problem has been fixed.
#
do_test pragma-3.30 {
  catch { db close }
  delete_file test.db
  sqlite3 db test.db
  db eval {
    CREATE TABLE t1(a,b,c);
    WITH RECURSIVE
      c(i) AS (VALUES(1) UNION ALL SELECT i+1 FROM c WHERE i<100)
    INSERT INTO t1(a,b,c) SELECT i, printf('xyz%08x',i), 2000-i FROM c;
1953
1954
1955
1956
1957
1958
1959

1960
1961
1962
1963
1964
1965
1966
1967

1968
1969
1970
1971
1972
1973
1974
  db eval {
    DROP INDEX IF EXISTS i3;
    CREATE INDEX i3 ON t1(d,b,c);
  }
  capture_pragma db2 out {PRAGMA index_list(t1)}
  db2 eval {SELECT seq, name, "unique", origin, '|' FROM out ORDER BY seq}
} {0 i3 0 c | 1 i2 0 c | 2 i2x 0 c | 3 i1 0 c |}

do_test 23.4 {
  db eval {
    ALTER TABLE t1 ADD COLUMN e;
  }
  db2 eval {
    PRAGMA table_info(t1);
  }
} {/4 e {} 0 {} 0/}

do_test 23.5 {
  db eval {
    DROP TABLE t2;
    CREATE TABLE t2(x, y INTEGER REFERENCES t1);
  }
  db2 eval {
    PRAGMA foreign_key_list(t2);







>
|
|
|
|
|
|
|
|
>







1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
  db eval {
    DROP INDEX IF EXISTS i3;
    CREATE INDEX i3 ON t1(d,b,c);
  }
  capture_pragma db2 out {PRAGMA index_list(t1)}
  db2 eval {SELECT seq, name, "unique", origin, '|' FROM out ORDER BY seq}
} {0 i3 0 c | 1 i2 0 c | 2 i2x 0 c | 3 i1 0 c |}
ifcapable altertable {
  do_test 23.4 {
    db eval {
      ALTER TABLE t1 ADD COLUMN e;
    }
    db2 eval {
      PRAGMA table_info(t1);
    }
  } {/4 e {} 0 {} 0/}
}
do_test 23.5 {
  db eval {
    DROP TABLE t2;
    CREATE TABLE t2(x, y INTEGER REFERENCES t1);
  }
  db2 eval {
    PRAGMA foreign_key_list(t2);
Changes to test/quote.test.
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
  {CREATE INDEX i2 ON t1(x, y, z||"abc")}
  {CREATE INDEX i3 ON t1("w"||"")}
  {CREATE INDEX i4 ON t1(x) WHERE z="w"}
}

# 2021-03-13
# ticket 1c24a659e6d7f3a1

reset_db
do_catchsql_test 3.0 {
  CREATE TABLE t1(a,b);
  CREATE INDEX x1 on t1("b");
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.1 {
  DROP TABLE t1;
  CREATE TABLE t1(a,"b");
  CREATE INDEX x1 on t1("b");
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.2 {
  DROP TABLE t1;
  CREATE TABLE t1(a,'b');
  CREATE INDEX x1 on t1("b");
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.3 {
  DROP TABLE t1;
  CREATE TABLE t1(a,"b");
  CREATE INDEX x1 on t1('b');
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.4 {
  DROP TABLE t1;
  CREATE TABLE t1(a, b, c);
  CREATE INDEX x1 ON t1("a"||"b");
  INSERT INTO t1 VALUES(1,2,3),(1,4,5);
  ALTER TABLE t1 DROP COLUMN b;
} {1 {error in index x1 after drop column: no such column: b}}
do_catchsql_test 3.5 {
  DROP TABLE t1;
  CREATE TABLE t1(a, b, c);
  CREATE INDEX x1 ON t1("a"||"x");
  INSERT INTO t1 VALUES(1,2,3),(1,4,5);
  ALTER TABLE t1 DROP COLUMN b;
} {0 {}}


finish_test







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


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
  {CREATE INDEX i2 ON t1(x, y, z||"abc")}
  {CREATE INDEX i3 ON t1("w"||"")}
  {CREATE INDEX i4 ON t1(x) WHERE z="w"}
}

# 2021-03-13
# ticket 1c24a659e6d7f3a1
ifcapable altertable {
  reset_db
    do_catchsql_test 3.0 {
      CREATE TABLE t1(a,b);
      CREATE INDEX x1 on t1("b");
      ALTER TABLE t1 DROP COLUMN b;
    } {1 {error in index x1 after drop column: no such column: b}}
  do_catchsql_test 3.1 {
    DROP TABLE t1;
    CREATE TABLE t1(a,"b");
    CREATE INDEX x1 on t1("b");
    ALTER TABLE t1 DROP COLUMN b;
  } {1 {error in index x1 after drop column: no such column: b}}
  do_catchsql_test 3.2 {
    DROP TABLE t1;
    CREATE TABLE t1(a,'b');
    CREATE INDEX x1 on t1("b");
    ALTER TABLE t1 DROP COLUMN b;
  } {1 {error in index x1 after drop column: no such column: b}}
  do_catchsql_test 3.3 {
    DROP TABLE t1;
    CREATE TABLE t1(a,"b");
    CREATE INDEX x1 on t1('b');
    ALTER TABLE t1 DROP COLUMN b;
  } {1 {error in index x1 after drop column: no such column: b}}
  do_catchsql_test 3.4 {
    DROP TABLE t1;
    CREATE TABLE t1(a, b, c);
    CREATE INDEX x1 ON t1("a"||"b");
    INSERT INTO t1 VALUES(1,2,3),(1,4,5);
    ALTER TABLE t1 DROP COLUMN b;
  } {1 {error in index x1 after drop column: no such column: b}}
  do_catchsql_test 3.5 {
    DROP TABLE t1;
    CREATE TABLE t1(a, b, c);
    CREATE INDEX x1 ON t1("a"||"x");
    INSERT INTO t1 VALUES(1,2,3),(1,4,5);
    ALTER TABLE t1 DROP COLUMN b;
  } {0 {}}
}

finish_test
Changes to test/releasetest_data.tcl.
145
146
147
148
149
150
151

152
153
154
155
156
157
158
    -O6
    -DSQLITE_ENABLE_FTS4=1
    -DSQLITE_ENABLE_RTREE=1
    -DSQLITE_ENABLE_STAT4
    -DSQLITE_ENABLE_RBU
    -DSQLITE_MAX_ATTACHED=125
    -DSQLITE_MAX_MMAP_SIZE=12884901888

    -DLONGDOUBLE_TYPE=double
    --enable-session
  }
  "Device-One" {
    -O2
    -DSQLITE_DEBUG=1
    -DSQLITE_DEFAULT_AUTOVACUUM=1







>







145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    -O6
    -DSQLITE_ENABLE_FTS4=1
    -DSQLITE_ENABLE_RTREE=1
    -DSQLITE_ENABLE_STAT4
    -DSQLITE_ENABLE_RBU
    -DSQLITE_MAX_ATTACHED=125
    -DSQLITE_MAX_MMAP_SIZE=12884901888
    -DSQLITE_ENABLE_SORTER_MMAP=1
    -DLONGDOUBLE_TYPE=double
    --enable-session
  }
  "Device-One" {
    -O2
    -DSQLITE_DEBUG=1
    -DSQLITE_DEFAULT_AUTOVACUUM=1
Changes to test/schema3.test.
11
12
13
14
15
16
17






18
19
20
21
22
23
24
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
source $testdir/lock_common.tcl







# This block tests that if one client modifies the database schema, a
# second client updates its internal cache of the database schema before
# executing any queries. Specifically, it does not return a "no such column"
# or "no such table" error if the table or column in question does exist
# but was added after the second client loaded its cache of the database
# schema.







>
>
>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# This file implements regression tests for SQLite library.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
source $testdir/malloc_common.tcl
source $testdir/lock_common.tcl

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

# This block tests that if one client modifies the database schema, a
# second client updates its internal cache of the database schema before
# executing any queries. Specifically, it does not return a "no such column"
# or "no such table" error if the table or column in question does exist
# but was added after the second client loaded its cache of the database
# schema.
Changes to test/shell1.test.
14
15
16
17
18
19
20


21
22
23
24
25
26
27
#

# Test plan:
#
#   shell1-1.*: Basic command line option handling.
#   shell1-2.*: Basic "dot" command token parsing.
#   shell1-3.*: Basic test that "dot" command can be called.


#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
db close
forcedelete test.db test.db-journal test.db-wal
sqlite3 db test.db







>
>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#

# Test plan:
#
#   shell1-1.*: Basic command line option handling.
#   shell1-2.*: Basic "dot" command token parsing.
#   shell1-3.*: Basic test that "dot" command can be called.
#   shell1-{4-8}.*: Test various "dot" commands's functionality.
#   shell1-9.*: Basic test that "dot" commands and SQL intermix ok.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
db close
forcedelete test.db test.db-journal test.db-wal
sqlite3 db test.db
1219
1220
1221
1222
1223
1224
1225
1226


















1227
do_test shell1-8.4 {
  catchcmd ":memory: --table" {SELECT ieee754_mantissa(47.49) AS M, ieee754_exponent(47.49) AS E;}
} {0 {+------------------+-----+
|        M         |  E  |
+------------------+-----+
| 6683623321994527 | -47 |
+------------------+-----+}}



















finish_test








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

1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
do_test shell1-8.4 {
  catchcmd ":memory: --table" {SELECT ieee754_mantissa(47.49) AS M, ieee754_exponent(47.49) AS E;}
} {0 {+------------------+-----+
|        M         |  E  |
+------------------+-----+
| 6683623321994527 | -47 |
+------------------+-----+}}

#----------------------------------------------------------------------------
# Test cases shell1-9.*: Basic test that "dot" commands and SQL intermix ok.
#
do_test shell1-9.1 {
  catchcmd :memory: {
.mode csv
/*
x */ select 1,2; --x
 -- .nada
;
.mode csv
--x
select 2,1; select 3,4;
}
} {0 {1,2
2,1
3,4}}

finish_test
Changes to test/shell2.test.
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
  set fexist [file exist foo.db]
  list $rc $fexist
} {{0 {}} 1}

# Shell silently ignores extra parameters.
# Ticket [f5cb008a65].
do_test shell2-1.2.1 {
  set rc [catch { eval exec $CLI \":memory:\" \"select+3\" \"select+4\" } msg]
  list $rc $msg
} {0 {3

4}}

# Test a problem reported on the mailing list. The shell was at one point
# returning the generic SQLITE_ERROR message ("SQL error or missing database")
# instead of the "too many levels..." message in the test below.
#
do_test shell2-1.3 {
  catchcmd "-batch test.db" {







|
<

>
|







39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
  set fexist [file exist foo.db]
  list $rc $fexist
} {{0 {}} 1}

# Shell silently ignores extra parameters.
# Ticket [f5cb008a65].
do_test shell2-1.2.1 {
  catchcmdex {:memory: "select+3" "select+4"}

} {0 {3
4
}}

# Test a problem reported on the mailing list. The shell was at one point
# returning the generic SQLITE_ERROR message ("SQL error or missing database")
# instead of the "too many levels..." message in the test below.
#
do_test shell2-1.3 {
  catchcmd "-batch test.db" {
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
1}}

# Test with echo on using dot command and 
# multiple commands per line.
# NB. whitespace is important
do_test shell2-1.4.5 {
  forcedelete foo.db
  catchcmd "foo.db" {.echo ON
CREATE TABLE foo1(a);
INSERT INTO foo1(a) VALUES(1);
CREATE TABLE foo2(b);
INSERT INTO foo2(b) VALUES(1);
SELECT * FROM foo1; SELECT * FROM foo2;
INSERT INTO foo1(a) VALUES(2); INSERT INTO foo2(b) VALUES(2);
SELECT * FROM foo1; SELECT * FROM foo2;







|







119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
1}}

# Test with echo on using dot command and 
# multiple commands per line.
# NB. whitespace is important
do_test shell2-1.4.5 {
  forcedelete foo.db
  catchcmdex "foo.db" {.echo ON
CREATE TABLE foo1(a);
INSERT INTO foo1(a) VALUES(1);
CREATE TABLE foo2(b);
INSERT INTO foo2(b) VALUES(1);
SELECT * FROM foo1; SELECT * FROM foo2;
INSERT INTO foo1(a) VALUES(2); INSERT INTO foo2(b) VALUES(2);
SELECT * FROM foo1; SELECT * FROM foo2;
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
}}

# Test with echo on and headers on using dot command and 
# multiple commands per line.
# NB. whitespace is important
do_test shell2-1.4.6 {
  forcedelete foo.db
  catchcmd "foo.db" {.echo ON
.headers ON
CREATE TABLE foo1(a);
INSERT INTO foo1(a) VALUES(1);
CREATE TABLE foo2(b);
INSERT INTO foo2(b) VALUES(1);
SELECT * FROM foo1; SELECT * FROM foo2;
INSERT INTO foo1(a) VALUES(2); INSERT INTO foo2(b) VALUES(2);







|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
}}

# Test with echo on and headers on using dot command and 
# multiple commands per line.
# NB. whitespace is important
do_test shell2-1.4.6 {
  forcedelete foo.db
  catchcmdex "foo.db" {.echo ON
.headers ON
CREATE TABLE foo1(a);
INSERT INTO foo1(a) VALUES(1);
CREATE TABLE foo2(b);
INSERT INTO foo2(b) VALUES(1);
SELECT * FROM foo1; SELECT * FROM foo2;
INSERT INTO foo1(a) VALUES(2); INSERT INTO foo2(b) VALUES(2);
Changes to test/shell3.test.
14
15
16
17
18
19
20

21
22
23
24
25
26
27

28
29
30
31
32
33
34
# $Id: shell2.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
#

# Test plan:
#
#   shell3-1.*: Basic tests for running SQL statments from command line.
#   shell3-2.*: Basic tests for running SQL file from command line.

#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
db close
forcedelete test.db test.db-journal test.db-wal
sqlite3 db test.db


# There are inconsistencies in command-line argument quoting on Windows.
# In particular, individual applications are responsible for command-line
# parsing in Windows, not the shell.  Depending on whether the sqlite3.exe
# program is compiled with MinGW or MSVC, the command-line parsing is
# different.  This causes problems for the tests below.  To avoid
# issues, these tests are disabled for windows.







>







>







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# $Id: shell2.test,v 1.7 2009/07/17 16:54:48 shaneh Exp $
#

# Test plan:
#
#   shell3-1.*: Basic tests for running SQL statments from command line.
#   shell3-2.*: Basic tests for running SQL file from command line.
#   shell3-3.*: Basic tests for processing odd SQL constructs.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set CLI [test_find_cli]
db close
forcedelete test.db test.db-journal test.db-wal
sqlite3 db test.db


# There are inconsistencies in command-line argument quoting on Windows.
# In particular, individual applications are responsible for command-line
# parsing in Windows, not the shell.  Depending on whether the sqlite3.exe
# program is compiled with MinGW or MSVC, the command-line parsing is
# different.  This causes problems for the tests below.  To avoid
# issues, these tests are disabled for windows.
94
95
96
97
98
99
100



































101
do_test shell3-2.6 {
  catchcmd "foo.db" ".tables"
} {0 {}}
do_test shell3-2.7 {
  catchcmd "foo.db" "CREATE TABLE"
} {1 {Error: near line 1: incomplete input}}




































finish_test







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

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
do_test shell3-2.6 {
  catchcmd "foo.db" ".tables"
} {0 {}}
do_test shell3-2.7 {
  catchcmd "foo.db" "CREATE TABLE"
} {1 {Error: near line 1: incomplete input}}


#----------------------------------------------------------------------------
#   shell3-3.*: Basic tests for processing odd SQL constructs.
#

# Run combinations of odd identifiers, comments, semicolon placement
do_test shell3-3.1 {
  forcedelete foo.db
  set rc [ catchcmd "foo.db" {CREATE TABLE t1("
a--.
" --x
); CREATE TABLE t2("a[""b""]");
.header on
INSERT INTO t1 VALUES ('
x''y');
INSERT INTO t2 VALUES ('
/*.
.*/ x
''y');
SELECT * from t1 limit 1;
SELECT * from t2 limit 1;
} ]
  set fexist [file exist foo.db]
  list $rc $fexist
} {{0 {
a--.


x'y
a["b"]

/*.
.*/ x
'y}} 1}

finish_test
Changes to test/shrink.test.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
unset -nocomplain baseline
do_test shrink-1.1 {
  db eval {
    PRAGMA cache_size = 2000;
    CREATE TABLE t1(x,y);
    INSERT INTO t1 VALUES(randomblob(1000000),1);
  }
  set ::baseline sqlite3_memory_used
  # EVIDENCE-OF: R-58814-63508 The sqlite3_db_release_memory(D) interface
  # attempts to free as much heap memory as possible from database
  # connection D.
  sqlite3_db_release_memory db
  expr {$::baseline > [sqlite3_memory_used]+500000}
} {1}
do_test shrink-1.2 {







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
unset -nocomplain baseline
do_test shrink-1.1 {
  db eval {
    PRAGMA cache_size = 2000;
    CREATE TABLE t1(x,y);
    INSERT INTO t1 VALUES(randomblob(1000000),1);
  }
  set ::baseline [sqlite3_memory_used]
  # EVIDENCE-OF: R-58814-63508 The sqlite3_db_release_memory(D) interface
  # attempts to free as much heap memory as possible from database
  # connection D.
  sqlite3_db_release_memory db
  expr {$::baseline > [sqlite3_memory_used]+500000}
} {1}
do_test shrink-1.2 {
Changes to test/skipscan2.test.
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
    role TEXT NOT NULL,
    height INT NOT NULL, -- in cm
    CHECK( role IN ('student','teacher') )
  ) WITHOUT ROWID;
  CREATE INDEX peoplew_idx1 ON peoplew(role, height);
  INSERT INTO peoplew(name,role,height)
     SELECT name, role, height FROM  people;
  ALTER TABLE people RENAME TO old_people;
  SELECT name FROM peoplew WHERE height>=180 ORDER BY +name;
} {David Jack Patrick Quiana Xavier}
do_execsql_test skipscan2-2.2 {
  SELECT name FROM peoplew
   WHERE role IN (SELECT DISTINCT role FROM peoplew)
     AND height>=180 ORDER BY +name;
} {David Jack Patrick Quiana Xavier}







<







153
154
155
156
157
158
159

160
161
162
163
164
165
166
    role TEXT NOT NULL,
    height INT NOT NULL, -- in cm
    CHECK( role IN ('student','teacher') )
  ) WITHOUT ROWID;
  CREATE INDEX peoplew_idx1 ON peoplew(role, height);
  INSERT INTO peoplew(name,role,height)
     SELECT name, role, height FROM  people;

  SELECT name FROM peoplew WHERE height>=180 ORDER BY +name;
} {David Jack Patrick Quiana Xavier}
do_execsql_test skipscan2-2.2 {
  SELECT name FROM peoplew
   WHERE role IN (SELECT DISTINCT role FROM peoplew)
     AND height>=180 ORDER BY +name;
} {David Jack Patrick Quiana Xavier}
Changes to test/sorterref.test.
9
10
11
12
13
14
15






16
17
18
19
20
21
22
#
#***********************************************************************
#

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







do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  ALTER TABLE t1 ADD COLUMN d DEFAULT 'string';
  INSERT INTO t1 VALUES(7, 8, 9, 'text');







>
>
>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#
#***********************************************************************
#

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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a, b, c);
  INSERT INTO t1 VALUES(1, 2, 3);
  INSERT INTO t1 VALUES(4, 5, 6);
  ALTER TABLE t1 ADD COLUMN d DEFAULT 'string';
  INSERT INTO t1 VALUES(7, 8, 9, 'text');
Changes to test/statfault.test.
37
38
39
40
41
42
43








44

45

  execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
} -body {
  execsql { SELECT count(*) FROM sss }
} -test {
  faultsim_test_result {0 8} 
}











finish_test








>
>
>
>
>
>
>
>
|
>

>
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
} -body {
  execsql { SELECT count(*) FROM sss }
} -test {
  faultsim_test_result {0 8} 
}

do_faultsim_test 2 -faults * -prep {
  faultsim_restore_and_reopen
  register_dbstat_vtab db
  execsql { SELECT 1 FROM sqlite_master LIMIT 1 }
} -body {
  db eval { SELECT * FROM sss } { db eval { SELECT randomblob(5000) } }
} -test {
  faultsim_test_result {0 {}} 
}

finish_test

Added test/strict1.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
# 2021-08-18
#
# 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 STRICT tables.
#

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

# STRICT tables have on a limited number of allowed datatypes.
#
do_catchsql_test strict1-1.1 {
  CREATE TABLE t1(a) STRICT;
} {1 {missing datatype for t1.a}}
do_catchsql_test strict1-1.2 {
  CREATE TABLE t1(a PRIMARY KEY) STRICT, WITHOUT ROWID;
} {1 {missing datatype for t1.a}}
do_catchsql_test strict1-1.3 {
  CREATE TABLE t1(a PRIMARY KEY) WITHOUT ROWID, STRICT;
} {1 {missing datatype for t1.a}}
do_catchsql_test strict1-1.4 {
  CREATE TABLE t1(a BANJO PRIMARY KEY) WITHOUT ROWID, STRICT;
} {1 {unknown datatype for t1.a: "BANJO"}}
do_catchsql_test strict1-1.5 {
  CREATE TABLE t1(a TEXT PRIMARY KEY, b INT, c INTEGER, d REAL, e BLOB, f DATE) strict;
} {1 {unknown datatype for t1.f: "DATE"}}
do_catchsql_test strict1-1.6 {
  CREATE TABLE t1(a TEXT PRIMARY KEY, b INT, c INTEGER, d REAL, e BLOB, f TEXT(50)) WITHOUT ROWID, STRICT;
} {1 {unknown datatype for t1.f: "TEXT(50)"}}

do_execsql_test strict1-2.0 {
  CREATE TABLE t1(
    a INT,
    b INTEGER,
    c BLOB,
    d TEXT,
    e REAL
  ) STRICT;
} {}
ifcapable vtab {
  do_execsql_test strict1-2.0a {
    SELECT strict FROM pragma_table_list('t1');
  } {1}
}
do_catchsql_test strict1-2.1 {
  INSERT INTO t1(a) VALUES('xyz');
} {1 {cannot store TEXT value in INT column t1.a}}
do_catchsql_test strict1-2.2 {
  INSERT INTO t1(b) VALUES('xyz');
} {1 {cannot store TEXT value in INTEGER column t1.b}}
do_catchsql_test strict1-2.3 {
  INSERT INTO t1(c) VALUES('xyz');
} {1 {cannot store TEXT value in BLOB column t1.c}}
do_catchsql_test strict1-2.4 {
  INSERT INTO t1(d) VALUES(x'3142536475');
} {1 {cannot store BLOB value in TEXT column t1.d}}
do_catchsql_test strict1-2.5 {
  INSERT INTO t1(e) VALUES('xyz');
} {1 {cannot store TEXT value in REAL column t1.e}}


do_execsql_test strict1-3.1 {
  INSERT INTO t1(a, b) VALUES(1,2),('3','4'),(5.0, 6.0),(null,null);
  SELECT a, b, '|' FROM t1;
} {1 2 | 3 4 | 5 6 | {} {} |}
do_catchsql_test strict1-3.2 {
  INSERT INTO t1(a) VALUES(1.2);
} {1 {cannot store REAL value in INT column t1.a}}
do_catchsql_test strict1-3.3 {
  INSERT INTO t1(a) VALUES(x'313233');
} {1 {cannot store BLOB value in INT column t1.a}}
do_catchsql_test strict1-3.4 {
  INSERT INTO t1(b) VALUES(1.2);
} {1 {cannot store REAL value in INTEGER column t1.b}}
do_catchsql_test strict1-3.5 {
  INSERT INTO t1(b) VALUES(x'313233');
} {1 {cannot store BLOB value in INTEGER column t1.b}}

do_execsql_test strict1-4.1 {
  DELETE FROM t1;
  INSERT INTO t1(c) VALUES(x'313233'), (NULL);
  SELECT typeof(c), c FROM t1;
} {blob 123 null {}}
do_catchsql_test strict1-4.2 {
  INSERT INTO t1(c) VALUES('456');
} {1 {cannot store TEXT value in BLOB column t1.c}}

do_execsql_test strict1-5.1 {
  DELETE FROM t1;
  INSERT INTO t1(d) VALUES('xyz'),(4),(5.5),(NULL);
  SELECT typeof(d), d FROM t1;
} {text xyz text 4 text 5.5 null {}}
do_catchsql_test strict1-5.2 {
  INSERT INTO t1(d) VALUES(x'4567');
} {1 {cannot store BLOB value in TEXT column t1.d}}

do_execsql_test strict1-6.1 {
  DELETE FROM t1;
  INSERT INTO t1(e) VALUES(1),(2.5),('3'),('4.5'),(6.0),(NULL);
  SELECT typeof(e), e FROM t1;
} {real 1.0 real 2.5 real 3.0 real 4.5 real 6.0 null {}}
do_catchsql_test strict1-6.2 {
  INSERT INTO t1(e) VALUES('xyz');
} {1 {cannot store TEXT value in REAL column t1.e}}
do_catchsql_test strict1-6.3 {
  INSERT INTO t1(e) VALUES(x'3456');
} {1 {cannot store BLOB value in REAL column t1.e}}

finish_test
Added test/strict2.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
# 2021-08-19
#
# 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 STRICT tables.
#

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

# PRAGMA integrity_check on a STRICT table should verify that
# all of the values are of the correct type.
#
do_execsql_test strict2-1.1 {
  CREATE TABLE t1(
    a INT,
    b INTEGER,
    c TEXT,
    d REAL,
    e BLOB
  ) STRICT;
  CREATE TABLE t1nn(
    a INT NOT NULL,
    b INTEGER NOT NULL,
    c TEXT NOT NULL,
    d REAL NOT NULL,
    e BLOB NOT NULL
  ) STRICT;
  CREATE TABLE t2(a,b,c,d,e);
  INSERT INTO t1(a,b,c,d,e) VALUES(1,1,'one',1.0,x'b1'),(2,2,'two',2.25,x'b2b2b2');
  PRAGMA writable_schema=on;
  UPDATE sqlite_schema SET rootpage=(SELECT rootpage FROM sqlite_schema WHERE name='t1');
} {}
db close
sqlite3 db test.db
do_execsql_test strict2-1.2 {
  PRAGMA quick_check('t1');
} {ok}
do_execsql_test strict2-1.3 {
  UPDATE t2 SET a=2.5 WHERE b=2;
  PRAGMA quick_check('t1');
} {{non-INT value in t1.a}}
do_execsql_test strict2-1.4 {
  UPDATE t2 SET a='xyz' WHERE b=2;
  PRAGMA quick_check('t1');
} {{non-INT value in t1.a}}
do_execsql_test strict2-1.5 {
  UPDATE t2 SET a=x'445566' WHERE b=2;
  PRAGMA quick_check('t1');
} {{non-INT value in t1.a}}
do_execsql_test strict2-1.6 {
  UPDATE t2 SET a=2.5 WHERE b=2;
  PRAGMA quick_check('t1nn');
} {{non-INT value in t1nn.a}}
do_execsql_test strict2-1.7 {
  UPDATE t2 SET a='xyz' WHERE b=2;
  PRAGMA quick_check('t1nn');
} {{non-INT value in t1nn.a}}
do_execsql_test strict2-1.8 {
  UPDATE t2 SET a=x'445566' WHERE b=2;
  PRAGMA quick_check('t1nn');
} {{non-INT value in t1nn.a}}

do_execsql_test strict2-1.13 {
  UPDATE t2 SET a=2 WHERE b=2;
  UPDATE t2 SET b=2.5 WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-INTEGER value in t1.b}}
do_execsql_test strict2-1.14 {
  UPDATE t2 SET b='two' WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-INTEGER value in t1.b}}
do_execsql_test strict2-1.15 {
  UPDATE t2 SET b=x'b0b1b2b3b4' WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-INTEGER value in t1.b}}
do_execsql_test strict2-1.16 {
  UPDATE t2 SET b=NULL WHERE a=2;
  PRAGMA quick_check('t1');
} {ok}
do_execsql_test strict2-1.17 {
  UPDATE t2 SET b=2.5 WHERE a=2;
  PRAGMA quick_check('t1nn');
} {{non-INTEGER value in t1nn.b}}
do_execsql_test strict2-1.18 {
  UPDATE t2 SET b=NULL WHERE a=2;
  PRAGMA quick_check('t1nn');
} {{NULL value in t1nn.b}}

do_execsql_test strict2-1.23 {
  UPDATE t2 SET b=2 WHERE a=2;
  UPDATE t2 SET c=9 WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-TEXT value in t1.c}}
do_execsql_test strict2-1.24 {
  UPDATE t2 SET c=9.5 WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-TEXT value in t1.c}}
do_execsql_test strict2-1.25 {
  UPDATE t2 SET c=x'b0b1b2b3b4' WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-TEXT value in t1.c}}

do_execsql_test strict2-1.33 {
  UPDATE t2 SET c='two' WHERE a=2;
  UPDATE t2 SET d=9 WHERE a=2;
  PRAGMA quick_check('t1');
} {ok}
do_execsql_test strict2-1.34 {
  UPDATE t2 SET d='nine' WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-REAL value in t1.d}}
do_execsql_test strict2-1.35 {
  UPDATE t2 SET d=x'b0b1b2b3b4' WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-REAL value in t1.d}}

do_execsql_test strict2-1.43 {
  UPDATE t2 SET d=2.5 WHERE a=2;
  UPDATE t2 SET e=9 WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-BLOB value in t1.e}}
do_execsql_test strict2-1.44 {
  UPDATE t2 SET e=9.5 WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-BLOB value in t1.e}}
do_execsql_test strict2-1.45 {
  UPDATE t2 SET e='hello' WHERE a=2;
  PRAGMA quick_check('t1');
} {{non-BLOB value in t1.e}}

do_execsql_test strict2-2.0 {
  DROP TABLE IF EXISTS t2;
  CREATE TABLE t2(a INT, b ANY) STRICT;
  INSERT INTO t2(a,b) VALUES(1,2),(3,4.5),(5,'six'),(7,x'8888'),(9,NULL);
  PRAGMA integrity_check(t2);
} {ok}

finish_test
Changes to test/tclsqlite.test.
844
845
846
847
848
849
850



































851

  db bind_fallback bind_fallback_does_not_exist
} {}
do_catchsql_test 19.911 {
  SELECT $abc, typeof($abc), $def, typeof($def), $ghi, typeof($ghi);
} {1 {invalid command name "bind_fallback_does_not_exist"}}
db bind_fallback {}




































finish_test








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

>
844
845
846
847
848
849
850
851
852
853
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
883
884
885
886
887
  db bind_fallback bind_fallback_does_not_exist
} {}
do_catchsql_test 19.911 {
  SELECT $abc, typeof($abc), $def, typeof($def), $ghi, typeof($ghi);
} {1 {invalid command name "bind_fallback_does_not_exist"}}
db bind_fallback {}

#-------------------------------------------------------------------------
do_test 20.0 {
  db transaction {
    db close
  }
} {}

do_test 20.1 {
  sqlite3 db test.db
  set rc [catch {
    db eval {SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3} { db close }
  } msg]
  list $rc $msg
} {1 {invalid command name "db"}}
  

proc closedb {} {
  db close
  return 10
}
proc func1 {} { return 1 }

sqlite3 db test.db
db func closedb closedb
db func func1 func1

do_test 20.2 {
  set rc [catch {
    db eval {
      SELECT closedb(),func1() UNION ALL SELECT 20,30 UNION ALL SELECT 30,40
    }
  } msg]
  list $rc $msg
} {0 {10 1 20 30 30 40}}

finish_test

Changes to test/tester.tcl.
84
85
86
87
88
89
90



91
92
93
94
95
96
97
#
# Command to test whether or not --verbose=1 was specified on the command
# line (returns 0 for not-verbose, 1 for verbose and 2 for "verbose in the
# output file only").
#
#      verbose
#




# Set the precision of FP arithmatic used by the interpreter. And
# configure SQLite to take database file locks on the page that begins
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
# very large database files.
#







>
>
>







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#
# Command to test whether or not --verbose=1 was specified on the command
# line (returns 0 for not-verbose, 1 for verbose and 2 for "verbose in the
# output file only").
#
#      verbose
#

# Only run this script once.  If sourced a second time, make it a no-op
if {[info exists ::tester_tcl_has_run]} return

# Set the precision of FP arithmatic used by the interpreter. And
# configure SQLite to take database file locks on the page that begins
# 64KB into the database file instead of the one 1GB in. This means
# the code that handles that special case can be tested without creating
# very large database files.
#
1200
1201
1202
1203
1204
1205
1206











1207
1208
1209
1210
1211
1212
1213
    }
  }
}

# Run this routine last
#
proc finish_test {} {











  catch {db close}
  catch {db1 close}
  catch {db2 close}
  catch {db3 close}
  if {0==[info exists ::SLAVE]} { finalize_testing }
}
proc finalize_testing {} {







>
>
>
>
>
>
>
>
>
>
>







1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
    }
  }
}

# Run this routine last
#
proc finish_test {} {
  global argv
  if {[llength $argv]>0} {
    # If additional test scripts are specified on the command-line, 
    # run them also, before quitting.
    proc finish_test {} {return}
    foreach extra $argv {
      puts "Running \"$extra\""
      db_delete_and_reopen
      uplevel #0 source $extra
    }
  }
  catch {db close}
  catch {db1 close}
  catch {db2 close}
  catch {db3 close}
  if {0==[info exists ::SLAVE]} { finalize_testing }
}
proc finalize_testing {} {
2509
2510
2511
2512
2513
2514
2515


# this setting by invoking "database_can_be_corrupt"
#
database_never_corrupt
extra_schema_checks 1

source $testdir/thread_common.tcl
source $testdir/malloc_common.tcl









>
>
2523
2524
2525
2526
2527
2528
2529
2530
2531
# this setting by invoking "database_can_be_corrupt"
#
database_never_corrupt
extra_schema_checks 1

source $testdir/thread_common.tcl
source $testdir/malloc_common.tcl

set tester_tcl_has_run 1
Changes to test/tkt-8454a207b9.test.
13
14
15
16
17
18
19






20
21
22
23
24
25
26
# it tests that ticket [8454a207b9fd2243c4c6b7a73f67ea0315717c1a].  Verify
# that a negative default value on an added text column actually comes
# out negative.
#

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







do_test tkt-8454a207b9.1 {
  db eval {
    CREATE TABLE t1(a);
    INSERT INTO t1 VALUES(1);
    ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT -123.0;
    SELECT b, typeof(b) FROM t1;







>
>
>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# it tests that ticket [8454a207b9fd2243c4c6b7a73f67ea0315717c1a].  Verify
# that a negative default value on an added text column actually comes
# out negative.
#

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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

do_test tkt-8454a207b9.1 {
  db eval {
    CREATE TABLE t1(a);
    INSERT INTO t1 VALUES(1);
    ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT -123.0;
    SELECT b, typeof(b) FROM t1;
Changes to test/tkt-f67b41381a.test.
10
11
12
13
14
15
16





17
18
19
20
21
22
23
#***********************************************************************
# Test that ticket f67b41381a has been resolved.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-f67b41381a






do_execsql_test 1.0 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1);
  ALTER TABLE t1 ADD COLUMN b DEFAULT 2;
  CREATE TABLE t2(a, b);
  INSERT INTO t2 SELECT * FROM t1;







>
>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#***********************************************************************
# Test that ticket f67b41381a has been resolved.
#

set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix tkt-f67b41381a

ifcapable !altertable {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1);
  ALTER TABLE t1 ADD COLUMN b DEFAULT 2;
  CREATE TABLE t2(a, b);
  INSERT INTO t2 SELECT * FROM t1;
Changes to test/transitive1.test.
375
376
377
378
379
380
381
































382
383
  CREATE TABLE t1(c0 INT);
  INSERT INTO t0(c0, c1) VALUES (0, 1);
  INSERT INTO t1(c0) VALUES (1);
  SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (t1.c0=t0.c1);
  SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (likely(t1.c0=t0.c1));
  SELECT ALL * FROM t1,t0 WHERE (likely(t1.c0=t0.c1) AND t1.c0=t0.c0);
} {}

































finish_test







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


375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
  CREATE TABLE t1(c0 INT);
  INSERT INTO t0(c0, c1) VALUES (0, 1);
  INSERT INTO t1(c0) VALUES (1);
  SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (t1.c0=t0.c1);
  SELECT ALL * FROM t1 NATURAL JOIN t0 WHERE (likely(t1.c0=t0.c1));
  SELECT ALL * FROM t1,t0 WHERE (likely(t1.c0=t0.c1) AND t1.c0=t0.c0);
} {}

#-------------------------------------------------------------------------
# 2021-08-31 forum https://sqlite.org/forum/forumpost/8d1b58f112
reset_db
do_execsql_test transitive1-700 {
  CREATE TABLE t1(a INT PRIMARY KEY);
  INSERT INTO t1(a) VALUES(1),(2),(3);
  CREATE TABLE t2(x INTEGER PRIMARY KEY,y INT);
  INSERT INTO t2(y) VALUES(2),(3);
}

do_execsql_test transitive1-710 {
  SELECT * FROM t1 CROSS JOIN t2 WHERE t2.y=t1.a AND t1.a=t2.x
} {}

do_execsql_test transitive1-720 {
  SELECT * FROM t1 CROSS JOIN t2 WHERE likely(t2.y=t1.a) AND unlikely(t1.a=t2.x)
} {}

# 2021-10-04 forum https://sqlite.org/forum/forumpost/a65cacbf5e1c41ba
#
reset_db
do_execsql_test transitive1-800 {
  CREATE TABLE t1(a INT);
  INSERT INTO t1 VALUES(0),(3);
  CREATE TABLE t2(b INT UNIQUE, c INT);
  INSERT INTO t2 VALUES(1,4)	,(0,5);
  SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a AND b IS a);
  SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE a=c AND a IS b);
  SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE a=c AND b IS a);
  SELECT * FROM t1 WHERE EXISTS (SELECT 1 FROM t2 WHERE c=a AND a IS b);
} {}

finish_test
Changes to test/update.test.
615
616
617
618
619
620
621

622
623
624
625
626
627
628
629
630
631

632
633
634
635
636
637
638
} {1 {no such column: nosuchcol}}

} ;# ifcapable {trigger}

# Ticket [https://www.sqlite.org/src/tktview/43107840f1c02] on 2014-10-29
# An assertion fault on UPDATE
#

do_execsql_test update-15.1 {
  CREATE TABLE t15(a INTEGER PRIMARY KEY, b);
  INSERT INTO t15(a,b) VALUES(10,'abc'),(20,'def'),(30,'ghi');
  ALTER TABLE t15 ADD COLUMN c;
  CREATE INDEX t15c ON t15(c);
  INSERT INTO t15(a,b)
   VALUES(5,'zyx'),(15,'wvu'),(25,'tsr'),(35,'qpo');
  UPDATE t15 SET c=printf("y%d",a) WHERE c IS NULL;
  SELECT a,b,c,'|' FROM t15 ORDER BY a;
} {5 zyx y5 | 10 abc y10 | 15 wvu y15 | 20 def y20 | 25 tsr y25 | 30 ghi y30 | 35 qpo y35 |}


# Unreleased bug in UPDATE caused by the UPSERT changes.
# Found by OSSFuzz as soon as the UPSERT changes landed on trunk.
# Never released into the wild.  2018-04-19.
#
do_execsql_test update-16.1 {
  CREATE TABLE t16(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b UNIQUE);







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







615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
} {1 {no such column: nosuchcol}}

} ;# ifcapable {trigger}

# Ticket [https://www.sqlite.org/src/tktview/43107840f1c02] on 2014-10-29
# An assertion fault on UPDATE
#
ifcapable altertable {
  do_execsql_test update-15.1 {
    CREATE TABLE t15(a INTEGER PRIMARY KEY, b);
    INSERT INTO t15(a,b) VALUES(10,'abc'),(20,'def'),(30,'ghi');
    ALTER TABLE t15 ADD COLUMN c;
    CREATE INDEX t15c ON t15(c);
    INSERT INTO t15(a,b)
      VALUES(5,'zyx'),(15,'wvu'),(25,'tsr'),(35,'qpo');
    UPDATE t15 SET c=printf("y%d",a) WHERE c IS NULL;
    SELECT a,b,c,'|' FROM t15 ORDER BY a;
  } {5 zyx y5 | 10 abc y10 | 15 wvu y15 | 20 def y20 | 25 tsr y25 | 30 ghi y30 | 35 qpo y35 |}
}

# Unreleased bug in UPDATE caused by the UPSERT changes.
# Found by OSSFuzz as soon as the UPSERT changes landed on trunk.
# Never released into the wild.  2018-04-19.
#
do_execsql_test update-16.1 {
  CREATE TABLE t16(a INTEGER PRIMARY KEY ON CONFLICT REPLACE, b UNIQUE);
Changes to test/view.test.
51
52
53
54
55
56
57





58
59
60
61
62
63
64
do_test view-1.1.110 {
  db config enable_view on
  catchsql {
    SELECT * FROM v1 ORDER BY a;
    SELECT * FROM v1temp ORDER BY a;
  }
} {0 {1 2 4 5 7 8 1 2 4 5 7 8}}





do_test view-1.2 {
  catchsql {
    ROLLBACK;
    SELECT * FROM v1 ORDER BY a;
  }
} {1 {no such table: v1}}
do_test view-1.3 {







>
>
>
>
>







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
do_test view-1.1.110 {
  db config enable_view on
  catchsql {
    SELECT * FROM v1 ORDER BY a;
    SELECT * FROM v1temp ORDER BY a;
  }
} {0 {1 2 4 5 7 8 1 2 4 5 7 8}}
ifcapable vtab {
  do_execsql_test view-1.1.120 {
    SELECT name, type FROM pragma_table_list('v1');
  } {v1 view}
}
do_test view-1.2 {
  catchsql {
    ROLLBACK;
    SELECT * FROM v1 ORDER BY a;
  }
} {1 {no such table: v1}}
do_test view-1.3 {
Added test/vtabK.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
# 2020-09-24
#
# 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 tests for a strange scenario discovered by
# dbsqlfuzz (0ad6d441f9bf3dfc32626a9900bc1700495b16f9) in which a
# virtual table is named "sqlite_stat1".
#

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

ifcapable !vtab||!rtree||!fts5 {
  finish_test
  return
}

do_execsql_test 100 {
  CREATE TABLE t1(x);
  INSERT INTO t1 VALUES(123);
  PRAGMA writable_schema=ON;
  CREATE VIRTUAL TABLE sqlite_stat1 USING fts5(a);
  PRAGMA writable_schema=OFF;
  CREATE VIRTUAL TABLE t3 USING fts5(b);
  INSERT INTO t3 VALUES('this is a test');
}
do_catchsql_test 110 {
  CREATE VIRTUAL TABLE t2 USING rtree(id,x,y);
} {1 {no such column: stat}}
do_execsql_test 120 {
  SELECT * FROM t1;
} {123}
do_execsql_test 130 {
  INSERT INTO t3(b) VALUES('Four score and seven years ago');
  SELECT * FROM t3 WHERE t3 MATCH 'this';
} {{this is a test}}
do_execsql_test 140 {
  SELECT * FROM t3 WHERE t3 MATCH 'four seven';
} {{Four score and seven years ago}}
do_execsql_test 150 {
  INSERT INTO sqlite_stat1(a)
  VALUES('We hold these truths to be self-evident...');
  SELECT * FROM sqlite_stat1;
} {{We hold these truths to be self-evident...}}
do_catchsql_test 160 {
  ANALYZE;
} {1 {database disk image is malformed}}
do_execsql_test 170 {
  PRAGMA integrity_check;
} {ok}

# Follow-on dbsqlfuzz bc02a0cde82dee801a8d6f653d2831680f87dca1
reset_db
do_execsql_test 200 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES('Ebed-malech');
  CREATE TABLE x(a);
  PRAGMA writable_schema=ON;
  CREATE VIRTUAL TABLE sqlite_stat1 USING fts5(a);
} {}
do_catchsql_test 210 {
  CREATE VIRTUAL TABLE t2 USING rtree(id,x,y);
} {1 {no such column: stat}}
do_execsql_test 220 {
  SELECT * FROM t1;
} {Ebed-malech}

# Follow-on dbsqlfuzz a097eaad43c3c845b236126df92fb49b25449b0c
reset_db
do_catchsql_test 300 {
  CREATE VIRTUAL TABLE t1 USING rtree(a,b,c);
  CREATE TABLE t2(x);
  ALTER TABLE t2 ADD d GENERATED ALWAYS AS (c IN (SELECT 1 FROM t1)) VIRTUAL;
} {1 {error in table t2 after rename: subqueries prohibited in generated columns}}
  
finish_test
Changes to test/whereE.test.
13
14
15
16
17
18
19






20
21
22
23
24
25
26
# is making good planning decisions.
#


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







do_execsql_test 1.1 {
  CREATE TABLE t1(a,b);
  INSERT INTO t1 VALUES(1,10), (2,20), (3,30), (2,22), (3, 33);
  INSERT INTO t1 SELECT * FROM t1;
  INSERT INTO t1 SELECT * FROM t1;
  INSERT INTO t1 SELECT * FROM t1;







>
>
>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# is making good planning decisions.
#


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

# If SQLITE_OMIT_ALTERTABLE is defined, omit this file.
ifcapable !altertable {
  finish_test
  return
}

do_execsql_test 1.1 {
  CREATE TABLE t1(a,b);
  INSERT INTO t1 VALUES(1,10), (2,20), (3,30), (2,22), (3, 33);
  INSERT INTO t1 SELECT * FROM t1;
  INSERT INTO t1 SELECT * FROM t1;
  INSERT INTO t1 SELECT * FROM t1;
Changes to test/window1.test.
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
  )
  FROM (
    SELECT * FROM t2
  );
} {1 {frame ending offset must be a non-negative integer}}

# 2019-11-16 chromium issue 1025467

db close
sqlite3 db :memory:
do_catchsql_test 32.10 {
  CREATE VIEW a AS SELECT NULL INTERSECT SELECT NULL ORDER BY s() OVER R;
  CREATE TABLE a0 AS SELECT 0;
  ALTER TABLE a0 RENAME TO S;
} {1 {error in view a: 1st ORDER BY term does not match any column in the result set}}


reset_db
do_execsql_test 33.1 {
  CREATE TABLE t1(aa, bb);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(5, 6);
  CREATE TABLE t2(x);







>
|
|
|
|
|
|
|
>







1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
  )
  FROM (
    SELECT * FROM t2
  );
} {1 {frame ending offset must be a non-negative integer}}

# 2019-11-16 chromium issue 1025467
ifcapable altertable {
  db close
  sqlite3 db :memory:
  do_catchsql_test 32.10 {
    CREATE VIEW a AS SELECT NULL INTERSECT SELECT NULL ORDER BY s() OVER R;
    CREATE TABLE a0 AS SELECT 0;
    ALTER TABLE a0 RENAME TO S;
  } {1 {error in view a: 1st ORDER BY term does not match any column in the result set}}
}

reset_db
do_execsql_test 33.1 {
  CREATE TABLE t1(aa, bb);
  INSERT INTO t1 VALUES(1, 2);
  INSERT INTO t1 VALUES(5, 6);
  CREATE TABLE t2(x);
Changes to test/windowB.test.
1
2
3
4
5
6
7
8
9
10
11

12
13
14
15
16
17
18
# 2019-08-30
#
# 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 RANGE BETWEEN and especially with NULLS LAST

#

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

ifcapable !windowfunc {











>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 2019-08-30
#
# 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 RANGE BETWEEN and especially with NULLS LAST
# and for varying separator handling by group_concat().
#

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

ifcapable !windowfunc {
352
353
354
355
356
357
358







359
360

do_execsql_test 8.1 {
  SELECT sum(c) OVER
    (ORDER BY a COLLATE nocase RANGE BETWEEN 10.0 PRECEDING AND 5.0 PRECEDING)
  FROM t1;
} {111 660 938 979}









finish_test







>
>
>
>
>
>
>


353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368

do_execsql_test 8.1 {
  SELECT sum(c) OVER
    (ORDER BY a COLLATE nocase RANGE BETWEEN 10.0 PRECEDING AND 5.0 PRECEDING)
  FROM t1;
} {111 660 938 979}

do_execsql_test 9.0 {
  CREATE TABLE seps(x);
  INSERT INTO seps(x) VALUES ('1'), ('22'), ('333'), ('4444');
  SELECT group_concat('-', x)
    OVER ( ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING )
  FROM seps;
} {-22- -22-333- -333-4444- -4444-}

finish_test
Added test/windowC.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
# 2021-09-29
#
# 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 varying separator handling by group_concat().
#

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

ifcapable !windowfunc {
  finish_test
  return
}

do_execsql_test 1.0 {
  CREATE TABLE x1(i INTEGER PRIMARY KEY, x);
}

foreach {tn bBlob seps} {
  1 0 {a b c def g}
  2 0 {abcdefg {} {} abcdefg}
  3 0 {a bc def ghij klmno pqrstu}
  4 1 {a bc def ghij klmno pqrstu}
  5 1 {, , , , , , , , , , , , ....... , ,}
} {
  foreach type {text blob} {
    do_test 1.$type.$tn.1 {
      execsql { DELETE FROM x1 }
      foreach s $seps {
        if {$type=="text"} {
          execsql {INSERT INTO x1 VALUES(NULL, $s)}
        } else {
          execsql {INSERT INTO x1 VALUES(NULL, CAST ($s AS blob))}
        }
      }
    } {}

    foreach {tn2 win} {
      1     "ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING"
      2     "ROWS BETWEEN 2 PRECEDING AND CURRENT ROW"
      3     "ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING"
    } {
      do_test 1.$type.$tn.2.$tn2 {
        db eval "
          SELECT group_concat('val', x) OVER ( ORDER BY i $win ) AS val FROM x1
          " {
            if {[string range $val 0 2]!="val"
              || [string range $val end-2 end]!="val"
            } {
              error "unexpected return value: $val"
            }
          }
      } {} 
    }
  }
}

finish_test
Changes to test/windowfault.test.
287
288
289
290
291
292
293







































294
295
      SELECT a, b, row_number() OVER (PARTITION BY a COLLATE nocase ORDER BY b) FROM t1
    )
    SELECT * FROM v WHERE a=2
  }
} -test {
  faultsim_test_result {0 {}}
}








































finish_test







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


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
      SELECT a, b, row_number() OVER (PARTITION BY a COLLATE nocase ORDER BY b) FROM t1
    )
    SELECT * FROM v WHERE a=2
  }
} -test {
  faultsim_test_result {0 {}}
}

#-------------------------------------------------------------------------
reset_db
do_execsql_test 13.0 {
  CREATE TABLE t1(id INTEGER PRIMARY KEY, a, b);
  INSERT INTO t1 VALUES(1, '1', 'a');
  INSERT INTO t1 VALUES(2, '22', 'b');
  INSERT INTO t1 VALUES(3, '333', 'c');
  INSERT INTO t1 VALUES(4, '4444', 'dddd');
  INSERT INTO t1 VALUES(5, '55555', 'e');
  INSERT INTO t1 VALUES(6, '666666', 'f');
  INSERT INTO t1 VALUES(7, '7777777', 'gggggggggg');
} {}

set queryres [list {*}{
  1b22
  1b22c333
  22c333dddd4444 
  333dddd4444e55555 
  4444e55555f666666
  55555f666666gggggggggg7777777 
  666666gggggggggg7777777
}]
do_execsql_test 13.1 {
  SELECT group_concat(a, b) OVER (
    ORDER BY id RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
  ) FROM t1
} $queryres

do_faultsim_test 13 -faults oom* -prep {
} -body {
  execsql {
    SELECT group_concat(a, b) OVER (
        ORDER BY id RANGE BETWEEN 1 PRECEDING AND 1 FOLLOWING
    ) FROM t1
  }
} -test {
  faultsim_test_result [list 0 $::queryres]
}

finish_test
Changes to test/with2.test.
548
549
550
551
552
553
554

555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
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
    )
  )
} {1}

# 2021-05-21
# Forum post https://sqlite.org/forum/forumpost/aa4a7a3980
#

reset_db
do_execsql_test 11.1 {
  CREATE TABLE t1(a);
  CREATE VIEW v2(c) AS
      WITH x AS (
        WITH y AS (
           WITH z AS(SELECT * FROM t1)
           SELECT * FROM v2
        ) SELECT a
      ) SELECT * from t1;
  ALTER TABLE t1 RENAME COLUMN a TO b;
  SELECT sql FROM sqlite_schema WHERE name='t1';
} {{CREATE TABLE t1(b)}}
do_catchsql_test 11.2 {
  INSERT INTO t1 VALUES(55);
  SELECT * FROM v2;
} {0 55}
do_catchsql_test 11.3 {
  DROP VIEW v2;
  CREATE VIEW v2(c) AS
      WITH x AS (
        WITH y AS (
           WITH z AS(SELECT * FROM t1)
           SELECT * FROM v2
        ) SELECT a
      ) SELECT * from t1, x;
  SELECT * FROM v2;
} {1 {no such column: a}}
do_catchsql_test 11.4 {
  DROP VIEW v2;
  CREATE VIEW v2(c) AS
      WITH x AS (
        WITH y AS (
           WITH z AS(SELECT * FROM t1)
           SELECT * FROM v2
        ) SELECT *
      ) SELECT * from t1, x;
  SELECT * FROM v2;
} {1 {no tables specified}}
do_catchsql_test 11.5 {
  WITH x AS (
    WITH y AS (
       WITH z AS(SELECT * FROM t1)
       SELECT * FROM no_such_table
    ) SELECT a
  ) SELECT * from t1;
} {0 55}


# 2021-05-23 dbsqlfuzz 6b7a144674e215f06ddfeb9042c873d9ee956ac0 */
reset_db

do_execsql_test 12.1 {
  CREATE TABLE t1(a);
  INSERT INTO t1 VALUES(1),('hello'),(4.25),(NULL),(x'3c626c6f623e');
  CREATE VIEW v2(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM t1) SELECT * FROM v2) SELECT a) SELECT * from t1;
  CREATE VIEW v3(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM v2) SELECT * FROM v3) SELECT a) SELECT * from t1;
  ALTER TABLE t1 RENAME TO t1x;
  SELECT quote(c) FROM v3;
} {1 'hello' 4.25 NULL X'3C626C6F623E'}












finish_test







>

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



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


548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
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
618
619
620
621
622
623
624
625
626
627
628
    )
  )
} {1}

# 2021-05-21
# Forum post https://sqlite.org/forum/forumpost/aa4a7a3980
#
ifcapable altertable {
reset_db
  do_execsql_test 11.1 {
    CREATE TABLE t1(a);
    CREATE VIEW v2(c) AS
        WITH x AS (
          WITH y AS (
             WITH z AS(SELECT * FROM t1)
             SELECT * FROM v2
          ) SELECT a
        ) SELECT * from t1;
    ALTER TABLE t1 RENAME COLUMN a TO b;
    SELECT sql FROM sqlite_schema WHERE name='t1';
  } {{CREATE TABLE t1(b)}}
  do_catchsql_test 11.2 {
    INSERT INTO t1 VALUES(55);
    SELECT * FROM v2;
  } {0 55}
  do_catchsql_test 11.3 {
    DROP VIEW v2;
    CREATE VIEW v2(c) AS
        WITH x AS (
          WITH y AS (
             WITH z AS(SELECT * FROM t1)
             SELECT * FROM v2
          ) SELECT a
        ) SELECT * from t1, x;
    SELECT * FROM v2;
  } {1 {no such column: a}}
  do_catchsql_test 11.4 {
    DROP VIEW v2;
    CREATE VIEW v2(c) AS
        WITH x AS (
          WITH y AS (
             WITH z AS(SELECT * FROM t1)
             SELECT * FROM v2
          ) SELECT *
        ) SELECT * from t1, x;
    SELECT * FROM v2;
  } {1 {no tables specified}}
  do_catchsql_test 11.5 {
    WITH x AS (
      WITH y AS (
         WITH z AS(SELECT * FROM t1)
         SELECT * FROM no_such_table
      ) SELECT a
    ) SELECT * from t1;
  } {0 55}
}

# 2021-05-23 dbsqlfuzz 6b7a144674e215f06ddfeb9042c873d9ee956ac0 */
reset_db
ifcapable altertable {
  do_execsql_test 12.1 {
    CREATE TABLE t1(a);
    INSERT INTO t1 VALUES(1),('hello'),(4.25),(NULL),(x'3c626c6f623e');
    CREATE VIEW v2(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM t1) SELECT * FROM v2) SELECT a) SELECT * from t1;
    CREATE VIEW v3(c) AS WITH x AS (WITH y AS (WITH z AS(SELECT * FROM v2) SELECT * FROM v3) SELECT a) SELECT * from t1;
    ALTER TABLE t1 RENAME TO t1x;
    SELECT quote(c) FROM v3;
  } {1 'hello' 4.25 NULL X'3C626C6F623E'}
}

# 2021-08-11 https://sqlite.org/forum/forumpost/d496c3d29bc93736
reset_db
do_execsql_test 13.1 {
  WITH
    t1(x) AS (SELECT 111),
    t2(y) AS (SELECT 222),
    t3(z) AS (SELECT * FROM t2 WHERE false UNION ALL SELECT * FROM t2)
  SELECT * FROM t1, t3;
} {111 222}

finish_test
Changes to test/without_rowid1.test.
34
35
36
37
38
39
40



41
42
43
44
45
46
47
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

integrity_check without_rowid1-1.0ic

do_execsql_test_if_vtab without_rowid1-1.0ixi {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {c 1 a 1 b 0 d 0}




do_execsql_test without_rowid1-1.1 {
  SELECT *, '|' FROM t1 ORDER BY +c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

do_execsql_test without_rowid1-1.2 {
  SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC;







>
>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

integrity_check without_rowid1-1.0ic

do_execsql_test_if_vtab without_rowid1-1.0ixi {
  SELECT name, key FROM pragma_index_xinfo('t1');
} {c 1 a 1 b 0 d 0}
do_execsql_test_if_vtab without_rowid1-1.0tl {
  SELECT wr FROM pragma_table_list('t1');
} {1}

do_execsql_test without_rowid1-1.1 {
  SELECT *, '|' FROM t1 ORDER BY +c, a;
} {arctic sleep ammonia helena | journal sherman ammonia helena | dynamic juliet flipper command | journal sherman gamma patriot |}

do_execsql_test without_rowid1-1.2 {
  SELECT *, '|' FROM t1 ORDER BY c DESC, a DESC;
451
452
453
454
455
456
457

458
459
460
461
462
463
464
465
466
467
468

469
  INSERT INTO t1 SELECT * FROM t0;
  PRAGMA integrity_check;
  SELECT * FROM t0, t1;
} {ok abc xyz abc xyz}

# 2021-05-13 https://sqlite.org/forum/forumpost/6c8960f545
reset_db

do_execsql_test 14.1 {
  CREATE TABLE t1(a INT PRIMARY KEY) WITHOUT ROWID;
  INSERT INTO t1(a) VALUES(10);
  ALTER TABLE t1 ADD COLUMN b INT;
  SELECT * FROM t1 WHERE a=20 OR (a=10 AND b=10);
} {}
do_execsql_test 14.2 {
  CREATE TABLE dual AS SELECT 'X' AS dummy;
  EXPLAIN QUERY PLAN SELECT * FROM dual, t1 WHERE a=10 AND b=10;
} {~/b=/}
  

finish_test







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

454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
  INSERT INTO t1 SELECT * FROM t0;
  PRAGMA integrity_check;
  SELECT * FROM t0, t1;
} {ok abc xyz abc xyz}

# 2021-05-13 https://sqlite.org/forum/forumpost/6c8960f545
reset_db
ifcapable altertable {
  do_execsql_test 14.1 {
    CREATE TABLE t1(a INT PRIMARY KEY) WITHOUT ROWID;
    INSERT INTO t1(a) VALUES(10);
    ALTER TABLE t1 ADD COLUMN b INT;
    SELECT * FROM t1 WHERE a=20 OR (a=10 AND b=10);
  } {}
  do_execsql_test 14.2 {
    CREATE TABLE dual AS SELECT 'X' AS dummy;
    EXPLAIN QUERY PLAN SELECT * FROM dual, t1 WHERE a=10 AND b=10;
  } {~/b=/}
}
  
finish_test
Changes to test/without_rowid5.test.
181
182
183
184
185
186
187

















































































188
189
190
191
192
193
194
} {1 {NOT NULL constraint failed: nnw.c}}
do_catchsql_test without_rowid5-5.8 {
  INSERT INTO nnw VALUES(4,5,6,7,NULL)
} {1 {NOT NULL constraint failed: nnw.e}}
do_execsql_test without_rowid5-5.9 {
  SELECT count(*) FROM nnw;
} {1}


















































































# EVIDENCE-OF: R-12643-30541 The incremental blob I/O mechanism does not
# work for WITHOUT ROWID tables.
#
# EVIDENCE-OF: R-40134-30296 Table zTable is a WITHOUT ROWID table
#
do_execsql_test without_rowid5-6.1 {







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







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
} {1 {NOT NULL constraint failed: nnw.c}}
do_catchsql_test without_rowid5-5.8 {
  INSERT INTO nnw VALUES(4,5,6,7,NULL)
} {1 {NOT NULL constraint failed: nnw.e}}
do_execsql_test without_rowid5-5.9 {
  SELECT count(*) FROM nnw;
} {1}

# Ticket f2be158c57aaa8c6 (2021-08-18)
# NOT NULL ON CONFLICT clauses work on WITHOUT ROWID tables now.
# 
do_test without_rowid5-5.100 {
  db eval {
    DROP TABLE IF EXISTS t5;
    CREATE TABLE t5(
      a INT NOT NULL ON CONFLICT ROLLBACK,
      b TEXT,
      c TEXT,
      PRIMARY KEY(a,b)
    ) WITHOUT ROWID;
    BEGIN;
    INSERT INTO t5(a,b,c) VALUES(1,2,3);
  }
  catch {db eval {INSERT INTO t5(a,b,c) VALUES(NULL,6,7);}}
  db eval {
    SELECT * FROM t5;
  }
} {}
do_test without_rowid5-5.101 {
  db eval {
    DROP TABLE IF EXISTS t5;
    CREATE TABLE t5(
      a INT NOT NULL ON CONFLICT ABORT,
      b TEXT,
      c TEXT,
      PRIMARY KEY(a,b)
    ) WITHOUT ROWID;
    BEGIN;
    INSERT INTO t5(a,b,c) VALUES(1,2,3);
  }
  catch {db eval {INSERT INTO t5(a,b,c) VALUES(NULL,6,7);}}
  db eval {
    COMMIT;
    SELECT * FROM t5;
  }
} {1 2 3}
do_test without_rowid5-5.102 {
  db eval {
    DROP TABLE IF EXISTS t5;
    CREATE TABLE t5(
      a INT NOT NULL ON CONFLICT FAIL,
      b TEXT,
      c TEXT,
      PRIMARY KEY(a,b)
    ) WITHOUT ROWID;
  }
  catch {db eval {INSERT INTO t5(a,b,c) VALUES(1,2,3),(NULL,4,5),(6,7,8);}}
  db eval {
    SELECT * FROM t5;
  }
} {1 2 3}
do_test without_rowid5-5.103 {
  db eval {
    DROP TABLE IF EXISTS t5;
    CREATE TABLE t5(
      a INT NOT NULL ON CONFLICT IGNORE,
      b TEXT,
      c TEXT,
      PRIMARY KEY(a,b)
    ) WITHOUT ROWID;
    INSERT INTO t5(a,b,c) VALUES(1,2,3),(NULL,4,5),(6,7,8);
    SELECT * FROM t5;
  }
} {1 2 3 6 7 8}
do_test without_rowid5-5.104 {
  db eval {
    DROP TABLE IF EXISTS t5;
    CREATE TABLE t5(
      a INT NOT NULL ON CONFLICT REPLACE DEFAULT 3,
      b TEXT,
      c TEXT,
      PRIMARY KEY(a,b)
    ) WITHOUT ROWID;
    INSERT INTO t5(a,b,c) VALUES(1,2,3),(NULL,4,5),(6,7,8);
    SELECT * FROM t5;
  }
} {1 2 3 3 4 5 6 7 8}


# EVIDENCE-OF: R-12643-30541 The incremental blob I/O mechanism does not
# work for WITHOUT ROWID tables.
#
# EVIDENCE-OF: R-40134-30296 Table zTable is a WITHOUT ROWID table
#
do_execsql_test without_rowid5-6.1 {
Changes to tool/lemon.c.
3567
3568
3569
3570
3571
3572
3573
3574


3575
3576
3577
3578
3579
3580
3581
  int act;
  switch( ap->type ){
    case SHIFT:  act = ap->x.stp->statenum;                        break;
    case SHIFTREDUCE: {
      /* Since a SHIFT is inherient after a prior REDUCE, convert any
      ** SHIFTREDUCE action with a nonterminal on the LHS into a simple
      ** REDUCE action: */
      if( ap->sp->index>=lemp->nterminal ){


        act = lemp->minReduce + ap->x.rp->iRule;
      }else{
        act = lemp->minShiftReduce + ap->x.rp->iRule;
      }
      break;
    }
    case REDUCE: act = lemp->minReduce + ap->x.rp->iRule;          break;







|
>
>







3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
  int act;
  switch( ap->type ){
    case SHIFT:  act = ap->x.stp->statenum;                        break;
    case SHIFTREDUCE: {
      /* Since a SHIFT is inherient after a prior REDUCE, convert any
      ** SHIFTREDUCE action with a nonterminal on the LHS into a simple
      ** REDUCE action: */
      if( ap->sp->index>=lemp->nterminal
       && (lemp->errsym==0 || ap->sp->index!=lemp->errsym->index)
      ){
        act = lemp->minReduce + ap->x.rp->iRule;
      }else{
        act = lemp->minShiftReduce + ap->x.rp->iRule;
      }
      break;
    }
    case REDUCE: act = lemp->minReduce + ap->x.rp->iRule;          break;
Changes to tool/lempar.c.
977
978
979
980
981
982
983
984
985
986
987
988

989
990
991
992
993
994
995
996
997
998
          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
             yyTracePrompt,yyTokenName[yymajor]);
        }
#endif
        yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
        yymajor = YYNOCODE;
      }else{
        while( yypParser->yytos >= yypParser->yystack
            && (yyact = yy_find_reduce_action(
                        yypParser->yytos->stateno,
                        YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
        ){

          yy_pop_parser_stack(yypParser);
        }
        if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
          yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
          yy_parse_failed(yypParser);
#ifndef YYNOERRORRECOVERY
          yypParser->yyerrcnt = -1;
#endif
          yymajor = YYNOCODE;
        }else if( yymx!=YYERRORSYMBOL ){







|
|
<
|
<
>


|







977
978
979
980
981
982
983
984
985

986

987
988
989
990
991
992
993
994
995
996
997
          fprintf(yyTraceFILE,"%sDiscard input token %s\n",
             yyTracePrompt,yyTokenName[yymajor]);
        }
#endif
        yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
        yymajor = YYNOCODE;
      }else{
        while( yypParser->yytos > yypParser->yystack ){
          yyact = yy_find_reduce_action(yypParser->yytos->stateno,

                                        YYERRORSYMBOL);

          if( yyact<=YY_MAX_SHIFTREDUCE ) break;
          yy_pop_parser_stack(yypParser);
        }
        if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){
          yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
          yy_parse_failed(yypParser);
#ifndef YYNOERRORRECOVERY
          yypParser->yyerrcnt = -1;
#endif
          yymajor = YYNOCODE;
        }else if( yymx!=YYERRORSYMBOL ){
Changes to tool/mkkeywordhash.c.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  int substrOffset;    /* Offset into substrId for start of this keyword */
  char zOrigName[20];  /* Original keyword name before processing */
};

/*
** Define masks used to determine which keywords are allowed
*/
#ifdef SQLITE_OMIT_ALTERTABLE
#  define ALTER      0
#else
#  define ALTER      0x00000001
#endif
#define ALWAYS       0x00000002
#ifdef SQLITE_OMIT_ANALYZE
#  define ANALYZE    0







|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
  int substrOffset;    /* Offset into substrId for start of this keyword */
  char zOrigName[20];  /* Original keyword name before processing */
};

/*
** Define masks used to determine which keywords are allowed
*/
#if defined(SQLITE_OMIT_ALTERTABLE) || defined(SQLITE_OMIT_VIRTUALTABLE)
#  define ALTER      0
#else
#  define ALTER      0x00000001
#endif
#define ALWAYS       0x00000002
#ifdef SQLITE_OMIT_ANALYZE
#  define ANALYZE    0
Changes to tool/mkpragmatab.tcl.
227
228
229
230
231
232
233






234
235
236
237
238
239
240
  NAME: table_xinfo
  TYPE: TABLE_INFO
  FLAG: NeedSchema Result1 SchemaOpt
  ARG:  1
  COLS: cid name type notnull dflt_value pk hidden
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)







  NAME: stats
  FLAG: NeedSchema Result0 SchemaReq
  COLS: tbl idx wdth hght flgs
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)

  NAME: index_info
  TYPE: INDEX_INFO







>
>
>
>
>
>







227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  NAME: table_xinfo
  TYPE: TABLE_INFO
  FLAG: NeedSchema Result1 SchemaOpt
  ARG:  1
  COLS: cid name type notnull dflt_value pk hidden
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: table_list
  TYPE: TABLE_LIST
  FLAG: NeedSchema Result1 SchemaOpt
  COLS: schema name type ncol wr strict
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS)

  NAME: stats
  FLAG: NeedSchema Result0 SchemaReq
  COLS: tbl idx wdth hght flgs
  IF:   !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) && defined(SQLITE_DEBUG)

  NAME: index_info
  TYPE: INDEX_INFO
Changes to tool/replace.tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/tcl
#
# Replace string with another string -OR- include
# only lines successfully modified with a regular
# expression.
#
fconfigure stdout -translation binary -encoding binary
fconfigure stderr -translation binary -encoding binary
set mode [string tolower [lindex $argv 0]]
set from [lindex $argv 1]
set to [lindex $argv 2]
if {$mode ni [list exact regsub include]} {exit 1}
if {[string length $from]==0} {exit 2}
while {![eof stdin]} {
  set line [gets stdin]
  if {[eof stdin]} break
  switch -exact $mode {
    exact {set line [string map [list $from $to] $line]}
    regsub {regsub -all -- $from $line $to line}











|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#!/usr/bin/tcl
#
# Replace string with another string -OR- include
# only lines successfully modified with a regular
# expression.
#
fconfigure stdout -translation binary -encoding binary
fconfigure stderr -translation binary -encoding binary
set mode [string tolower [lindex $argv 0]]
set from [lindex $argv 1]
set to [lindex $argv 2]
if {-1 == [lsearch -exact [list exact regsub include] $mode]} {exit 1}
if {[string length $from]==0} {exit 2}
while {![eof stdin]} {
  set line [gets stdin]
  if {[eof stdin]} break
  switch -exact $mode {
    exact {set line [string map [list $from $to] $line]}
    regsub {regsub -all -- $from $line $to line}
Changes to tool/sqldiff.c.
31
32
33
34
35
36
37

38
39
40
41
42
43
44
*/
struct GlobalVars {
  const char *zArgv0;       /* Name of program */
  int bSchemaOnly;          /* Only show schema differences */
  int bSchemaPK;            /* Use the schema-defined PK, not the true PK */
  int bHandleVtab;          /* Handle fts3, fts4, fts5 and rtree vtabs */
  unsigned fDebug;          /* Debug flags */

  sqlite3 *db;              /* The database connection */
} g;

/*
** Allowed values for g.fDebug
*/
#define DEBUG_COLUMN_NAMES  0x000001







>







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
*/
struct GlobalVars {
  const char *zArgv0;       /* Name of program */
  int bSchemaOnly;          /* Only show schema differences */
  int bSchemaPK;            /* Use the schema-defined PK, not the true PK */
  int bHandleVtab;          /* Handle fts3, fts4, fts5 and rtree vtabs */
  unsigned fDebug;          /* Debug flags */
  int bSchemaCompare;       /* Doing single-table sqlite_schema compare */
  sqlite3 *db;              /* The database connection */
} g;

/*
** Allowed values for g.fDebug
*/
#define DEBUG_COLUMN_NAMES  0x000001
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
    int i;
    for(i=0; az[i]; i++) sqlite3_free(az[i]);
    sqlite3_free(az);
  }
}

/*
** Return a list of column names for the table zDb.zTab.  Space to
** hold the list is obtained from sqlite3_malloc() and should released
** using namelistFree() when no longer needed.
**
** Primary key columns are listed first, followed by data columns.
** The number of columns in the primary key is returned in *pnPkey.
**
** Normally, the "primary key" in the previous sentence is the true
** primary key - the rowid or INTEGER PRIMARY KEY for ordinary tables
** or the declared PRIMARY KEY for WITHOUT ROWID tables.  However, if
** the g.bSchemaPK flag is set, then the schema-defined PRIMARY KEY is
** used in all cases.  In that case, entries that have NULL values in
** any of their primary key fields will be excluded from the analysis.
**
** If the primary key for a table is the rowid but rowid is inaccessible,
** then this routine returns a NULL pointer.



**
** Examples:
**    CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
**    *pnPKey = 1;
**    az = { "rowid", "a", "b", "c", 0 }  // Normal case
**    az = { "c", "a", "b", 0 }           // g.bSchemaPK==1
**







|






|








>
>
>







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
    int i;
    for(i=0; az[i]; i++) sqlite3_free(az[i]);
    sqlite3_free(az);
  }
}

/*
** Return a list of column names [a] for the table zDb.zTab.  Space to
** hold the list is obtained from sqlite3_malloc() and should released
** using namelistFree() when no longer needed.
**
** Primary key columns are listed first, followed by data columns.
** The number of columns in the primary key is returned in *pnPkey.
**
** Normally [a], the "primary key" in the previous sentence is the true
** primary key - the rowid or INTEGER PRIMARY KEY for ordinary tables
** or the declared PRIMARY KEY for WITHOUT ROWID tables.  However, if
** the g.bSchemaPK flag is set, then the schema-defined PRIMARY KEY is
** used in all cases.  In that case, entries that have NULL values in
** any of their primary key fields will be excluded from the analysis.
**
** If the primary key for a table is the rowid but rowid is inaccessible,
** then this routine returns a NULL pointer.
**
** [a. If the lone, named table is "sqlite_schema", "rootpage" column is
**  omitted and the "type" and "name" columns are made to be the PK.]
**
** Examples:
**    CREATE TABLE t1(a INT UNIQUE, b INTEGER, c TEXT, PRIMARY KEY(c));
**    *pnPKey = 1;
**    az = { "rowid", "a", "b", "c", 0 }  // Normal case
**    az = { "c", "a", "b", 0 }           // g.bSchemaPK==1
**
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
    pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      if( sqlite3_column_int(pStmt,5)>0 ) nPK++;
    }
    sqlite3_reset(pStmt);
    if( nPK==0 ) nPK = 1;
    truePk = 1;







  }
  *pnPKey = nPK;
  naz = nPK;
  az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
  if( az==0 ) runtimeError("out of memory");
  memset(az, 0, sizeof(char*)*(nPK+1));




  while( SQLITE_ROW==sqlite3_step(pStmt) ){

    int iPKey;
    if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
      az[iPKey-1] = safeId((char*)sqlite3_column_text(pStmt,1));
    }else{




      az = sqlite3_realloc(az, sizeof(char*)*(naz+2) );
      if( az==0 ) runtimeError("out of memory");
      az[naz++] = safeId((char*)sqlite3_column_text(pStmt,1));

    }
  }
  sqlite3_finalize(pStmt);
  if( az ) az[naz] = 0;

  /* If it is non-NULL, set *pbRowid to indicate whether or not the PK of 
  ** this table is an implicit rowid (*pbRowid==1) or not (*pbRowid==0).  */
  if( pbRowid ) *pbRowid = (az[0]==0);

  /* If this table has an implicit rowid for a PK, figure out how to refer
  ** to it. There are three options - "rowid", "_rowid_" and "oid". Any
  ** of these will work, unless the table has an explicit column of the
  ** same name.  */


  if( az[0]==0 ){
    const char *azRowid[] = { "rowid", "_rowid_", "oid" };
    for(i=0; i<sizeof(azRowid)/sizeof(azRowid[0]); i++){
      for(j=1; j<naz; j++){
        if( sqlite3_stricmp(az[j], azRowid[i])==0 ) break;
      }
      if( j>=naz ){







>
>
>
>
>
>
>






>
>
>
>

>


|

>
>
>
>
|
|
|
>










|
|
|
>
>







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
354
355
356
357
    pStmt = db_prepare("PRAGMA %s.table_info=%Q", zDb, zTab);
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      if( sqlite3_column_int(pStmt,5)>0 ) nPK++;
    }
    sqlite3_reset(pStmt);
    if( nPK==0 ) nPK = 1;
    truePk = 1;
  }
  if( g.bSchemaCompare ){
    assert( sqlite3_stricmp(zTab,"sqlite_schema")==0
            || sqlite3_stricmp(zTab,"sqlite_master")==0 );
    /* For sqlite_schema, will use type and name as the PK. */
    nPK = 2;
    truePk = 0;
  }
  *pnPKey = nPK;
  naz = nPK;
  az = sqlite3_malloc( sizeof(char*)*(nPK+1) );
  if( az==0 ) runtimeError("out of memory");
  memset(az, 0, sizeof(char*)*(nPK+1));
  if( g.bSchemaCompare ){
    az[0] = sqlite3_mprintf("%s", "type");
    az[1] = sqlite3_mprintf("%s", "name");
  }
  while( SQLITE_ROW==sqlite3_step(pStmt) ){
    char * sid = safeId((char*)sqlite3_column_text(pStmt,1));
    int iPKey;
    if( truePk && (iPKey = sqlite3_column_int(pStmt,5))>0 ){
      az[iPKey-1] = sid;
    }else{
      if( !g.bSchemaCompare
          || !(strcmp(sid,"rootpage")==0
               ||strcmp(sid,"name")==0
               ||strcmp(sid,"type")==0)){
        az = sqlite3_realloc(az, sizeof(char*)*(naz+2) );
        if( az==0 ) runtimeError("out of memory");
        az[naz++] = sid;
      }
    }
  }
  sqlite3_finalize(pStmt);
  if( az ) az[naz] = 0;

  /* If it is non-NULL, set *pbRowid to indicate whether or not the PK of 
  ** this table is an implicit rowid (*pbRowid==1) or not (*pbRowid==0).  */
  if( pbRowid ) *pbRowid = (az[0]==0);

  /* If this table has an implicit rowid for a PK, figure out how to refer
  ** to it. There are usually three options - "rowid", "_rowid_" and "oid".
  ** Any of these will work, unless the table has an explicit column of the
  ** same name or the sqlite_schema tables are to be compared. In the latter
  ** case, pretend that the "true" primary key is the name column, which
  ** avoids extraneous diffs against the schemas due to rowid variance. */
  if( az[0]==0 ){
    const char *azRowid[] = { "rowid", "_rowid_", "oid" };
    for(i=0; i<sizeof(azRowid)/sizeof(azRowid[0]); i++){
      for(j=1; j<naz; j++){
        if( sqlite3_stricmp(az[j], azRowid[i])==0 ) break;
      }
      if( j>=naz ){
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
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
  }
  sqlite3_finalize(pStmt);
  sqlite3_free(zId);
}


/*
** Compute all differences for a single table.

*/
static void diff_one_table(const char *zTab, FILE *out){
  char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
  char **az = 0;            /* Columns in main */
  char **az2 = 0;           /* Columns in aux */
  int nPk;                  /* Primary key columns in main */
  int nPk2;                 /* Primary key columns in aux */
  int n = 0;                /* Number of columns in main */
  int n2;                   /* Number of columns in aux */
  int nQ;                   /* Number of output columns in the diff query */
  int i;                    /* Loop counter */
  const char *zSep;         /* Separator string */
  Str sql;                  /* Comparison query */
  sqlite3_stmt *pStmt;      /* Query statement to do the diff */



  strInit(&sql);
  if( g.fDebug==DEBUG_COLUMN_NAMES ){
    /* Simply run columnNames() on all tables of the origin
    ** database and show the results.  This is used for testing
    ** and debugging of the columnNames() function.
    */
    az = columnNames("aux",zTab, &nPk, 0);
    if( az==0 ){
      printf("Rowid not accessible for %s\n", zId);
    }else{
      printf("%s:", zId);
      for(i=0; az[i]; i++){
        printf(" %s", az[i]);
        if( i+1==nPk ) printf(" *");
      }
      printf("\n");
    }
    goto end_diff_one_table;
  }
    

  if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
    if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
      /* Table missing from second database. */



      fprintf(out, "DROP TABLE %s;\n", zId);
    }
    goto end_diff_one_table;
  }

  if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
    /* Table missing from source */



    dump_table(zTab, out);
    goto end_diff_one_table;
  }

  az = columnNames("main", zTab, &nPk, 0);
  az2 = columnNames("aux", zTab, &nPk2, 0);
  if( az && az2 ){
    for(n=0; az[n] && az2[n]; n++){
      if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
    }
  }
  if( az==0
   || az2==0
   || nPk!=nPk2
   || az[n]
  ){
    /* Schema mismatch */
    fprintf(out, "DROP TABLE %s; -- due to schema mismatch\n", zId);
    dump_table(zTab, out);
    goto end_diff_one_table;
  }

  /* Build the comparison query */
  for(n2=n; az2[n2]; n2++){
    fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, safeId(az2[n2]));







|
>














>
>




















<




>
>
>
|






>
>
>
|
















|







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
550
551
552
553
554
555
556
557

558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
  }
  sqlite3_finalize(pStmt);
  sqlite3_free(zId);
}


/*
** Compute all differences for a single table, except if the
** table name is sqlite_schema, ignore the rootpage column.
*/
static void diff_one_table(const char *zTab, FILE *out){
  char *zId = safeId(zTab); /* Name of table (translated for us in SQL) */
  char **az = 0;            /* Columns in main */
  char **az2 = 0;           /* Columns in aux */
  int nPk;                  /* Primary key columns in main */
  int nPk2;                 /* Primary key columns in aux */
  int n = 0;                /* Number of columns in main */
  int n2;                   /* Number of columns in aux */
  int nQ;                   /* Number of output columns in the diff query */
  int i;                    /* Loop counter */
  const char *zSep;         /* Separator string */
  Str sql;                  /* Comparison query */
  sqlite3_stmt *pStmt;      /* Query statement to do the diff */
  const char *zLead =       /* Becomes line-comment for sqlite_schema */
    (g.bSchemaCompare)? "-- " : "";

  strInit(&sql);
  if( g.fDebug==DEBUG_COLUMN_NAMES ){
    /* Simply run columnNames() on all tables of the origin
    ** database and show the results.  This is used for testing
    ** and debugging of the columnNames() function.
    */
    az = columnNames("aux",zTab, &nPk, 0);
    if( az==0 ){
      printf("Rowid not accessible for %s\n", zId);
    }else{
      printf("%s:", zId);
      for(i=0; az[i]; i++){
        printf(" %s", az[i]);
        if( i+1==nPk ) printf(" *");
      }
      printf("\n");
    }
    goto end_diff_one_table;
  }


  if( sqlite3_table_column_metadata(g.db,"aux",zTab,0,0,0,0,0,0) ){
    if( !sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
      /* Table missing from second database. */
      if( g.bSchemaCompare )
        fprintf(out, "-- 2nd DB has no %s table\n", zTab);
      else
        fprintf(out, "DROP TABLE %s;\n", zId);
    }
    goto end_diff_one_table;
  }

  if( sqlite3_table_column_metadata(g.db,"main",zTab,0,0,0,0,0,0) ){
    /* Table missing from source */
    if( g.bSchemaCompare )
      fprintf(out, "-- 1st DB has no %s table\n", zTab);
    else
      dump_table(zTab, out);
    goto end_diff_one_table;
  }

  az = columnNames("main", zTab, &nPk, 0);
  az2 = columnNames("aux", zTab, &nPk2, 0);
  if( az && az2 ){
    for(n=0; az[n] && az2[n]; n++){
      if( sqlite3_stricmp(az[n],az2[n])!=0 ) break;
    }
  }
  if( az==0
   || az2==0
   || nPk!=nPk2
   || az[n]
  ){
    /* Schema mismatch */
    fprintf(out, "%sDROP TABLE %s; -- due to schema mismatch\n", zLead, zId);
    dump_table(zTab, out);
    goto end_diff_one_table;
  }

  /* Build the comparison query */
  for(n2=n; az2[n2]; n2++){
    fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, safeId(az2[n2]));
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
  /* Run the query and output differences */
  if( !g.bSchemaOnly ){
    pStmt = db_prepare("%s", sql.z);
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      int iType = sqlite3_column_int(pStmt, nPk);
      if( iType==1 || iType==2 ){
        if( iType==1 ){       /* Change the content of a row */
          fprintf(out, "UPDATE %s", zId);
          zSep = " SET";
          for(i=nPk+1; i<nQ; i+=2){
            if( sqlite3_column_int(pStmt,i)==0 ) continue;
            fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
            zSep = ",";
            printQuoted(out, sqlite3_column_value(pStmt,i+1));
          }
        }else{                /* Delete a row */
          fprintf(out, "DELETE FROM %s", zId);
        }
        zSep = " WHERE";
        for(i=0; i<nPk; i++){
          fprintf(out, "%s %s=", zSep, az2[i]);
          printQuoted(out, sqlite3_column_value(pStmt,i));
          zSep = " AND";
        }
        fprintf(out, ";\n");
      }else{                  /* Insert a row */
        fprintf(out, "INSERT INTO %s(%s", zId, az2[0]);
        for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
        fprintf(out, ") VALUES");
        zSep = "(";
        for(i=0; i<nPk2; i++){
          fprintf(out, "%s", zSep);
          zSep = ",";
          printQuoted(out, sqlite3_column_value(pStmt,i));







|








|









|







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
  /* Run the query and output differences */
  if( !g.bSchemaOnly ){
    pStmt = db_prepare("%s", sql.z);
    while( SQLITE_ROW==sqlite3_step(pStmt) ){
      int iType = sqlite3_column_int(pStmt, nPk);
      if( iType==1 || iType==2 ){
        if( iType==1 ){       /* Change the content of a row */
          fprintf(out, "%sUPDATE %s", zLead, zId);
          zSep = " SET";
          for(i=nPk+1; i<nQ; i+=2){
            if( sqlite3_column_int(pStmt,i)==0 ) continue;
            fprintf(out, "%s %s=", zSep, az2[(i+nPk-1)/2]);
            zSep = ",";
            printQuoted(out, sqlite3_column_value(pStmt,i+1));
          }
        }else{                /* Delete a row */
          fprintf(out, "%sDELETE FROM %s", zLead, zId);
        }
        zSep = " WHERE";
        for(i=0; i<nPk; i++){
          fprintf(out, "%s %s=", zSep, az2[i]);
          printQuoted(out, sqlite3_column_value(pStmt,i));
          zSep = " AND";
        }
        fprintf(out, ";\n");
      }else{                  /* Insert a row */
        fprintf(out, "%sINSERT INTO %s(%s", zLead, zId, az2[0]);
        for(i=1; az2[i]; i++) fprintf(out, ",%s", az2[i]);
        fprintf(out, ") VALUES");
        zSep = "(";
        for(i=0; i<nPk2; i++){
          fprintf(out, "%s", zSep);
          zSep = ",";
          printQuoted(out, sqlite3_column_value(pStmt,i));
1887
1888
1889
1890
1891
1892
1893

1894
1895
1896
1897
1898
1899
1900
"  --primarykey          Use schema-defined PRIMARY KEYs\n"
"  --rbu                 Output SQL to create/populate RBU table(s)\n"
"  --schema              Show only differences in the schema\n"
"  --summary             Show only a summary of the differences\n"
"  --table TAB           Show only differences in table TAB\n"
"  --transaction         Show SQL output inside a transaction\n"
"  --vtab                Handle fts3, fts4, fts5 and rtree tables\n"

  );
}

int main(int argc, char **argv){
  const char *zDb1 = 0;
  const char *zDb2 = 0;
  int i;







>







1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
"  --primarykey          Use schema-defined PRIMARY KEYs\n"
"  --rbu                 Output SQL to create/populate RBU table(s)\n"
"  --schema              Show only differences in the schema\n"
"  --summary             Show only a summary of the differences\n"
"  --table TAB           Show only differences in table TAB\n"
"  --transaction         Show SQL output inside a transaction\n"
"  --vtab                Handle fts3, fts4, fts5 and rtree tables\n"
"See https://sqlite.org/sqldiff.html for detailed explanation.\n"
  );
}

int main(int argc, char **argv){
  const char *zDb1 = 0;
  const char *zDb2 = 0;
  int i;
1953
1954
1955
1956
1957
1958
1959



1960
1961
1962
1963
1964
1965
1966
      }else
      if( strcmp(z,"summary")==0 ){
        xDiff = summarize_one_table;
      }else
      if( strcmp(z,"table")==0 ){
        if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
        zTab = argv[++i];



      }else
      if( strcmp(z,"transaction")==0 ){
        useTransaction = 1;
      }else
      if( strcmp(z,"vtab")==0 ){
        g.bHandleVtab = 1;
      }else







>
>
>







1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
      }else
      if( strcmp(z,"summary")==0 ){
        xDiff = summarize_one_table;
      }else
      if( strcmp(z,"table")==0 ){
        if( i==argc-1 ) cmdlineError("missing argument to %s", argv[i]);
        zTab = argv[++i];
        g.bSchemaCompare =
          sqlite3_stricmp(zTab, "sqlite_schema")==0
          || sqlite3_stricmp(zTab, "sqlite_master")==0;
      }else
      if( strcmp(z,"transaction")==0 ){
        useTransaction = 1;
      }else
      if( strcmp(z,"vtab")==0 ){
        g.bHandleVtab = 1;
      }else
1974
1975
1976
1977
1978
1979
1980



1981
1982
1983
1984
1985
1986
1987
    }else{
      cmdlineError("unknown argument: %s", argv[i]);
    }
  }
  if( zDb2==0 ){
    cmdlineError("two database arguments required");
  }



  rc = sqlite3_open(zDb1, &g.db);
  if( rc ){
    cmdlineError("cannot open database file \"%s\"", zDb1);
  }
  rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_schema", 0, 0, &zErrMsg);
  if( rc || zErrMsg ){
    cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);







>
>
>







2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
    }else{
      cmdlineError("unknown argument: %s", argv[i]);
    }
  }
  if( zDb2==0 ){
    cmdlineError("two database arguments required");
  }
  if( g.bSchemaOnly && g.bSchemaCompare ){
    cmdlineError("The --schema option is useless with --table %s .", zTab);
  }
  rc = sqlite3_open(zDb1, &g.db);
  if( rc ){
    cmdlineError("cannot open database file \"%s\"", zDb1);
  }
  rc = sqlite3_exec(g.db, "SELECT * FROM sqlite_schema", 0, 0, &zErrMsg);
  if( rc || zErrMsg ){
    cmdlineError("\"%s\" does not appear to be a valid SQLite database", zDb1);