/ Check-in [2c76ce4f]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Merge the pre-3.26.0 fixes from trunk.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | apple-osx
Files: files | file ages | folders
SHA3-256: 2c76ce4f42c486c7c2ead64a602ae02eaefcb1438ed1d401221a2e0ff6c9cf23
User & Date: drh 2018-11-30 18:22:49
Context
2018-12-05
18:28
Merge enhancements and the ALTER TABLE bug fix from trunk. check-in: edfc2acf user: drh tags: apple-osx
2018-11-30
18:22
Merge the pre-3.26.0 fixes from trunk. check-in: 2c76ce4f user: drh tags: apple-osx
2018-11-29
12:00
Fix the name of the trig function approximation in geopoly. No functional changes to the code. check-in: 33576b12 user: drh tags: trunk
2018-11-26
23:35
Merge recent enhancements from trunk. check-in: e8c20a88 user: drh tags: apple-osx
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Makefile.in.

28
29
30
31
32
33
34

35
36
37
38
39
40
41
...
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
...
355
356
357
358
359
360
361



362
363
364
365
366
367
368
...
454
455
456
457
458
459
460
461

462
463
464
465
466
467
468
...
560
561
562
563
564
565
566


567
568
569
570
571
572
573
....
1127
1128
1129
1130
1131
1132
1133



1134
1135
1136
1137
1138
1139
1140
1141
# are provide so that these aspects of the build process can be changed
# on the "make" command-line.  Ex:  "make CC=clang CFLAGS=-fsanitize=undefined"
#
CC = @CC@
CFLAGS = @CPPFLAGS@ @CFLAGS@
TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu
TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session


# Define this for the autoconf-based build, so that the code knows it can
# include the generated config.h
#
TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite

# Define -DNDEBUG to compile without debugging (i.e., for production usage)
................................................................................
         memdb.lo memjournal.lo \
         mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
         notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
         pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
         random.lo resolve.lo rowset.lo rtree.lo \
         sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
         table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
         update.lo upsert.lo util.lo vacuum.lo \
         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
         vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
         window.lo utf.lo vtab.lo

# Object files for the amalgamation.
#
LIBOBJS1 = sqlite3.lo
................................................................................
SRC += \
  $(TOP)/ext/sqlrr/sqlrr.h \
  $(TOP)/ext/sqlrr/sqlrr.c
SRC += \
  $(TOP)/ext/session/sqlite3session.c \
  $(TOP)/ext/session/sqlite3session.h
SRC += \



  $(TOP)/ext/rbu/sqlite3rbu.h \
  $(TOP)/ext/rbu/sqlite3rbu.c
SRC += \
  $(TOP)/ext/misc/json1.c \
  $(TOP)/ext/misc/stmt.c

# Generated source code files
................................................................................
  $(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/misc/zipfile.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 \
................................................................................
EXTHDR += \
  $(TOP)/ext/rtree/rtree.h \
  $(TOP)/ext/rtree/geopoly.c
EXTHDR += \
  $(TOP)/ext/icu/sqliteicu.h
EXTHDR += \
  $(TOP)/ext/rtree/sqlite3rtree.h


EXTHDR += \
  $(TOP)/ext/sqlrr/sqlrr.h

# If using the amalgamation, use sqlite3.c directly to build the test
# fixture.  Otherwise link against libsqlite3.la.  (This distinction is
# necessary because the test fixture requires non-API symbols which are
# hidden when the library is built via the amalgamation).
................................................................................

fts3_write.lo:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c

rtree.lo:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c




sqlite3session.lo:	$(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c

json1.lo:	$(TOP)/ext/misc/json1.c
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c

stmt.lo:	$(TOP)/ext/misc/stmt.c
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c







>







 







|







 







>
>
>







 







|
>







 







>
>







 







>
>
>
|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
...
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
...
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
....
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
# are provide so that these aspects of the build process can be changed
# on the "make" command-line.  Ex:  "make CC=clang CFLAGS=-fsanitize=undefined"
#
CC = @CC@
CFLAGS = @CPPFLAGS@ @CFLAGS@
TCC = ${CC} ${CFLAGS} -I. -I${TOP}/src -I${TOP}/ext/rtree -I${TOP}/ext/icu
TCC += -I${TOP}/ext/fts3 -I${TOP}/ext/async -I${TOP}/ext/session
TCC += -I${TOP}/ext/userauth

# Define this for the autoconf-based build, so that the code knows it can
# include the generated config.h
#
TCC += -D_HAVE_SQLITE_CONFIG_H -DBUILD_sqlite

# Define -DNDEBUG to compile without debugging (i.e., for production usage)
................................................................................
         memdb.lo memjournal.lo \
         mutex.lo mutex_noop.lo mutex_unix.lo mutex_w32.lo \
         notify.lo opcodes.lo os.lo os_unix.lo os_win.lo \
         pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
         random.lo resolve.lo rowset.lo rtree.lo \
         sqlite3session.lo select.lo sqlite3rbu.lo status.lo stmt.lo \
         table.lo threads.lo tokenize.lo treeview.lo trigger.lo \
         update.lo userauth.lo upsert.lo util.lo vacuum.lo \
         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo vdbesort.lo \
         vdbetrace.lo wal.lo walker.lo where.lo wherecode.lo whereexpr.lo \
         window.lo utf.lo vtab.lo

# Object files for the amalgamation.
#
LIBOBJS1 = sqlite3.lo
................................................................................
SRC += \
  $(TOP)/ext/sqlrr/sqlrr.h \
  $(TOP)/ext/sqlrr/sqlrr.c
SRC += \
  $(TOP)/ext/session/sqlite3session.c \
  $(TOP)/ext/session/sqlite3session.h
SRC += \
  $(TOP)/ext/userauth/userauth.c \
  $(TOP)/ext/userauth/sqlite3userauth.h
SRC += \
  $(TOP)/ext/rbu/sqlite3rbu.h \
  $(TOP)/ext/rbu/sqlite3rbu.c
SRC += \
  $(TOP)/ext/misc/json1.c \
  $(TOP)/ext/misc/stmt.c

# Generated source code files
................................................................................
  $(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/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 \
................................................................................
EXTHDR += \
  $(TOP)/ext/rtree/rtree.h \
  $(TOP)/ext/rtree/geopoly.c
EXTHDR += \
  $(TOP)/ext/icu/sqliteicu.h
EXTHDR += \
  $(TOP)/ext/rtree/sqlite3rtree.h
EXTHDR += \
  $(TOP)/ext/userauth/sqlite3userauth.h
EXTHDR += \
  $(TOP)/ext/sqlrr/sqlrr.h

# If using the amalgamation, use sqlite3.c directly to build the test
# fixture.  Otherwise link against libsqlite3.la.  (This distinction is
# necessary because the test fixture requires non-API symbols which are
# hidden when the library is built via the amalgamation).
................................................................................

fts3_write.lo:	$(TOP)/ext/fts3/fts3_write.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/fts3/fts3_write.c

rtree.lo:	$(TOP)/ext/rtree/rtree.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/rtree/rtree.c

sqlite3session.lo:	$(TOP)/ext/userauth/userauth.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/userauth/userauth.c

userauth.lo:	$(TOP)/ext/session/sqlite3session.c $(HDR) $(EXTHDR)
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/session/sqlite3session.c

json1.lo:	$(TOP)/ext/misc/json1.c
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/json1.c

stmt.lo:	$(TOP)/ext/misc/stmt.c
	$(LTCOMPILE) -DSQLITE_CORE -c $(TOP)/ext/misc/stmt.c

Changes to Makefile.msc.

341
342
343
344
345
346
347

348
349
350
351
352
353
354
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1

!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF

# Should the session extension be enabled?  If so, add compilation options
# to enable it.
#







>







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_JSON1=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBPAGE_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DBSTAT_VTAB=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_INTROSPECTION_PRAGMAS=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_DESERIALIZE=1
!ENDIF
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_COLUMN_METADATA=1
!ENDIF

# Should the session extension be enabled?  If so, add compilation options
# to enable it.
#

Changes to doc/lemon.html.

772
773
774
775
776
777
778



779
780
781
782
783
784
785

<p><pre>
   %include {#include &lt;unistd.h&gt;}
</pre></p>

<p>This might be needed, for example, if some of the C actions in the
grammar call functions that are prototyped in unistd.h.</p>




<a name='pleft'></a>
<h4>The <tt>%left</tt> directive</h4>

The <tt>%left</tt> directive is used (along with the
<tt><a href='#pright'>%right</a></tt> and
<tt><a href='#pnonassoc'>%nonassoc</a></tt> directives) to declare







>
>
>







772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788

<p><pre>
   %include {#include &lt;unistd.h&gt;}
</pre></p>

<p>This might be needed, for example, if some of the C actions in the
grammar call functions that are prototyped in unistd.h.</p>

<p>Use the <tt><a href="#pcode">%code</a></tt> directive to add code to
the end of the generated parser.</p>

<a name='pleft'></a>
<h4>The <tt>%left</tt> directive</h4>

The <tt>%left</tt> directive is used (along with the
<tt><a href='#pright'>%right</a></tt> and
<tt><a href='#pnonassoc'>%nonassoc</a></tt> directives) to declare

Changes to ext/fts3/fts3.c.

4162
4163
4164
4165
4166
4167
4168

4169
4170
4171
4172
4173
4174
4175
....
4265
4266
4267
4268
4269
4270
4271

4272
4273
4274
4275
4276
4277
4278
    }
    assert( pToken->pSegcsr==0 );
  }

  return rc;
}


/*
** This function is called on each phrase after the position lists for
** any deferred tokens have been loaded into memory. It updates the phrases
** current position list to include only those positions that are really
** instances of the phrase (after considering deferred tokens). If this
** means that the phrase does not appear in the current row, doclist.pList
** and doclist.nList are both zeroed.
................................................................................
      }
      sqlite3_free(aPoslist);
    }
  }

  return SQLITE_OK;
}


/*
** Maximum number of tokens a phrase may have to be considered for the
** incremental doclists strategy.
*/
#define MAX_INCR_PHRASE_TOKENS 4








>







 







>







4162
4163
4164
4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
....
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
    }
    assert( pToken->pSegcsr==0 );
  }

  return rc;
}

