Compare commits

...

46 Commits

Author SHA1 Message Date
drh 61f92cd045 In LEMON, fix a bug in the text formatter introduced by the previous
commit.  Also add the new "%token_class" directive for defining symbolic
names that stand any one of a collection of tokens.

FossilOrigin-Name: da7890ca6b1d8e511377a469047120220e8c3b2d
2014-01-11 03:06:18 +00:00
drh 898799fa00 Do not use sprintf(), strcpy() or strcat() in the implementation of the
lemon parser generator tool, to avoid compiler warnings in OpenBSD.

FossilOrigin-Name: e43c522dde01e134f1adc94f534d2b3eda74afc2
2014-01-10 23:21:00 +00:00
drh 144ffe7bfb Remove unused structure definition from parse.y.
FossilOrigin-Name: 7f1e7ae313c7625ef2623d78883dce776eecca30
2014-01-10 20:51:16 +00:00
drh 75593d96be Allow a VALUES clause to be used any place that a SELECT statement can be
used.

FossilOrigin-Name: c9ea7d199f06a7801ab639e7ac98ebeb98706f24
2014-01-10 20:46:55 +00:00
drh c740752470 Fix CREATE TABLE ... AS so that it works with column names that are empty
strings.

FossilOrigin-Name: 632045f21c553e10f59a14c772d50d7824ca0c2c
2014-01-10 20:38:12 +00:00
dan 9871c59a2d Fix another harmless compiler warning in unixUnfetch().
FossilOrigin-Name: 0484549bb82ca5246488330c8d266e429ccd19b9
2014-01-10 16:40:21 +00:00
drh 1bcbc621df Fix harmless compiler warning in unixUnfetch().
FossilOrigin-Name: 618f248f4ea9fb0b6ff019a4c2cd72857389301f
2014-01-09 13:39:07 +00:00
drh b66e21fda5 Fix an typo that breaks the build when SQLITE_ENABLE_TREE_EXPLAIN is defined.
FossilOrigin-Name: f461e2b3973d0fe6a7b8cb7a3aaab8a30b3e16c0
2014-01-04 20:00:14 +00:00
dan 2e08486a08 Add the usual "fts3" prefix to new static method setEstimatedRows() in fts3.c. This fixes a problem when compiling the amalgamation, as the r-tree module also contains a static method named setEstimatedRows.
FossilOrigin-Name: d6fcfc8890489b942e5b3f1bc271835d77c5ef96
2014-01-04 19:58:29 +00:00
drh 1c2c0b776f Avoid redundant register loads during index key generation when doing a
DELETE or INTEGRITY_CHECK on a table with multiple indices.

FossilOrigin-Name: 8f6e6149a165f516be6395fd753e163d52ffd52e
2014-01-04 19:27:05 +00:00
drh 61019c7883 Omit OP_Close operations that occur immediately prior to OP_Halt and which
cannot be jumped over.

FossilOrigin-Name: 874b7e9999811c288ad41d07709f88e458d2d497
2014-01-04 16:49:02 +00:00
drh 54e2adb5f3 Improvements to the column-cache for nested AND/OR operators.
FossilOrigin-Name: 4e725f53131d3584319c710c8710a068989543c6
2014-01-04 15:17:04 +00:00
dan 8c7d4ddd5a Have FTS assign extremely high costs to plans that feature unusable MATCH constraints. This discourages the planner from choosing such plans, which lead to "unable to use function MATCH in the requested context" errors.
FossilOrigin-Name: fa8be488a3ad290722dae7a1a7396c77277b2149
2014-01-04 14:46:39 +00:00
dan 69014393f8 Instead of having the planner ignore plans with unusable MATCH constraints, have FTS assign extremely high costs to such plans in order to discourage the planner from using them.
FossilOrigin-Name: 24f84b38131866f7b435ffe641bb2f6991a70db2
2014-01-04 14:42:14 +00:00
dan 42899543f8 Have the planner detect cases where a MATCH constraint is applied to a virtual table, and ignore any plans that do not allow the virtual table implementation to implement the MATCH filtering.
FossilOrigin-Name: 19f3208b26597625728d1ef716d4e44407cf96ac
2014-01-04 14:16:06 +00:00
drh 5426d80948 Avoid some unnecessary OP_SCopy operations when inserting into a table
with multiple indices.

FossilOrigin-Name: 429018b19cb525a4bb0843d20955457b53900d4b
2014-01-03 16:03:43 +00:00
drh 759e858811 Try to factor constant subcomponents of the WHERE clause out of the loop.
FossilOrigin-Name: 9d05777fe24e1a5ce71762de38db840931ef0bc8
2014-01-02 21:05:10 +00:00
drh 762c1c4071 Avoid unnecessary affinity transformations when building indices using
data from a table.

FossilOrigin-Name: 10d851353c2abeadbd2852c210a7ff9f7f513e5d
2014-01-02 19:35:30 +00:00
drh 991a198511 Be more aggressive in optimizing constant conditional expressions.
FossilOrigin-Name: b7e39851a75b87ebca747b26a39989560fd6362b
2014-01-02 17:57:16 +00:00
drh b00d862139 Try to detect process ID changes due to fork() calls in os_unix.c and
reset the PRNG when a process ID change is detected.

FossilOrigin-Name: e1eba1fb09d7db49d77928bd115b27b8002ae640
2014-01-01 15:18:36 +00:00
drh fe98081e18 Enhance sqlite3_randomness(N,P) such that it resets the internal PRNG
if N is less than 1.  Subsequent calls to sqlite3_randomness() will reinitialize
the internal PRNG by calling the xRandomness() method of the default VFS.

FossilOrigin-Name: a221aa82bb5496885fd0bf76e4601443799511de
2014-01-01 14:00:13 +00:00
drh 3312348cf8 Add -I. to the main.mk makefile for building sqlite3.o and speedtest1.
FossilOrigin-Name: cc72c5aec7fe93d4a1368517aab949dc98d33003
2013-12-24 12:04:24 +00:00
drh 73d5b8f550 Move elements of the Vdbe object that are only used during statement
preparation out into the Parse object.

FossilOrigin-Name: c289a253c0c053ac8fc344efe138262c327d8096
2013-12-23 19:09:07 +00:00
drh 58c960816f Remove a stray tab character.
FossilOrigin-Name: 25b8a1c9ba77df3b7c78cbce922cb593d661696d
2013-12-23 11:33:32 +00:00
drh eaf4f523a5 Remove a condition that is always in the logic that handles reading
default values for columns.

FossilOrigin-Name: 895af097e71749f423b63ece17c5a4b4dfcd164d
2013-12-22 22:45:14 +00:00
drh 6c1de308f2 Make sure the WhereLoop.aLTerm[] array is large enough when processing
the skip-scan optimization.  Fix for ticket [520070ec7fbaac].

FossilOrigin-Name: 46d040591f27be01b1860344f8a268797fe344f4
2013-12-22 20:44:10 +00:00
drh 25555506df Fix speedtest1.c so that in --explain mode it only outputs non-explain text
for DDL statements.

FossilOrigin-Name: 2d2b3c4951dc2b8317d5ba8b5cf72b1f4a6668f6
2013-12-21 17:14:58 +00:00
drh 685e3c481c Avoid compiler warnings by only enabling sqlite3ErrName() when
SQLITE_TEST is defined.

FossilOrigin-Name: 862228e50534a6b89c9498c4db664610db11485e
2013-12-21 17:07:13 +00:00
drh c73d0d9dec Fix harmless compiler warnings in FTS4. This involved corrupting
Martin Porter's beautifully written and elegant stemmer code, making it
a little less beautiful and a little less elegant.  Today is a sad
day.  But the warnings from GCC grow increasingly verbose and irksome
with each new release and so something had to be done.

FossilOrigin-Name: df05679838b571c16a7ab7e135f9564cd2d9647c
2013-12-21 16:06:47 +00:00
drh 849a9d92ba Fix the ".echo on" dot-command of the shell so that it echos comments in
addition to SQL statements and dot-commands.  Add the --explain option
to speedtest1 so that the output can be piped into the command-line shell
to show nicely-formated VDBE code for the entire test.

FossilOrigin-Name: 96397263f94256e284aae9506de1fc48fea89193
2013-12-21 15:46:06 +00:00
drh ae28d6efc6 Add a case to speedtest1.c that demonstrates the need to factor OP_Column
operators out of inner loops.

FossilOrigin-Name: 69a17336fdf4ae891e815914be8942f7222230c2
2013-12-21 00:04:37 +00:00
drh a47941fe42 Fix compiler harmless warnings in tclsqlite.c that appeared with GCC 4.8.x.
FossilOrigin-Name: d93ae6833a7fca0672caf902a7b48846e54242cd
2013-12-20 18:57:44 +00:00
drh d42ef839bc Code simplification in sqlite3GenerateIndexKey() by making use of a subroutine
found over in expr.c.

FossilOrigin-Name: 0026d3355340d66687a3fd4cbece28811ef1b505
2013-12-20 18:44:35 +00:00
drh 4eded604ea Combine adjacent single-register OP_Copy instructions into a single
multi-register OP_Copy, where possible.  Fix the Synopsis comment for
multi-register OP_Copy instructions to show the correct register ranges.

FossilOrigin-Name: 2ae22dc0cbed2feca4baf89d02aaace0331971d6
2013-12-20 15:59:20 +00:00
drh aed1819875 Allow any arbitrary expression as the filename in an ATTACH statement,
including functions and subqueries.

FossilOrigin-Name: df70a1f30393b34146d6b8bf1df5a76aaf362efe
2013-12-20 14:48:12 +00:00
drh 7e61d18eb4 Simplify the accumulator reset for aggregate query processing so that it
uses a single multi-register OP_Null rather than a separate OP_Null for each
register.

FossilOrigin-Name: 2c7fd9b043f5f3d9d8e22dbefa84a9770ca951d0
2013-12-20 13:11:45 +00:00
dan 1001ee8819 Do not inject OOM faults into SQLITE_FCNTL_COMMIT_PHASE_TWO file-control invocations. It causes problems for test scripts.
FossilOrigin-Name: 8eb28d23e353139d24a8af78309d39249ab9eaf0
2013-12-19 17:04:58 +00:00
drh f6b1a8e1a5 Make sure errors encountered while initializing extensions such as FTS4
get reported out from sqlite3_open().  This fixes a bug introduced by
check-in [9d347f547e7ba9].  Also remove lots of forgotten "breakpoint"
commands left in test scripts over the years.

FossilOrigin-Name: ca3fdfd41961d8d3d1e39d20dc628e8a95dabb2f
2013-12-19 16:26:05 +00:00
drh a021f121c9 Remove an unneeded column-cache flush in aggregate SELECT
and an unreachable branch in the INSERT logic.

FossilOrigin-Name: ffa092e13b3781677b18418cca40e3dd1e388aed
2013-12-19 14:34:34 +00:00
drh edfac3456e Omit an unnecessary OP_Null opcode from UPDATE.
FossilOrigin-Name: 72d111336c5016e5b5092dfebcd01253266a7685
2013-12-19 02:56:01 +00:00
drh 46d03fcbfc Omit one or more pointless instructions that occur in between OP_NoConflict
and OP_Halt.

FossilOrigin-Name: 61e2f3575c4a94f9571c28fb2bd19da84b0edceb
2013-12-19 02:23:45 +00:00
drh 935c34711b Remove an unnecessary column-cache flush operation. Add code to trace the
column cache when compiled with SQLITE_DEBUG and using
PRAGMA vdbe_addoptrace=ON.

FossilOrigin-Name: 58704ed1f4cd78bb3b0c095ffd1626906a95a413
2013-12-18 18:44:43 +00:00
drh 039468ef2d Remove an unnecessary column-cache flush. Add another test case to the
speedtest1.c program to accentuate the benefit of not flushing the cache at
that point.

FossilOrigin-Name: 97fdfc6b79833011fc0c506fe5e0985c0fb1906c
2013-12-18 16:27:48 +00:00
drh 9ac7962ace Show changes to the column cache when PRAGMA vdbe_addoptrace=ON is set.
FossilOrigin-Name: 4c6a659c432e4f7c0285f58675a67f967b07bb0d
2013-12-18 15:11:47 +00:00
drh 3a8aec5e13 Add evidence marks and additional test cases for the printf() SQL function.
FossilOrigin-Name: 93121d3097a43997af3c0de65bd9bd7663845fa2
2013-12-17 16:32:56 +00:00
drh afa5af807c Add the printf() SQL function.
FossilOrigin-Name: a1bb62f91a85af0584100c3ad77877a949c30cca
2013-12-17 16:10:57 +00:00
57 changed files with 915 additions and 407 deletions
+27 -1
View File
@@ -1472,6 +1472,19 @@ static int fts3CreateMethod(
return fts3InitVtab(1, db, pAux, argc, argv, ppVtab, pzErr);
}
/*
** Set the pIdxInfo->estimatedRows variable to nRow. Unless this
** extension is currently being used by a version of SQLite too old to
** support estimatedRows. In that case this function is a no-op.
*/
static void fts3SetEstimatedRows(sqlite3_index_info *pIdxInfo, i64 nRow){
#if SQLITE_VERSION_NUMBER>=3008002
if( sqlite3_libversion_number()>=3008002 ){
pIdxInfo->estimatedRows = nRow;
}
#endif
}
/*
** Implementation of the xBestIndex method for FTS3 tables. There
** are three possible strategies, in order of preference:
@@ -1499,7 +1512,20 @@ static int fts3BestIndexMethod(sqlite3_vtab *pVTab, sqlite3_index_info *pInfo){
for(i=0; i<pInfo->nConstraint; i++){
int bDocid; /* True if this constraint is on docid */
struct sqlite3_index_constraint *pCons = &pInfo->aConstraint[i];
if( pCons->usable==0 ) continue;
if( pCons->usable==0 ){
if( pCons->op==SQLITE_INDEX_CONSTRAINT_MATCH ){
/* There exists an unusable MATCH constraint. This means that if
** the planner does elect to use the results of this call as part
** of the overall query plan the user will see an "unable to use
** function MATCH in the requested context" error. To discourage
** this, return a very high cost here. */
pInfo->idxNum = FTS3_FULLSCAN_SEARCH;
pInfo->estimatedCost = 1e50;
fts3SetEstimatedRows(pInfo, ((sqlite3_int64)1) << 50);
return SQLITE_OK;
}
continue;
}
bDocid = (pCons->iColumn<0 || pCons->iColumn==p->nColumn+1);
+45 -29
View File
@@ -403,12 +403,14 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
/* Step 2 */
switch( z[1] ){
case 'a':
stem(&z, "lanoita", "ate", m_gt_0) ||
stem(&z, "lanoit", "tion", m_gt_0);
if( !stem(&z, "lanoita", "ate", m_gt_0) ){
stem(&z, "lanoit", "tion", m_gt_0);
}
break;
case 'c':
stem(&z, "icne", "ence", m_gt_0) ||
stem(&z, "icna", "ance", m_gt_0);
if( !stem(&z, "icne", "ence", m_gt_0) ){
stem(&z, "icna", "ance", m_gt_0);
}
break;
case 'e':
stem(&z, "rezi", "ize", m_gt_0);
@@ -417,43 +419,54 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
stem(&z, "igol", "log", m_gt_0);
break;
case 'l':
stem(&z, "ilb", "ble", m_gt_0) ||
stem(&z, "illa", "al", m_gt_0) ||
stem(&z, "iltne", "ent", m_gt_0) ||
stem(&z, "ile", "e", m_gt_0) ||
stem(&z, "ilsuo", "ous", m_gt_0);
if( !stem(&z, "ilb", "ble", m_gt_0)
&& !stem(&z, "illa", "al", m_gt_0)
&& !stem(&z, "iltne", "ent", m_gt_0)
&& !stem(&z, "ile", "e", m_gt_0)
){
stem(&z, "ilsuo", "ous", m_gt_0);
}
break;
case 'o':
stem(&z, "noitazi", "ize", m_gt_0) ||
stem(&z, "noita", "ate", m_gt_0) ||
stem(&z, "rota", "ate", m_gt_0);
if( !stem(&z, "noitazi", "ize", m_gt_0)
&& !stem(&z, "noita", "ate", m_gt_0)
){
stem(&z, "rota", "ate", m_gt_0);
}
break;
case 's':
stem(&z, "msila", "al", m_gt_0) ||
stem(&z, "ssenevi", "ive", m_gt_0) ||
stem(&z, "ssenluf", "ful", m_gt_0) ||
stem(&z, "ssensuo", "ous", m_gt_0);
if( !stem(&z, "msila", "al", m_gt_0)
&& !stem(&z, "ssenevi", "ive", m_gt_0)
&& !stem(&z, "ssenluf", "ful", m_gt_0)
){
stem(&z, "ssensuo", "ous", m_gt_0);
}
break;
case 't':
stem(&z, "itila", "al", m_gt_0) ||
stem(&z, "itivi", "ive", m_gt_0) ||
stem(&z, "itilib", "ble", m_gt_0);
if( !stem(&z, "itila", "al", m_gt_0)
&& !stem(&z, "itivi", "ive", m_gt_0)
){
stem(&z, "itilib", "ble", m_gt_0);
}
break;
}
/* Step 3 */
switch( z[0] ){
case 'e':
stem(&z, "etaci", "ic", m_gt_0) ||
stem(&z, "evita", "", m_gt_0) ||
stem(&z, "ezila", "al", m_gt_0);
if( !stem(&z, "etaci", "ic", m_gt_0)
&& !stem(&z, "evita", "", m_gt_0)
){
stem(&z, "ezila", "al", m_gt_0);
}
break;
case 'i':
stem(&z, "itici", "ic", m_gt_0);
break;
case 'l':
stem(&z, "laci", "ic", m_gt_0) ||
stem(&z, "luf", "", m_gt_0);
if( !stem(&z, "laci", "ic", m_gt_0) ){
stem(&z, "luf", "", m_gt_0);
}
break;
case 's':
stem(&z, "ssen", "", m_gt_0);
@@ -494,9 +507,11 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
z += 3;
}
}else if( z[2]=='e' ){
stem(&z, "tneme", "", m_gt_1) ||
stem(&z, "tnem", "", m_gt_1) ||
stem(&z, "tne", "", m_gt_1);
if( !stem(&z, "tneme", "", m_gt_1)
&& !stem(&z, "tnem", "", m_gt_1)
){
stem(&z, "tne", "", m_gt_1);
}
}
}
break;
@@ -515,8 +530,9 @@ static void porter_stemmer(const char *zIn, int nIn, char *zOut, int *pnOut){
}
break;
case 't':
stem(&z, "eta", "", m_gt_1) ||
stem(&z, "iti", "", m_gt_1);
if( !stem(&z, "eta", "", m_gt_1) ){
stem(&z, "iti", "", m_gt_1);
}
break;
case 'u':
if( z[0]=='s' && z[2]=='o' && m_gt_1(z+3) ){
+2 -2
View File
@@ -389,7 +389,7 @@ mptester$(EXE): sqlite3.c $(TOP)/mptest/mptest.c
$(TLIBS) $(THREADLIB)
sqlite3.o: sqlite3.c
$(TCCX) -c sqlite3.c
$(TCCX) -I. -c sqlite3.c
# This target creates a directory named "tsrc" and fills it with
# copies of all of the C source code and header files needed to
@@ -631,7 +631,7 @@ wordcount$(EXE): $(TOP)/test/wordcount.c sqlite3.c
$(TOP)/test/wordcount.c sqlite3.c
speedtest1$(EXE): $(TOP)/test/speedtest1.c sqlite3.o
$(TCC) -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB)
$(TCC) -I. -o speedtest1$(EXE) $(TOP)/test/speedtest1.c sqlite3.o $(THREADLIB)
# This target will fail if the SQLite amalgamation contains any exported
# symbols that do not begin with "sqlite3_". It is run as part of the
+60 -59
View File
@@ -1,5 +1,5 @@
C Fix\sthe\sformatting\sof\s%c\sin\sthe\sprintf()\sSQL\sfunction.
D 2013-12-17T15:58:42.950
C In\sLEMON,\sfix\sa\sbug\sin\sthe\stext\sformatter\sintroduced\sby\sthe\sprevious\ncommit.\s\sAlso\sadd\sthe\snew\s"%token_class"\sdirective\sfor\sdefining\ssymbolic\nnames\sthat\sstand\sany\sone\sof\sa\scollection\sof\stokens.
D 2014-01-11T03:06:18.172
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 2ef13430cd359f7b361bb863504e227b25cc7f81
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -78,7 +78,7 @@ F ext/fts3/README.content fdc666a70d5257a64fee209f97cf89e0e6e32b51
F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a
F ext/fts3/README.tokenizers e0a8b81383ea60d0334d274fadf305ea14a8c314
F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d
F ext/fts3/fts3.c 1e667eacb3fe4b4ad6f863920da4286f071f6e07
F ext/fts3/fts3.c 3fe91e36a0304ad4b35020f0e22ff37e95873166
F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe
F ext/fts3/fts3Int.h eb5f8029589f3d8f1dc7fd50c773326a640388b1
F ext/fts3/fts3_aux.c 5c211e17a64885faeb16b9ba7772f9d5445c2365
@@ -86,7 +86,7 @@ F ext/fts3/fts3_expr.c 5165c365cb5a035f5be8bb296f7aa3211d43e4ac
F ext/fts3/fts3_hash.c 8dd2d06b66c72c628c2732555a32bc0943114914
F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf
F ext/fts3/fts3_icu.c e319e108661147bcca8dd511cd562f33a1ba81b5
F ext/fts3/fts3_porter.c a465b49fcb8249a755792f87516eff182efa42b3
F ext/fts3/fts3_porter.c 7f8b4bf5af7c0f20f73b8e87e14fa9298f52e290
F ext/fts3/fts3_snippet.c 51beb5c1498176fd9caccaf1c75b55cb803a985a
F ext/fts3/fts3_term.c a521f75132f9a495bdca1bdd45949b3191c52763
F ext/fts3/fts3_test.c 8a3a78c4458b2d7c631fcf4b152a5cd656fa7038
@@ -142,7 +142,7 @@ F ext/rtree/viewrtree.tcl eea6224b3553599ae665b239bd827e182b466024
F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x
F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
F magic.txt f439556c5ce01ced70987e5ee86549a45165d9ff
F main.mk 9f091ea7920f8b15e48c7b6e5b6fb0182577ab2e
F main.mk 3ae543fa446525c1dec55f58de67f41b78651812
F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
F mkextw.sh d2a981497b404d6498f5ff3e3b1f3816bdfcb338
@@ -161,7 +161,7 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a
F src/alter.c 2af0330bb1b601af7a7789bf7229675fd772a083
F src/analyze.c 581d5c18ce89c6f45d4dca65914d0de5b4dad41f
F src/attach.c 0a17c9364895316ca4f52d06a97a72c0af1ae8b3
F src/attach.c 3801129015ef59d76bf23c95ef9b0069d18a0c52
F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
F src/backup.c a729e63cf5cd1829507cb7b8e89f99b95141bb53
F src/bitvec.c 19a4ba637bd85f8f63fc8c9bae5ade9fb05ec1cb
@@ -169,13 +169,13 @@ F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
F src/btree.c 11e29ef8cf16a42925fde036bcffbeffd9cc82df
F src/btree.h a61ddebc78c66795a2b93181321a116746302cc9
F src/btreeInt.h f038e818bfadf75afbd09819ed93c26a333d39e0
F src/build.c 47ef8209e56d840d2b35b8a243c6ee567ad52bda
F src/build.c 8c56d91447770a746b16d08a6510109c161dbc1a
F src/callback.c 174e3c8656bc29f91d710ab61550d16eea34be98
F src/complete.c dc1d136c0feee03c2f7550bafc0d29075e36deac
F src/ctime.c 77779efbe78dd678d84bfb4fc2e87b6b6ad8dccd
F src/date.c 593c744b2623971e45affd0bde347631bdfa4625
F src/delete.c b36db1f79ee50eaca979660c9dd36437f5410b93
F src/expr.c 31a2b65339f6c3795d4cfa5e99798cd72f9fdfdf
F src/delete.c 91e1321021db5dc266360531b8b6550009d771ff
F src/expr.c 4115ad67088cdd55f4fa0ef3ddd22cb8da8f9c94
F src/fault.c 160a0c015b6c2629d3899ed2daf63d75754a32bb
F src/fkey.c 2ab0f5384b70594468ef3ac5c7ed8ca24bfd17d5
F src/func.c 6325ac2ec10833ccf4d5c36d323709221d37ea19
@@ -183,12 +183,12 @@ F src/global.c 1d7bb7ea8254ae6a68ed9bfaf65fcb3d1690b486
F src/hash.c ac3470bbf1ca4ae4e306a8ecb0fdf1731810ffe4
F src/hash.h 8890a25af81fb85a9ad7790d32eedab4b994da22
F src/hwtime.h d32741c8f4df852c7d959236615444e2b1063b08
F src/insert.c 3cf8012325857d162f74389420b14be7976a538d
F src/insert.c 5ddb48c7f1cb399993744f23f03948989ce1790e
F src/journal.c b4124532212b6952f42eb2c12fa3c25701d8ba8d
F src/legacy.c 0df0b1550b9cc1f58229644735e317ac89131f12
F src/lempar.c cdf0a000315332fc9b50b62f3b5e22e080a0952b
F src/loadext.c 867c7b330b740c6c917af9956b13b81d0a048303
F src/main.c 45e08d8ca4808625c4512a14898e9c61553e3d2a
F src/main.c 37f55de2000f6c882414ad3e1bcdb751c531fddd
F src/malloc.c 0203ebce9152c6a0e5de520140b8ba65187350be
F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
F src/mem1.c c0c990fcaddff810ea277b4fb5d9138603dd5d4b
@@ -202,34 +202,34 @@ F src/mutex_noop.c 7682796b7d8d39bf1c138248858efcd10c9e1553
F src/mutex_unix.c c3a4e00f96ba068a8dbef34084465979aaf369cc
F src/mutex_w32.c 6108c88e1cb38d8fbb3534b170793815cbedbf97
F src/notify.c 976dd0f6171d4588e89e874fcc765e92914b6d30
F src/os.c b4ad71336fd96f97776f75587cd9e8218288f5be
F src/os.c 1b147e4cf7cc39e618115c14a086aed44bc91ace
F src/os.h 4a46270a64e9193af4a0aaa3bc2c66dc07c29b3f
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
F src/os_unix.c 60a7b3b23e6fcf83a50d1e320b280b551724e11f
F src/os_unix.c 3a4dcb554d3c915075766162f28c3fd4cdb75968
F src/os_win.c 16eac0961603182ffc10c02b39fe830126538e07
F src/pager.c efa923693e958696eee69b205a20bfbc402c8480
F src/pager.h ffd5607f7b3e4590b415b007a4382f693334d428
F src/parse.y acee1a9958539e21263362b194594c5255ad2fca
F src/parse.y 60baa3aced02c9f91259719d196315bc28580719
F src/pcache.c f8043b433a57aba85384a531e3937a804432a346
F src/pcache.h a5e4f5d9f5d592051d91212c5949517971ae6222
F src/pcache1.c 57fee9a9a617218f5037afbbe49b09da65bde56b
F src/pragma.c 5ab7279d132143feb77f773688a24ab05da75fd7
F src/prepare.c 359d1a1e9c9bd4488e4dd3a1aaaf2d2ebb9bb768
F src/pragma.c ed409ce4104cf4d9de6ead40ace70974f124853b
F src/prepare.c 677521ab7132615a8a26107a1d1c3132f44ae337
F src/printf.c 85d07756e45d7496d19439dcae3e6e9e0090f269
F src/random.c 0b2dbc37fdfbfa6bd455b091dfcef5bdb32dba68
F src/random.c d10c1f85b6709ca97278428fd5db5bbb9c74eece
F src/resolve.c 7eda9097b29fcf3d2b42fdc17d1de672134e09b6
F src/rowset.c 64655f1a627c9c212d9ab497899e7424a34222e0
F src/select.c d41381d80a22d3a83352aeca274cccf264ac277a
F src/shell.c 18924f6ccfa70da98bf9e388bab512c0fd1e792e
F src/sqlite.h.in 4ef56464aeaa3785a2c5ca37fb3a0fb229d68b2e
F src/select.c 819bb090c9a348d17f69f136cad2bfa9ee9cbb41
F src/shell.c a3541193d5fce37e91dad8ef46a9505aa7c9b344
F src/sqlite.h.in d94a8b89522f526ba711182ee161e06f8669bcc9
F src/sqlite3.rc 11094cc6a157a028b301a9f06b3d03089ea37c3e
F src/sqlite3ext.h 886f5a34de171002ad46fae8c36a7d8051c190fc
F src/sqliteInt.h b7e9da87740488671cfe4c70038a8eef3a1d317e
F src/sqliteInt.h 0c65967bb807dee3c9eef2bbd17f880eeb28ea30
F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
F src/status.c 7ac05a5c7017d0b9f0b4bcd701228b784f987158
F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
F src/tclsqlite.c 651b10698c87bbc3ae5772e2491e3444c5bbf153
F src/test1.c 633e5e6a116acf4473b9289240bcceb5320a9d93
F src/tclsqlite.c c43379f77f90399802b0e215faa71c0adc3a4d2e
F src/test1.c db16ba651453b15001c7f2838c446284dde4ecaf
F src/test2.c 7355101c085304b90024f2261e056cdff13c6c35
F src/test3.c 1c0e5d6f080b8e33c1ce8b3078e7013fdbcd560c
F src/test4.c 9b32d22f5f150abe23c1830e2057c4037c45b3df
@@ -275,17 +275,17 @@ F src/test_vfs.c e72f555ef7a59080f898fcf1a233deb9eb704ea9
F src/test_vfstrace.c 3a0ab304682fecbceb689e7d9b904211fde11d78
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
F src/tokenize.c ec4c1a62b890bf1dbcdb966399e140b904c700a4
F src/trigger.c d84e1f3669e9a217731a14a9d472b1c7b87c87ba
F src/update.c d1c2477dcf14d90999d1935af4efb4806553250b
F src/trigger.c 5c1c0b899ac0ce284763dcb8fdbaa38ecf15ef98
F src/update.c c2706a6eb232a96345c35b7e1e75a188e26812bb
F src/utf.c 6fc6c88d50448c469c5c196acf21617a24f90269
F src/util.c e71f19b272f05c8695cf747b4bac1732685f9e5c
F src/vacuum.c 3728d74919d4fb1356f9e9a13e27773db60b7179
F src/vdbe.c 919422843c859a1db08db0c88189912dbf625fc7
F src/vdbe.h c06f0813f853566457ce9cfb1a4a4bc39a5da644
F src/vdbeInt.h a7bc268f844d75be48bb7ae16f77b418fd3c641c
F src/vdbe.c b110887e415b5d2af58c2374c4dfdcf774c5d46c
F src/vdbe.h e6c4c610fcabad4fa80ebb1efc6822a9367e2b26
F src/vdbeInt.h 42db251e9f863401ff847b90d5fe1614c89a6a56
F src/vdbeapi.c ce4e68ea4842cc6081046f533d088dcf01d247ad
F src/vdbeaux.c a22cbd91b24503b82690cb03324ffec9f4ef63f6
F src/vdbeblob.c 8cd05a5630e6d5563ad017bf82edaf812b28acde
F src/vdbeaux.c 9f4bfc52672acbb0bb4493d6a03603dc5a595ac1
F src/vdbeblob.c bc40f98f256f0b34116d6a44b114da4a81a15d33
F src/vdbemem.c 0e69351b2c6ff7d8b638688c0ae336a26befa6b2
F src/vdbesort.c 9d83601f9d6243fe70dd0169a2820c5ddfd48147
F src/vdbetrace.c 6f52bc0c51e144b7efdcfb2a8f771167a8816767
@@ -293,7 +293,7 @@ F src/vtab.c 21b932841e51ebd7d075e2d0ad1415dce8d2d5fd
F src/wal.c 7dc3966ef98b74422267e7e6e46e07ff6c6eb1b4
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
F src/walker.c e9e593d5bb798c3e67fc3893dfe7055c9e7d8d74
F src/where.c b8f3aab1e5843012895b89a183dcdd6cef0708db
F src/where.c 18f07fd0fd116a5880773c689eb7cd8e60175107
F src/whereInt.h 96a75c61f1d2b9d4a8e4bb17d89deb0cf7cba358
F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
@@ -324,7 +324,7 @@ F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0
F test/atof1.test 08a61df9365c341f334a65f4348897312d8f3db7
F test/attach.test 0d112b7713611fdf0340260192749737135fda5f
F test/attach2.test 0ec5defa340363de6cd50fd595046465e9aaba2d
F test/attach3.test d89ccfe4fe6e2b5e368d480fcdfe4b496c54cf4e
F test/attach3.test 359eb65d00102cdfcef6fa4e81dc1648f8f80b27
F test/attach4.test 53bf502f17647c6d6c5add46dda6bac8b6f4665c
F test/attachmalloc.test 3a4bfca9545bfe906a8d2e622de10fbac5b711b0
F test/auth.test 9bea29041871807d9f289ee679d05d3ed103642f
@@ -364,7 +364,7 @@ F test/btreefault.test c2bcb542685eea44621275cfedbd8a13f65201e3
F test/busy.test 76b4887f8b9160ba903c1ac22e8ff406ad6ae2f0
F test/cache.test 13bc046b26210471ca6f2889aceb1ea52dc717de
F test/capi2.test 011c16da245fdc0106a2785035de6b242c05e738
F test/capi3.test f5eab498a0927d498e6d75c14567addb995ceccb
F test/capi3.test 56ab450125ead38846cbae7e5b6a216686c3cffa
F test/capi3b.test efb2b9cfd127efa84433cd7a2d72ce0454ae0dc4
F test/capi3c.test 93d24621c9ff84da9da060f30431e0453db1cdb0
F test/capi3d.test 6d0fc0a86d73f42dd19a7d8b7761ab9bc02277d0
@@ -374,7 +374,7 @@ F test/check.test 5831ddb6f2c687782eaf2e1a07b6e17f24c4f763
F test/close.test 340bd24cc58b16c6bc01967402755027c37eb815
F test/closure01.test dbb28f1ea9eeaf0a53ec5bc0fed352e479def8c7
F test/coalesce.test cee0dccb9fbd2d494b77234bccf9dc6c6786eb91
F test/collate1.test b709989e6e6ff6e1d2bd64231c2c1d8146846c9e
F test/collate1.test 73b91005f264b7c403e2d63a6708d150679ac99a
F test/collate2.test 9aaa410a00734e48bcb27f3872617d6f69b2a621
F test/collate3.test 79558a286362cb9ed603c6fa543f1cda7f563f0f
F test/collate4.test f04d5168685f2eef637ecfa2d4ddf8ec0d600177
@@ -456,7 +456,7 @@ F test/eqp.test 57c6c604c2807fb5531731c5323133453c24afac
F test/errmsg.test f31592a594b44ee121371d25ddd5d63497bb3401
F test/eval.test bc269c365ba877554948441e91ad5373f9f91be3
F test/exclusive.test c7ebbc756eacf544c108b15eed64d7d4e5f86b75
F test/exclusive2.test 881193eccec225cfed9d7f744b65e57f26adee25
F test/exclusive2.test 32798111aae78a5deec980eee383213f189df308
F test/exec.test e949714dc127eaa5ecc7d723efec1ec27118fdd7
F test/exists.test 8f7b27b61c2fbe5822f0a1f899c715d14e416e30
F test/expr.test 67c9fd6f8f829e239dc8b0f4a08a73c08b09196d
@@ -509,13 +509,13 @@ F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e
F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a
F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654
F test/fts3_common.tcl 99cf6659b87c0f74f55963c2aea03b3a7d66ceb0
F test/fts3aa.test ad272d695095a55c16a5091dbdcce7c5f55da605
F test/fts3ab.test 09aeaa162aee6513d9ff336b6932211008b9d1f9
F test/fts3aa.test edd20ddbbc5b6015ab340abf2ca278ae11ec387d
F test/fts3ab.test 7f6cf260ae80dda064023df8e8e503e9a412b91f
F test/fts3ac.test 636ed7486043055d4f126a0e385f2d5a82ebbf63
F test/fts3ad.test e40570cb6f74f059129ad48bcef3d7cbc20dda49
F test/fts3ae.test ce32a13b34b0260928e4213b4481acf801533bda
F test/fts3af.test d394978c534eabf22dd0837e718b913fd66b499c
F test/fts3ag.test 0b7d303f61ae5d620c4efb5e825713ea34ff9441
F test/fts3ag.test c003672a215124df7fc6000036d896f498b26b53
F test/fts3ah.test dc9f66c32c296f1bc8bcc4535126bddfeca62894
F test/fts3ai.test 24058fdc6e9e5102c1fd8459591b114b6a85d285
F test/fts3aj.test 0ed71e1dd9b03b843a857dc3eb9b15630e0104fc
@@ -535,7 +535,7 @@ F test/fts3conf.test ee8500c86dd58ec075e8831a1e216a79989436de
F test/fts3corrupt.test 2710b77983cc7789295ddbffea52c1d3b7506dbb
F test/fts3corrupt2.test 6d96efae2f8a6af3eeaf283aba437e6d0e5447ba
F test/fts3cov.test e0fb00d8b715ddae4a94c305992dfc3ef70353d7
F test/fts3d.test bf640d79722b720fa1c81834c48cdaa45d531b1a
F test/fts3d.test c8a193513a269ec4c205ca09645e26e0bc71b860
F test/fts3defer.test 0be4440b73a2e651fc1e472066686d6ada4b9963
F test/fts3defer2.test a3b6cbeabaf28c9398652a4d101ea224d9358479
F test/fts3defer3.test dd53fc13223c6d8264a98244e9b19abd35ed71cd
@@ -547,9 +547,10 @@ F test/fts3expr3.test 9e91b8edbcb197bf2e92161aa7696446d96dce5f
F test/fts3fault.test cb72dccb0a3b9f730f16c5240f3fcb9303eb1660
F test/fts3fault2.test 3198eef2804deea7cac8403e771d9cbcb752d887
F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641
F test/fts3join.test 53e66a0c21eb568580674a43b21c059acb26f499
F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6
F test/fts3matchinfo.test ff423e73faab8fc6d7adeefedf74dd8e2b0b14e0
F test/fts3near.test 12895557870b0f9af7cc0be81a0171abb2d12f12
F test/fts3near.test 7e3354d46f155a822b59c0e957fd2a70c1d7e905
F test/fts3prefix.test b36d4f00b128a51e7b386cc013a874246d9d7dc1
F test/fts3prefix2.test e1f0a822ca661dced7f12ce392e14eaf65609dce
F test/fts3query.test 4fefd43ff24993bc2c9b2778f2bec0cc7629e7ed
@@ -557,7 +558,7 @@ F test/fts3rnd.test 1320d8826a845e38a96e769562bf83d7a92a15d0
F test/fts3shared.test 57e26a801f21027b7530da77db54286a6fe4997e
F test/fts3snippet.test d524af6bcef4714e059ef559113dbdc924cd33d1
F test/fts3sort.test ed34c716a11cc2009a35210e84ad5f9c102362ca
F test/fts3tok1.test b10d0a12a0ab5f905cea1200b745de233f37443f
F test/fts3tok1.test c551043de056b0b1582a54e878991f57bad074bc
F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d
F test/fts3varint.test 752c08ed5d32c5d7dc211b056f4ed68a76b7e36e
F test/fts4aa.test 0c3152322c7f0b548cc942ad763eaba0da87ccca
@@ -571,7 +572,7 @@ F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891
F test/fts4merge3.test aab02a09f50fe6baaddc2e159c3eabc116d45fc7
F test/fts4merge4.test c19c85ca1faa7b6d536832b49c12e1867235f584
F test/fts4noti.test aed33ba44808852dcb24bf70fa132e7bf530f057
F test/fts4unicode.test e28ba1a14181e709dcdf47455f207adf14c7cfe0
F test/fts4unicode.test 01ec3fe2a7c3cfff3b4c0581b83caa11b33efa36
F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d
F test/func.test 00667bbeac044d007f6f021af1b9f6150f0c7ff8
F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f
@@ -692,7 +693,7 @@ F test/minmax.test 42fbad0e81afaa6e0de41c960329f2b2c3526efd
F test/minmax2.test b44bae787fc7b227597b01b0ca5575c7cb54d3bc
F test/minmax3.test cc1e8b010136db0d01a6f2a29ba5a9f321034354
F test/minmax4.test 536a3360470633a177e42fbc19660d146b51daef
F test/misc1.test 9bed1bd334065a57dc841cff969d4fc1eeb6d49b
F test/misc1.test 441a0fafc7087f841db09fbfca54e7aea9f5a84c
F test/misc2.test 00d7de54eda90e237fc9a38b9e5ccc769ebf6d4d
F test/misc3.test cf3dda47d5dda3e53fc5804a100d3c82be736c9d
F test/misc4.test 9c078510fbfff05a9869a0b6d8b86a623ad2c4f6
@@ -703,7 +704,7 @@ F test/misuse.test ba4fb5d1a6101d1c171ea38b3c613d0661c83054
F test/mmap1.test 93d167b328255cbe6679fe1e1a23be1b1197d07b
F test/mmap2.test 9d6dd9ddb4ad2379f29cc78f38ce1e63ed418022
F test/mmap3.test c92273e16eb8d23c1d55c9815b446bb72ef0512e
F test/mmapfault.test 97507ee06172df99057dbf1c40294eabd82cbb13
F test/mmapfault.test d4c9eff9cd8c2dc14bc43e71e042f175b0a26fe3
F test/multiplex.test e08cc7177bd6d85990ee1d71100bb6c684c02256
F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a
F test/multiplex3.test d228f59eac91839a977eac19f21d053f03e4d101
@@ -739,7 +740,7 @@ F test/permutations.test af3278cbea3a19e025d5169be8193ff48dc3f862
F test/pragma.test e882183ecd21d064cec5c7aaea174fbd36293429
F test/pragma2.test aea7b3d82c76034a2df2b38a13745172ddc0bc13
F test/printf.test ec9870c4dce8686a37818e0bf1aba6e6a1863552
F test/printf2.test 2f0978059768bb039d3ee09466bdcd06fc7a6a86
F test/printf2.test 414fcba6d6c10e0a5e58efd213811e5ead4635a0
F test/progress.test a282973d1d17f08071bc58a77d6b80f2a81c354d
F test/ptrchng.test ef1aa72d6cf35a2bbd0869a649b744e9d84977fc
F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca
@@ -773,7 +774,7 @@ F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5
F test/schema3.test 1bc1008e1f8cb5654b248c55f27249366eb7ed38
F test/schema4.test e6a66e20cc69f0e306667c08be7fda3d11707dc5
F test/schema5.test 29699b4421f183c8f0e88bd28ce7d75d13ea653e
F test/securedel.test 87a2561151af1f1e349071a89fdd77059f50113c
F test/securedel.test 21749c32ccc30f1ea9e4b9f33295a6521ec20fa0
F test/securedel2.test 2d54c28e46eb1fd6902089958b20b1b056c6f1c5
F test/select1.test fc2a61f226a649393664ad54bc5376631801517c
F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56
@@ -802,14 +803,14 @@ F test/sharedA.test 0cdf1a76dfa00e6beee66af5b534b1e8df2720f5
F test/shared_err.test 0079c05c97d88cfa03989b7c20a8b266983087aa
F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304
F test/shell1.test e7c0b9ebda25d5e78f0a3ea0dc4e31bb6d8098c0
F test/shell2.test e1d3790f064e50b2f973502f45750012667486df
F test/shell2.test c57da3a381c099b02c813ba156298d5c2f5c93a3
F test/shell3.test 5e8545ec72c4413a0e8d4c6be56496e3c257ca29
F test/shell4.test aa4eef8118b412d1a01477a53426ece169ea86a9
F test/shell5.test cee83b4385f842fec1f2a0bec9ea811f35386edf
F test/shortread1.test bb591ef20f0fd9ed26d0d12e80eee6d7ac8897a3
F test/shrink.test 8c70f62b6e8eb4d54533de6d65bd06b1b9a17868
F test/sidedelete.test f0ad71abe6233e3b153100f3b8d679b19a488329
F test/skipscan1.test 6bb4891c2cc5efd5690a9da9e7508e53d4a68e10
F test/skipscan1.test 8c777ffd9dad6ee6d2568160cb2158f0b5cd9dd2
F test/skipscan2.test 5a4db0799c338ddbacb154aaa5589c0254b36a8d
F test/soak.test 0b5b6375c9f4110c828070b826b3b4b0bb65cd5f
F test/softheap1.test 40562fe6cac6d9827b7b42b86d45aedf12c15e24
@@ -822,10 +823,10 @@ F test/speed3.test d32043614c08c53eafdc80f33191d5bd9b920523
F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715
F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa
F test/speed4p.test 0e51908951677de5a969b723e03a27a1c45db38b
F test/speedtest1.c bb3a4cc62b6cf29f5bc72c85d2bee5991e207be7
F test/speedtest1.c 7130d2cb6db45baa553a4ab2f715116c71c2d9f4
F test/spellfix.test 8c40b169b104086d8795781f670ba3c786d6d8be
F test/sqllimits1.test b1aae27cc98eceb845e7f7adf918561256e31298
F test/stat.test c8eccfe8fcd3f3cfc864ce22d5b9e803a3c69940
F test/stat.test 76fd746b85459e812a0193410fb599f0531f22de
F test/stmt.test 25d64e3dbf9a3ce89558667d7f39d966fe2a71b9
F test/subquery.test 666fdecceac258f5fd84bed09a64e49d9f37edd9
F test/subquery2.test 91e1e364072aeff431d1f9689b15147e421d88c7
@@ -882,7 +883,7 @@ F test/tkt-80e031a00f.test 9a154173461a4dbe2de49cda73963e04842d52f7
F test/tkt-8454a207b9.test c583a9f814a82a2b5ba95207f55001c9f0cd816c
F test/tkt-868145d012.test a5f941107ece6a64410ca4755c6329b7eb57a356
F test/tkt-91e2e8ba6f.test 08c4f94ae07696b05c9b822da0b4e5337a2f54c5
F test/tkt-94c04eaadb.test fa9c71192f7e2ea2d51bf078bc34e8da6088bf71
F test/tkt-94c04eaadb.test f738c57c7f68ab8be1c054415af7774617cb6223
F test/tkt-9d68c883.test 458f7d82a523d7644b54b497c986378a7d8c8b67
F test/tkt-9f2eb3abac.test 85bc63e749f050e6a61c8f9207f1eee65c9d3395
F test/tkt-a7b7803e.test 159ef554234fa1f9fb318c751b284bd1cf858da4
@@ -1042,9 +1043,9 @@ F test/vtabE.test 7c4693638d7797ce2eda17af74292b97e705cc61
F test/vtabF.test fd5ad376f5a34fe0891df1f3cddb4fe7c3eb077e
F test/vtab_alter.test 9e374885248f69e251bdaacf480b04a197f125e5
F test/vtab_err.test 0d4d8eb4def1d053ac7c5050df3024fd47a3fbd8
F test/vtab_shared.test 82f463886e18d7f8395a4b6167c91815efe54839
F test/wal.test a59d00eaa0901e42b8a2ef21f2a4c972ee1f1bd4
F test/wal2.test d4b470f13c87f6d8268b004380afa04c3c67cb90
F test/vtab_shared.test 6acafaae7126c9f49be72c2f57eb8bef3024f1cb
F test/wal.test 40073e54359d43354925b2b700b7eebd5e207285
F test/wal2.test a8e3963abf6b232cf0b852b09b53665ef34007af
F test/wal3.test b22eb662bcbc148c5f6d956eaf94b047f7afe9c0
F test/wal4.test 4744e155cd6299c6bd99d3eab1c82f77db9cdb3c
F test/wal5.test 8f888b50f66b78821e61ed0e233ded5de378224b
@@ -1059,7 +1060,7 @@ F test/walcksum.test 9afeb96240296c08c72fc524d199c912cfe34daa
F test/walcrash.test 451d79e528add5c42764cea74aa2750754171b25
F test/walcrash2.test a0edab4e5390f03b99a790de89aad15d6ec70b36
F test/walcrash3.test e426aa58122d20f2b9fbe9a507f9eb8cab85b8af
F test/walfault.test 54ad6e849c727f4da463964b9eb8c8e8e155cf82
F test/walfault.test 1f8389f7709877e9b4cc679033d71d6fe529056b
F test/walhook.test ed00a40ba7255da22d6b66433ab61fab16a63483
F test/walmode.test 4022fe03ae6e830583672caa101f046438a0473c
F test/walnoshm.test 84ca10c544632a756467336b7c3b864d493ee496
@@ -1108,7 +1109,7 @@ F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439
F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4
F tool/genfkey.test 4196a8928b78f51d54ef58e99e99401ab2f0a7e5
F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce
F tool/lemon.c 796930d5fc2036c7636f3f1ee12f9ae03719a2eb
F tool/lemon.c 4a3d4a579c5dff6a42785e97d1f2b59789f3b8dd
F tool/lempar.c 01ca97f87610d1dac6d8cd96ab109ab1130e76dc
F tool/logest.c 7ad625cac3d54012b27d468b7af6612f78b9ba75
F tool/mkautoconfamal.sh f8d8dbf7d62f409ebed5134998bf5b51d7266383
@@ -1147,7 +1148,7 @@ F tool/vdbe-compress.tcl 0cf56e9263a152b84da86e75a5c0cdcdb7a47891
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
F tool/warnings.sh d1a6de74685f360ab718efda6265994b99bbea01
F tool/win/sqlite.vsix 030f3eeaf2cb811a3692ab9c14d021a75ce41fff
P 6db7052eeefafdbf26b3153bc38600fecfb53ae6
R 2f73ea36e182ebaad881490b3d78bb71
P e43c522dde01e134f1adc94f534d2b3eda74afc2
R 498b2eca2a4d9bdf3c22bba6f4386191
U drh
Z 671b11d5131d6faea51d8a864c8026f9
Z 303f39885598d1865b7eb401105ea9ea
+1 -1
View File
@@ -1 +1 @@
3375571a5e267744c19a7c310840256cec57a242
da7890ca6b1d8e511377a469047120220e8c3b2d
-4
View File
@@ -38,10 +38,6 @@ static int resolveAttachExpr(NameContext *pName, Expr *pExpr)
if( pExpr ){
if( pExpr->op!=TK_ID ){
rc = sqlite3ResolveExprNames(pName, pExpr);
if( rc==SQLITE_OK && !sqlite3ExprIsConstant(pExpr) ){
sqlite3ErrorMsg(pName->pParse, "invalid name: \"%s\"", pExpr->u.zToken);
return SQLITE_ERROR;
}
}else{
pExpr->op = TK_STRING;
}
+6 -5
View File
@@ -140,6 +140,7 @@ void sqlite3FinishCoding(Parse *pParse){
assert( !pParse->isMultiWrite
|| sqlite3VdbeAssertMayAbort(v, pParse->mayAbort));
if( v ){
while( sqlite3VdbeDeletePriorOpcode(v, OP_Close) ){}
sqlite3VdbeAddOp0(v, OP_Halt);
/* The cookie mask contains one bit for each database file open.
@@ -1451,10 +1452,10 @@ static void identPut(char *z, int *pIdx, char *zSignedIdent){
for(j=0; zIdent[j]; j++){
if( !sqlite3Isalnum(zIdent[j]) && zIdent[j]!='_' ) break;
}
needQuote = sqlite3Isdigit(zIdent[0]) || sqlite3KeywordCode(zIdent, j)!=TK_ID;
if( !needQuote ){
needQuote = zIdent[j];
}
needQuote = sqlite3Isdigit(zIdent[0])
|| sqlite3KeywordCode(zIdent, j)!=TK_ID
|| zIdent[j]!=0
|| j==0;
if( needQuote ) z[i++] = '"';
for(j=0; zIdent[j]; j++){
@@ -2677,7 +2678,7 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){
addr1 = sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse, pIndex, iTab, regRecord, 0, &iPartIdxLabel);
sqlite3GenerateIndexKey(pParse,pIndex,iTab,regRecord,0,&iPartIdxLabel,0,0);
sqlite3VdbeAddOp2(v, OP_SorterInsert, iSorter, regRecord);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1);
+30 -22
View File
@@ -716,9 +716,10 @@ void sqlite3GenerateRowIndexDelete(
int *aRegIdx /* Only delete if aRegIdx!=0 && aRegIdx[i]>0 */
){
int i; /* Index loop counter */
int r1; /* Register holding an index key */
int r1 = -1; /* Register holding an index key */
int iPartIdxLabel; /* Jump destination for skipping partial index entries */
Index *pIdx; /* Current index */
Index *pPrior = 0; /* Prior index */
Vdbe *v; /* The prepared statement under construction */
Index *pPk; /* PRIMARY KEY index, or NULL for rowid tables */
@@ -729,10 +730,12 @@ void sqlite3GenerateRowIndexDelete(
if( aRegIdx!=0 && aRegIdx[i]==0 ) continue;
if( pIdx==pPk ) continue;
VdbeModuleComment((v, "GenRowIdxDel for %s", pIdx->zName));
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1, &iPartIdxLabel);
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 1,
&iPartIdxLabel, pPrior, r1);
sqlite3VdbeAddOp3(v, OP_IdxDelete, iIdxCur+i, r1,
pIdx->uniqNotNull ? pIdx->nKeyCol : pIdx->nColumn);
sqlite3VdbeResolveLabel(v, iPartIdxLabel);
pPrior = pIdx;
}
}
@@ -754,6 +757,17 @@ void sqlite3GenerateRowIndexDelete(
** to false or null. If pIdx is not a partial index, *piPartIdxLabel
** will be set to zero which is an empty label that is ignored by
** sqlite3VdbeResolveLabel().
**
** The pPrior and regPrior parameters are used to implement a cache to
** avoid unnecessary register loads. If pPrior is not NULL, then it is
** a pointer to a different index for which an index key has just been
** computed into register regPrior. If the current pIdx index is generating
** its key into the same sequence of registers and if pPrior and pIdx share
** a column in common, then the register corresponding to that column already
** holds the correct value and the loading of that register is skipped.
** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK
** on a table with multiple indices, and especially with the ROWID or
** PRIMARY KEY columns of the index.
*/
int sqlite3GenerateIndexKey(
Parse *pParse, /* Parsing context */
@@ -761,14 +775,15 @@ int sqlite3GenerateIndexKey(
int iDataCur, /* Cursor number from which to take column data */
int regOut, /* Put the new key into this register if not 0 */
int prefixOnly, /* Compute only a unique prefix of the key */
int *piPartIdxLabel /* OUT: Jump to this label to skip partial index */
int *piPartIdxLabel, /* OUT: Jump to this label to skip partial index */
Index *pPrior, /* Previously generated index key */
int regPrior /* Register holding previous generated key */
){
Vdbe *v = pParse->pVdbe;
int j;
Table *pTab = pIdx->pTable;
int regBase;
int nCol;
Index *pPk;
if( piPartIdxLabel ){
if( pIdx->pPartIdxWhere ){
@@ -782,28 +797,21 @@ int sqlite3GenerateIndexKey(
}
nCol = (prefixOnly && pIdx->uniqNotNull) ? pIdx->nKeyCol : pIdx->nColumn;
regBase = sqlite3GetTempRange(pParse, nCol);
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
if( pPrior && (regBase!=regPrior || pPrior->pPartIdxWhere) ) pPrior = 0;
for(j=0; j<nCol; j++){
i16 idx = pIdx->aiColumn[j];
if( pPk ) idx = sqlite3ColumnOfIndex(pPk, idx);
if( idx<0 || idx==pTab->iPKey ){
sqlite3VdbeAddOp2(v, OP_Rowid, iDataCur, regBase+j);
}else{
sqlite3VdbeAddOp3(v, OP_Column, iDataCur, idx, regBase+j);
sqlite3ColumnDefault(v, pTab, pIdx->aiColumn[j], -1);
}
if( pPrior && pPrior->aiColumn[j]==pIdx->aiColumn[j] ) continue;
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, pIdx->aiColumn[j],
regBase+j);
/* If the column affinity is REAL but the number is an integer, then it
** might be stored in the table as an integer (using a compact
** representation) then converted to REAL by an OP_RealAffinity opcode.
** But we are getting ready to store this value back into an index, where
** it should be converted by to INTEGER again. So omit the OP_RealAffinity
** opcode if it is present */
sqlite3VdbeDeletePriorOpcode(v, OP_RealAffinity);
}
if( regOut ){
const char *zAff;
if( pTab->pSelect
|| OptimizationDisabled(pParse->db, SQLITE_IdxRealAsInt)
){
zAff = 0;
}else{
zAff = sqlite3IndexAffinityStr(v, pIdx);
}
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regOut);
sqlite3VdbeChangeP4(v, -1, zAff, P4_TRANSIENT);
}
sqlite3ReleaseTempRange(pParse, regBase, nCol);
return regBase;
+66 -16
View File
@@ -523,16 +523,25 @@ Expr *sqlite3PExpr(
}
/*
** Return 1 if an expression must be FALSE in all cases and 0 if the
** expression might be true. This is an optimization. If is OK to
** return 0 here even if the expression really is always false (a
** false negative). But it is a bug to return 1 if the expression
** might be true in some rare circumstances (a false positive.)
** If the expression is always either TRUE or FALSE (respectively),
** then return 1. If one cannot determine the truth value of the
** expression at compile-time return 0.
**
** This is an optimization. If is OK to return 0 here even if
** the expression really is always false or false (a false negative).
** But it is a bug to return 1 if the expression might have different
** boolean values in different circumstances (a false positive.)
**
** Note that if the expression is part of conditional for a
** LEFT JOIN, then we cannot determine at compile-time whether or not
** is it true or false, so always return 0.
*/
static int exprAlwaysTrue(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
if( !sqlite3ExprIsInteger(p, &v) ) return 0;
return v!=0;
}
static int exprAlwaysFalse(Expr *p){
int v = 0;
if( ExprHasProperty(p, EP_FromJoin) ) return 0;
@@ -2170,6 +2179,11 @@ void sqlite3ExprCacheRemove(Parse *pParse, int iReg, int nReg){
*/
void sqlite3ExprCachePush(Parse *pParse){
pParse->iCacheLevel++;
#ifdef SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("PUSH to %d\n", pParse->iCacheLevel);
}
#endif
}
/*
@@ -2183,6 +2197,11 @@ void sqlite3ExprCachePop(Parse *pParse, int N){
assert( N>0 );
assert( pParse->iCacheLevel>=N );
pParse->iCacheLevel -= N;
#ifdef SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("POP to %d\n", pParse->iCacheLevel);
}
#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg && p->iLevel>pParse->iCacheLevel ){
cacheEntryClear(pParse, p);
@@ -2277,6 +2296,11 @@ void sqlite3ExprCacheClear(Parse *pParse){
int i;
struct yColCache *p;
#if SQLITE_DEBUG
if( pParse->db->flags & SQLITE_VdbeAddopTrace ){
printf("CLEAR\n");
}
#endif
for(i=0, p=pParse->aColCache; i<SQLITE_N_COLCACHE; i++, p++){
if( p->iReg ){
cacheEntryClear(pParse, p);
@@ -3413,7 +3437,17 @@ int sqlite3ExprCodeExprList(
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
sqlite3VdbeAddOp2(pParse->pVdbe, copyOp, inReg, target+i);
VdbeOp *pOp;
Vdbe *v = pParse->pVdbe;
if( copyOp==OP_Copy
&& (pOp=sqlite3VdbeGetOp(v, -1))->opcode==OP_Copy
&& pOp->p1+pOp->p3+1==inReg
&& pOp->p2+pOp->p3+1==target+i
){
pOp->p3++;
}else{
sqlite3VdbeAddOp2(v, copyOp, inReg, target+i);
}
}
}
}
@@ -3504,8 +3538,8 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
case TK_AND: {
int d2 = sqlite3VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pLeft, d2,jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
sqlite3ExprCachePop(pParse, 1);
@@ -3514,7 +3548,9 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
case TK_OR: {
testcase( jumpIfNull==0 );
sqlite3ExprIfTrue(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3ExprCachePop(pParse, 1);
break;
}
case TK_NOT: {
@@ -3589,10 +3625,16 @@ void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
}
#endif
default: {
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
if( exprAlwaysTrue(pExpr) ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
}else if( exprAlwaysFalse(pExpr) ){
/* No-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
sqlite3VdbeAddOp3(v, OP_If, r1, dest, jumpIfNull!=0);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
}
break;
}
}
@@ -3655,14 +3697,16 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
case TK_AND: {
testcase( jumpIfNull==0 );
sqlite3ExprIfFalse(pParse, pExpr->pLeft, dest, jumpIfNull);
sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3ExprCachePop(pParse, 1);
break;
}
case TK_OR: {
int d2 = sqlite3VdbeMakeLabel(v);
testcase( jumpIfNull==0 );
sqlite3ExprCachePush(pParse);
sqlite3ExprIfTrue(pParse, pExpr->pLeft, d2, jumpIfNull^SQLITE_JUMPIFNULL);
sqlite3ExprCachePush(pParse);
sqlite3ExprIfFalse(pParse, pExpr->pRight, dest, jumpIfNull);
sqlite3VdbeResolveLabel(v, d2);
sqlite3ExprCachePop(pParse, 1);
@@ -3734,10 +3778,16 @@ void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int jumpIfNull){
}
#endif
default: {
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
if( exprAlwaysFalse(pExpr) ){
sqlite3VdbeAddOp2(v, OP_Goto, 0, dest);
}else if( exprAlwaysTrue(pExpr) ){
/* no-op */
}else{
r1 = sqlite3ExprCodeTemp(pParse, pExpr, &regFree1);
sqlite3VdbeAddOp3(v, OP_IfNot, r1, dest, jumpIfNull!=0);
testcase( regFree1==0 );
testcase( jumpIfNull==0 );
}
break;
}
}
+56 -40
View File
@@ -540,7 +540,6 @@ static int xferOptimization(
void sqlite3Insert(
Parse *pParse, /* Parser context */
SrcList *pTabList, /* Name of table into which we are inserting */
ExprList *pList, /* List of values to be inserted */
Select *pSelect, /* A SELECT statement to use as the data source */
IdList *pColumn, /* Column names corresponding to IDLIST. */
int onError /* How to handle constraint errors */
@@ -568,6 +567,7 @@ void sqlite3Insert(
Db *pDb; /* The database containing table being inserted into */
int appendFlag = 0; /* True if the insert is likely to be an append */
int withoutRowid; /* 0 for normal table. 1 for WITHOUT ROWID table */
ExprList *pList = 0; /* List of VALUES() to be inserted */
/* Register allocations */
int regFromSelect = 0;/* Base register for data coming from SELECT */
@@ -591,6 +591,17 @@ void sqlite3Insert(
goto insert_cleanup;
}
/* If the Select object is really just a simple VALUES() list with a
** single row values (the common case) then keep that one row of values
** and go ahead and discard the Select object
*/
if( pSelect && (pSelect->selFlags & SF_Values)!=0 && pSelect->pPrior==0 ){
pList = pSelect->pEList;
pSelect->pEList = 0;
sqlite3SelectDelete(db, pSelect);
pSelect = 0;
}
/* Locate the table into which we will be inserting new information.
*/
assert( pTabList->nSrc==1 );
@@ -1233,6 +1244,7 @@ void sqlite3GenerateConstraintChecks(
int ipkTop = 0; /* Top of the rowid change constraint check */
int ipkBottom = 0; /* Bottom of the rowid change constraint check */
u8 isUpdate; /* True if this is an UPDATE operation */
int regRowid = -1; /* Register holding ROWID value */
isUpdate = regOldData!=0;
db = pParse->db;
@@ -1463,7 +1475,9 @@ void sqlite3GenerateConstraintChecks(
int iField = pIdx->aiColumn[i];
int x;
if( iField<0 || iField==pTab->iPKey ){
if( regRowid==regIdx+i ) continue; /* ROWID already in regIdx+i */
x = regNewData;
regRowid = pIdx->pPartIdxWhere ? -1 : regIdx+i;
}else{
x = iField + regNewData + 1;
}
@@ -1503,47 +1517,49 @@ void sqlite3GenerateConstraintChecks(
/* Generate code to handle collisions */
regR = (pIdx==pPk) ? regIdx : sqlite3GetTempRange(pParse, nPkField);
if( HasRowid(pTab) ){
sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
/* Conflict only if the rowid of the existing index entry
** is different from old-rowid */
if( isUpdate ){
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
}
}else{
int x;
/* Extract the PRIMARY KEY from the end of the index entry and
** store it in registers regR..regR+nPk-1 */
if( (isUpdate || onError==OE_Replace) && pIdx!=pPk ){
for(i=0; i<pPk->nKeyCol; i++){
x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
VdbeComment((v, "%s.%s", pTab->zName,
pTab->aCol[pPk->aiColumn[i]].zName));
if( isUpdate || onError==OE_Replace ){
if( HasRowid(pTab) ){
sqlite3VdbeAddOp2(v, OP_IdxRowid, iThisCur, regR);
/* Conflict only if the rowid of the existing index entry
** is different from old-rowid */
if( isUpdate ){
sqlite3VdbeAddOp3(v, OP_Eq, regR, addrUniqueOk, regOldData);
}
}
if( isUpdate ){
/* If currently processing the PRIMARY KEY of a WITHOUT ROWID
** table, only conflict if the new PRIMARY KEY values are actually
** different from the old.
**
** For a UNIQUE index, only conflict if the PRIMARY KEY values
** of the matched index row are different from the original PRIMARY
** KEY values of this row before the update. */
int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
int op = OP_Ne;
int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
for(i=0; i<pPk->nKeyCol; i++){
char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
x = pPk->aiColumn[i];
if( i==(pPk->nKeyCol-1) ){
addrJump = addrUniqueOk;
op = OP_Eq;
}else{
int x;
/* Extract the PRIMARY KEY from the end of the index entry and
** store it in registers regR..regR+nPk-1 */
if( pIdx!=pPk ){
for(i=0; i<pPk->nKeyCol; i++){
x = sqlite3ColumnOfIndex(pIdx, pPk->aiColumn[i]);
sqlite3VdbeAddOp3(v, OP_Column, iThisCur, x, regR+i);
VdbeComment((v, "%s.%s", pTab->zName,
pTab->aCol[pPk->aiColumn[i]].zName));
}
}
if( isUpdate ){
/* If currently processing the PRIMARY KEY of a WITHOUT ROWID
** table, only conflict if the new PRIMARY KEY values are actually
** different from the old.
**
** For a UNIQUE index, only conflict if the PRIMARY KEY values
** of the matched index row are different from the original PRIMARY
** KEY values of this row before the update. */
int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol;
int op = OP_Ne;
int regCmp = (pIdx->autoIndex==2 ? regIdx : regR);
for(i=0; i<pPk->nKeyCol; i++){
char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]);
x = pPk->aiColumn[i];
if( i==(pPk->nKeyCol-1) ){
addrJump = addrUniqueOk;
op = OP_Eq;
}
sqlite3VdbeAddOp4(v, op,
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
);
}
sqlite3VdbeAddOp4(v, op,
regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ
);
}
}
}
+4 -3
View File
@@ -1062,8 +1062,7 @@ void sqlite3RollbackAll(sqlite3 *db, int tripCode){
** Return a static string containing the name corresponding to the error code
** specified in the argument.
*/
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \
defined(SQLITE_DEBUG_OS_TRACE)
#if defined(SQLITE_TEST)
const char *sqlite3ErrName(int rc){
const char *zName = 0;
int i, origRc = rc;
@@ -2641,6 +2640,8 @@ static int openDatabase(
SQLITE_DEFAULT_LOCKING_MODE);
#endif
if( rc ) sqlite3Error(db, rc, 0);
/* Enable the lookaside-malloc subsystem */
setupLookaside(db, 0, sqlite3GlobalConfig.szLookaside,
sqlite3GlobalConfig.nLookaside);
@@ -3100,7 +3101,7 @@ int sqlite3_test_control(int op, ...){
** to the xRandomness method of the default VFS.
*/
case SQLITE_TESTCTRL_PRNG_RESET: {
sqlite3PrngResetState();
sqlite3_randomness(0,0);
break;
}
+15 -1
View File
@@ -107,7 +107,21 @@ int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
** routine has no return value since the return value would be meaningless.
*/
int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
DO_OS_MALLOC_TEST(id);
#ifdef SQLITE_TEST
if( op!=SQLITE_FCNTL_COMMIT_PHASETWO ){
/* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite
** is using a regular VFS, it is called after the corresponding
** transaction has been committed. Injecting a fault at this point
** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM
** but the transaction is committed anyway.
**
** The core must call OsFileControl() though, not OsFileControlHint(),
** as if a custom VFS (e.g. zipvfs) returns an error here, it probably
** means the commit really has failed and an error should be returned
** to the user. */
DO_OS_MALLOC_TEST(id);
}
#endif
return id->pMethods->xFileControl(id, op, pArg);
}
void sqlite3OsFileControlHint(sqlite3_file *id, int op, void *pArg){
+26 -6
View File
@@ -260,6 +260,12 @@ struct unixFile {
#endif
};
/* This variable holds the process id (pid) from when the xRandomness()
** method was called. If xOpen() is called from a different process id,
** indicating that a fork() has occurred, the PRNG will be reset.
*/
static int randomnessPid = 0;
/*
** Allowed values for the unixFile.ctrlFlags bitmask:
*/
@@ -4842,10 +4848,10 @@ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){
** may now be invalid and should be unmapped.
*/
static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
#if SQLITE_MAX_MMAP_SIZE>0
unixFile *pFd = (unixFile *)fd; /* The underlying database file */
UNUSED_PARAMETER(iOff);
#if SQLITE_MAX_MMAP_SIZE>0
/* If p==0 (unmap the entire file) then there must be no outstanding
** xFetch references. Or, if p!=0 (meaning it is an xFetch reference),
** then there must be at least one outstanding. */
@@ -4861,6 +4867,10 @@ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){
}
assert( pFd->nFetchOut>=0 );
#else
UNUSED_PARAMETER(fd);
UNUSED_PARAMETER(p);
UNUSED_PARAMETER(iOff);
#endif
return SQLITE_OK;
}
@@ -5651,6 +5661,16 @@ static int unixOpen(
|| eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL
);
/* Detect a pid change and reset the PRNG. There is a race condition
** here such that two or more threads all trying to open databases at
** the same instant might all reset the PRNG. But multiple resets
** are harmless.
*/
if( randomnessPid!=getpid() ){
randomnessPid = getpid();
sqlite3_randomness(0,0);
}
memset(p, 0, sizeof(unixFile));
if( eType==SQLITE_OPEN_MAIN_DB ){
@@ -6038,18 +6058,18 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){
** tests repeatable.
*/
memset(zBuf, 0, nBuf);
randomnessPid = getpid();
#if !defined(SQLITE_TEST)
{
int pid, fd, got;
int fd, got;
fd = robust_open("/dev/urandom", O_RDONLY, 0);
if( fd<0 ){
time_t t;
time(&t);
memcpy(zBuf, &t, sizeof(t));
pid = getpid();
memcpy(&zBuf[sizeof(t)], &pid, sizeof(pid));
assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf );
nBuf = sizeof(t) + sizeof(pid);
memcpy(&zBuf[sizeof(t)], &randomnessPid, sizeof(randomnessPid));
assert( sizeof(t)+sizeof(randomnessPid)<=(size_t)nBuf );
nBuf = sizeof(t) + sizeof(randomnessPid);
}else{
do{ got = osRead(fd, zBuf, nBuf); }while( got<0 && errno==EINTR );
robust_close(0, fd, __LINE__);
+20 -58
View File
@@ -94,14 +94,6 @@ struct TrigEvent { int a; IdList * b; };
*/
struct AttachKey { int type; Token key; };
/*
** One or more VALUES claues
*/
struct ValueList {
ExprList *pList;
Select *pSelect;
};
} // end %include
// Input is a single SQL command
@@ -442,6 +434,23 @@ oneselect(A) ::= SELECT distinct(D) selcollist(W) from(X) where_opt(Y)
groupby_opt(P) having_opt(Q) orderby_opt(Z) limit_opt(L). {
A = sqlite3SelectNew(pParse,W,X,Y,P,Q,Z,D,L.pLimit,L.pOffset);
}
oneselect(A) ::= values(X). {A = X;}
%type values {Select*}
%destructor values {sqlite3SelectDelete(pParse->db, $$);}
values(A) ::= VALUES LP nexprlist(X) RP. {
A = sqlite3SelectNew(pParse,X,0,0,0,0,0,SF_Values,0,0);
}
values(A) ::= values(X) COMMA LP exprlist(Y) RP. {
Select *pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values,0,0);
if( pRight ){
pRight->op = TK_ALL;
pRight->pPrior = X;
A = pRight;
}else{
A = X;
}
}
// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
// present and false (0) if it is not.
@@ -696,58 +705,15 @@ setlist(A) ::= nm(X) EQ expr(Y). {
////////////////////////// The INSERT command /////////////////////////////////
//
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) valuelist(Y).
{sqlite3Insert(pParse, X, Y.pList, Y.pSelect, F, R);}
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) select(S).
{sqlite3Insert(pParse, X, 0, S, F, R);}
{sqlite3Insert(pParse, X, S, F, R);}
cmd ::= insert_cmd(R) INTO fullname(X) inscollist_opt(F) DEFAULT VALUES.
{sqlite3Insert(pParse, X, 0, 0, F, R);}
{sqlite3Insert(pParse, X, 0, F, R);}
%type insert_cmd {u8}
insert_cmd(A) ::= INSERT orconf(R). {A = R;}
insert_cmd(A) ::= REPLACE. {A = OE_Replace;}
// A ValueList is either a single VALUES clause or a comma-separated list
// of VALUES clauses. If it is a single VALUES clause then the
// ValueList.pList field points to the expression list of that clause.
// If it is a list of VALUES clauses, then those clauses are transformed
// into a set of SELECT statements without FROM clauses and connected by
// UNION ALL and the ValueList.pSelect points to the right-most SELECT in
// that compound.
%type valuelist {struct ValueList}
%destructor valuelist {
sqlite3ExprListDelete(pParse->db, $$.pList);
sqlite3SelectDelete(pParse->db, $$.pSelect);
}
valuelist(A) ::= VALUES LP nexprlist(X) RP. {
A.pList = X;
A.pSelect = 0;
}
// Since a list of VALUEs is inplemented as a compound SELECT, we have
// to disable the value list option if compound SELECTs are disabled.
%ifndef SQLITE_OMIT_COMPOUND_SELECT
valuelist(A) ::= valuelist(X) COMMA LP exprlist(Y) RP. {
Select *pRight = sqlite3SelectNew(pParse, Y, 0, 0, 0, 0, 0, 0, 0, 0);
if( X.pList ){
X.pSelect = sqlite3SelectNew(pParse, X.pList, 0, 0, 0, 0, 0, 0, 0, 0);
X.pList = 0;
}
A.pList = 0;
if( X.pSelect==0 || pRight==0 ){
sqlite3SelectDelete(pParse->db, pRight);
sqlite3SelectDelete(pParse->db, X.pSelect);
A.pSelect = 0;
}else{
pRight->op = TK_ALL;
pRight->pPrior = X.pSelect;
pRight->selFlags |= SF_Values;
pRight->pPrior->selFlags |= SF_Values;
A.pSelect = pRight;
}
}
%endif SQLITE_OMIT_COMPOUND_SELECT
%type inscollist_opt {IdList*}
%destructor inscollist_opt {sqlite3IdListDelete(pParse->db, $$);}
%type idlist {IdList*}
@@ -1295,12 +1261,8 @@ trigger_cmd(A) ::=
{ A = sqlite3TriggerUpdateStep(pParse->db, &X, Y, Z, R); }
// INSERT
trigger_cmd(A) ::=
insert_cmd(R) INTO trnm(X) inscollist_opt(F) valuelist(Y).
{A = sqlite3TriggerInsertStep(pParse->db, &X, F, Y.pList, Y.pSelect, R);}
trigger_cmd(A) ::= insert_cmd(R) INTO trnm(X) inscollist_opt(F) select(S).
{A = sqlite3TriggerInsertStep(pParse->db, &X, F, 0, S, R);}
{A = sqlite3TriggerInsertStep(pParse->db, &X, F, S, R);}
// DELETE
trigger_cmd(A) ::= DELETE FROM trnm(X) tridxby where_opt(Y).
+5 -2
View File
@@ -1881,8 +1881,10 @@ void sqlite3Pragma(
for(x=sqliteHashFirst(pTbls); x && !isQuick; x=sqliteHashNext(x)){
Table *pTab = sqliteHashData(x);
Index *pIdx, *pPk;
Index *pPrior = 0;
int loopTop;
int iDataCur, iIdxCur;
int r1 = -1;
if( pTab->pIndex==0 ) continue;
pPk = HasRowid(pTab) ? 0 : sqlite3PrimaryKeyIndex(pTab);
@@ -1901,9 +1903,10 @@ void sqlite3Pragma(
loopTop = sqlite3VdbeAddOp2(v, OP_AddImm, 7, 1);
for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){
int jmp2, jmp3, jmp4;
int r1;
if( pPk==pIdx ) continue;
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3);
r1 = sqlite3GenerateIndexKey(pParse, pIdx, iDataCur, 0, 0, &jmp3,
pPrior, r1);
pPrior = pIdx;
sqlite3VdbeAddOp2(v, OP_AddImm, 8+j, 1); /* increment entry count */
jmp2 = sqlite3VdbeAddOp4Int(v, OP_Found, iIdxCur+j, 0, r1,
pIdx->nColumn);
+5 -1
View File
@@ -528,7 +528,11 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
** Free all memory allocations in the pParse object
*/
void sqlite3ParserReset(Parse *pParse){
if( pParse ) sqlite3ExprListDelete(pParse->db, pParse->pConstExpr);
if( pParse ){
sqlite3 *db = pParse->db;
sqlite3DbFree(db, pParse->aLabel);
sqlite3ExprListDelete(db, pParse->pConstExpr);
}
}
/*
+9 -5
View File
@@ -52,6 +52,12 @@ void sqlite3_randomness(int N, void *pBuf){
sqlite3_mutex_enter(mutex);
#endif
if( N<=0 ){
wsdPrng.isInit = 0;
sqlite3_mutex_leave(mutex);
return;
}
/* Initialize the state of the random number generator once,
** the first time this routine is called. The seed value does
** not need to contain a lot of randomness since we are not
@@ -79,7 +85,8 @@ void sqlite3_randomness(int N, void *pBuf){
wsdPrng.isInit = 1;
}
while( N-- ){
assert( N>0 );
do{
wsdPrng.i++;
t = wsdPrng.s[wsdPrng.i];
wsdPrng.j += t;
@@ -87,7 +94,7 @@ void sqlite3_randomness(int N, void *pBuf){
wsdPrng.s[wsdPrng.j] = t;
t += wsdPrng.s[wsdPrng.i];
*(zBuf++) = wsdPrng.s[t];
}
}while( --N );
sqlite3_mutex_leave(mutex);
}
@@ -116,7 +123,4 @@ void sqlite3PrngRestoreState(void){
sizeof(sqlite3Prng)
);
}
void sqlite3PrngResetState(void){
GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
}
#endif /* SQLITE_OMIT_BUILTIN_TEST */
+17 -8
View File
@@ -598,7 +598,6 @@ static void selectInnerLoop(
/* If the destination is an EXISTS(...) expression, the actual
** values returned by the SELECT are not required.
*/
sqlite3ExprCacheClear(pParse);
sqlite3ExprCodeExprList(pParse, pEList, regResult,
(eDest==SRT_Output)?SQLITE_ECEL_DUP:0);
}
@@ -1565,7 +1564,7 @@ Table *sqlite3ResultSetOfSelect(Parse *pParse, Select *pSelect){
Vdbe *sqlite3GetVdbe(Parse *pParse){
Vdbe *v = pParse->pVdbe;
if( v==0 ){
v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);
v = pParse->pVdbe = sqlite3VdbeCreate(pParse);
#ifndef SQLITE_OMIT_TRACE
if( v ){
sqlite3VdbeAddOp0(v, OP_Trace);
@@ -3823,14 +3822,23 @@ static void resetAccumulator(Parse *pParse, AggInfo *pAggInfo){
Vdbe *v = pParse->pVdbe;
int i;
struct AggInfo_func *pFunc;
if( pAggInfo->nFunc+pAggInfo->nColumn==0 ){
return;
}
int nReg = pAggInfo->nFunc + pAggInfo->nColumn;
if( nReg==0 ) return;
#ifdef SQLITE_DEBUG
/* Verify that all AggInfo registers are within the range specified by
** AggInfo.mnReg..AggInfo.mxReg */
assert( nReg==pAggInfo->mxReg-pAggInfo->mnReg+1 );
for(i=0; i<pAggInfo->nColumn; i++){
sqlite3VdbeAddOp2(v, OP_Null, 0, pAggInfo->aCol[i].iMem);
assert( pAggInfo->aCol[i].iMem>=pAggInfo->mnReg
&& pAggInfo->aCol[i].iMem<=pAggInfo->mxReg );
}
for(i=0; i<pAggInfo->nFunc; i++){
assert( pAggInfo->aFunc[i].iMem>=pAggInfo->mnReg
&& pAggInfo->aFunc[i].iMem<=pAggInfo->mxReg );
}
#endif
sqlite3VdbeAddOp3(v, OP_Null, 0, pAggInfo->mnReg, pAggInfo->mxReg);
for(pFunc=pAggInfo->aFunc, i=0; i<pAggInfo->nFunc; i++, pFunc++){
sqlite3VdbeAddOp2(v, OP_Null, 0, pFunc->iMem);
if( pFunc->iDistinct>=0 ){
Expr *pE = pFunc->pExpr;
assert( !ExprHasProperty(pE, EP_xIsSelect) );
@@ -3876,7 +3884,6 @@ static void updateAccumulator(Parse *pParse, AggInfo *pAggInfo){
struct AggInfo_col *pC;
pAggInfo->directMode = 1;
sqlite3ExprCacheClear(pParse);
for(i=0, pF=pAggInfo->aFunc; i<pAggInfo->nFunc; i++, pF++){
int nArg;
int addrNext = 0;
@@ -4409,6 +4416,7 @@ int sqlite3Select(
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.pAggInfo = &sAggInfo;
sAggInfo.mnReg = pParse->nMem+1;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr+1 : 0;
sAggInfo.pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
@@ -4423,6 +4431,7 @@ int sqlite3Select(
sqlite3ExprAnalyzeAggList(&sNC, sAggInfo.aFunc[i].pExpr->x.pList);
sNC.ncFlags &= ~NC_InAggFunc;
}
sAggInfo.mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
/* Processing for aggregates with GROUP BY is very different and
+5 -1
View File
@@ -3038,7 +3038,10 @@ static int process_input(struct callback_data *p, FILE *in){
seenInterrupt = 0;
}
lineno++;
if( nSql==0 && _all_whitespace(zLine) ) continue;
if( nSql==0 && _all_whitespace(zLine) ){
if( p->echoOn ) printf("%s\n", zLine);
continue;
}
if( zLine && zLine[0]=='.' && nSql==0 ){
if( p->echoOn ) printf("%s\n", zLine);
rc = do_meta_command(zLine, p);
@@ -3100,6 +3103,7 @@ static int process_input(struct callback_data *p, FILE *in){
}
nSql = 0;
}else if( nSql && _all_whitespace(zSql) ){
if( p->echoOn ) printf("%s\n", zSql);
nSql = 0;
}
}
+6 -4
View File
@@ -2395,11 +2395,13 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag);
** applications to access the same PRNG for other purposes.
**
** ^A call to this routine stores N bytes of randomness into buffer P.
** ^If N is less than one, then P can be a NULL pointer.
**
** ^The first time this routine is invoked (either internally or by
** the application) the PRNG is seeded using randomness obtained
** from the xRandomness method of the default [sqlite3_vfs] object.
** ^On all subsequent invocations, the pseudo-randomness is generated
** ^If this routine has not been previously called or if the previous
** call had N less than one, then the PRNG is seeded using randomness
** obtained from the xRandomness method of the default [sqlite3_vfs] object.
** ^If the previous call to this routine had an N of 1 or more then
** the pseudo-randomness is generated
** internally and without recourse to the [sqlite3_vfs] xRandomness
** method.
*/
+11 -8
View File
@@ -1056,7 +1056,7 @@ struct sqlite3 {
#define SQLITE_ColumnCache 0x0002 /* Column cache */
#define SQLITE_GroupByOrder 0x0004 /* GROUPBY cover of ORDERBY */
#define SQLITE_FactorOutConst 0x0008 /* Constant factoring */
#define SQLITE_IdxRealAsInt 0x0010 /* Store REAL as INT in indices */
/* not used 0x0010 // Was: SQLITE_IdxRealAsInt */
#define SQLITE_DistinctOpt 0x0020 /* DISTINCT using indexes */
#define SQLITE_CoverIdxScan 0x0040 /* Covering index scans */
#define SQLITE_OrderByIdxJoin 0x0080 /* ORDER BY of joins via index */
@@ -1688,6 +1688,7 @@ struct AggInfo {
int sortingIdx; /* Cursor number of the sorting index */
int sortingIdxPTab; /* Cursor number of pseudo-table */
int nSortingColumn; /* Number of columns in the sorting index */
int mnReg, mxReg; /* Range of registers allocated for aCol and aFunc */
ExprList *pGroupBy; /* The group by clause */
struct AggInfo_col { /* For each column used in source tables */
Table *pTab; /* Source table */
@@ -2289,6 +2290,10 @@ struct Parse {
int nMem; /* Number of memory cells used so far */
int nSet; /* Number of sets used so far */
int nOnce; /* Number of OP_Once instructions so far */
int nOpAlloc; /* Number of slots allocated for Vdbe.aOp[] */
int nLabel; /* Number of labels used */
int *aLabel; /* Space to hold the labels */
int iFixedOp; /* Never back out opcodes iFixedOp-1 or earlier */
int ckBase; /* Base register of data during check constraints */
int iPartIdxTab; /* Table corresponding to a partial index */
int iCacheLevel; /* ColCache valid when aColCache[].iLevel<=iCacheLevel */
@@ -2478,7 +2483,7 @@ struct TriggerStep {
Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */
Token target; /* Target table for DELETE, UPDATE, INSERT */
Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */
ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */
ExprList *pExprList; /* SET clause for UPDATE. */
IdList *pIdList; /* Column names for INSERT */
TriggerStep *pNext; /* Next in the link-list */
TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */
@@ -2893,7 +2898,7 @@ void sqlite3DeleteTable(sqlite3*, Table*);
# define sqlite3AutoincrementEnd(X)
#endif
int sqlite3CodeCoroutine(Parse*, Select*, SelectDest*);
void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int);
void sqlite3Insert(Parse*, SrcList*, Select*, IdList*, int);
void *sqlite3ArrayAllocate(sqlite3*,void*,int,int*,int*);
IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*);
int sqlite3IdListIndex(IdList*,const char*);
@@ -2968,7 +2973,6 @@ int sqlite3FunctionUsesThisSrc(Expr*, SrcList*);
Vdbe *sqlite3GetVdbe(Parse*);
void sqlite3PrngSaveState(void);
void sqlite3PrngRestoreState(void);
void sqlite3PrngResetState(void);
void sqlite3RollbackAll(sqlite3*,int);
void sqlite3CodeVerifySchema(Parse*, int);
void sqlite3CodeVerifyNamedSchema(Parse*, const char *zDb);
@@ -2988,7 +2992,7 @@ int sqlite3ExprNeedsNoAffinityChange(const Expr*, char);
int sqlite3IsRowid(const char*);
void sqlite3GenerateRowDelete(Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8);
void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*);
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*);
int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int, int*,Index*,int);
void sqlite3GenerateConstraintChecks(Parse*,Table*,int*,int,int,int,int,
u8,u8,int,int*);
void sqlite3CompleteInsertion(Parse*,Table*,int,int,int,int*,int,int,int);
@@ -3032,7 +3036,7 @@ void sqlite3MaterializeView(Parse*, Table*, Expr*, int);
void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*);
TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*);
TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*,
ExprList*,Select*,u8);
Select*,u8);
TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8);
TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*);
void sqlite3DeleteTrigger(sqlite3*, Trigger*);
@@ -3137,8 +3141,7 @@ void *sqlite3HexToBlob(sqlite3*, const char *z, int n);
u8 sqlite3HexToInt(int h);
int sqlite3TwoPartName(Parse *, Token *, Token *, Token **);
#if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) || \
defined(SQLITE_DEBUG_OS_TRACE)
#if defined(SQLITE_TEST)
const char *sqlite3ErrName(int);
#endif
+4 -5
View File
@@ -1530,9 +1530,9 @@ static int DbUseNre(void){
*/
# define SQLITE_TCL_NRE 0
# define DbUseNre() 0
# define Tcl_NRAddCallback(a,b,c,d,e,f) 0
# define Tcl_NRAddCallback(a,b,c,d,e,f) (void)0
# define Tcl_NREvalObj(a,b,c) 0
# define Tcl_NRCreateCommand(a,b,c,d,e,f) 0
# define Tcl_NRCreateCommand(a,b,c,d,e,f) (void)0
#endif
/*
@@ -2770,7 +2770,7 @@ static int DbObjCmd(void *cd, Tcl_Interp *interp, int objc,Tcl_Obj *const*objv){
** or savepoint. */
if( DbUseNre() ){
Tcl_NRAddCallback(interp, DbTransPostCmd, cd, 0, 0, 0);
Tcl_NREvalObj(interp, pScript, 0);
(void)Tcl_NREvalObj(interp, pScript, 0);
}else{
rc = DbTransPostCmd(&cd, interp, Tcl_EvalObjEx(interp, pScript, 0));
}
@@ -3371,8 +3371,7 @@ static void MD5Final(unsigned char digest[16], MD5Context *ctx){
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
((uint32 *)ctx->in)[ 14 ] = ctx->bits[0];
((uint32 *)ctx->in)[ 15 ] = ctx->bits[1];
memcpy(ctx->in + 14*4, ctx->bits, 8);
MD5Transform(ctx->buf, (uint32 *)ctx->in);
byteReverse((unsigned char *)ctx->buf, 4);
-1
View File
@@ -6160,7 +6160,6 @@ static int optimization_control(
{ "column-cache", SQLITE_ColumnCache },
{ "groupby-order", SQLITE_GroupByOrder },
{ "factor-constants", SQLITE_FactorOutConst },
{ "real-as-int", SQLITE_IdxRealAsInt },
{ "distinct-opt", SQLITE_DistinctOpt },
{ "cover-idx-scan", SQLITE_CoverIdxScan },
{ "order-by-idx-join", SQLITE_OrderByIdxJoin },
+1 -6
View File
@@ -397,25 +397,21 @@ TriggerStep *sqlite3TriggerInsertStep(
sqlite3 *db, /* The database connection */
Token *pTableName, /* Name of the table into which we insert */
IdList *pColumn, /* List of columns in pTableName to insert into */
ExprList *pEList, /* The VALUE clause: a list of values to be inserted */
Select *pSelect, /* A SELECT statement that supplies values */
u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */
){
TriggerStep *pTriggerStep;
assert(pEList == 0 || pSelect == 0);
assert(pEList != 0 || pSelect != 0 || db->mallocFailed);
assert(pSelect != 0 || db->mallocFailed);
pTriggerStep = triggerStepAllocate(db, TK_INSERT, pTableName);
if( pTriggerStep ){
pTriggerStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE);
pTriggerStep->pIdList = pColumn;
pTriggerStep->pExprList = sqlite3ExprListDup(db, pEList, EXPRDUP_REDUCE);
pTriggerStep->orconf = orconf;
}else{
sqlite3IdListDelete(db, pColumn);
}
sqlite3ExprListDelete(db, pEList);
sqlite3SelectDelete(db, pSelect);
return pTriggerStep;
@@ -753,7 +749,6 @@ static int codeTriggerProgram(
case TK_INSERT: {
sqlite3Insert(pParse,
targetSrcList(pParse, pStep),
sqlite3ExprListDup(db, pStep->pExprList, 0),
sqlite3SelectDup(db, pStep->pSelect, 0),
sqlite3IdListDup(db, pStep->pIdList),
pParse->eOrconf
+5 -3
View File
@@ -72,7 +72,7 @@ void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){
sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM);
}
#ifndef SQLITE_OMIT_FLOATING_POINT
if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
if( pTab->aCol[i].affinity==SQLITE_AFF_REAL ){
sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg);
}
#endif
@@ -496,10 +496,10 @@ void sqlite3Update(
newmask = sqlite3TriggerColmask(
pParse, pTrigger, pChanges, 1, TRIGGER_BEFORE, pTab, onError
);
sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);
/*sqlite3VdbeAddOp3(v, OP_Null, 0, regNew, regNew+pTab->nCol-1);*/
for(i=0; i<pTab->nCol; i++){
if( i==pTab->iPKey ){
/*sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);*/
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}else{
j = aXRef[i];
if( j>=0 ){
@@ -513,6 +513,8 @@ void sqlite3Update(
testcase( i==31 );
testcase( i==32 );
sqlite3ExprCodeGetColumnOfTable(v, pTab, iDataCur, i, regNew+i);
}else{
sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i);
}
}
}
+2 -2
View File
@@ -1111,7 +1111,7 @@ case OP_Move: {
}
/* Opcode: Copy P1 P2 P3 * *
** Synopsis: r[P2@P3]=r[P1@P3]
** Synopsis: r[P2@P3+1]=r[P1@P3+1]
**
** Make a copy of registers P1..P1+P3 into registers P2..P2+P3.
**
@@ -2454,7 +2454,7 @@ case OP_Column: {
VdbeMemRelease(pDest);
sqlite3VdbeSerialGet(pC->aRow+aOffset[p2], aType[p2], pDest);
}else{
/* This branch happens only when content is on overflow pages */
/* This branch happens only when content is on overflow pages */
t = aType[p2];
if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0
&& ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0))
+2 -1
View File
@@ -160,7 +160,7 @@ typedef struct VdbeOpList VdbeOpList;
** Prototypes for the VDBE interface. See comments on the implementation
** for a description of what each of these routines does.
*/
Vdbe *sqlite3VdbeCreate(sqlite3*);
Vdbe *sqlite3VdbeCreate(Parse*);
int sqlite3VdbeAddOp0(Vdbe*,int);
int sqlite3VdbeAddOp1(Vdbe*,int,int);
int sqlite3VdbeAddOp2(Vdbe*,int,int,int);
@@ -175,6 +175,7 @@ void sqlite3VdbeChangeP3(Vdbe*, u32 addr, int P3);
void sqlite3VdbeChangeP5(Vdbe*, u8 P5);
void sqlite3VdbeJumpHere(Vdbe*, int addr);
void sqlite3VdbeChangeToNoop(Vdbe*, int addr);
int sqlite3VdbeDeletePriorOpcode(Vdbe*, u8 op);
void sqlite3VdbeChangeP4(Vdbe*, int addr, const char *zP4, int N);
void sqlite3VdbeSetP4KeyInfo(Parse*, Index*);
void sqlite3VdbeUsesBtree(Vdbe*, int);
+2 -4
View File
@@ -312,12 +312,9 @@ struct Vdbe {
Mem **apArg; /* Arguments to currently executing user function */
Mem *aColName; /* Column names to return */
Mem *pResultSet; /* Pointer to an array of results */
Parse *pParse; /* Parsing context used to create this Vdbe */
int nMem; /* Number of memory locations currently allocated */
int nOp; /* Number of instructions in the program */
int nOpAlloc; /* Number of slots allocated for aOp[] */
int nLabel; /* Number of labels used */
int *aLabel; /* Space to hold the labels */
u16 nResColumn; /* Number of columns in one row of the result set */
int nCursor; /* Number of slots in apCsr[] */
u32 magic; /* Magic number for sanity checking */
char *zErrMsg; /* Error message written here */
@@ -330,6 +327,7 @@ struct Vdbe {
u32 cacheCtr; /* VdbeCursor row cache generation counter */
int pc; /* The program counter */
int rc; /* Value to return */
u16 nResColumn; /* Number of columns in one row of the result set */
u8 errorAction; /* Recovery action to do in case of an error */
u8 minWriteFileFormat; /* Minimum file format for writable database files */
bft explain:2; /* True if EXPLAIN present on SQL command */
+73 -21
View File
@@ -20,7 +20,8 @@
/*
** Create a new virtual database engine.
*/
Vdbe *sqlite3VdbeCreate(sqlite3 *db){
Vdbe *sqlite3VdbeCreate(Parse *pParse){
sqlite3 *db = pParse->db;
Vdbe *p;
p = sqlite3DbMallocZero(db, sizeof(Vdbe) );
if( p==0 ) return 0;
@@ -32,6 +33,10 @@ Vdbe *sqlite3VdbeCreate(sqlite3 *db){
p->pPrev = 0;
db->pVdbe = p;
p->magic = VDBE_MAGIC_INIT;
p->pParse = pParse;
assert( pParse->aLabel==0 );
assert( pParse->nLabel==0 );
assert( pParse->nOpAlloc==0 );
return p;
}
@@ -87,13 +92,14 @@ void sqlite3VdbeSwap(Vdbe *pA, Vdbe *pB){
** unchanged (this is so that any opcodes already allocated can be
** correctly deallocated along with the rest of the Vdbe).
*/
static int growOpArray(Vdbe *p){
static int growOpArray(Vdbe *v){
VdbeOp *pNew;
Parse *p = v->pParse;
int nNew = (p->nOpAlloc ? p->nOpAlloc*2 : (int)(1024/sizeof(Op)));
pNew = sqlite3DbRealloc(p->db, p->aOp, nNew*sizeof(Op));
pNew = sqlite3DbRealloc(p->db, v->aOp, nNew*sizeof(Op));
if( pNew ){
p->nOpAlloc = sqlite3DbMallocSize(p->db, pNew)/sizeof(Op);
p->aOp = pNew;
v->aOp = pNew;
}
return (pNew ? SQLITE_OK : SQLITE_NOMEM);
}
@@ -132,7 +138,7 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
i = p->nOp;
assert( p->magic==VDBE_MAGIC_INIT );
assert( op>0 && op<0xff );
if( p->nOpAlloc<=i ){
if( p->pParse->nOpAlloc<=i ){
if( growOpArray(p) ){
return 1;
}
@@ -151,6 +157,15 @@ int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){
#endif
#ifdef SQLITE_DEBUG
if( p->db->flags & SQLITE_VdbeAddopTrace ){
int jj, kk;
Parse *pParse = p->pParse;
for(jj=kk=0; jj<SQLITE_N_COLCACHE; jj++){
struct yColCache *x = pParse->aColCache + jj;
if( x->iLevel>pParse->iCacheLevel || x->iReg==0 ) continue;
printf(" r[%d]={%d:%d}", x->iReg, x->iTable, x->iColumn);
kk++;
}
if( kk ) printf("\n");
sqlite3VdbePrintOp(0, i, &p->aOp[i]);
test_addop_breakpoint();
}
@@ -234,9 +249,10 @@ int sqlite3VdbeAddOp4Int(
**
** Zero is returned if a malloc() fails.
*/
int sqlite3VdbeMakeLabel(Vdbe *p){
int sqlite3VdbeMakeLabel(Vdbe *v){
Parse *p = v->pParse;
int i = p->nLabel++;
assert( p->magic==VDBE_MAGIC_INIT );
assert( v->magic==VDBE_MAGIC_INIT );
if( (i & (i-1))==0 ){
p->aLabel = sqlite3DbReallocOrFree(p->db, p->aLabel,
(i*2+1)*sizeof(p->aLabel[0]));
@@ -252,13 +268,15 @@ int sqlite3VdbeMakeLabel(Vdbe *p){
** be inserted. The parameter "x" must have been obtained from
** a prior call to sqlite3VdbeMakeLabel().
*/
void sqlite3VdbeResolveLabel(Vdbe *p, int x){
void sqlite3VdbeResolveLabel(Vdbe *v, int x){
Parse *p = v->pParse;
int j = -1-x;
assert( p->magic==VDBE_MAGIC_INIT );
assert( v->magic==VDBE_MAGIC_INIT );
assert( j<p->nLabel );
if( j>=0 && p->aLabel ){
p->aLabel[j] = p->nOp;
p->aLabel[j] = v->nOp;
}
p->iFixedOp = v->nOp - 1;
}
/*
@@ -406,7 +424,8 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
int i;
int nMaxArgs = *pMaxFuncArgs;
Op *pOp;
int *aLabel = p->aLabel;
Parse *pParse = p->pParse;
int *aLabel = pParse->aLabel;
p->readOnly = 1;
p->bIsReader = 0;
for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
@@ -469,12 +488,13 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){
pOp->opflags = sqlite3OpcodeProperty[opcode];
if( (pOp->opflags & OPFLG_JUMP)!=0 && pOp->p2<0 ){
assert( -1-pOp->p2<p->nLabel );
assert( -1-pOp->p2<pParse->nLabel );
pOp->p2 = aLabel[-1-pOp->p2];
}
}
sqlite3DbFree(p->db, p->aLabel);
p->aLabel = 0;
sqlite3DbFree(p->db, pParse->aLabel);
pParse->aLabel = 0;
pParse->nLabel = 0;
*pMaxFuncArgs = nMaxArgs;
assert( p->bIsReader!=0 || p->btreeMask==0 );
}
@@ -518,7 +538,7 @@ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){
int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp){
int addr;
assert( p->magic==VDBE_MAGIC_INIT );
if( p->nOp + nOp > p->nOpAlloc && growOpArray(p) ){
if( p->nOp + nOp > p->pParse->nOpAlloc && growOpArray(p) ){
return 0;
}
addr = p->nOp;
@@ -605,7 +625,8 @@ void sqlite3VdbeChangeP5(Vdbe *p, u8 val){
** the address of the next instruction to be coded.
*/
void sqlite3VdbeJumpHere(Vdbe *p, int addr){
if( ALWAYS(addr>=0) ) sqlite3VdbeChangeP2(p, addr, p->nOp);
sqlite3VdbeChangeP2(p, addr, p->nOp);
p->pParse->iFixedOp = p->nOp - 1;
}
@@ -707,6 +728,18 @@ void sqlite3VdbeChangeToNoop(Vdbe *p, int addr){
}
}
/*
** Remove the last opcode inserted
*/
int sqlite3VdbeDeletePriorOpcode(Vdbe *p, u8 op){
if( (p->nOp-1)>(p->pParse->iFixedOp) && p->aOp[p->nOp-1].opcode==op ){
sqlite3VdbeChangeToNoop(p, p->nOp-1);
return 1;
}else{
return 0;
}
}
/*
** Change the value of the P4 operand for a specific instruction.
** This routine is useful when a large program is loaded from a
@@ -872,7 +905,17 @@ static int translateP(char c, const Op *pOp){
}
/*
** Compute a string for the "comment" field of a VDBE opcode listing
** Compute a string for the "comment" field of a VDBE opcode listing.
**
** The Synopsis: field in comments in the vdbe.c source file gets converted
** to an extra string that is appended to the sqlite3OpcodeName(). In the
** absence of other comments, this synopsis becomes the comment on the opcode.
** Some translation occurs:
**
** "PX" -> "r[X]"
** "PX@PY" -> "r[X..X+Y-1]" or "r[x]" if y is 0 or 1
** "PX@PY+1" -> "r[X..X+Y]" or "r[x]" if y is 0
** "PY..PY" -> "r[X..Y]" or "r[x]" if y<=x
*/
static int displayComment(
const Op *pOp, /* The opcode to be commented */
@@ -906,7 +949,13 @@ static int displayComment(
ii += 3;
jj += sqlite3Strlen30(zTemp+jj);
v2 = translateP(zSynopsis[ii], pOp);
if( v2>1 ) sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
if( strncmp(zSynopsis+ii+1,"+1",2)==0 ){
ii += 2;
v2++;
}
if( v2>1 ){
sqlite3_snprintf(nTemp-jj, zTemp+jj, "..%d", v1+v2-1);
}
}else if( strncmp(zSynopsis+ii+1, "..P3", 4)==0 && pOp->p3==0 ){
ii += 4;
}
@@ -1138,6 +1187,9 @@ void sqlite3VdbePrintOp(FILE *pOut, int pc, Op *pOp){
#else
zCom[0] = 0
#endif
/* NB: The sqlite3OpcodeName() function is implemented by code created
** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the
** information from the vdbe.c source text */
fprintf(pOut, zFormat1, pc,
sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4, pOp->p5,
zCom
@@ -1569,6 +1621,7 @@ void sqlite3VdbeMakeReady(
assert( p->nOp>0 );
assert( pParse!=0 );
assert( p->magic==VDBE_MAGIC_INIT );
assert( pParse==p->pParse );
db = p->db;
assert( db->mallocFailed==0 );
nVar = pParse->nVar;
@@ -1592,8 +1645,8 @@ void sqlite3VdbeMakeReady(
/* Allocate space for memory registers, SQL variables, VDBE cursors and
** an array to marshal SQL function arguments in.
*/
zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
zEnd = (u8*)&p->aOp[p->nOpAlloc]; /* First byte past end of zCsr[] */
zCsr = (u8*)&p->aOp[p->nOp]; /* Memory avaliable for allocation */
zEnd = (u8*)&p->aOp[pParse->nOpAlloc]; /* First byte past end of zCsr[] */
resolveP2Values(p, &nArg);
p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort);
@@ -2596,7 +2649,6 @@ void sqlite3VdbeClearObject(sqlite3 *db, Vdbe *p){
}
for(i=p->nzVar-1; i>=0; i--) sqlite3DbFree(db, p->azVar[i]);
vdbeFreeOpArray(db, p->aOp, p->nOp);
sqlite3DbFree(db, p->aLabel);
sqlite3DbFree(db, p->aColName);
sqlite3DbFree(db, p->zSql);
sqlite3DbFree(db, p->pFree);
+1 -1
View File
@@ -255,7 +255,7 @@ int sqlite3_blob_open(
}
}
pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(db);
pBlob->pStmt = (sqlite3_stmt *)sqlite3VdbeCreate(pParse);
assert( pBlob->pStmt || db->mallocFailed );
if( pBlob->pStmt ){
Vdbe *v = (Vdbe *)pBlob->pStmt;
+8 -4
View File
@@ -1710,7 +1710,7 @@ static void constructAutomaticIndex(
/* Fill the automatic index with content */
addrTop = sqlite3VdbeAddOp1(v, OP_Rewind, pLevel->iTabCur);
regRecord = sqlite3GetTempReg(pParse);
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0);
sqlite3GenerateIndexKey(pParse, pIdx, pLevel->iTabCur, regRecord, 0, 0, 0, 0);
sqlite3VdbeAddOp2(v, OP_IdxInsert, pLevel->iIdxCur, regRecord);
sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT);
sqlite3VdbeAddOp2(v, OP_Next, pLevel->iTabCur, addrTop+1);
@@ -3928,6 +3928,7 @@ static int whereLoopAddBtreeIndex(
&& saved_nEq==saved_nSkip
&& saved_nEq+1<pProbe->nKeyCol
&& pProbe->aiRowEst[saved_nEq+1]>=18 /* TUNING: Minimum for skip-scan */
&& (rc = whereLoopResize(db, pNew, pNew->nLTerm+1))==SQLITE_OK
){
LogEst nIter;
pNew->u.btree.nEq++;
@@ -5429,9 +5430,12 @@ WhereInfo *sqlite3WhereBegin(
/* Special case: a WHERE clause that is constant. Evaluate the
** expression and either jump over all of the code or fall thru.
*/
if( pWhere && (nTabList==0 || sqlite3ExprIsConstantNotJoin(pWhere)) ){
sqlite3ExprIfFalse(pParse, pWhere, pWInfo->iBreak, SQLITE_JUMPIFNULL);
pWhere = 0;
for(ii=0; ii<sWLB.pWC->nTerm; ii++){
if( nTabList==0 || sqlite3ExprIsConstantNotJoin(sWLB.pWC->a[ii].pExpr) ){
sqlite3ExprIfFalse(pParse, sWLB.pWC->a[ii].pExpr, pWInfo->iBreak,
SQLITE_JUMPIFNULL);
sWLB.pWC->a[ii].wtFlags |= TERM_CODED;
}
}
/* Special case: No FROM clause
-1
View File
@@ -322,7 +322,6 @@ do_test attach3-12.9 {
db_list
} {main temp {}}
do_test attach3-12.10 {
breakpoint
execsql {
DETACH ?
}
-1
View File
@@ -1191,7 +1191,6 @@ do_test capi3-18.2 {
sqlite3_reset $STMT
sqlite3_errcode db
} {SQLITE_SCHEMA}
breakpoint
do_test capi3-18.3 {
sqlite3_errmsg db
} {database schema has changed}
-1
View File
@@ -75,7 +75,6 @@ do_test collate1-1.1 {
}
} {{} 0x119 0x2D}
do_test collate1-1.2 {
breakpoint
execsql {
SELECT c2 FROM collate1t1 ORDER BY 1 COLLATE hex;
}
-1
View File
@@ -301,7 +301,6 @@ do_test exclusive2-3.3 {
readPagerChangeCounter test.db
} {4}
do_test exclusive2-3.4 {
breakpoint
execsql {
INSERT INTO t1 VALUES(randstr(200, 200));
}
-1
View File
@@ -146,7 +146,6 @@ do_test fts3aa-3.3 {
execsql {SELECT rowid FROM t1 WHERE content MATCH '-two one'}
} {1 5 9 13 17 21 25 29}
breakpoint
do_test fts3aa-4.1 {
execsql {SELECT rowid FROM t1 WHERE content MATCH 'one OR two'}
} {1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 23 25 26 27 29 30 31}
-1
View File
@@ -115,7 +115,6 @@ for {set i 1} {$i<=15} {incr i} {
db eval "INSERT INTO t4(norm,plusone,invert) VALUES([join $vset ,]);"
}
breakpoint
do_test fts3ab-4.1 {
execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one'}
} {1 3 5 7 9 11 13 15}
-1
View File
@@ -78,7 +78,6 @@ do_test fts3ag-1.10 {
# Test that docListOrMerge() correctly handles reaching the end of one
# doclist before it reaches the end of the other.
do_test fts3ag-1.11 {
breakpoint
execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this OR also'}
} {1 2}
do_test fts3ag-1.12 {
-1
View File
@@ -253,7 +253,6 @@ check_doclist fts3d-4.4.10 1 0 was {[2 0[1]]}
# Optimize should leave the result in the level of the highest-level
# prior segment.
breakpoint
do_test fts3d-4.5 {
execsql {
SELECT OPTIMIZE(t1) FROM t1 LIMIT 1;
+66
View File
@@ -0,0 +1,66 @@
# 2014 January 4
#
# 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 script is testing the FTS3 module.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set ::testprefix fts3join
# If SQLITE_ENABLE_FTS3 is defined, omit this file.
ifcapable !fts3 {
finish_test
return
}
do_execsql_test 1.0 {
CREATE VIRTUAL TABLE ft1 USING fts4(x);
INSERT INTO ft1 VALUES('aaa aaa');
INSERT INTO ft1 VALUES('aaa bbb');
INSERT INTO ft1 VALUES('bbb aaa');
INSERT INTO ft1 VALUES('bbb bbb');
CREATE TABLE t1(id, y);
INSERT INTO t1 VALUES(1, 'aaa');
INSERT INTO t1 VALUES(2, 'bbb');
}
do_execsql_test 1.1 {
SELECT docid FROM ft1, t1 WHERE ft1 MATCH y AND id=1;
} {1 2 3}
do_execsql_test 1.2 {
SELECT docid FROM ft1, t1 WHERE ft1 MATCH y AND id=1 ORDER BY docid;
} {1 2 3}
do_execsql_test 2.0 {
CREATE VIRTUAL TABLE ft2 USING fts4(x);
CREATE VIRTUAL TABLE ft3 USING fts4(y);
INSERT INTO ft2 VALUES('abc');
INSERT INTO ft2 VALUES('def');
INSERT INTO ft3 VALUES('ghi');
INSERT INTO ft3 VALUES('abc');
}
do_execsql_test 2.1 { SELECT * FROM ft2, ft3 WHERE x MATCH y; } {abc abc}
do_execsql_test 2.2 { SELECT * FROM ft2, ft3 WHERE y MATCH x; } {abc abc}
do_execsql_test 2.3 { SELECT * FROM ft3, ft2 WHERE x MATCH y; } {abc abc}
do_execsql_test 2.4 { SELECT * FROM ft3, ft2 WHERE y MATCH x; } {abc abc}
do_catchsql_test 2.5 {
SELECT * FROM ft3, ft2 WHERE y MATCH x AND x MATCH y;
} {1 {unable to use function MATCH in the requested context}}
finish_test
-1
View File
@@ -165,7 +165,6 @@ do_test fts3near-3.6 {
SELECT offsets(t1) FROM t1 WHERE content MATCH 'three NEAR/0 "two four"'
}
} {{0 0 8 5 0 1 14 3 0 2 18 4}}
breakpoint
do_test fts3near-3.7 {
execsql {
SELECT offsets(t1) FROM t1 WHERE content MATCH '"two four" NEAR/0 three'}
-1
View File
@@ -90,7 +90,6 @@ do_execsql_test 1.13.1 {
INSERT INTO c1(x) VALUES('a b c');
INSERT INTO c1(x) VALUES('d e f');
}
breakpoint
do_execsql_test 1.13.2 {
SELECT * FROM c1, t1 WHERE input = x AND c1.rowid=t1.rowid;
} {
-5
View File
@@ -392,7 +392,6 @@ foreach T $tokenizers {
#-------------------------------------------------------------------------
# Test that the private use ranges are treated as alphanumeric.
#
breakpoint
foreach {tn1 c} {
1 \ue000 2 \ue001 3 \uf000 4 \uf8fe 5 \uf8ff
} {
@@ -557,7 +556,3 @@ do_execsql_test 11.1 {
}
finish_test
+13
View File
@@ -592,4 +592,17 @@ do_test misc1-18.1 {
expr {$n>=100}
} {1}
# 2014-01-10: In a CREATE TABLE AS, if one or more of the column names
# are an empty string, that is still OK.
#
do_execsql_test misc1-19.1 {
CREATE TABLE t19 AS SELECT 1, 2 AS '', 3;
SELECT * FROM t19;
} {1 2 3}
do_execsql_test misc1-19.2 {
CREATE TABLE t19b AS SELECT 4 AS '', 5 AS '', 6 AS '';
SELECT * FROM t19b;
} {4 5 6}
finish_test
-1
View File
@@ -41,7 +41,6 @@ do_test 1-pre {
do_faultsim_test 1 -prep {
faultsim_restore_and_reopen
db func a_string a_string
breakpoint
execsql {
PRAGMA mmap_size = 1000000;
PRAGMA cache_size = 5;
+42 -2
View File
@@ -11,13 +11,23 @@
# This file implements regression tests for SQLite library. The
# focus of this file is testing the printf() SQL function.
#
#
# EVIDENCE-OF: R-63057-40065 The printf(FORMAT,...) SQL function works
# like the sqlite3_mprintf() C-language function and the printf()
# function from the standard C library.
#
set testdir [file dirname $argv0]
source $testdir/tester.tcl
# EVIDENCE-OF: R-40086-60101 If the FORMAT argument is missing or NULL
# then the result is NULL.
#
do_execsql_test printf2-1.1 {
SELECT printf();
} {{}}
SELECT quote(printf()), quote(printf(NULL,1,2,3));
} {NULL NULL}
do_execsql_test printf2-1.2 {
SELECT printf('hello');
} {hello}
@@ -48,6 +58,9 @@ do_execsql_test printf2-1.10 {
do_execsql_test printf2-1.11 {
SELECT printf('%lld%n',314159.2653,'hi');
} {314159}
# EVIDENCE-OF: R-20555-31089 The %z format is interchangable with %s.
#
do_execsql_test printf2-1.12 {
SELECT printf('%.*z',5,'abcdefghijklmnop');
} {abcde}
@@ -55,5 +68,32 @@ do_execsql_test printf2-1.13 {
SELECT printf('%c','abcdefghijklmnop');
} {a}
# EVIDENCE-OF: R-02347-27622 The %n format is silently ignored and does
# not consume an argument.
#
do_execsql_test printf2-2.1 {
CREATE TABLE t1(a,b,c);
INSERT INTO t1 VALUES(1,2,3);
INSERT INTO t1 VALUES(-1,-2,-3);
INSERT INTO t1 VALUES('abc','def','ghi');
INSERT INTO t1 VALUES(1.5,2.25,3.125);
SELECT printf('(%s)-%n-(%s)',a,b,c) FROM t1 ORDER BY rowid;
} {(1)--(2) (-1)--(-2) (abc)--(def) (1.5)--(2.25)}
# EVIDENCE-OF: R-56064-04001 The %p format is an alias for %X.
#
do_execsql_test printf2-2.2 {
SELECT printf('%s=(%p)',a,a) FROM t1 ORDER BY a;
} {-1=(FFFFFFFFFFFFFFFF) 1=(1) 1.5=(1) abc=(0)}
# EVIDENCE-OF: R-29410-53018 If there are too few arguments in the
# argument list, missing arguments are assumed to have a NULL value,
# which is translated into 0 or 0.0 for numeric formats or an empty
# string for %s.
#
do_execsql_test printf2-2.3 {
SELECT printf('%s=(%d/%g/%s)',a) FROM t1 ORDER BY a;
} {-1=(0/0/) 1=(0/0/) 1.5=(0/0/) abc=(0/0/)}
finish_test
-1
View File
@@ -47,7 +47,6 @@ do_test securedel-1.3 {
}
} {0 0}
do_test securedel-1.4 {
breakpoint
db eval {
PRAGMA secure_delete=ON;
PRAGMA db2.secure_delete;
+4 -2
View File
@@ -155,7 +155,8 @@ SELECT * FROM foo1;
2
SELECT * FROM foo2;
1
2}}
2
}}
# Test with echo on and headers on using dot command and
# multiple commands per line.
@@ -192,6 +193,7 @@ a
SELECT * FROM foo2;
b
1
2}}
2
}}
finish_test
+22
View File
@@ -187,4 +187,26 @@ do_execsql_test skipscan1-3.2sort {
SELECT a,b,c,d,'|' FROM t3 WHERE b=345 ORDER BY a;
} {~/*ORDER BY*/}
# Ticket 520070ec7fbaac: Array overrun in the skip-scan optimization
# 2013-12-22
#
do_execsql_test skipscan1-4.1 {
CREATE TABLE t4(a,b,c,d,e,f,g,h,i);
CREATE INDEX t4all ON t4(a,b,c,d,e,f,g,h);
INSERT INTO t4 VALUES(1,2,3,4,5,6,7,8,9);
ANALYZE;
DELETE FROM sqlite_stat1;
INSERT INTO sqlite_stat1
VALUES('t4','t4all','655360 163840 40960 10240 2560 640 160 40 10');
ANALYZE sqlite_master;
SELECT i FROM t4 WHERE a=1;
SELECT i FROM t4 WHERE b=2;
SELECT i FROM t4 WHERE c=3;
SELECT i FROM t4 WHERE d=4;
SELECT i FROM t4 WHERE e=5;
SELECT i FROM t4 WHERE f=6;
SELECT i FROM t4 WHERE g=7;
SELECT i FROM t4 WHERE h=8;
} {9 9 9 9 9 9 9 9}
finish_test
+66 -21
View File
@@ -9,6 +9,7 @@ static const char zHelp[] =
" --autovacuum Enable AUTOVACUUM mode\n"
" --cachesize N Set the cache size to N\n"
" --exclusive Enable locking_mode=EXCLUSIVE\n"
" --explain Like --sqlonly but with added EXPLAIN keywords\n"
" --heap SZ MIN Memory allocator uses SZ bytes & min allocation MIN\n"
" --incrvacuum Enable incremenatal vacuum mode\n"
" --journalmode M Set the journal_mode to MODE\n"
@@ -49,6 +50,7 @@ static struct Global {
int bWithoutRowid; /* True for --without-rowid */
int bReprepare; /* True to reprepare the SQL on each rerun */
int bSqlOnly; /* True to print the SQL once only */
int bExplain; /* Print SQL with EXPLAIN prefix */
int szTest; /* Scale factor for test iterations */
const char *zWR; /* Might be WITHOUT ROWID */
const char *zNN; /* Might be NOT NULL */
@@ -290,6 +292,24 @@ void speedtest1_final(void){
}
}
/* Print an SQL statement to standard output */
static void printSql(const char *zSql){
int n = (int)strlen(zSql);
while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; }
if( g.bExplain ) printf("EXPLAIN ");
printf("%.*s;\n", n, zSql);
if( g.bExplain
#if SQLITE_VERSION_NUMBER>=3007010
&& ( sqlite3_strglob("CREATE *", zSql)==0
|| sqlite3_strglob("DROP *", zSql)==0
|| sqlite3_strglob("ALTER *", zSql)==0
)
#endif
){
printf("%.*s;\n", n, zSql);
}
}
/* Run SQL */
void speedtest1_exec(const char *zFormat, ...){
va_list ap;
@@ -298,9 +318,7 @@ void speedtest1_exec(const char *zFormat, ...){
zSql = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( g.bSqlOnly ){
int n = (int)strlen(zSql);
while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; }
printf("%.*s;\n", n, zSql);
printSql(zSql);
}else{
char *zErrMsg = 0;
int rc = sqlite3_exec(g.db, zSql, 0, 0, &zErrMsg);
@@ -318,9 +336,7 @@ void speedtest1_prepare(const char *zFormat, ...){
zSql = sqlite3_vmprintf(zFormat, ap);
va_end(ap);
if( g.bSqlOnly ){
int n = (int)strlen(zSql);
while( n>0 && (zSql[n-1]==';' || isspace(zSql[n-1])) ){ n--; }
printf("%.*s;\n", n, zSql);
printSql(zSql);
}else{
int rc;
if( g.pStmt ) sqlite3_finalize(g.pStmt);
@@ -378,6 +394,19 @@ static void randomFunc(
sqlite3_result_int64(context, (sqlite3_int64)speedtest1_random());
}
/* Estimate the square root of an integer */
static int est_square_root(int x){
int y0 = x/2;
int y1;
int n;
for(n=0; y0>0 && n<10; n++){
y1 = (y0 + x/y0)/2;
if( y1==y0 ) break;
y0 = y1;
}
return y0;
}
/*
** The main and default testset
*/
@@ -484,15 +513,13 @@ void testset_main(void){
speedtest1_begin_test(150, "CREATE INDEX five times");
speedtest1_exec(
"BEGIN;\n"
"CREATE UNIQUE INDEX t1b ON t1(b);\n"
"CREATE INDEX t1c ON t1(c);\n"
"CREATE UNIQUE INDEX t2b ON t2(b);\n"
"CREATE INDEX t2c ON t2(c DESC);\n"
"CREATE INDEX t3bc ON t3(b,c);\n"
"COMMIT;\n"
);
speedtest1_exec("BEGIN;");
speedtest1_exec("CREATE UNIQUE INDEX t1b ON t1(b);");
speedtest1_exec("CREATE INDEX t1c ON t1(c);");
speedtest1_exec("CREATE UNIQUE INDEX t2b ON t2(b);");
speedtest1_exec("CREATE INDEX t2c ON t2(c DESC);");
speedtest1_exec("CREATE INDEX t3bc ON t3(b,c);");
speedtest1_exec("COMMIT;");
speedtest1_end_test();
@@ -566,10 +593,8 @@ void testset_main(void){
n = sz;
speedtest1_begin_test(190, "DELETE and REFILL one table", n);
speedtest1_exec(
"DELETE FROM t2;"
"INSERT INTO t2 SELECT * FROM t1;"
);
speedtest1_exec("DELETE FROM t2;");
speedtest1_exec("INSERT INTO t2 SELECT * FROM t1;");
speedtest1_end_test();
@@ -663,9 +688,17 @@ void testset_main(void){
speedtest1_exec("REPLACE INTO t3(a,b,c) SELECT a,b,c FROM t1");
speedtest1_end_test();
speedtest1_begin_test(300, "Refill a %d-row table using (b&1)==(a&1)", sz);
speedtest1_exec("DELETE FROM t2;");
speedtest1_exec("INSERT INTO t2(a,b,c)\n"
" SELECT a,b,c FROM t1 WHERE (b&1)==(a&1);");
speedtest1_exec("INSERT INTO t2(a,b,c)\n"
" SELECT a,b,c FROM t1 WHERE (b&1)<>(a&1);");
speedtest1_end_test();
n = sz/5;
speedtest1_begin_test(300, "%d four-ways joins", n);
speedtest1_begin_test(310, "%d four-ways joins", n);
speedtest1_exec("BEGIN");
speedtest1_prepare(
"SELECT t1.c FROM t1, t2, t3, t4\n"
@@ -684,7 +717,15 @@ void testset_main(void){
speedtest1_exec("COMMIT");
speedtest1_end_test();
speedtest1_begin_test(320, "subquery in result set", n);
speedtest1_prepare(
"SELECT sum(a), max(c),\n"
" avg((SELECT a FROM t2 WHERE 5+t2.b=t1.b) AND rowid<?1), max(c)\n"
" FROM t1 WHERE rowid<?1;"
);
sqlite3_bind_int(g.pStmt, 1, est_square_root(g.szTest)*50);
speedtest1_run();
speedtest1_end_test();
speedtest1_begin_test(980, "PRAGMA integrity_check");
speedtest1_exec("PRAGMA integrity_check");
@@ -757,6 +798,9 @@ int main(int argc, char **argv){
cacheSize = integerValue(argv[i]);
}else if( strcmp(z,"exclusive")==0 ){
doExclusive = 1;
}else if( strcmp(z,"explain")==0 ){
g.bSqlOnly = 1;
g.bExplain = 1;
}else if( strcmp(z,"heap")==0 ){
if( i>=argc-2 ) fatal_error("missing arguments on %s\n", argv[i]);
nHeap = integerValue(argv[i+1]);
@@ -896,6 +940,7 @@ int main(int argc, char **argv){
speedtest1_exec("PRAGMA journal_mode=%s", zJMode);
}
if( g.bExplain ) printf(".explain\n.echo on\n");
if( strcmp(zTSet,"main")==0 ){
testset_main();
}else if( strcmp(zTSet,"debug1")==0 ){
-1
View File
@@ -164,7 +164,6 @@ db close
forcedelete test.db
sqlite3 db test.db
register_dbstat_vtab db
breakpoint
do_execsql_test stat-5.1 {
PRAGMA auto_vacuum = OFF;
CREATE VIRTUAL TABLE temp.stat USING dbstat;
-1
View File
@@ -44,7 +44,6 @@ do_test tkt-94c94-2.1 {
execsql { CREATE TABLE t2(x, y) } db
} {}
do_test tkt-94c94-2.2 {
breakpoint
execsql { INSERT INTO t2 VALUES(1, 2) } db2
} {}
do_test tkt-94c94-2.3 {
-1
View File
@@ -116,7 +116,6 @@ do_test vtab_shared-1.10 {
} {1 {database table is locked: sqlite_master}}
do_test vtab_shared-1.11 {
breakpoint
execsql {
CREATE VIRTUAL TABLE t2 USING echo(t0);
CREATE VIRTUAL TABLE t3 USING echo(t0);
-1
View File
@@ -852,7 +852,6 @@ do_test wal-13.1.2 {
sqlite3 db test.db
execsql { SELECT * FROM t2 }
} {B 2}
breakpoint
do_test wal-13.1.3 {
db close
file exists test.db-wal
-1
View File
@@ -1279,7 +1279,6 @@ foreach {tn settings restart_sync commit_sync ckpt_sync} {
PRAGMA synchronous = [lindex $settings 2];
" {0 wal}
if { $tn==2} breakpoint
do_test 15.$tn.2 {
set sync(normal) 0
set sync(full) 0
-1
View File
@@ -567,7 +567,6 @@ do_test walfault-14-pre {
} {}
do_faultsim_test walfault-14 -prep {
faultsim_restore_and_reopen
breakpoint
execsql {
SELECT count(*) FROM abc;
PRAGMA locking_mode = exclusive;
+188 -35
View File
@@ -50,6 +50,107 @@ static char *msort(char*,char**,int(*)(const char*,const char*));
*/
#define lemonStrlen(X) ((int)strlen(X))
/*
** Compilers are starting to complain about the use of sprintf() and strcpy(),
** saying they are unsafe. So we define our own versions of those routines too.
**
** There are three routines here: lemon_sprintf(), lemon_vsprintf(), and
** lemon_addtext(). The first two are replacements for sprintf() and vsprintf().
** The third is a helper routine for vsnprintf() that adds texts to the end of a
** buffer, making sure the buffer is always zero-terminated.
**
** The string formatter is a minimal subset of stdlib sprintf() supporting only
** a few simply conversions:
**
** %d
** %s
** %.*s
**
*/
static void lemon_addtext(
char *zBuf, /* The buffer to which text is added */
int *pnUsed, /* Slots of the buffer used so far */
const char *zIn, /* Text to add */
int nIn, /* Bytes of text to add. -1 to use strlen() */
int iWidth /* Field width. Negative to left justify */
){
if( nIn<0 ) for(nIn=0; zIn[nIn]; nIn++){}
while( iWidth>nIn ){ zBuf[*(pnUsed++)] = ' '; iWidth--; }
if( nIn==0 ) return;
memcpy(&zBuf[*pnUsed], zIn, nIn);
*pnUsed += nIn;
while( (-iWidth)>nIn ){ zBuf[*(pnUsed++)] = ' '; iWidth++; }
zBuf[*pnUsed] = 0;
}
static int lemon_vsprintf(char *str, const char *zFormat, va_list ap){
int i, j, k, c, size;
int nUsed = 0;
const char *z;
char zTemp[50];
str[0] = 0;
for(i=j=0; (c = zFormat[i])!=0; i++){
if( c=='%' ){
int iWidth = 0;
lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
c = zFormat[++i];
if( isdigit(c) || (c=='-' && isdigit(zFormat[i+1])) ){
if( c=='-' ) i++;
while( isdigit(zFormat[i]) ) iWidth = iWidth*10 + zFormat[i++] - '0';
if( c=='-' ) iWidth = -iWidth;
c = zFormat[i];
}
if( c=='d' ){
int v = va_arg(ap, int);
if( v<0 ){
lemon_addtext(str, &nUsed, "-", 1, iWidth);
v = -v;
}else if( v==0 ){
lemon_addtext(str, &nUsed, "0", 1, iWidth);
}
k = 0;
while( v>0 ){
k++;
zTemp[sizeof(zTemp)-k] = (v%10) + '0';
v /= 10;
}
lemon_addtext(str, &nUsed, &zTemp[sizeof(zTemp)-k], k, iWidth);
}else if( c=='s' ){
z = va_arg(ap, const char*);
lemon_addtext(str, &nUsed, z, -1, iWidth);
}else if( c=='.' && memcmp(&zFormat[i], ".*s", 3)==0 ){
i += 2;
k = va_arg(ap, int);
z = va_arg(ap, const char*);
lemon_addtext(str, &nUsed, z, k, iWidth);
}else if( c=='%' ){
lemon_addtext(str, &nUsed, "%", 1, 0);
}else{
fprintf(stderr, "illegal format\n");
exit(1);
}
j = i+1;
}
}
lemon_addtext(str, &nUsed, &zFormat[j], i-j, 0);
return nUsed;
}
static int lemon_sprintf(char *str, const char *format, ...){
va_list ap;
int rc;
va_start(ap, format);
rc = lemon_vsprintf(str, format, ap);
va_end(ap);
return rc;
}
static void lemon_strcpy(char *dest, const char *src){
while( (*(dest++) = *(src++))!=0 ){}
}
static void lemon_strcat(char *dest, const char *src){
while( *dest ) dest++;
lemon_strcpy(dest, src);
}
/* a few forward declarations... */
struct rule;
struct lemon;
@@ -1367,7 +1468,7 @@ static void handle_D_option(char *z){
fprintf(stderr,"out of memory\n");
exit(1);
}
strcpy(*paz, z);
lemon_strcpy(*paz, z);
for(z=*paz; *z && *z!='='; z++){}
*z = 0;
}
@@ -1378,7 +1479,7 @@ static void handle_T_option(char *z){
if( user_templatename==0 ){
memory_error();
}
strcpy(user_templatename, z);
lemon_strcpy(user_templatename, z);
}
/* The main program. Parse the command line and do it... */
@@ -1447,12 +1548,15 @@ int main(int argc, char **argv)
}
/* Count and index the symbols of the grammar */
lem.nsymbol = Symbol_count();
Symbol_new("{default}");
lem.nsymbol = Symbol_count();
lem.symbols = Symbol_arrayof();
for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
qsort(lem.symbols,lem.nsymbol+1,sizeof(struct symbol*), Symbolcmpp);
for(i=0; i<=lem.nsymbol; i++) lem.symbols[i]->index = i;
for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
qsort(lem.symbols,lem.nsymbol,sizeof(struct symbol*), Symbolcmpp);
for(i=0; i<lem.nsymbol; i++) lem.symbols[i]->index = i;
while( lem.symbols[i-1]->type==MULTITERMINAL ){ i--; }
assert( strcmp(lem.symbols[i-1]->name,"{default}")==0 );
lem.nsymbol = i - 1;
for(i=1; isupper(lem.symbols[i]->name[0]); i++);
lem.nterminal = i;
@@ -1940,7 +2044,9 @@ enum e_state {
WAITING_FOR_DESTRUCTOR_SYMBOL,
WAITING_FOR_DATATYPE_SYMBOL,
WAITING_FOR_FALLBACK_ID,
WAITING_FOR_WILDCARD_ID
WAITING_FOR_WILDCARD_ID,
WAITING_FOR_CLASS_ID,
WAITING_FOR_CLASS_TOKEN
};
struct pstate {
char *filename; /* Name of the input file */
@@ -1950,6 +2056,7 @@ struct pstate {
struct lemon *gp; /* Global state vector */
enum e_state state; /* The state of the parser */
struct symbol *fallback; /* The fallback token */
struct symbol *tkclass; /* Token class symbol */
struct symbol *lhs; /* Left-hand side of current rule */
const char *lhsalias; /* Alias for the LHS */
int nrhs; /* Number of right-hand side symbols seen */
@@ -2254,6 +2361,8 @@ to follow the previous rule.");
psp->state = WAITING_FOR_FALLBACK_ID;
}else if( strcmp(x,"wildcard")==0 ){
psp->state = WAITING_FOR_WILDCARD_ID;
}else if( strcmp(x,"token_class")==0 ){
psp->state = WAITING_FOR_CLASS_ID;
}else{
ErrorMsg(psp->filename,psp->tokenlineno,
"Unknown declaration keyword: \"%%%s\".",x);
@@ -2347,7 +2456,7 @@ to follow the previous rule.");
for(z=psp->filename, nBack=0; *z; z++){
if( *z=='\\' ) nBack++;
}
sprintf(zLine, "#line %d ", psp->tokenlineno);
lemon_sprintf(zLine, "#line %d ", psp->tokenlineno);
nLine = lemonStrlen(zLine);
n += nLine + lemonStrlen(psp->filename) + nBack;
}
@@ -2422,6 +2531,40 @@ to follow the previous rule.");
}
}
break;
case WAITING_FOR_CLASS_ID:
if( !islower(x[0]) ){
ErrorMsg(psp->filename, psp->tokenlineno,
"%%token_class must be followed by an identifier: ", x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
}else if( Symbol_find(x) ){
ErrorMsg(psp->filename, psp->tokenlineno,
"Symbol \"%s\" already used", x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
}else{
psp->tkclass = Symbol_new(x);
psp->tkclass->type = MULTITERMINAL;
psp->state = WAITING_FOR_CLASS_TOKEN;
}
break;
case WAITING_FOR_CLASS_TOKEN:
if( x[0]=='.' ){
psp->state = WAITING_FOR_DECL_OR_RULE;
}else if( isupper(x[0]) || ((x[0]=='|' || x[0]=='/') && isupper(x[1])) ){
struct symbol *msp = psp->tkclass;
msp->nsubsym++;
msp->subsym = (struct symbol **) realloc(msp->subsym,
sizeof(struct symbol*)*msp->nsubsym);
if( !isupper(x[0]) ) x++;
msp->subsym[msp->nsubsym-1] = Symbol_new(x);
}else{
ErrorMsg(psp->filename, psp->tokenlineno,
"%%token_class argument \"%s\" should be a token", x);
psp->errorcnt++;
psp->state = RESYNC_AFTER_DECL_ERROR;
}
break;
case RESYNC_AFTER_RULE_ERROR:
/* if( x[0]=='.' ) psp->state = WAITING_FOR_DECL_OR_RULE;
** break; */
@@ -2716,10 +2859,10 @@ PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
fprintf(stderr,"Can't allocate space for a filename.\n");
exit(1);
}
strcpy(name,lemp->filename);
lemon_strcpy(name,lemp->filename);
cp = strrchr(name,'.');
if( cp ) *cp = 0;
strcat(name,suffix);
lemon_strcat(name,suffix);
return name;
}
@@ -2776,11 +2919,13 @@ void Reprint(struct lemon *lemp)
printf(" ::=");
for(i=0; i<rp->nrhs; i++){
sp = rp->rhs[i];
printf(" %s", sp->name);
if( sp->type==MULTITERMINAL ){
printf(" %s", sp->subsym[0]->name);
for(j=1; j<sp->nsubsym; j++){
printf("|%s", sp->subsym[j]->name);
}
}else{
printf(" %s", sp->name);
}
/* if( rp->rhsalias[i] ) printf("(%s)",rp->rhsalias[i]); */
}
@@ -2802,11 +2947,13 @@ void ConfigPrint(FILE *fp, struct config *cfp)
if( i==cfp->dot ) fprintf(fp," *");
if( i==rp->nrhs ) break;
sp = rp->rhs[i];
fprintf(fp," %s", sp->name);
if( sp->type==MULTITERMINAL ){
fprintf(fp," %s", sp->subsym[0]->name);
for(j=1; j<sp->nsubsym; j++){
fprintf(fp,"|%s",sp->subsym[j]->name);
}
}else{
fprintf(fp," %s", sp->name);
}
}
}
@@ -2916,7 +3063,7 @@ void ReportOutput(struct lemon *lemp)
while( cfp ){
char buf[20];
if( cfp->dot==cfp->rp->nrhs ){
sprintf(buf,"(%d)",cfp->rp->index);
lemon_sprintf(buf,"(%d)",cfp->rp->index);
fprintf(fp," %5s ",buf);
}else{
fprintf(fp," ");
@@ -2981,7 +3128,7 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
c = *cp;
*cp = 0;
path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
if( path ) sprintf(path,"%s/%s",argv0,name);
if( path ) lemon_sprintf(path,"%s/%s",argv0,name);
*cp = c;
}else{
pathlist = getenv("PATH");
@@ -2990,13 +3137,13 @@ PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
if( (pathbuf != 0) && (path!=0) ){
pathbufptr = pathbuf;
strcpy(pathbuf, pathlist);
lemon_strcpy(pathbuf, pathlist);
while( *pathbuf ){
cp = strchr(pathbuf,':');
if( cp==0 ) cp = &pathbuf[lemonStrlen(pathbuf)];
c = *cp;
*cp = 0;
sprintf(path,"%s/%s",pathbuf,name);
lemon_sprintf(path,"%s/%s",pathbuf,name);
*cp = c;
if( c==0 ) pathbuf[0] = 0;
else pathbuf = &cp[1];
@@ -3087,9 +3234,9 @@ PRIVATE FILE *tplt_open(struct lemon *lemp)
cp = strrchr(lemp->filename,'.');
if( cp ){
sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename);
lemon_sprintf(buf,"%.*s.lt",(int)(cp-lemp->filename),lemp->filename);
}else{
sprintf(buf,"%s.lt",lemp->filename);
lemon_sprintf(buf,"%s.lt",lemp->filename);
}
if( access(buf,004)==0 ){
tpltname = buf;
@@ -3240,9 +3387,9 @@ PRIVATE char *append_str(const char *zText, int n, int p1, int p2){
while( n-- > 0 ){
c = *(zText++);
if( c=='%' && n>0 && zText[0]=='d' ){
sprintf(zInt, "%d", p1);
lemon_sprintf(zInt, "%d", p1);
p1 = p2;
strcpy(&z[used], zInt);
lemon_strcpy(&z[used], zInt);
used += lemonStrlen(&z[used]);
zText++;
n--;
@@ -3467,7 +3614,7 @@ void print_stack_union(
fprintf(stderr,"Out of memory.\n");
exit(1);
}
strcpy(types[hash],stddt);
lemon_strcpy(types[hash],stddt);
}
}
@@ -3553,9 +3700,11 @@ static void writeRuleText(FILE *out, struct rule *rp){
fprintf(out,"%s ::=", rp->lhs->name);
for(j=0; j<rp->nrhs; j++){
struct symbol *sp = rp->rhs[j];
fprintf(out," %s", sp->name);
if( sp->type==MULTITERMINAL ){
if( sp->type!=MULTITERMINAL ){
fprintf(out," %s", sp->name);
}else{
int k;
fprintf(out," %s", sp->subsym[0]->name);
for(k=1; k<sp->nsubsym; k++){
fprintf(out,"|%s",sp->subsym[k]->name);
}
@@ -3856,7 +4005,7 @@ void ReportTable(
/* Generate a table containing the symbolic name of every symbol
*/
for(i=0; i<lemp->nsymbol; i++){
sprintf(line,"\"%s\",",lemp->symbols[i]->name);
lemon_sprintf(line,"\"%s\",",lemp->symbols[i]->name);
fprintf(out," %-15s",line);
if( (i&3)==3 ){ fprintf(out,"\n"); lineno++; }
}
@@ -4023,7 +4172,8 @@ void ReportHeader(struct lemon *lemp)
if( in ){
int nextChar;
for(i=1; i<lemp->nterminal && fgets(line,LINESIZE,in); i++){
sprintf(pattern,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
lemon_sprintf(pattern,"#define %s%-30s %3d\n",
prefix,lemp->symbols[i]->name,i);
if( strcmp(line,pattern) ) break;
}
nextChar = fgetc(in);
@@ -4036,7 +4186,7 @@ void ReportHeader(struct lemon *lemp)
out = file_open(lemp,".h","wb");
if( out ){
for(i=1; i<lemp->nterminal; i++){
fprintf(out,"#define %s%-30s %2d\n",prefix,lemp->symbols[i]->name,i);
fprintf(out,"#define %s%-30s %3d\n",prefix,lemp->symbols[i]->name,i);
}
fclose(out);
}
@@ -4253,7 +4403,7 @@ const char *Strsafe(const char *y)
if( y==0 ) return 0;
z = Strsafe_find(y);
if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
strcpy(cpy,y);
lemon_strcpy(cpy,y);
z = cpy;
Strsafe_insert(z);
}
@@ -4406,11 +4556,15 @@ struct symbol *Symbol_new(const char *x)
return sp;
}
/* Compare two symbols for working purposes
/* Compare two symbols for sorting purposes. Return negative,
** zero, or positive if a is less then, equal to, or greater
** than b.
**
** Symbols that begin with upper case letters (terminals or tokens)
** must sort before symbols that begin with lower case letters
** (non-terminals). Other than that, the order does not matter.
** (non-terminals). And MULTITERMINAL symbols (created using the
** %token_class directive) must sort at the very end. Other than
** that, the order does not matter.
**
** We find experimentally that leaving the symbols in their original
** order (the order they appeared in the grammar file) gives the
@@ -4418,12 +4572,11 @@ struct symbol *Symbol_new(const char *x)
*/
int Symbolcmpp(const void *_a, const void *_b)
{
const struct symbol **a = (const struct symbol **) _a;
const struct symbol **b = (const struct symbol **) _b;
int i1 = (**a).index + 10000000*((**a).name[0]>'Z');
int i2 = (**b).index + 10000000*((**b).name[0]>'Z');
assert( i1!=i2 || strcmp((**a).name,(**b).name)==0 );
return i1-i2;
const struct symbol *a = *(const struct symbol **) _a;
const struct symbol *b = *(const struct symbol **) _b;
int i1 = a->type==MULTITERMINAL ? 3 : a->name[0]>'Z' ? 2 : 1;
int i2 = b->type==MULTITERMINAL ? 3 : b->name[0]>'Z' ? 2 : 1;
return i1==i2 ? a->index - b->index : i1 - i2;
}
/* There is one instance of the following structure for each