#ifndef SQLITE_DISABLE_FTS4_DEFERRED
/*
** This function is called on each phrase after the position lists for
** any deferred tokens have been loaded into memory. It updates the phrases
** current position list to include only those positions that are really
** instances of the phrase (after considering deferred tokens). If this
** means that the phrase does not appear in the current row, doclist.pList
** and doclist.nList are both zeroed.
................................................................................
      }
      sqlite3_free(aPoslist);
    }
  }

  return SQLITE_OK;
}
#endif /* SQLITE_DISABLE_FTS4_DEFERRED */

/*
** Maximum number of tokens a phrase may have to be considered for the
** incremental doclists strategy.
*/
#define MAX_INCR_PHRASE_TOKENS 4

Changes to ext/rtree/geopoly.c.

540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
       4+8*p->nVertex, SQLITE_TRANSIENT);
    sqlite3_free(p);
  }            
}

#define GEOPOLY_PI 3.1415926535897932385

/* Fast approximation for cosine(X) for X between -0.5*pi and 2*pi
*/
static double geopolyCosine(double r){
  assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
  if( r>=1.5*GEOPOLY_PI ){
    r -= 2.0*GEOPOLY_PI;
  }
  if( r>=0.5*GEOPOLY_PI ){
    return -geopolyCosine(r-GEOPOLY_PI);
  }else{
    double r2 = r*r;
    double r3 = r2*r;
    double r5 = r3*r2;
    return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
  }
}
................................................................................
  i = 1;
  p->hdr[0] = *(unsigned char*)&i;
  p->hdr[1] = 0;
  p->hdr[2] = (n>>8)&0xff;
  p->hdr[3] = n&0xff;
  for(i=0; i<n; i++){
    double rAngle = 2.0*GEOPOLY_PI*i/n;
    p->a[i*2] = x - r*geopolyCosine(rAngle-0.5*GEOPOLY_PI);
    p->a[i*2+1] = y + r*geopolyCosine(rAngle);
  }
  sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
  sqlite3_free(p);
}

/*
** If pPoly is a polygon, compute its bounding box. Then:







|

|





|







 







|
|







540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
...
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
       4+8*p->nVertex, SQLITE_TRANSIENT);
    sqlite3_free(p);
  }            
}

#define GEOPOLY_PI 3.1415926535897932385

/* Fast approximation for sine(X) for X between -0.5*pi and 2*pi
*/
static double geopolySine(double r){
  assert( r>=-0.5*GEOPOLY_PI && r<=2.0*GEOPOLY_PI );
  if( r>=1.5*GEOPOLY_PI ){
    r -= 2.0*GEOPOLY_PI;
  }
  if( r>=0.5*GEOPOLY_PI ){
    return -geopolySine(r-GEOPOLY_PI);
  }else{
    double r2 = r*r;
    double r3 = r2*r;
    double r5 = r3*r2;
    return 0.9996949*r - 0.1656700*r3 + 0.0075134*r5;
  }
}
................................................................................
  i = 1;
  p->hdr[0] = *(unsigned char*)&i;
  p->hdr[1] = 0;
  p->hdr[2] = (n>>8)&0xff;
  p->hdr[3] = n&0xff;
  for(i=0; i<n; i++){
    double rAngle = 2.0*GEOPOLY_PI*i/n;
    p->a[i*2] = x - r*geopolySine(rAngle-0.5*GEOPOLY_PI);
    p->a[i*2+1] = y + r*geopolySine(rAngle);
  }
  sqlite3_result_blob(context, p->hdr, 4+8*n, SQLITE_TRANSIENT);
  sqlite3_free(p);
}

/*
** If pPoly is a polygon, compute its bounding box. Then:

Changes to src/build.c.

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
....
1890
1891
1892
1893
1894
1895
1896

1897
1898
1899
1900
1901
1902
1903
....
1915
1916
1917
1918
1919
1920
1921



1922
1923
1924
1925
1926
1927
1928
/*
** Erase all schema information from all attached databases (including
** "main" and "temp") for a single database connection.
*/
void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
  int i;
  sqlite3BtreeEnterAll(db);
  assert( db->nSchemaLock==0 );
  for(i=0; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    if( pDb->pSchema ){

      sqlite3SchemaClear(pDb->pSchema);



    }
  }
  db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
  sqlite3VtabUnlockList(db);
  sqlite3BtreeLeaveAll(db);

  sqlite3CollapseDatabaseArray(db);

}

/*
** This routine is called when a commit occurs.
*/
void sqlite3CommitInternalChanges(sqlite3 *db){
  db->mDbFlags &= ~DBFLAG_SchemaChange;
................................................................................
    assert( pTab->nCol==j );
  }else{
    pPk->nColumn = pTab->nCol;
  }
  recomputeColumnsNotIndexed(pPk);
}


/*
** Return true if zName is a shadow table name in the current database
** connection.
**
** zName is temporarily modified while this routine is running, but is
** restored to its original value prior to this routine returning.
*/
................................................................................
  if( !IsVirtual(pTab) ) return 0;
  pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
  if( pMod==0 ) return 0;
  if( pMod->pModule->iVersion<3 ) return 0;
  if( pMod->pModule->xShadowName==0 ) return 0;
  return pMod->pModule->xShadowName(zTail+1);
}




/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have







<



>
|
>
>
>





>
|
>







 







>







 







>
>
>







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
....
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
....
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
/*
** Erase all schema information from all attached databases (including
** "main" and "temp") for a single database connection.
*/
void sqlite3ResetAllSchemasOfConnection(sqlite3 *db){
  int i;
  sqlite3BtreeEnterAll(db);

  for(i=0; i<db->nDb; i++){
    Db *pDb = &db->aDb[i];
    if( pDb->pSchema ){
      if( db->nSchemaLock==0 ){
        sqlite3SchemaClear(pDb->pSchema);
      }else{
        DbSetProperty(db, i, DB_ResetWanted);
      }
    }
  }
  db->mDbFlags &= ~(DBFLAG_SchemaChange|DBFLAG_SchemaKnownOk);
  sqlite3VtabUnlockList(db);
  sqlite3BtreeLeaveAll(db);
  if( db->nSchemaLock==0 ){
    sqlite3CollapseDatabaseArray(db);
  }
}

/*
** This routine is called when a commit occurs.
*/
void sqlite3CommitInternalChanges(sqlite3 *db){
  db->mDbFlags &= ~DBFLAG_SchemaChange;
................................................................................
    assert( pTab->nCol==j );
  }else{
    pPk->nColumn = pTab->nCol;
  }
  recomputeColumnsNotIndexed(pPk);
}

#ifndef SQLITE_OMIT_VIRTUALTABLE
/*
** Return true if zName is a shadow table name in the current database
** connection.
**
** zName is temporarily modified while this routine is running, but is
** restored to its original value prior to this routine returning.
*/
................................................................................
  if( !IsVirtual(pTab) ) return 0;
  pMod = (Module*)sqlite3HashFind(&db->aModule, pTab->azModuleArg[0]);
  if( pMod==0 ) return 0;
  if( pMod->pModule->iVersion<3 ) return 0;
  if( pMod->pModule->xShadowName==0 ) return 0;
  return pMod->pModule->xShadowName(zTail+1);
}
#else
# define isShadowTableName(x,y) 0
#endif /* ifndef SQLITE_OMIT_VIRTUALTABLE */

/*
** This routine is called to report the final ")" that terminates
** a CREATE TABLE statement.
**
** The table structure that other action routines have been building
** is added to the internal hash tables, assuming no errors have

Changes to src/delete.c.

66
67
68
69
70
71
72
73
74
75


76
77
78
79
80
81
82
  }
  if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
  db = pParse->db;
  if( (pTab->tabFlags & TF_Readonly)!=0 ){
    return sqlite3WritableSchema(db)==0 && pParse->nested==0;
  }
  assert( pTab->tabFlags & TF_Shadow );
  return (db->flags & SQLITE_Defensive)!=0
           && db->nVdbeExec==0
           && db->pVtabCtx==0;


}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/







|
|
|
>
>







66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
  }
  if( (pTab->tabFlags & (TF_Readonly|TF_Shadow))==0 ) return 0;
  db = pParse->db;
  if( (pTab->tabFlags & TF_Readonly)!=0 ){
    return sqlite3WritableSchema(db)==0 && pParse->nested==0;
  }
  assert( pTab->tabFlags & TF_Shadow );
  return (db->flags & SQLITE_Defensive)!=0 
#ifndef SQLITE_OMIT_VIRTUALTABLE
          && db->pVtabCtx==0
#endif
          && db->nVdbeExec==0;
}

/*
** Check to make sure the given table is writable.  If it is not
** writable, generate an error message and return 1.  If it is
** writable return 0;
*/

Changes to src/loadext.c.

80
81
82
83
84
85
86

87
88
89
90
91
92
93

#ifdef SQLITE_OMIT_VIRTUALTABLE
# define sqlite3_create_module 0
# define sqlite3_create_module_v2 0
# define sqlite3_declare_vtab 0
# define sqlite3_vtab_config 0
# define sqlite3_vtab_on_conflict 0

#endif

#ifdef SQLITE_OMIT_SHARED_CACHE
# define sqlite3_enable_shared_cache 0
#endif

#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)







>







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

#ifdef SQLITE_OMIT_VIRTUALTABLE
# define sqlite3_create_module 0
# define sqlite3_create_module_v2 0
# define sqlite3_declare_vtab 0
# define sqlite3_vtab_config 0
# define sqlite3_vtab_on_conflict 0
# define sqlite3_vtab_collation 0
#endif

#ifdef SQLITE_OMIT_SHARED_CACHE
# define sqlite3_enable_shared_cache 0
#endif

#if defined(SQLITE_OMIT_TRACE) || defined(SQLITE_OMIT_DEPRECATED)

Changes to src/pager.c.

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
....
7076
7077
7078
7079
7080
7081
7082
7083
7084



7085
7086
7087
7088
7089
7090
7091
    return (rc==SQLITE_OK && iRead==0);
  }
#endif
  return 1;
}
#endif

/*
** Return true if this pager uses a write-ahead log to read page pgno.
** Return false if the pager reads pgno directly from the database.
*/
#if !defined(SQLITE_OMIT_WAL) && defined(SQLITE_DIRECT_OVERFLOW_READ)
int sqlite3PagerUseWal(Pager *pPager, Pgno pgno){
  u32 iRead = 0;
  int rc;
  if( pPager->pWal==0 ) return 0;
  rc = sqlite3WalFindFrame(pPager->pWal, pgno, &iRead);
  return rc || iRead;
}
#endif
#ifndef SQLITE_OMIT_WAL
# define pagerUseWal(x) ((x)->pWal!=0)
#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
# define pagerWalFrames(v,w,x,y) 0
# define pagerOpenWalIfPresent(z) SQLITE_OK
................................................................................
void sqlite3PagerSetCodec(
  Pager *pPager,
  void *(*xCodec)(void*,void*,Pgno,int),
  void (*xCodecSizeChng)(void*,int,int),
  void (*xCodecFree)(void*),
  void *pCodec
){
  pager_reset(pPager);
  if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec);



  pPager->xCodec = pPager->memDb ? 0 : xCodec;
  pPager->xCodecSizeChng = xCodecSizeChng;
  pPager->xCodecFree = xCodecFree;
  pPager->pCodec = pCodec;
  setGetterMethod(pPager);
  pagerReportSize(pPager);
}







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







 







|
|
>
>
>







845
846
847
848
849
850
851













852
853
854
855
856
857
858
....
7063
7064
7065
7066
7067
7068
7069
7070
7071
7072
7073
7074
7075
7076
7077
7078
7079
7080
7081
    return (rc==SQLITE_OK && iRead==0);
  }
#endif
  return 1;
}
#endif














#ifndef SQLITE_OMIT_WAL
# define pagerUseWal(x) ((x)->pWal!=0)
#else
# define pagerUseWal(x) 0
# define pagerRollbackWal(x) 0
# define pagerWalFrames(v,w,x,y) 0
# define pagerOpenWalIfPresent(z) SQLITE_OK
................................................................................
void sqlite3PagerSetCodec(
  Pager *pPager,
  void *(*xCodec)(void*,void*,Pgno,int),
  void (*xCodecSizeChng)(void*,int,int),
  void (*xCodecFree)(void*),
  void *pCodec
){
  if( pPager->xCodecFree ){
    pPager->xCodecFree(pPager->pCodec);
  }else{
    pager_reset(pPager);
  }
  pPager->xCodec = pPager->memDb ? 0 : xCodec;
  pPager->xCodecSizeChng = xCodecSizeChng;
  pPager->xCodecFree = xCodecFree;
  pPager->pCodec = pCodec;
  setGetterMethod(pPager);
  pagerReportSize(pPager);
}

Changes to src/pager.h.

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

#ifndef SQLITE_OMIT_WAL
  int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
  int sqlite3PagerWalSupported(Pager *pPager);
  int sqlite3PagerWalCallback(Pager *pPager);
  int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
  int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);
# ifdef SQLITE_DIRECT_OVERFLOW_READ
  int sqlite3PagerUseWal(Pager *pPager, Pgno);
# endif
# ifdef SQLITE_ENABLE_SNAPSHOT
  int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
  int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
  int sqlite3PagerSnapshotRecover(Pager *pPager);
  int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
  void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif
#else
# define sqlite3PagerUseWal(x,y) 0
#endif

#ifdef SQLITE_DIRECT_OVERFLOW_READ
  int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif

#ifdef SQLITE_ENABLE_ZIPVFS







<
<
<







<
<







175
176
177
178
179
180
181



182
183
184
185
186
187
188


189
190
191
192
193
194
195

#ifndef SQLITE_OMIT_WAL
  int sqlite3PagerCheckpoint(Pager *pPager, sqlite3*, int, int*, int*);
  int sqlite3PagerWalSupported(Pager *pPager);
  int sqlite3PagerWalCallback(Pager *pPager);
  int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
  int sqlite3PagerCloseWal(Pager *pPager, sqlite3*);



# ifdef SQLITE_ENABLE_SNAPSHOT
  int sqlite3PagerSnapshotGet(Pager *pPager, sqlite3_snapshot **ppSnapshot);
  int sqlite3PagerSnapshotOpen(Pager *pPager, sqlite3_snapshot *pSnapshot);
  int sqlite3PagerSnapshotRecover(Pager *pPager);
  int sqlite3PagerSnapshotCheck(Pager *pPager, sqlite3_snapshot *pSnapshot);
  void sqlite3PagerSnapshotUnlock(Pager *pPager);
# endif


#endif

#ifdef SQLITE_DIRECT_OVERFLOW_READ
  int sqlite3PagerDirectReadOk(Pager *pPager, Pgno pgno);
#endif

#ifdef SQLITE_ENABLE_ZIPVFS

Changes to src/pcache1.c.

101
102
103
104
105
106
107
108

109
110
111
112
113
114
115
  PgHdr1 *pNext;                 /* Next in hash table chain */
  PCache1 *pCache;               /* Cache that currently owns this page */
  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
};

/*
** A page is pinned if it is no on the LRU list

*/
#define PAGE_IS_PINNED(p)    ((p)->pLruNext==0)
#define PAGE_IS_UNPINNED(p)  ((p)->pLruNext!=0)

/* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
** of one or more PCaches that are able to recycle each other's unpinned
** pages when they are under memory pressure.  A PGroup is an instance of







|
>







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  PgHdr1 *pNext;                 /* Next in hash table chain */
  PCache1 *pCache;               /* Cache that currently owns this page */
  PgHdr1 *pLruNext;              /* Next in LRU list of unpinned pages */
  PgHdr1 *pLruPrev;              /* Previous in LRU list of unpinned pages */
};

/*
** A page is pinned if it is not on the LRU list.  To be "pinned" means
** that the page is in active use and must not be deallocated.
*/
#define PAGE_IS_PINNED(p)    ((p)->pLruNext==0)
#define PAGE_IS_UNPINNED(p)  ((p)->pLruNext!=0)

/* Each page cache (or PCache) belongs to a PGroup.  A PGroup is a set 
** of one or more PCaches that are able to recycle each other's unpinned
** pages when they are under memory pressure.  A PGroup is an instance of

Changes to src/sqlite.h.in.

3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
** deplete the limited store of lookaside memory. Future versions of
** SQLite may act on this hint differently.
**
** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
** representation of the SQL statement should be calculated and then
** associated with the prepared statement, which can be obtained via
** the [sqlite3_normalized_sql()] interface.  The semantics used to
** normalize a SQL statement are unspecified and subject to change.
** At a minimum, literal values will be replaced with suitable
** placeholders.
** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT              0x01
#define SQLITE_PREPARE_NORMALIZE               0x02







|







3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
** deplete the limited store of lookaside memory. Future versions of
** SQLite may act on this hint differently.
**
** [[SQLITE_PREPARE_NORMALIZE]] ^(<dt>SQLITE_PREPARE_NORMALIZE</dt>
** <dd>The SQLITE_PREPARE_NORMALIZE flag indicates that a normalized
** representation of the SQL statement should be calculated and then
** associated with the prepared statement, which can be obtained via
** the [sqlite3_normalized_sql()] interface.)^  The semantics used to
** normalize a SQL statement are unspecified and subject to change.
** At a minimum, literal values will be replaced with suitable
** placeholders.
** </dl>
*/
#define SQLITE_PREPARE_PERSISTENT              0x01
#define SQLITE_PREPARE_NORMALIZE               0x02

Changes to test/attach.test.

722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
    catchsql {
      CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN
        DELETE FROM t1 WHERE x<(SELECT min(x) FROM temp.t6);
      END;
    } db2
  } {1 {trigger r5 cannot reference objects in database temp}}
} ;# endif subquery
ifcapable json1 {
  do_test attach-5.10 {
    db close
    catch {db2 close}
    forcedelete test.db
    sqlite3 db test.db
    db eval {
      CREATE TABLE t1(x);







|







722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
    catchsql {
      CREATE TRIGGER r5 AFTER INSERT ON t5 BEGIN
        DELETE FROM t1 WHERE x<(SELECT min(x) FROM temp.t6);
      END;
    } db2
  } {1 {trigger r5 cannot reference objects in database temp}}
} ;# endif subquery
ifcapable json1&&vtab {
  do_test attach-5.10 {
    db close
    catch {db2 close}
    forcedelete test.db
    sqlite3 db test.db
    db eval {
      CREATE TABLE t1(x);

Changes to test/incrvacuum.test.

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
} {ok}

#-------------------------------------------------------------------------
# At one point it was unsafe to truncate a db file on windows while there
# were outstanding xFetch() references. This test case attempts to hit
# that case.
#

reset_db
do_execsql_test incrvacuum-16.0 {
  PRAGMA auto_vacuum = 2;
  CREATE TABLE t3(a);
  INSERT INTO t3 VALUES(1), (2), (3), (4);

  CREATE TABLE t2(x);
  INSERT INTO t2 VALUES( randomblob(1000) );
  INSERT INTO t2 VALUES( randomblob(1000) );
  INSERT INTO t2 VALUES( randomblob(1000) );
  INSERT INTO t2 VALUES( randomblob(1000) );
  INSERT INTO t2 VALUES( randomblob(1000) );
  INSERT INTO t2 VALUES( randomblob(1000) );
} {}

# Reopen db to ensure the page-cache is empty.
#
db close
sqlite3 db test.db

# Open db in mmap-mode. Open a transaction, delete some data, then run
# incremental-vacuum. Do not commit the transaction. 
#
do_execsql_test incrvacuum-16.1 {
  PRAGMA mmap_size = 1000000;
  BEGIN;
  DELETE FROM t2;
  PRAGMA incremental_vacuum = 1000;
} {1000000}

# Scan through table t3 (which is all clean pages - so mmap is used). Then,
# midway through, commit the transaction. This causes the db to be truncated
# while there are outstanding xFetch pages.
#
do_test incrvacuum-16.2 {
  set res [list]
  db eval { SELECT a FROM t3 } {
    if {$a==3} { db eval COMMIT }
    lappend res $a
  }
  set res
} {1 2 3 4}


finish_test







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

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

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
} {ok}

#-------------------------------------------------------------------------
# At one point it was unsafe to truncate a db file on windows while there
# were outstanding xFetch() references. This test case attempts to hit
# that case.
#
ifcapable mmap {
  reset_db
  do_execsql_test incrvacuum-16.0 {
    PRAGMA auto_vacuum = 2;
    CREATE TABLE t3(a);
    INSERT INTO t3 VALUES(1), (2), (3), (4);
  
    CREATE TABLE t2(x);
    INSERT INTO t2 VALUES( randomblob(1000) );
    INSERT INTO t2 VALUES( randomblob(1000) );
    INSERT INTO t2 VALUES( randomblob(1000) );
    INSERT INTO t2 VALUES( randomblob(1000) );
    INSERT INTO t2 VALUES( randomblob(1000) );
    INSERT INTO t2 VALUES( randomblob(1000) );
  } {}
  
  # Reopen db to ensure the page-cache is empty.
  #
  db close
  sqlite3 db test.db
  
  # Open db in mmap-mode. Open a transaction, delete some data, then run
  # incremental-vacuum. Do not commit the transaction. 
  #
  do_execsql_test incrvacuum-16.1 {
    PRAGMA mmap_size = 1000000;
    BEGIN;
    DELETE FROM t2;
    PRAGMA incremental_vacuum = 1000;
  } {1000000}

  # Scan through table t3 (which is all clean pages - so mmap is used). Then,
  # midway through, commit the transaction. This causes the db to be truncated
  # while there are outstanding xFetch pages.
  #
  do_test incrvacuum-16.2 {
    set res [list]
    db eval { SELECT a FROM t3 } {
      if {$a==3} { db eval COMMIT }
      lappend res $a
    }
    set res
  } {1 2 3 4}
}
  
finish_test

Changes to test/indexexpr2.test.

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
  set ::cnt
  # Refcnt() should not be invoked because that index does not change.
} {0}

# Additional test cases to show that UPDATE does not modify indexes that
# do not involve unchanged columns.
#

load_static_extension db explain
do_execsql_test 4.200 {
  CREATE TABLE t2(a,b,c,d,e,f);
  INSERT INTO t2 VALUES(2,3,4,5,6,7);
  CREATE INDEX t2abc ON t2(a+b+c);
  CREATE INDEX t2cd ON t2(c*d);
  CREATE INDEX t2def ON t2(d,e+25*f);
  SELECT sqlite_master.name 
    FROM sqlite_master, explain('UPDATE t2 SET b=b+1')
   WHERE explain.opcode LIKE 'Open%'
     AND sqlite_master.rootpage=explain.p2
   ORDER BY 1;
} {t2 t2abc}
do_execsql_test 4.210 {
  SELECT sqlite_master.name 
    FROM sqlite_master, explain('UPDATE t2 SET c=c+1')
   WHERE explain.opcode LIKE 'Open%'
     AND sqlite_master.rootpage=explain.p2
   ORDER BY 1;
} {t2 t2abc t2cd}
do_execsql_test 4.220 {
  SELECT sqlite_master.name 
    FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
   WHERE explain.opcode LIKE 'Open%'
     AND sqlite_master.rootpage=explain.p2
   ORDER BY 1;
} {t2 t2abc t2cd t2def}



finish_test







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

>

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
  set ::cnt
  # Refcnt() should not be invoked because that index does not change.
} {0}

# Additional test cases to show that UPDATE does not modify indexes that
# do not involve unchanged columns.
#
ifcapable vtab {
  load_static_extension db explain
  do_execsql_test 4.200 {
    CREATE TABLE t2(a,b,c,d,e,f);
    INSERT INTO t2 VALUES(2,3,4,5,6,7);
    CREATE INDEX t2abc ON t2(a+b+c);
    CREATE INDEX t2cd ON t2(c*d);
    CREATE INDEX t2def ON t2(d,e+25*f);
    SELECT sqlite_master.name 
      FROM sqlite_master, explain('UPDATE t2 SET b=b+1')
     WHERE explain.opcode LIKE 'Open%'
       AND sqlite_master.rootpage=explain.p2
     ORDER BY 1;
  } {t2 t2abc}
  do_execsql_test 4.210 {
    SELECT sqlite_master.name 
      FROM sqlite_master, explain('UPDATE t2 SET c=c+1')
     WHERE explain.opcode LIKE 'Open%'
       AND sqlite_master.rootpage=explain.p2
     ORDER BY 1;
  } {t2 t2abc t2cd}
  do_execsql_test 4.220 {
    SELECT sqlite_master.name 
      FROM sqlite_master, explain('UPDATE t2 SET c=c+1, f=NULL')
     WHERE explain.opcode LIKE 'Open%'
       AND sqlite_master.rootpage=explain.p2
     ORDER BY 1;
  } {t2 t2abc t2cd t2def}
}


finish_test

Added test/lemon-test01.y.























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
// A test case for the LEMON parser generator.  Run as follows:
//
//     lemon lemon-test01.y && gcc -g lemon-test01.c && ./a.out
//
%token_prefix TK_
%token_type   int
%default_type int
%include {
  static int nSyntaxError = 0;
  static int nAccept = 0;
  static int nFailure = 0;
}

all ::=  A B.
all ::=  error B.

%syntax_error {
  nSyntaxError++;
}
%parse_accept {
  nAccept++;
}
%parse_failure {
  nFailure++;
}
%code {
  #include <assert.h>
  #include "lemon-test01.h"
  static int nTest = 0;
  static int nErr = 0;
  static int testCase(int testId, int shouldBe, int actual){
    nTest++;
    if( shouldBe==actual ){
      printf("test %d: ok\n", testId);
    }else{
      printf("test %d: got %d, expected %d\n", testId, actual, shouldBe);
      nErr++;
    }
  }
  int main(int argc, char **argv){
    yyParser xp;
    ParseInit(&xp);
    Parse(&xp, TK_A, 0);
    Parse(&xp, TK_B, 0);
    Parse(&xp, 0, 0);
    ParseFinalize(&xp);
    testCase(100, 0, nSyntaxError);
    testCase(110, 1, nAccept);
    testCase(120, 0, nFailure);
    nSyntaxError = nAccept = nFailure = 0;
    ParseInit(&xp);
    Parse(&xp, TK_B, 0);
    Parse(&xp, TK_B, 0);
    Parse(&xp, 0, 0);
    ParseFinalize(&xp);
    testCase(200, 1, nSyntaxError);
    testCase(210, 1, nAccept);
    testCase(220, 0, nFailure);
    nSyntaxError = nAccept = nFailure = 0;
    ParseInit(&xp);
    Parse(&xp, TK_A, 0);
    Parse(&xp, TK_A, 0);
    Parse(&xp, 0, 0);
    ParseFinalize(&xp);
    testCase(200, 1, nSyntaxError);
    testCase(210, 0, nAccept);
    testCase(220, 0, nFailure);
    if( nErr==0 ){
      printf("%d tests pass\n", nTest);
    }else{
      printf("%d errors out %d tests\n", nErr, nTest);
    }
    return nErr;
  }
}

Changes to test/pragma4.test.

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
...
222
223
224
225
226
227
228
229
}
do_test 4.1.4 { 
  sqlite3 db3 test.db
  sqlite3 db2 test.db2
  execsql { DROP TABLE t1 } db3
  execsql { DROP TABLE t2 } db2
} {}
do_execsql_test 4.1.5 { PRAGMA table_info = t1 }
do_execsql_test 4.1.6 { PRAGMA table_info = t2 }

db2 close
db3 close
reset_db
forcedelete test.db2
do_execsql_test 4.2.1 {
  CREATE TABLE t1(a, b, c);
  ATTACH 'test.db2' AS aux;
  CREATE TABLE aux.t2(d, e, f);
}

do_execsql_test 4.2.2 { SELECT * FROM pragma_table_info('t1') } {
  0 a {} 0 {} 0 1 b {} 0 {} 0 2 c {} 0 {} 0
}
do_execsql_test 4.2.3 { SELECT * FROM pragma_table_info('t2') } {
  0 d {} 0 {} 0 1 e {} 0 {} 0 2 f {} 0 {} 0

}
do_test 4.2.4 { 
  sqlite3 db3 test.db
  sqlite3 db2 test.db2
  execsql { DROP TABLE t1 } db3
  execsql { DROP TABLE t2 } db2
} {}

do_execsql_test 4.2.5 { SELECT * FROM pragma_table_info('t1') } 
do_execsql_test 4.2.6 { SELECT * FROM pragma_table_info('t2') } 


db2 close
db3 close
reset_db
forcedelete test.db2
do_execsql_test 4.3.1 {
  CREATE TABLE t1(a, b, c);
  CREATE INDEX i1 ON t1(b);
  ATTACH 'test.db2' AS aux;
  CREATE TABLE aux.t2(d, e, f);
  CREATE INDEX aux.i2 ON t2(e);
}

do_execsql_test 4.3.2 { SELECT * FROM pragma_index_info('i1') } {0 1 b}
do_execsql_test 4.3.3 { SELECT * FROM pragma_index_info('i2') } {0 1 e}

do_test 4.3.4 { 
  sqlite3 db3 test.db
  sqlite3 db2 test.db2
  execsql { DROP INDEX i1 } db3
  execsql { DROP INDEX i2 } db2
} {}

do_execsql_test 4.3.5 { SELECT * FROM pragma_index_info('i1') } 
do_execsql_test 4.3.6 { SELECT * FROM pragma_index_info('i2') } 



do_execsql_test 4.4.0 {
  CREATE INDEX main.i1 ON t1(b, c);
  CREATE INDEX aux.i2 ON t2(e, f);
}

do_execsql_test 4.4.1 { SELECT * FROM pragma_index_list('t1') } {0 i1 0 c 0}
do_execsql_test 4.4.2 { SELECT * FROM pragma_index_list('t2') } {0 i2 0 c 0}

do_test 4.4.3 { 
  execsql { DROP INDEX i1 } db3
  execsql { DROP INDEX i2 } db2
} {}

do_execsql_test 4.4.5 { SELECT * FROM pragma_index_list('t1') } {}
do_execsql_test 4.4.6 { SELECT * FROM pragma_index_list('t2') } {}



do_execsql_test 4.5.0 {
  CREATE UNIQUE INDEX main.i1 ON t1(a);
  CREATE UNIQUE INDEX aux.i2 ON t2(d);
  CREATE TABLE main.c1 (a, b, c REFERENCES t1(a));
  CREATE TABLE aux.c2 (d, e, r REFERENCES t2(d));
}

do_execsql_test 4.5.1 { SELECT * FROM pragma_foreign_key_list('c1') } {
  0 0 t1 c a {NO ACTION} {NO ACTION} NONE
}
do_execsql_test 4.5.2 { SELECT * FROM pragma_foreign_key_list('c2') } {
  0 0 t2 r d {NO ACTION} {NO ACTION} NONE

}
do_test 4.5.3 { 
  execsql { DROP TABLE c1 } db3
  execsql { DROP TABLE c2 } db2
} {}

do_execsql_test 4.5.1 { SELECT * FROM pragma_foreign_key_list('c1') }
do_execsql_test 4.5.2 { SELECT * FROM pragma_foreign_key_list('c2') } 



do_execsql_test 4.6.0 {
  CREATE TABLE main.c1 (a, b, c REFERENCES t1(a));
  CREATE TABLE aux.c2 (d, e, r REFERENCES t2(d));
  INSERT INTO main.c1 VALUES(1, 2, 3);
  INSERT INTO aux.c2 VALUES(4, 5, 6);
}
................................................................................
} {}
do_execsql_test 4.6.4 { pragma foreign_key_check('c1') } {c1 1 t1 0}
do_catchsql_test 4.6.5 { 
  pragma foreign_key_check('c2') 
} {1 {no such table: c2}}

finish_test








|
|










>
|
|
|
|
|
>







>
|
|
>












>
|
|
>






>
|
|
|
>
>




>
|
|
>




>
|
|
>
>







>
|
|
|
|
|
>





>
|
|
>
>







 







<
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
...
241
242
243
244
245
246
247

}
do_test 4.1.4 { 
  sqlite3 db3 test.db
  sqlite3 db2 test.db2
  execsql { DROP TABLE t1 } db3
  execsql { DROP TABLE t2 } db2
} {}
do_execsql_test 4.1.5 { PRAGMA table_info(t1) }
do_execsql_test 4.1.6 { PRAGMA table_info(t2) }

db2 close
db3 close
reset_db
forcedelete test.db2
do_execsql_test 4.2.1 {
  CREATE TABLE t1(a, b, c);
  ATTACH 'test.db2' AS aux;
  CREATE TABLE aux.t2(d, e, f);
}
ifcapable vtab {
  do_execsql_test 4.2.2 { SELECT * FROM pragma_table_info('t1') } {
    0 a {} 0 {} 0 1 b {} 0 {} 0 2 c {} 0 {} 0
  }
  do_execsql_test 4.2.3 { SELECT * FROM pragma_table_info('t2') } {
    0 d {} 0 {} 0 1 e {} 0 {} 0 2 f {} 0 {} 0
  }
}
do_test 4.2.4 { 
  sqlite3 db3 test.db
  sqlite3 db2 test.db2
  execsql { DROP TABLE t1 } db3
  execsql { DROP TABLE t2 } db2
} {}
ifcapable vtab {
  do_execsql_test 4.2.5 { SELECT * FROM pragma_table_info('t1') } 
  do_execsql_test 4.2.6 { SELECT * FROM pragma_table_info('t2') } 
}

db2 close
db3 close
reset_db
forcedelete test.db2
do_execsql_test 4.3.1 {
  CREATE TABLE t1(a, b, c);
  CREATE INDEX i1 ON t1(b);
  ATTACH 'test.db2' AS aux;
  CREATE TABLE aux.t2(d, e, f);
  CREATE INDEX aux.i2 ON t2(e);
}
ifcapable vtab {
  do_execsql_test 4.3.2 { SELECT * FROM pragma_index_info('i1') } {0 1 b}
  do_execsql_test 4.3.3 { SELECT * FROM pragma_index_info('i2') } {0 1 e}
}
do_test 4.3.4 { 
  sqlite3 db3 test.db
  sqlite3 db2 test.db2
  execsql { DROP INDEX i1 } db3
  execsql { DROP INDEX i2 } db2
} {}
ifcapable vtab {
  do_execsql_test 4.3.5 { SELECT * FROM pragma_index_info('i1') } 
  do_execsql_test 4.3.6 { SELECT * FROM pragma_index_info('i2') } 
}

execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}
do_execsql_test 4.4.0 {
  CREATE INDEX main.i1 ON t1(b, c);
  CREATE INDEX aux.i2 ON t2(e, f);
}
ifcapable vtab {
  do_execsql_test 4.4.1 { SELECT * FROM pragma_index_list('t1') } {0 i1 0 c 0}
  do_execsql_test 4.4.2 { SELECT * FROM pragma_index_list('t2') } {0 i2 0 c 0}
}
do_test 4.4.3 { 
  execsql { DROP INDEX i1 } db3
  execsql { DROP INDEX i2 } db2
} {}
ifcapable vtab {
  do_execsql_test 4.4.5 { SELECT * FROM pragma_index_list('t1') } {}
  do_execsql_test 4.4.6 { SELECT * FROM pragma_index_list('t2') } {}
}
execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}

do_execsql_test 4.5.0 {
  CREATE UNIQUE INDEX main.i1 ON t1(a);
  CREATE UNIQUE INDEX aux.i2 ON t2(d);
  CREATE TABLE main.c1 (a, b, c REFERENCES t1(a));
  CREATE TABLE aux.c2 (d, e, r REFERENCES t2(d));
}
ifcapable vtab {
  do_execsql_test 4.5.1 { SELECT * FROM pragma_foreign_key_list('c1') } {
    0 0 t1 c a {NO ACTION} {NO ACTION} NONE
  }
  do_execsql_test 4.5.2 { SELECT * FROM pragma_foreign_key_list('c2') } {
    0 0 t2 r d {NO ACTION} {NO ACTION} NONE
  }
}
do_test 4.5.3 { 
  execsql { DROP TABLE c1 } db3
  execsql { DROP TABLE c2 } db2
} {}
ifcapable vtab {
  do_execsql_test 4.5.4 { SELECT * FROM pragma_foreign_key_list('c1') }
  do_execsql_test 4.5.5 { SELECT * FROM pragma_foreign_key_list('c2') } 
}
execsql {SELECT * FROM main.sqlite_master, aux.sqlite_master}

do_execsql_test 4.6.0 {
  CREATE TABLE main.c1 (a, b, c REFERENCES t1(a));
  CREATE TABLE aux.c2 (d, e, r REFERENCES t2(d));
  INSERT INTO main.c1 VALUES(1, 2, 3);
  INSERT INTO aux.c2 VALUES(4, 5, 6);
}
................................................................................
} {}
do_execsql_test 4.6.4 { pragma foreign_key_check('c1') } {c1 1 t1 0}
do_catchsql_test 4.6.5 { 
  pragma foreign_key_check('c2') 
} {1 {no such table: c2}}

finish_test

Changes to test/releasetest.tcl.

75
76
77
78
79
80
81



82
83
84
85
86
87
88
...
270
271
272
273
274
275
276

277
278
279
280
281
282
283
    -DHAVE_UTIME=0
  }
  "Unlock-Notify" {
    -O2
    -DSQLITE_ENABLE_UNLOCK_NOTIFY
    -DSQLITE_THREADSAFE
    -DSQLITE_TCL_DEFAULT_FULLMUTEX=1



    -DSQLITE_USER_AUTHENTICATION=1
  }
  "Secure-Delete" {
    -O2
    -DSQLITE_SECURE_DELETE=1
    -DSQLITE_SOUNDEX=1
  }
................................................................................
  Linux-x86_64 {
    "Check-Symbols"           checksymbols
    "Fast-One"                "fuzztest test"
    "Debug-One"               "mptest test"
    "Have-Not"                test
    "Secure-Delete"           test
    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"

    "Update-Delete-Limit"     test
    "Extra-Robustness"        test
    "Device-Two"              test
    "No-lookaside"            test
    "Devkit"                  test
    "Apple"                   test
    "Sanitize"                {QUICKTEST_OMIT=func4.test,nan.test test}







>
>
>







 







>







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
...
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
    -DHAVE_UTIME=0
  }
  "Unlock-Notify" {
    -O2
    -DSQLITE_ENABLE_UNLOCK_NOTIFY
    -DSQLITE_THREADSAFE
    -DSQLITE_TCL_DEFAULT_FULLMUTEX=1
  }
  "User-Auth" {
    -O2
    -DSQLITE_USER_AUTHENTICATION=1
  }
  "Secure-Delete" {
    -O2
    -DSQLITE_SECURE_DELETE=1
    -DSQLITE_SOUNDEX=1
  }
................................................................................
  Linux-x86_64 {
    "Check-Symbols"           checksymbols
    "Fast-One"                "fuzztest test"
    "Debug-One"               "mptest test"
    "Have-Not"                test
    "Secure-Delete"           test
    "Unlock-Notify"           "QUICKTEST_INCLUDE=notify2.test test"
    "User-Auth"               tcltest
    "Update-Delete-Limit"     test
    "Extra-Robustness"        test
    "Device-Two"              test
    "No-lookaside"            test
    "Devkit"                  test
    "Apple"                   test
    "Sanitize"                {QUICKTEST_OMIT=func4.test,nan.test test}

Changes to test/vtab_err.test.

16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
..
58
59
60
61
62
63
64
65






















66

ifcapable !vtab {
  finish_test
  return
}



unset -nocomplain echo_module_begin_fail
do_ioerr_test vtab_err-1 -tclprep {
  register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
  BEGIN;
  CREATE TABLE r(a PRIMARY KEY, b, c);
  CREATE VIRTUAL TABLE e USING echo(r);
................................................................................
    CREATE TABLE r2(a, b, c);
    INSERT INTO r2 SELECT * FROM e;
    INSERT INTO e SELECT a||'x', b, c FROM r2;
  COMMIT;
} 

sqlite3_memdebug_fail -1























finish_test







<







 








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

16
17
18
19
20
21
22

23
24
25
26
27
28
29
..
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

ifcapable !vtab {
  finish_test
  return
}



unset -nocomplain echo_module_begin_fail
do_ioerr_test vtab_err-1 -tclprep {
  register_echo_module [sqlite3_connection_pointer db]
} -sqlbody {
  BEGIN;
  CREATE TABLE r(a PRIMARY KEY, b, c);
  CREATE VIRTUAL TABLE e USING echo(r);
................................................................................
    CREATE TABLE r2(a, b, c);
    INSERT INTO r2 SELECT * FROM e;
    INSERT INTO e SELECT a||'x', b, c FROM r2;
  COMMIT;
} 

sqlite3_memdebug_fail -1

reset_db
register_echo_module [sqlite3_connection_pointer db]
do_execsql_test vtab_err-3.0 {
  CREATE TABLE r(a PRIMARY KEY, b, c);
  CREATE VIRTUAL TABLE e USING echo(r);
}
faultsim_save_and_close

do_faultsim_test vtab_err-3 -faults oom-t* -prep {
  faultsim_restore_and_reopen
  register_echo_module [sqlite3_connection_pointer db]
} -body {
  execsql {
    BEGIN;
      CREATE TABLE xyz(x);
      SELECT a FROM e;
    COMMIT;
  }
} -test {
  faultsim_test_result {0 {}}
}

finish_test

Changes to tool/lempar.c.

19
20
21
22
23
24
25

26
27
28
29
30
31
32
...
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
** of this template is copied straight through into the generate parser
** source file.
**
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
#include <stdio.h>

/************ Begin %include sections from the grammar ************************/
%%
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols
** in a format understandable to "makeheaders".  This section is blank unless
** "lemon" is run with the "-m" command-line option.
***************** Begin makeheaders token definitions *************************/
................................................................................
             yyTracePrompt,yyTokenName[yymajor]);
        }
#endif
        yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
        yymajor = YYNOCODE;
      }else{
        while( yypParser->yytos >= yypParser->yystack
            && yymx != YYERRORSYMBOL
            && (yyact = yy_find_reduce_action(
                        yypParser->yytos->stateno,
                        YYERRORSYMBOL)) >= YY_MIN_REDUCE
        ){
          yy_pop_parser_stack(yypParser);
        }
        if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
          yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
          yy_parse_failed(yypParser);
#ifndef YYNOERRORRECOVERY







>







 







<


|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
984
985
986
987
988
989
990

991
992
993
994
995
996
997
998
999
1000
** of this template is copied straight through into the generate parser
** source file.
**
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
#include <stdio.h>
#include <assert.h>
/************ Begin %include sections from the grammar ************************/
%%
/**************** End of %include directives **********************************/
/* These constants specify the various numeric values for terminal symbols
** in a format understandable to "makeheaders".  This section is blank unless
** "lemon" is run with the "-m" command-line option.
***************** Begin makeheaders token definitions *************************/
................................................................................
             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