Index: Makefile.in
==================================================================
--- Makefile.in
+++ Makefile.in
@@ -815,11 +815,12 @@
mv vdbe.new tsrc/vdbe.c
cp fts5.c fts5.h tsrc
touch .target_source
sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84
- $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC)
+ $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) \
+ $(EXTRA_SRC)
cp tsrc/sqlite3ext.h .
cp $(TOP)/ext/session/sqlite3session.h .
sqlite3r.h: sqlite3.h has_tclsh84
$(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h
@@ -826,11 +827,12 @@
sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84
cp $(TOP)/ext/recover/sqlite3recover.c tsrc/
cp $(TOP)/ext/recover/sqlite3recover.h tsrc/
cp $(TOP)/ext/recover/dbdata.c tsrc/
- $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC)
+ $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl --enable-recover \
+ $(AMALGAMATION_LINE_MACROS) $(EXTRA_SRC)
sqlite3ext.h: .target_source
cp tsrc/sqlite3ext.h .
tclsqlite3.c: sqlite3.c
Index: doc/testrunner.md
==================================================================
--- doc/testrunner.md
+++ doc/testrunner.md
@@ -15,10 +15,11 @@
3.1. Commands to Run SQLite Tests
3.2. Running ZipVFS Tests
3.3. Investigating Source Code Test Failures
4. Extra testrunner.tcl Options
+# 4. Extra testrunner.tcl Options
5. Controlling CPU Core Utilization
# 1. Overview
@@ -26,22 +27,16 @@
testrunner.tcl is a Tcl script used to run multiple SQLite tests using
multiple jobs. It supports the following types of tests:
* Tcl test scripts.
- * Tests run with `make` commands. Examples:
- - `make mdevtest`
- - `make releasetest`
- - `make sdevtest`
- - `make testrunner`
+ * Tests run with [make] commands. Specifically, at time of writing,
+ [make fuzztest], [make mptest], [make sourcetest] and [make threadtest].
testrunner.tcl pipes the output of all tests and builds run into log file
-**testrunner.log**, created in the current working directory. Search this
-file to find details of errors. Suggested search commands:
-
- * `grep "^!" testrunner.log`
- * `grep failed testrunner.log`
+**testrunner.log**, created in the cwd directory. Searching this file for
+"failed" is a good way to find the output of a failed test.
testrunner.tcl also populates SQLite database **testrunner.db**. This database
contains details of all tests run, running and to be run. A useful query
might be:
@@ -63,21 +58,21 @@
watch ./testfixture $(TESTDIR)/testrunner.tcl status
```
in another terminal is a good way to keep an eye on a long running test.
-Sometimes testrunner.tcl uses the `testfixture` binary that it is run with
+Sometimes testrunner.tcl uses the [testfixture] binary that it is run with
to run tests (see "Binary Tests" below). Sometimes it builds testfixture and
other binaries in specific configurations to test (see "Source Tests").
# 2. Binary Tests
The commands described in this section all run various combinations of the Tcl
-test scripts using the `testfixture` binary used to run the testrunner.tcl
+test scripts using the [testfixture] binary used to run the testrunner.tcl
script (i.e. they do not invoke the compiler to build new binaries, or the
-`make` command to run tests that are not Tcl scripts). The procedure to run
+[make] command to run tests that are not Tcl scripts). The procedure to run
these tests is therefore:
1. Build the "testfixture" (or "testfixture.exe" for windows) binary using
whatever method seems convenient.
@@ -196,11 +191,11 @@
## 3.1. Commands to Run SQLite Tests
The **mdevtest** command is equivalent to running the veryquick tests and
-the `make fuzztest` target once for each of two --enable-all builds - one
+the [make fuzztest] target once for each of two --enable-all builds - one
with debugging enabled and one without:
```
tclsh $TESTDIR/testrunner.tcl mdevtest
```
@@ -286,11 +281,11 @@
# Create a script that recreates build configuration "Have-Not" on Windows:
tclsh $TESTDIR/testrunner.tcl script Have-Not > make.bat
```
The generated bash or \*.bat file script accepts a single argument - a makefile
-target to build. This may be used either to run a `make` command test directly,
+target to build. This may be used either to run a [make] command test directly,
or else to build a testfixture (or testfixture.exe) binary with which to
run a Tcl test script, as described above.
# 4. Extra testrunner.tcl Options
@@ -313,20 +308,10 @@
```
# Log the shell commmands that make up the mdevtest test.
tclsh $TESTDIR/testrunner.tcl --dryrun mdevtest"
```
-The **--explain** option is similar to --dryrun in that it prevents testrunner.tcl
-from building any binaries or running any tests. The difference is that --explain
-prints on standard output a human-readable summary of all the builds and tests that
-would have been run.
-
-```
- # Show what builds and tests would have been run
- tclsh $TESTDIR/testrunner.tcl --explain mdevtest
-```
-
# 5. Controlling CPU Core Utilization
When running either binary or source code tests, testrunner.tcl reports the
number of jobs it intends to use to stdout. e.g.
@@ -352,5 +337,8 @@
testrunner.log and testrunner.db files:
```
$ ./testfixture $TESTDIR/testrunner.tcl njob $NEW_NUMBER_OF_JOBS
```
+
+
+
Index: ext/misc/cksumvfs.c
==================================================================
--- ext/misc/cksumvfs.c
+++ ext/misc/cksumvfs.c
@@ -444,13 +444,13 @@
** (1) the size indicates that we are dealing with a complete
** database page
** (2) checksum verification is enabled
** (3) we are not in the middle of checkpoint
*/
- if( iAmt>=512 && (iAmt & (iAmt-1))==0 /* (1) */
- && p->verifyCksm /* (2) */
- && !p->inCkpt /* (3) */
+ if( iAmt>=512 /* (1) */
+ && p->verifyCksm /* (2) */
+ && !p->inCkpt /* (3) */
){
u8 cksum[8];
cksmCompute((u8*)zBuf, iAmt-8, cksum);
if( memcmp((u8*)zBuf+iAmt-8, cksum, 8)!=0 ){
sqlite3_log(SQLITE_IOERR_DATA,
Index: ext/rbu/sqlite3rbu.c
==================================================================
--- ext/rbu/sqlite3rbu.c
+++ ext/rbu/sqlite3rbu.c
@@ -197,11 +197,10 @@
#if !defined(SQLITE_AMALGAMATION)
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef sqlite3_int64 i64;
-typedef sqlite3_uint64 u64;
#endif
/*
** These values must match the values defined in wal.c for the equivalent
** locks. These are not magic numbers as they are part of the SQLite file
@@ -884,11 +883,10 @@
pIter->bCleanup = 0;
rc = sqlite3_step(pIter->pTblIter);
if( rc!=SQLITE_ROW ){
rc = resetAndCollectError(pIter->pTblIter, &p->zErrmsg);
pIter->zTbl = 0;
- pIter->zDataTbl = 0;
}else{
pIter->zTbl = (const char*)sqlite3_column_text(pIter->pTblIter, 0);
pIter->zDataTbl = (const char*)sqlite3_column_text(pIter->pTblIter,1);
rc = (pIter->zDataTbl && pIter->zTbl) ? SQLITE_OK : SQLITE_NOMEM;
}
@@ -2979,11 +2977,11 @@
if( p->rc==SQLITE_OK ){
sqlite3_file *pDb = p->pTargetFd->pReal;
u32 volatile *ptr;
p->rc = pDb->pMethods->xShmMap(pDb, 0, 32*1024, 0, (void volatile**)&ptr);
if( p->rc==SQLITE_OK ){
- iRet = (i64)(((u64)ptr[10] << 32) + ptr[11]);
+ iRet = ((i64)ptr[10] << 32) + ptr[11];
}
}
return iRet;
}
Index: ext/wasm/api/sqlite3-opfs-async-proxy.js
==================================================================
--- ext/wasm/api/sqlite3-opfs-async-proxy.js
+++ ext/wasm/api/sqlite3-opfs-async-proxy.js
@@ -49,11 +49,11 @@
versions (approximately) 104-107 are extinct) should change our
usage of those methods to remove the "await".
*/
"use strict";
const wPost = (type,...args)=>postMessage({type, payload:args});
-const installAsyncProxy = function(){
+const installAsyncProxy = function(self){
const toss = function(...args){throw new Error(args.join(' '))};
if(globalThis.window === globalThis){
toss("This code cannot run from the main thread.",
"Load it as a Worker from a separate Worker.");
}else if(!navigator?.storage?.getDirectory){
@@ -561,13 +561,16 @@
mTimeEnd();
wTimeEnd();
return;
}
if( state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN & opfsFlags ){
+ //log("async proxy opfsFlags =",opfsFlags);
try{
await hDir.removeEntry(filenamePart);
- }catch(e){
+ //log("Unlinked",filename,hDir,filenamePart);
+ }
+ catch(e){
/* ignoring */
//warn("Ignoring failed Unlink of",filename,":",e);
}
}
const hFile = await hDir.getFileHandle(filenamePart, {create});
@@ -917,7 +920,7 @@
!globalThis.FileSystemFileHandle ||
!globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle ||
!navigator?.storage?.getDirectory){
wPost('opfs-unavailable',"Missing required OPFS APIs.");
}else{
- installAsyncProxy();
+ installAsyncProxy(self);
}
Index: src/build.c
==================================================================
--- src/build.c
+++ src/build.c
@@ -3004,16 +3004,13 @@
/* Legacy versions of SQLite allowed the use of the magic "rowid" column
** on a view, even though views do not have rowids. The following flag
** setting fixes this problem. But the fix can be disabled by compiling
** with -DSQLITE_ALLOW_ROWID_IN_VIEW in case there are legacy apps that
- ** depend upon the old buggy behavior. The ability can also be toggled
- ** using SQLITE_TESTCTRL_ROWID_IN_VIEW */
-#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
- p->tabFlags |= sqlite3Config.mNoVisibleRowid; /* Optional. Allow by default */
-#else
- p->tabFlags |= TF_NoVisibleRowid; /* Never allow rowid in view */
+ ** depend upon the old buggy behavior. */
+#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
+ p->tabFlags |= TF_NoVisibleRowid;
#endif
sqlite3TwoPartName(pParse, pName1, pName2, &pName);
iDb = sqlite3SchemaToIndex(db, p->pSchema);
sqlite3FixInit(&sFix, pParse, iDb, "view", pName);
Index: src/expr.c
==================================================================
--- src/expr.c
+++ src/expr.c
@@ -216,14 +216,13 @@
if( ExprHasProperty(pExpr, EP_Unlikely) ){
assert( ExprUseXList(pExpr) );
assert( pExpr->x.pList->nExpr>0 );
assert( pExpr->op==TK_FUNCTION );
pExpr = pExpr->x.pList->a[0].pExpr;
- }else if( pExpr->op==TK_COLLATE ){
- pExpr = pExpr->pLeft;
}else{
- break;
+ assert( pExpr->op==TK_COLLATE );
+ pExpr = pExpr->pLeft;
}
}
return pExpr;
}
@@ -1868,11 +1867,10 @@
pNewItem->zAlias = sqlite3DbStrDup(db, pOldItem->zAlias);
pNewItem->fg = pOldItem->fg;
pNewItem->iCursor = pOldItem->iCursor;
pNewItem->addrFillSub = pOldItem->addrFillSub;
pNewItem->regReturn = pOldItem->regReturn;
- pNewItem->regResult = pOldItem->regResult;
if( pNewItem->fg.isIndexedBy ){
pNewItem->u1.zIndexedBy = sqlite3DbStrDup(db, pOldItem->u1.zIndexedBy);
}
pNewItem->u2 = pOldItem->u2;
if( pNewItem->fg.isCte ){
@@ -2345,58 +2343,10 @@
}
}
return pExpr;
}
-/*
-** pExpr is a TK_FUNCTION node. Try to determine whether or not the
-** function is a constant function. A function is constant if all of
-** the following are true:
-**
-** (1) It is a scalar function (not an aggregate or window function)
-** (2) It has either the SQLITE_FUNC_CONSTANT or SQLITE_FUNC_SLOCHNG
-** property.
-** (3) All of its arguments are constants
-**
-** This routine sets pWalker->eCode to 0 if pExpr is not a constant.
-** It makes no changes to pWalker->eCode if pExpr is constant. In
-** every case, it returns WRC_Abort.
-**
-** Called as a service subroutine from exprNodeIsConstant().
-*/
-static SQLITE_NOINLINE int exprNodeIsConstantFunction(
- Walker *pWalker,
- Expr *pExpr
-){
- int n; /* Number of arguments */
- ExprList *pList; /* List of arguments */
- FuncDef *pDef; /* The function */
- sqlite3 *db; /* The database */
-
- assert( pExpr->op==TK_FUNCTION );
- if( ExprHasProperty(pExpr, EP_TokenOnly)
- || (pList = pExpr->x.pList)==0
- ){;
- n = 0;
- }else{
- n = pList->nExpr;
- sqlite3WalkExprList(pWalker, pList);
- if( pWalker->eCode==0 ) return WRC_Abort;
- }
- db = pWalker->pParse->db;
- pDef = sqlite3FindFunction(db, pExpr->u.zToken, n, ENC(db), 0);
- if( pDef==0
- || pDef->xFinalize!=0
- || (pDef->funcFlags & (SQLITE_FUNC_CONSTANT|SQLITE_FUNC_SLOCHNG))==0
- || ExprHasProperty(pExpr, EP_WinFunc)
- ){
- pWalker->eCode = 0;
- return WRC_Abort;
- }
- return WRC_Continue;
-}
-
/*
** These routines are Walker callbacks used to check expressions to
** see if they are "constant" for some definition of constant. The
** Walker.eCode value determines the type of "constant" we are looking
@@ -2421,11 +2371,10 @@
** contain a bound parameter because they were generated by older versions
** of SQLite to be parsed by newer versions of SQLite without raising a
** malformed schema error.
*/
static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
- assert( pWalker->eCode>0 );
/* If pWalker->eCode is 2 then any term of the expression that comes from
** the ON or USING clauses of an outer join disqualifies the expression
** from being considered constant. */
if( pWalker->eCode==2 && ExprHasProperty(pExpr, EP_OuterON) ){
@@ -2441,12 +2390,10 @@
if( (pWalker->eCode>=4 || ExprHasProperty(pExpr,EP_ConstFunc))
&& !ExprHasProperty(pExpr, EP_WinFunc)
){
if( pWalker->eCode==5 ) ExprSetProperty(pExpr, EP_FromDDL);
return WRC_Continue;
- }else if( pWalker->pParse ){
- return exprNodeIsConstantFunction(pWalker, pExpr);
}else{
pWalker->eCode = 0;
return WRC_Abort;
}
case TK_ID:
@@ -2495,14 +2442,13 @@
testcase( pExpr->op==TK_SELECT ); /* sqlite3SelectWalkFail() disallows */
testcase( pExpr->op==TK_EXISTS ); /* sqlite3SelectWalkFail() disallows */
return WRC_Continue;
}
}
-static int exprIsConst(Parse *pParse, Expr *p, int initFlag, int iCur){
+static int exprIsConst(Expr *p, int initFlag, int iCur){
Walker w;
w.eCode = initFlag;
- w.pParse = pParse;
w.xExprCallback = exprNodeIsConstant;
w.xSelectCallback = sqlite3SelectWalkFail;
#ifdef SQLITE_DEBUG
w.xSelectCallback2 = sqlite3SelectWalkAssert2;
#endif
@@ -2516,19 +2462,13 @@
** and 0 if it involves variables or function calls.
**
** For the purposes of this function, a double-quoted string (ex: "abc")
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
-**
-** The pParse parameter may be NULL. But if it is NULL, there is no way
-** to determine if function calls are constant or not, and hence all
-** function calls will be considered to be non-constant. If pParse is
-** not NULL, then a function call might be constant, depending on the
-** function and on its parameters.
*/
-int sqlite3ExprIsConstant(Parse *pParse, Expr *p){
- return exprIsConst(pParse, p, 1, 0);
+int sqlite3ExprIsConstant(Expr *p){
+ return exprIsConst(p, 1, 0);
}
/*
** Walk an expression tree. Return non-zero if
**
@@ -2540,22 +2480,22 @@
**
** When this routine returns true, it indicates that the expression
** can be added to the pParse->pConstExpr list and evaluated once when
** the prepared statement starts up. See sqlite3ExprCodeRunJustOnce().
*/
-static int sqlite3ExprIsConstantNotJoin(Parse *pParse, Expr *p){
- return exprIsConst(pParse, p, 2, 0);
+int sqlite3ExprIsConstantNotJoin(Expr *p){
+ return exprIsConst(p, 2, 0);
}
/*
** Walk an expression tree. Return non-zero if the expression is constant
** for any single row of the table with cursor iCur. In other words, the
** expression must not refer to any non-deterministic function nor any
** table other than iCur.
*/
int sqlite3ExprIsTableConstant(Expr *p, int iCur){
- return exprIsConst(0, p, 3, iCur);
+ return exprIsConst(p, 3, iCur);
}
/*
** Check pExpr to see if it is an constraint on the single data source
** pSrc = &pSrcList->a[iSrc]. In other words, check to see if pExpr
@@ -2708,11 +2648,11 @@
** is considered a variable but a single-quoted string (ex: 'abc') is
** a constant.
*/
int sqlite3ExprIsConstantOrFunction(Expr *p, u8 isInit){
assert( isInit==0 || isInit==1 );
- return exprIsConst(0, p, 4+isInit, 0);
+ return exprIsConst(p, 4+isInit, 0);
}
#ifdef SQLITE_ENABLE_CURSOR_HINTS
/*
** Walk an expression tree. Return 1 if the expression contains a
@@ -2953,17 +2893,17 @@
#ifndef SQLITE_OMIT_SUBQUERY
/*
** The argument is an IN operator with a list (not a subquery) on the
** right-hand side. Return TRUE if that list is constant.
*/
-static int sqlite3InRhsIsConstant(Parse *pParse, Expr *pIn){
+static int sqlite3InRhsIsConstant(Expr *pIn){
Expr *pLHS;
int res;
assert( !ExprHasProperty(pIn, EP_xIsSelect) );
pLHS = pIn->pLeft;
pIn->pLeft = 0;
- res = sqlite3ExprIsConstant(pParse, pIn);
+ res = sqlite3ExprIsConstant(pIn);
pIn->pLeft = pLHS;
return res;
}
#endif
@@ -3228,11 +3168,11 @@
** the IN operator so return IN_INDEX_NOOP.
*/
if( eType==0
&& (inFlags & IN_INDEX_NOOP_OK)
&& ExprUseXList(pX)
- && (!sqlite3InRhsIsConstant(pParse,pX) || pX->x.pList->nExpr<=2)
+ && (!sqlite3InRhsIsConstant(pX) || pX->x.pList->nExpr<=2)
){
pParse->nTab--; /* Back out the allocation of the unused cursor */
iTab = -1; /* Cursor is not allocated */
eType = IN_INDEX_NOOP;
}
@@ -3511,11 +3451,11 @@
/* If the expression is not constant then we will need to
** disable the test that was generated above that makes sure
** this code only executes once. Because for a non-constant
** expression we need to rerun this code each time.
*/
- if( addrOnce && !sqlite3ExprIsConstant(pParse, pE2) ){
+ if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
sqlite3VdbeChangeToNoop(v, addrOnce-1);
sqlite3VdbeChangeToNoop(v, addrOnce);
ExprClearProperty(pExpr, EP_Subrtn);
addrOnce = 0;
}
@@ -4848,13 +4788,11 @@
if( ExprHasProperty(pExpr, EP_WinFunc) ){
return pExpr->y.pWin->regResult;
}
#endif
- if( ConstFactorOk(pParse)
- && sqlite3ExprIsConstantNotJoin(pParse,pExpr)
- ){
+ if( ConstFactorOk(pParse) && sqlite3ExprIsConstantNotJoin(pExpr) ){
/* SQL functions can be expensive. So try to avoid running them
** multiple times if we know they always give the same result */
return sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
}
assert( !ExprHasProperty(pExpr, EP_TokenOnly) );
@@ -4881,11 +4819,11 @@
}else if( pDef->funcFlags & (SQLITE_FUNC_DIRECT|SQLITE_FUNC_UNSAFE) ){
sqlite3ExprFunctionUsable(pParse, pExpr, pDef);
}
for(i=0; ia[i].pExpr) ){
+ if( i<32 && sqlite3ExprIsConstant(pFarg->a[i].pExpr) ){
testcase( i==31 );
constMask |= MASKBIT32(i);
}
if( (pDef->funcFlags & SQLITE_FUNC_NEEDCOLL)!=0 && !pColl ){
pColl = sqlite3ExprCollSeq(pParse, pFarg->a[i].pExpr);
@@ -5348,11 +5286,11 @@
int r2;
pExpr = sqlite3ExprSkipCollateAndLikely(pExpr);
if( ConstFactorOk(pParse)
&& ALWAYS(pExpr!=0)
&& pExpr->op!=TK_REGISTER
- && sqlite3ExprIsConstantNotJoin(pParse, pExpr)
+ && sqlite3ExprIsConstantNotJoin(pExpr)
){
*pReg = 0;
r2 = sqlite3ExprCodeRunJustOnce(pParse, pExpr, -1);
}else{
int r1 = sqlite3GetTempReg(pParse);
@@ -5412,11 +5350,11 @@
** results in register target. The results are guaranteed to appear
** in register target. If the expression is constant, then this routine
** might choose to code the expression at initialization time.
*/
void sqlite3ExprCodeFactorable(Parse *pParse, Expr *pExpr, int target){
- if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pParse,pExpr) ){
+ if( pParse->okConstFactor && sqlite3ExprIsConstantNotJoin(pExpr) ){
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target);
}else{
sqlite3ExprCodeCopy(pParse, pExpr, target);
}
}
@@ -5471,11 +5409,11 @@
n--;
}else{
sqlite3VdbeAddOp2(v, copyOp, j+srcReg-1, target+i);
}
}else if( (flags & SQLITE_ECEL_FACTOR)!=0
- && sqlite3ExprIsConstantNotJoin(pParse,pExpr)
+ && sqlite3ExprIsConstantNotJoin(pExpr)
){
sqlite3ExprCodeRunJustOnce(pParse, pExpr, target+i);
}else{
int inReg = sqlite3ExprCodeTarget(pParse, pExpr, target+i);
if( inReg!=target+i ){
Index: src/global.c
==================================================================
--- src/global.c
+++ src/global.c
@@ -287,13 +287,10 @@
SQLITE_MEMDB_DEFAULT_MAXSIZE, /* mxMemdbSize */
#endif
#ifndef SQLITE_UNTESTABLE
0, /* xTestCallback */
#endif
-#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
- 0, /* mNoVisibleRowid. 0 == allow rowid-in-view */
-#endif
0, /* bLocaltimeFault */
0, /* xAltLocaltime */
0x7ffffffe, /* iOnceResetThreshold */
SQLITE_DEFAULT_SORTERREF_SIZE, /* szSorterRef */
0, /* iPrngSeed */
Index: src/insert.c
==================================================================
--- src/insert.c
+++ src/insert.c
@@ -575,197 +575,10 @@
*/
# define autoIncBegin(A,B,C) (0)
# define autoIncStep(A,B,C)
#endif /* SQLITE_OMIT_AUTOINCREMENT */
-/*
-** If argument pVal is a Select object returned by an sqlite3MultiValues()
-** that was able to use the co-routine optimization, finish coding the
-** co-routine.
-*/
-void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal){
- if( ALWAYS(pVal) && pVal->pSrc->nSrc>0 ){
- SrcItem *pItem = &pVal->pSrc->a[0];
- sqlite3VdbeEndCoroutine(pParse->pVdbe, pItem->regReturn);
- sqlite3VdbeJumpHere(pParse->pVdbe, pItem->addrFillSub - 1);
- }
-}
-
-/*
-** Return true if all expressions in the expression-list passed as the
-** only argument are constant.
-*/
-static int exprListIsConstant(Parse *pParse, ExprList *pRow){
- int ii;
- for(ii=0; iinExpr; ii++){
- if( 0==sqlite3ExprIsConstant(pParse, pRow->a[ii].pExpr) ) return 0;
- }
- return 1;
-}
-
-/*
-** Return true if all expressions in the expression-list passed as the
-** only argument are both constant and have no affinity.
-*/
-static int exprListIsNoAffinity(Parse *pParse, ExprList *pRow){
- int ii;
- if( exprListIsConstant(pParse,pRow)==0 ) return 0;
- for(ii=0; iinExpr; ii++){
- assert( pRow->a[ii].pExpr->affExpr==0 );
- if( 0!=sqlite3ExprAffinity(pRow->a[ii].pExpr) ) return 0;
- }
- return 1;
-
-}
-
-/*
-** This function is called by the parser for the second and subsequent
-** rows of a multi-row VALUES clause. Argument pLeft is the part of
-** the VALUES clause already parsed, argument pRow is the vector of values
-** for the new row. The Select object returned represents the complete
-** VALUES clause, including the new row.
-**
-** There are two ways in which this may be achieved - by incremental
-** coding of a co-routine (the "co-routine" method) or by returning a
-** Select object equivalent to the following (the "UNION ALL" method):
-**
-** "pLeft UNION ALL SELECT pRow"
-**
-** If the VALUES clause contains a lot of rows, this compound Select
-** object may consume a lot of memory.
-**
-** When the co-routine method is used, each row that will be returned
-** by the VALUES clause is coded into part of a co-routine as it is
-** passed to this function. The returned Select object is equivalent to:
-**
-** SELECT * FROM (
-** Select object to read co-routine
-** )
-**
-** The co-routine method is used in most cases. Exceptions are:
-**
-** a) If the current statement has a WITH clause. This is to avoid
-** statements like:
-**
-** WITH cte AS ( VALUES('x'), ('y') ... )
-** SELECT * FROM cte AS a, cte AS b;
-**
-** This will not work, as the co-routine uses a hard-coded register
-** for its OP_Yield instructions, and so it is not possible for two
-** cursors to iterate through it concurrently.
-**
-** b) The schema is currently being parsed (i.e. the VALUES clause is part
-** of a schema item like a VIEW or TRIGGER). In this case there is no VM
-** being generated when parsing is taking place, and so generating
-** a co-routine is not possible.
-**
-** c) There are non-constant expressions in the VALUES clause (e.g.
-** the VALUES clause is part of a correlated sub-query).
-**
-** d) One or more of the values in the first row of the VALUES clause
-** has an affinity (i.e. is a CAST expression). This causes problems
-** because the complex rules SQLite uses (see function
-** sqlite3SubqueryColumnTypes() in select.c) to determine the effective
-** affinity of such a column for all rows require access to all values in
-** the column simultaneously.
-*/
-Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow){
-
- if( pParse->bHasWith /* condition (a) above */
- || pParse->db->init.busy /* condition (b) above */
- || exprListIsConstant(pParse,pRow)==0 /* condition (c) above */
- || (pLeft->pSrc->nSrc==0 &&
- exprListIsNoAffinity(pParse,pLeft->pEList)==0) /* condition (d) above */
- || IN_SPECIAL_PARSE
- ){
- /* The co-routine method cannot be used. Fall back to UNION ALL. */
- Select *pSelect = 0;
- int f = SF_Values | SF_MultiValue;
- if( pLeft->pSrc->nSrc ){
- sqlite3MultiValuesEnd(pParse, pLeft);
- f = SF_Values;
- }else if( pLeft->pPrior ){
- /* In this case set the SF_MultiValue flag only if it was set on pLeft */
- f = (f & pLeft->selFlags);
- }
- pSelect = sqlite3SelectNew(pParse, pRow, 0, 0, 0, 0, 0, f, 0);
- pLeft->selFlags &= ~SF_MultiValue;
- if( pSelect ){
- pSelect->op = TK_ALL;
- pSelect->pPrior = pLeft;
- pLeft = pSelect;
- }
- }else{
- SrcItem *p = 0; /* SrcItem that reads from co-routine */
-
- if( pLeft->pSrc->nSrc==0 ){
- /* Co-routine has not yet been started and the special Select object
- ** that accesses the co-routine has not yet been created. This block
- ** does both those things. */
- Vdbe *v = sqlite3GetVdbe(pParse);
- Select *pRet = sqlite3SelectNew(pParse, 0, 0, 0, 0, 0, 0, 0, 0);
-
- /* Ensure the database schema has been read. This is to ensure we have
- ** the correct text encoding. */
- if( (pParse->db->mDbFlags & DBFLAG_SchemaKnownOk)==0 ){
- sqlite3ReadSchema(pParse);
- }
-
- if( pRet ){
- SelectDest dest;
- pRet->pSrc->nSrc = 1;
- pRet->pPrior = pLeft->pPrior;
- pRet->op = pLeft->op;
- pLeft->pPrior = 0;
- pLeft->op = TK_SELECT;
- assert( pLeft->pNext==0 );
- assert( pRet->pNext==0 );
- p = &pRet->pSrc->a[0];
- p->pSelect = pLeft;
- p->fg.viaCoroutine = 1;
- p->addrFillSub = sqlite3VdbeCurrentAddr(v) + 1;
- p->regReturn = ++pParse->nMem;
- p->iCursor = -1;
- p->u1.nRow = 2;
- sqlite3VdbeAddOp3(v,OP_InitCoroutine,p->regReturn,0,p->addrFillSub);
- sqlite3SelectDestInit(&dest, SRT_Coroutine, p->regReturn);
-
- /* Allocate registers for the output of the co-routine. Do so so
- ** that there are two unused registers immediately before those
- ** used by the co-routine. This allows the code in sqlite3Insert()
- ** to use these registers directly, instead of copying the output
- ** of the co-routine to a separate array for processing. */
- dest.iSdst = pParse->nMem + 3;
- dest.nSdst = pLeft->pEList->nExpr;
- pParse->nMem += 2 + dest.nSdst;
-
- pLeft->selFlags |= SF_MultiValue;
- sqlite3Select(pParse, pLeft, &dest);
- p->regResult = dest.iSdst;
- assert( pParse->nErr || dest.iSdst>0 );
- pLeft = pRet;
- }
- }else{
- p = &pLeft->pSrc->a[0];
- assert( !p->fg.isTabFunc && !p->fg.isIndexedBy );
- p->u1.nRow++;
- }
-
- if( pParse->nErr==0 ){
- assert( p!=0 );
- if( p->pSelect->pEList->nExpr!=pRow->nExpr ){
- sqlite3SelectWrongNumTermsError(pParse, p->pSelect);
- }else{
- sqlite3ExprCodeExprList(pParse, pRow, p->regResult, 0, 0);
- sqlite3VdbeAddOp1(pParse->pVdbe, OP_Yield, p->regReturn);
- }
- }
- sqlite3ExprListDelete(pParse->db, pRow);
- }
-
- return pLeft;
-}
/* Forward declaration */
static int xferOptimization(
Parse *pParse, /* Parser context */
Table *pDest, /* The table we are inserting into */
@@ -1098,44 +911,29 @@
** co-routine is the common header to the 3rd and 4th templates.
*/
if( pSelect ){
/* Data is coming from a SELECT or from a multi-row VALUES clause.
** Generate a co-routine to run the SELECT. */
+ int regYield; /* Register holding co-routine entry-point */
+ int addrTop; /* Top of the co-routine */
int rc; /* Result code */
- if( pSelect->pSrc->nSrc==1
- && pSelect->pSrc->a[0].fg.viaCoroutine
- && pSelect->pPrior==0
- ){
- SrcItem *pItem = &pSelect->pSrc->a[0];
- dest.iSDParm = pItem->regReturn;
- regFromSelect = pItem->regResult;
- nColumn = pItem->pSelect->pEList->nExpr;
- ExplainQueryPlan((pParse, 0, "SCAN %S", pItem));
- if( bIdListInOrder && nColumn==pTab->nCol ){
- regData = regFromSelect;
- regRowid = regData - 1;
- regIns = regRowid - (IsVirtual(pTab) ? 1 : 0);
- }
- }else{
- int addrTop; /* Top of the co-routine */
- int regYield = ++pParse->nMem;
- addrTop = sqlite3VdbeCurrentAddr(v) + 1;
- sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
- sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
- dest.iSdst = bIdListInOrder ? regData : 0;
- dest.nSdst = pTab->nCol;
- rc = sqlite3Select(pParse, pSelect, &dest);
- regFromSelect = dest.iSdst;
- assert( db->pParse==pParse );
- if( rc || pParse->nErr ) goto insert_cleanup;
- assert( db->mallocFailed==0 );
- sqlite3VdbeEndCoroutine(v, regYield);
- sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
- assert( pSelect->pEList );
- nColumn = pSelect->pEList->nExpr;
- }
+ regYield = ++pParse->nMem;
+ addrTop = sqlite3VdbeCurrentAddr(v) + 1;
+ sqlite3VdbeAddOp3(v, OP_InitCoroutine, regYield, 0, addrTop);
+ sqlite3SelectDestInit(&dest, SRT_Coroutine, regYield);
+ dest.iSdst = bIdListInOrder ? regData : 0;
+ dest.nSdst = pTab->nCol;
+ rc = sqlite3Select(pParse, pSelect, &dest);
+ regFromSelect = dest.iSdst;
+ assert( db->pParse==pParse );
+ if( rc || pParse->nErr ) goto insert_cleanup;
+ assert( db->mallocFailed==0 );
+ sqlite3VdbeEndCoroutine(v, regYield);
+ sqlite3VdbeJumpHere(v, addrTop - 1); /* label B: */
+ assert( pSelect->pEList );
+ nColumn = pSelect->pEList->nExpr;
/* Set useTempTable to TRUE if the result of the SELECT statement
** should be written into a temporary table (template 4). Set to
** FALSE if each output row of the SELECT can be written directly into
** the destination table (template 3).
Index: src/main.c
==================================================================
--- src/main.c
+++ src/main.c
@@ -4400,43 +4400,10 @@
typedef int(*sqlite3LocaltimeType)(const void*,void*);
sqlite3GlobalConfig.xAltLocaltime = va_arg(ap, sqlite3LocaltimeType);
}else{
sqlite3GlobalConfig.xAltLocaltime = 0;
}
- break;
- }
-
- /* sqlite3_test_control(SQLITE_TESTCTRL_ROWID_IN_VIEW, int *pVal);
- **
- ** Query or set the sqlite3Config.mNoVisibleRowid flag. Cases:
- **
- ** *pVal==1 Allow ROWID in VIEWs
- ** *pVal==0 Disallow ROWID in VIEWs
- ** *pVal<0 No change
- **
- ** In every case *pVal is written with 1 if ROWID is allowd in VIEWs and
- ** 0 if not. Changes to the setting only occur if SQLite is compiled
- ** with -DSQLITE_ALLOW_ROWID_IN_VIEW (hereafter: "SARIV"). With the
- ** "SARIV" compile-time option the default value for this setting is 1.
- ** Otherwise this setting defaults to 0. This setting may only be changed
- ** if SQLite is compiled with "SARIV". Hence, in the normal case when
- ** SQLite is compiled without "SARIV", this test-control is a no-op
- ** that always leaves *pVal set to 0.
- **
- ** IMPORTANT: If you change this setting while a database connection
- ** is option, it is very important to run "PRAGMA writable_schema=RESET"
- ** afterwards in order to reparse all VIEW definitions in the schema.
- */
- case SQLITE_TESTCTRL_ROWID_IN_VIEW: {
- int *pVal = va_arg(ap, int*);
-#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
- if( *pVal==0 ) sqlite3Config.mNoVisibleRowid = TF_NoVisibleRowid;
- if( *pVal==1 ) sqlite3Config.mNoVisibleRowid = 0;
- *pVal = (sqlite3Config.mNoVisibleRowid==0);
-#else
- *pVal = 0;
-#endif
break;
}
/* sqlite3_test_control(SQLITE_TESTCTRL_INTERNAL_FUNCTIONS, sqlite3*);
**
Index: src/parse.y
==================================================================
--- src/parse.y
+++ src/parse.y
@@ -563,11 +563,10 @@
%ifndef SQLITE_OMIT_CTE
select(A) ::= WITH wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);}
select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X).
{A = attachWithToSelect(pParse,X,W);}
-
%endif /* SQLITE_OMIT_CTE */
select(A) ::= selectnowith(A). {
Select *p = A;
if( p ){
parserDoubleLinkSelect(pParse, p);
@@ -621,31 +620,28 @@
}
}
%endif
-// Single row VALUES clause.
-//
-%type values {Select*}
oneselect(A) ::= values(A).
+
+%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);
}
-
-// Multiple row VALUES clause.
-//
-%type mvalues {Select*}
-oneselect(A) ::= mvalues(A). {
- sqlite3MultiValuesEnd(pParse, A);
-}
-%destructor mvalues {sqlite3SelectDelete(pParse->db, $$);}
-mvalues(A) ::= values(A) COMMA LP nexprlist(Y) RP. {
- A = sqlite3MultiValues(pParse, A, Y);
-}
-mvalues(A) ::= mvalues(A) COMMA LP nexprlist(Y) RP. {
- A = sqlite3MultiValues(pParse, A, Y);
+values(A) ::= values(A) COMMA LP nexprlist(Y) RP. {
+ Select *pRight, *pLeft = A;
+ pRight = sqlite3SelectNew(pParse,Y,0,0,0,0,0,SF_Values|SF_MultiValue,0);
+ if( ALWAYS(pLeft) ) pLeft->selFlags &= ~SF_MultiValue;
+ if( pRight ){
+ pRight->op = TK_ALL;
+ pRight->pPrior = pLeft;
+ A = pRight;
+ }else{
+ A = pLeft;
+ }
}
// The "distinct" nonterminal is true (1) if the DISTINCT keyword is
// present and false (0) if it is not.
//
@@ -1323,11 +1319,11 @@
sqlite3ExprUnmapAndDelete(pParse, A);
A = sqlite3Expr(pParse->db, TK_STRING, N ? "true" : "false");
if( A ) sqlite3ExprIdToTrueFalse(A);
}else{
Expr *pRHS = Y->a[0].pExpr;
- if( Y->nExpr==1 && sqlite3ExprIsConstant(pParse,pRHS) && A->op!=TK_VECTOR ){
+ if( Y->nExpr==1 && sqlite3ExprIsConstant(pRHS) && A->op!=TK_VECTOR ){
Y->a[0].pExpr = 0;
sqlite3ExprListDelete(pParse->db, Y);
pRHS = sqlite3PExpr(pParse, TK_UPLUS, pRHS, 0);
A = sqlite3PExpr(pParse, TK_EQ, A, pRHS);
}else if( Y->nExpr==1 && pRHS->op==TK_SELECT ){
@@ -1763,14 +1759,13 @@
%type wqas {u8}
wqas(A) ::= AS. {A = M10d_Any;}
wqas(A) ::= AS MATERIALIZED. {A = M10d_Yes;}
wqas(A) ::= AS NOT MATERIALIZED. {A = M10d_No;}
-wqitem(A) ::= withnm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. {
+wqitem(A) ::= nm(X) eidlist_opt(Y) wqas(M) LP select(Z) RP. {
A = sqlite3CteNew(pParse, &X, Y, Z, M); /*A-overwrites-X*/
}
-withnm(A) ::= nm(A). {pParse->bHasWith = 1;}
wqlist(A) ::= wqitem(X). {
A = sqlite3WithAdd(pParse, 0, X); /*A-overwrites-X*/
}
wqlist(A) ::= wqlist(A) COMMA wqitem(X). {
A = sqlite3WithAdd(pParse, A, X);
Index: src/printf.c
==================================================================
--- src/printf.c
+++ src/printf.c
@@ -858,14 +858,10 @@
}else{
Select *pSel = pItem->pSelect;
assert( pSel!=0 );
if( pSel->selFlags & SF_NestedFrom ){
sqlite3_str_appendf(pAccum, "(join-%u)", pSel->selId);
- }else if( pSel->selFlags & SF_MultiValue ){
- assert( !pItem->fg.isTabFunc && !pItem->fg.isIndexedBy );
- sqlite3_str_appendf(pAccum, "%u-ROW VALUES CLAUSE",
- pItem->u1.nRow);
}else{
sqlite3_str_appendf(pAccum, "(subquery-%u)", pSel->selId);
}
}
length = width = 0;
Index: src/select.c
==================================================================
--- src/select.c
+++ src/select.c
@@ -1951,11 +1951,15 @@
/* The "table" is actually a sub-select or a view in the FROM clause
** of the SELECT statement. Return the declaration type and origin
** data for the result-set column of the sub-select.
*/
if( iColpEList->nExpr
- && (!ViewCanHaveRowid || iCol>=0)
+#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
+ && iCol>=0
+#else
+ && ALWAYS(iCol>=0)
+#endif
){
/* If iCol is less than zero, then the expression requests the
** rowid of the sub-select or view. This expression is legal (see
** test case misc2.2.2) - it always evaluates to NULL.
*/
@@ -4770,11 +4774,11 @@
Expr *pValue, /* The VALUE part of the constraint */
Expr *pExpr /* Overall expression: COLUMN=VALUE or VALUE=COLUMN */
){
int i;
assert( pColumn->op==TK_COLUMN );
- assert( sqlite3ExprIsConstant(pConst->pParse, pValue) );
+ assert( sqlite3ExprIsConstant(pValue) );
if( ExprHasProperty(pColumn, EP_FixedCol) ) return;
if( sqlite3ExprAffinity(pValue)!=0 ) return;
if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pConst->pParse,pExpr)) ){
return;
@@ -4828,14 +4832,14 @@
if( pExpr->op!=TK_EQ ) return;
pRight = pExpr->pRight;
pLeft = pExpr->pLeft;
assert( pRight!=0 );
assert( pLeft!=0 );
- if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pLeft) ){
+ if( pRight->op==TK_COLUMN && sqlite3ExprIsConstant(pLeft) ){
constInsert(pConst,pRight,pLeft,pExpr);
}
- if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pConst->pParse, pRight) ){
+ if( pLeft->op==TK_COLUMN && sqlite3ExprIsConstant(pRight) ){
constInsert(pConst,pLeft,pRight,pExpr);
}
}
/*
@@ -5868,12 +5872,11 @@
pTab->nRowLogEst = 200; assert( 200==sqlite3LogEst(1048576) );
#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
/* The usual case - do not allow ROWID on a subquery */
pTab->tabFlags |= TF_Ephemeral | TF_NoVisibleRowid;
#else
- /* Legacy compatibility mode */
- pTab->tabFlags |= TF_Ephemeral | sqlite3Config.mNoVisibleRowid;
+ pTab->tabFlags |= TF_Ephemeral; /* Legacy compatibility mode */
#endif
return pParse->nErr ? SQLITE_ERROR : SQLITE_OK;
}
@@ -6137,11 +6140,11 @@
if( pFrom->fg.isNestedFrom ){
assert( pFrom->pSelect!=0 );
pNestedFrom = pFrom->pSelect->pEList;
assert( pNestedFrom!=0 );
assert( pNestedFrom->nExpr==pTab->nCol );
- assert( VisibleRowid(pTab)==0 || ViewCanHaveRowid );
+ assert( VisibleRowid(pTab)==0 );
}else{
if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
continue;
}
pNestedFrom = 0;
@@ -6169,17 +6172,11 @@
}
}else{
pUsing = 0;
}
- nAdd = pTab->nCol;
- if( VisibleRowid(pTab)
- && !ViewCanHaveRowid
- && (selFlags & SF_NestedFrom)!=0
- ){
- nAdd++;
- }
+ nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom));
for(j=0; jnCol ){
@@ -7637,11 +7634,11 @@
#if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
/* Generate code for all sub-queries in the FROM clause
*/
pSub = pItem->pSelect;
- if( pSub==0 || pItem->addrFillSub!=0 ) continue;
+ if( pSub==0 ) continue;
/* The code for a subquery should only be generated once. */
assert( pItem->addrFillSub==0 );
/* Increment Parse.nHeight by the height of the largest expression
Index: src/shell.c.in
==================================================================
--- src/shell.c.in
+++ src/shell.c.in
@@ -10891,11 +10891,10 @@
#endif
{"pending_byte", SQLITE_TESTCTRL_PENDING_BYTE,0, "OFFSET " },
{"prng_restore", SQLITE_TESTCTRL_PRNG_RESTORE,0, "" },
{"prng_save", SQLITE_TESTCTRL_PRNG_SAVE, 0, "" },
{"prng_seed", SQLITE_TESTCTRL_PRNG_SEED, 0, "SEED ?db?" },
- {"rowid_in_view", SQLITE_TESTCTRL_ROWID_IN_VIEW,0,"?BOOLEAN?" },
{"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" },
{"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" },
{"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" },
{"uselongdouble", SQLITE_TESTCTRL_USELONGDOUBLE,0,"?BOOLEAN|\"default\"?"},
};
@@ -11066,24 +11065,10 @@
isOk = 3;
}
break;
}
#endif
- case SQLITE_TESTCTRL_ROWID_IN_VIEW: {
- rc2 = -1;
- if( nArg>=3 ){
- if( !ShellHasFlag(p,SHFLG_TestingMode) ){
- eputz("The --unsafe-testing option is required to change "
- "this setting\n");
- }else{
- rc2 = booleanValue(azArg[2]);
- }
- }
- sqlite3_test_control(testctrl, &rc2);
- isOk = 1;
- break;
- }
#ifdef SQLITE_DEBUG
case SQLITE_TESTCTRL_TUNE: {
if( nArg==4 ){
int id = (int)integerValue(azArg[2]);
int val = (int)integerValue(azArg[3]);
Index: src/sqlite.h.in
==================================================================
--- src/sqlite.h.in
+++ src/sqlite.h.in
@@ -8305,11 +8305,10 @@
#define SQLITE_TESTCTRL_ALWAYS 13
#define SQLITE_TESTCTRL_RESERVE 14 /* NOT USED */
#define SQLITE_TESTCTRL_JSON_SELFCHECK 14
#define SQLITE_TESTCTRL_OPTIMIZATIONS 15
#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */
-#define SQLITE_TESTCTRL_ROWID_IN_VIEW 16
#define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */
#define SQLITE_TESTCTRL_INTERNAL_FUNCTIONS 17
#define SQLITE_TESTCTRL_LOCALTIME_FAULT 18
#define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */
#define SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD 19
Index: src/sqliteInt.h
==================================================================
--- src/sqliteInt.h
+++ src/sqliteInt.h
@@ -2533,19 +2533,10 @@
/* Does the table have a rowid */
#define HasRowid(X) (((X)->tabFlags & TF_WithoutRowid)==0)
#define VisibleRowid(X) (((X)->tabFlags & TF_NoVisibleRowid)==0)
-/* Macro is true if the SQLITE_ALLOW_ROWID_IN_VIEW (mis-)feature is
-** available. By default, this macro is false
-*/
-#ifndef SQLITE_ALLOW_ROWID_IN_VIEW
-# define ViewCanHaveRowid 0
-#else
-# define ViewCanHaveRowid (sqlite3Config.mNoVisibleRowid==0)
-#endif
-
/*
** Each foreign key constraint is an instance of the following structure.
**
** A foreign key is associated with two tables. The "from" table is
** the table that contains the REFERENCES clause that creates the foreign
@@ -3277,16 +3268,14 @@
** In the colUsed field, the high-order bit (bit 63) is set if the table
** contains more than 63 columns and the 64-th or later column is used.
**
** Union member validity:
**
-** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
-** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
-** u1.nRow !fg.isTabFunc && !fg.isIndexedBy
-**
-** u2.pIBIndex fg.isIndexedBy && !fg.isCte
-** u2.pCteUse fg.isCte && !fg.isIndexedBy
+** u1.zIndexedBy fg.isIndexedBy && !fg.isTabFunc
+** u1.pFuncArg fg.isTabFunc && !fg.isIndexedBy
+** u2.pIBIndex fg.isIndexedBy && !fg.isCte
+** u2.pCteUse fg.isCte && !fg.isIndexedBy
*/
struct SrcItem {
Schema *pSchema; /* Schema to which this item is fixed */
char *zDatabase; /* Name of database holding this table */
char *zName; /* Name of the table */
@@ -3320,11 +3309,10 @@
} u3;
Bitmask colUsed; /* Bit N set if column N used. Details above for N>62 */
union {
char *zIndexedBy; /* Identifier from "INDEXED BY " clause */
ExprList *pFuncArg; /* Arguments to table-valued-function */
- u32 nRow; /* Number of rows in a VALUES clause */
} u1;
union {
Index *pIBIndex; /* Index structure corresponding to u1.zIndexedBy */
CteUse *pCteUse; /* CTE Usage info when fg.isCte is true */
} u2;
@@ -3822,11 +3810,10 @@
u8 hasCompound; /* Need to invoke convertCompoundSelectToSubquery() */
u8 okConstFactor; /* OK to factor out constants */
u8 disableLookaside; /* Number of times lookaside has been disabled */
u8 prepFlags; /* SQLITE_PREPARE_* flags */
u8 withinRJSubrtn; /* Nesting level for RIGHT JOIN body subroutines */
- u8 bHasWith; /* True if statement contains WITH */
#if defined(SQLITE_DEBUG) || defined(SQLITE_COVERAGE_TEST)
u8 earlyCleanup; /* OOM inside sqlite3ParserAddCleanup() */
#endif
#ifdef SQLITE_DEBUG
u8 ifNotExists; /* Might be true if IF NOT EXISTS. Assert()s only */
@@ -4261,15 +4248,10 @@
sqlite3_int64 mxMemdbSize; /* Default max memdb size */
#endif
#ifndef SQLITE_UNTESTABLE
int (*xTestCallback)(int); /* Invoked by sqlite3FaultSim() */
#endif
-#ifdef SQLITE_ALLOW_ROWID_IN_VIEW
- u32 mNoVisibleRowid; /* TF_NoVisibleRowid if the ROWID_IN_VIEW
- ** feature is disabled. 0 if rowids can
- ** occur in views. */
-#endif
int bLocaltimeFault; /* True to fail localtime() calls */
int (*xAltLocaltime)(const void*,void*); /* Alternative localtime() routine */
int iOnceResetThreshold; /* When to reset OP_Once counters */
u32 szSorterRef; /* Min size in bytes to use sorter-refs */
unsigned int iPrngSeed; /* Alternative fixed seed for the PRNG */
@@ -4502,13 +4484,10 @@
int regEndRowid;
u8 bExprArgs; /* Defer evaluation of window function arguments
** due to the SQLITE_SUBTYPE flag */
};
-Select *sqlite3MultiValues(Parse *pParse, Select *pLeft, ExprList *pRow);
-void sqlite3MultiValuesEnd(Parse *pParse, Select *pVal);
-
#ifndef SQLITE_OMIT_WINDOWFUNC
void sqlite3WindowDelete(sqlite3*, Window*);
void sqlite3WindowUnlinkFromSelect(Window*);
void sqlite3WindowListDelete(sqlite3 *db, Window *p);
Window *sqlite3WindowAlloc(Parse*, int, int, Expr*, int , Expr*, u8);
@@ -5073,11 +5052,12 @@
void sqlite3CloseSavepoints(sqlite3 *);
void sqlite3LeaveMutexAndCloseZombie(sqlite3*);
u32 sqlite3IsTrueOrFalse(const char*);
int sqlite3ExprIdToTrueFalse(Expr*);
int sqlite3ExprTruthValue(const Expr*);
-int sqlite3ExprIsConstant(Parse*,Expr*);
+int sqlite3ExprIsConstant(Expr*);
+int sqlite3ExprIsConstantNotJoin(Expr*);
int sqlite3ExprIsConstantOrFunction(Expr*, u8);
int sqlite3ExprIsConstantOrGroupBy(Parse*, Expr*, ExprList*);
int sqlite3ExprIsTableConstant(Expr*,int);
int sqlite3ExprIsSingleTableConstraint(Expr*,const SrcList*,int);
#ifdef SQLITE_ENABLE_CURSOR_HINTS
Index: src/where.c
==================================================================
--- src/where.c
+++ src/where.c
@@ -1327,11 +1327,11 @@
for(i=0; ia[i].pExpr;
Expr *pE2;
/* Skip over constant terms in the ORDER BY clause */
- if( sqlite3ExprIsConstant(0, pExpr) ){
+ if( sqlite3ExprIsConstant(pExpr) ){
continue;
}
/* Virtual tables are unable to deal with NULLS FIRST */
if( pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_BIGNULL ) break;
@@ -1439,11 +1439,11 @@
}
assert( j==nTerm );
pIdxInfo->nConstraint = j;
for(i=j=0; ia[i].pExpr;
- if( sqlite3ExprIsConstant(0, pExpr) ) continue;
+ if( sqlite3ExprIsConstant(pExpr) ) continue;
assert( pExpr->op==TK_COLUMN
|| (pExpr->op==TK_COLLATE && pExpr->pLeft->op==TK_COLUMN
&& pExpr->iColumn==pExpr->pLeft->iColumn) );
pIdxOrderBy[j].iColumn = pExpr->iColumn;
pIdxOrderBy[j].desc = pOrderBy->a[i].fg.sortFlags & KEYINFO_ORDER_DESC;
@@ -3621,11 +3621,11 @@
Expr *pLeft = pPart->pLeft;
Expr *pRight = pPart->pRight;
u8 aff;
if( pLeft->op!=TK_COLUMN ) return;
- if( !sqlite3ExprIsConstant(0, pRight) ) return;
+ if( !sqlite3ExprIsConstant(pRight) ) return;
if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return;
if( pLeft->iColumn<0 ) return;
aff = pIdx->pTable->aCol[pLeft->iColumn].affinity;
if( aff>=SQLITE_AFF_TEXT ){
if( pItem ){
@@ -4995,11 +4995,11 @@
Expr *p;
Bitmask mTerm;
if( MASKBIT(i) & obSat ) continue;
p = pOrderBy->a[i].pExpr;
mTerm = sqlite3WhereExprUsage(&pWInfo->sMaskSet,p);
- if( mTerm==0 && !sqlite3ExprIsConstant(0,p) ) continue;
+ if( mTerm==0 && !sqlite3ExprIsConstant(p) ) continue;
if( (mTerm&~orderDistinctMask)==0 ){
obSat |= MASKBIT(i);
}
}
}
@@ -5864,11 +5864,11 @@
pExpr = sqlite3ColumnExpr(pTab, &pTab->aCol[j]);
bMaybeNullRow = 0;
}else{
continue;
}
- if( sqlite3ExprIsConstant(0,pExpr) ) continue;
+ if( sqlite3ExprIsConstant(pExpr) ) continue;
if( pExpr->op==TK_FUNCTION ){
/* Functions that might set a subtype should not be replaced by the
** value taken from an expression index since the index omits the
** subtype. https://sqlite.org/forum/forumpost/68d284c86b082c3e */
int n;
@@ -6142,15 +6142,11 @@
if( (wctrlFlags & WHERE_WANT_DISTINCT)!=0
&& OptimizationEnabled(db, SQLITE_DistinctOpt)
){
pWInfo->eDistinct = WHERE_DISTINCT_UNIQUE;
}
- if( ALWAYS(pWInfo->pSelect)
- && (pWInfo->pSelect->selFlags & SF_MultiValue)==0
- ){
- ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
- }
+ ExplainQueryPlan((pParse, 0, "SCAN CONSTANT ROW"));
}else{
/* Assign a bit from the bitmask to every term in the FROM clause.
**
** The N-th term of the FROM clause is assigned a bitmask of 1<fg.viaCoroutine ){
testcase( pParse->db->mallocFailed );
- assert( pTabItem->regResult>=0 );
translateColumnToCopy(pParse, pLevel->addrBody, pLevel->iTabCur,
pTabItem->regResult, 0);
continue;
}
Index: src/whereexpr.c
==================================================================
--- src/whereexpr.c
+++ src/whereexpr.c
@@ -987,11 +987,11 @@
if( pIdx->aColExpr==0 ) continue;
for(i=0; inKeyCol; i++){
if( pIdx->aiColumn[i]!=XN_EXPR ) continue;
assert( pIdx->bHasExpr );
if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0
- && !sqlite3ExprIsConstant(0,pIdx->aColExpr->a[i].pExpr)
+ && !sqlite3ExprIsConstant(pIdx->aColExpr->a[i].pExpr)
){
aiCurCol[0] = iCur;
aiCurCol[1] = XN_EXPR;
return 1;
}
Index: src/window.c
==================================================================
--- src/window.c
+++ src/window.c
@@ -1162,11 +1162,11 @@
** constant, change it to NULL. The fact that it is then a non-negative
** integer will be caught later. But it is important not to leave
** variable values in the expression tree.
*/
static Expr *sqlite3WindowOffsetExpr(Parse *pParse, Expr *pExpr){
- if( 0==sqlite3ExprIsConstant(0,pExpr) ){
+ if( 0==sqlite3ExprIsConstant(pExpr) ){
if( IN_RENAME_OBJECT ) sqlite3RenameExprUnmap(pParse, pExpr);
sqlite3ExprDelete(pParse->db, pExpr);
pExpr = sqlite3ExprAlloc(pParse->db, TK_NULL, 0, 0);
}
return pExpr;
Index: test/altertab3.test
==================================================================
--- test/altertab3.test
+++ test/altertab3.test
@@ -734,33 +734,6 @@
SELECT "t3".* FROM "t3"
);
END}
}
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 30.0 {
- CREATE TABLE t1(a, b);
- CREATE VIEW v1 AS
- SELECT ( VALUES(a), (b) ) FROM (
- SELECT a, b FROM t1
- )
- ;
-}
-
-do_execsql_test 30.1 {
- SELECT * FROM v1
-}
-
-do_execsql_test 30.1 {
- ALTER TABLE t1 RENAME TO t2;
-}
-do_execsql_test 30.2 {
- SELECT sql FROM sqlite_schema WHERE type='view'
-} {
- {CREATE VIEW v1 AS
- SELECT ( VALUES(a), (b) ) FROM (
- SELECT a, b FROM "t2"
- )}
-}
-
finish_test
DELETED test/cksumvfs.test
Index: test/cksumvfs.test
==================================================================
--- test/cksumvfs.test
+++ /dev/null
@@ -1,33 +0,0 @@
-# 2024 March 19
-#
-# The author disclaims copyright to this source code. In place of
-# a legal notice, here is a blessing:
-#
-# May you do good and not evil.
-# May you find forgiveness for yourself and forgive others.
-# May you share freely, never taking more than you give.
-#
-#***********************************************************************
-#
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-set testprefix cksumvfs
-
-sqlite3_register_cksumvfs
-db close
-sqlite3 db test.db
-file_control_reservebytes db 8
-
-set text [db one "SELECT hex(randomblob(5000))"]
-
-do_execsql_test 1.0 {
- CREATE TABLE t1(a INTEGER PRIMARY KEY, b);
- INSERT INTO t1 VALUES(1, $text);
-}
-
-do_execsql_test 1.1 {
- SELECT * FROM t1;
-} [list 1 $text]
-
-finish_test
Index: test/func4.test
==================================================================
--- test/func4.test
+++ test/func4.test
@@ -1,6 +1,6 @@
-# 2023-03-10
+# 2013 March 10
#
# 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.
@@ -7,14 +7,11 @@
# May you find forgiveness for yourself and forgive others.
# May you share freely, never taking more than you give.
#
#***********************************************************************
# This file implements regression tests for SQLite library. The focus of
-# this file is testing the tointeger() and toreal() functions that are
-# part of the "totype.c" extension. This file does not test the core
-# SQLite library. Failures of tests in this file are related to the
-# ext/misc/totype.c extension.
+# this file is testing the tointeger() and toreal() functions.
#
# Several of the toreal() tests are disabled on platforms where floating
# point precision is not high enough to represent their constant integer
# expression arguments as double precision floating point values.
#
@@ -24,24 +21,10 @@
set tcl_precision 0
load_static_extension db totype
set highPrecision(1) [expr \
{[db eval {SELECT tointeger(9223372036854775807 + 1);}] eq {{}}}]
-set highPrecision(2) [expr \
- {[db eval {SELECT toreal(-9223372036854775808 + 1);}] eq {{}}}]
-
-# highPrecision(3) is only known to be false on i586 with gcc-13 and -O2.
-# It is true on the exact same platform with -O0. Both results seem
-# reasonable, so we'll just very the expectation accordingly.
-#
-set highPrecision(3) [expr \
- {[db eval {SELECT toreal(9007199254740992 + 1);}] eq {{}}}]
-
-if {!$highPrecision(1) || !$highPrecision(2) || !$highPrecision(3)} {
- puts "NOTICE: use_long_double: [use_long_double] \
- highPrecision: $highPrecision(1) $highPrecision(2) $highPrecision(3)"
-}
do_execsql_test func4-1.1 {
SELECT tointeger(NULL);
} {{}}
do_execsql_test func4-1.2 {
@@ -210,10 +193,12 @@
do_execsql_test func4-1.55 {
SELECT tointeger(18446744073709551616 + 1);
} {{}}
ifcapable floatingpoint {
+ set highPrecision(2) [expr \
+ {[db eval {SELECT toreal(-9223372036854775808 + 1);}] eq {{}}}]
do_execsql_test func4-2.1 {
SELECT toreal(NULL);
} {{}}
do_execsql_test func4-2.2 {
@@ -354,18 +339,14 @@
SELECT toreal(9007199254740992 - 1);
} {9007199254740991.0}
do_execsql_test func4-2.45 {
SELECT toreal(9007199254740992);
} {9007199254740992.0}
- if {$highPrecision(3)} {
+ if {$highPrecision(2)} {
do_execsql_test func4-2.46 {
SELECT toreal(9007199254740992 + 1);
} {{}}
- } else {
- do_execsql_test func4-2.46 {
- SELECT toreal(9007199254740992 + 1);
- } {9007199254740992.0}
}
do_execsql_test func4-2.47 {
SELECT toreal(9007199254740992 + 2);
} {9007199254740994.0}
do_execsql_test func4-2.48 {
@@ -643,18 +624,14 @@
SELECT tointeger(toreal(9007199254740992 - 1));
} {9007199254740991}
do_execsql_test func4-5.22 {
SELECT tointeger(toreal(9007199254740992));
} {9007199254740992}
- if {$highPrecision(3)} {
+ if {$highPrecision(2)} {
do_execsql_test func4-5.23 {
SELECT tointeger(toreal(9007199254740992 + 1));
} {{}}
- } else {
- do_execsql_test func4-5.23 {
- SELECT tointeger(toreal(9007199254740992 + 1));
- } {9007199254740992}
}
do_execsql_test func4-5.24 {
SELECT tointeger(toreal(9007199254740992 + 2));
} {9007199254740994}
if {$highPrecision(1)} {
Index: test/in4.test
==================================================================
--- test/in4.test
+++ test/in4.test
@@ -456,18 +456,18 @@
ANALYZE sqlite_schema;
} {}
do_execsql_test 11.1 {
SELECT * FROM t1
WHERE b IN (345, (SELECT 1 FROM t1
- WHERE b IN (coalesce(1,random()))
+ WHERE b IN (345 NOT GLOB 510)
AND c GLOB 'abc*xyz'))
AND c BETWEEN 'abc' AND 'xyz';
} {xyz 1 abcdefxyz 99}
do_execsql_test 11.2 {
EXPLAIN SELECT * FROM t1
WHERE b IN (345, (SELECT 1 FROM t1
- WHERE b IN (coalesce(1,random()))
+ WHERE b IN (345 NOT GLOB 510)
AND c GLOB 'abc*xyz'))
AND c BETWEEN 'abc' AND 'xyz';
} {/ SeekScan /}
# 2021-06-25 ticket 6dcbfd11cf666e21
Index: test/sqllimits1.test
==================================================================
--- test/sqllimits1.test
+++ test/sqllimits1.test
@@ -920,11 +920,11 @@
} {0 {}}
do_catchsql_test sqllimits1-18.2 {
INSERT INTO b1 VALUES(1), (2), (3), (4), (5), (6), (7), (8), (9), (10)
UNION VALUES(11);
-} {0 {}}
+} {1 {too many terms in compound SELECT}}
#-------------------------------------------------------------------------
#
reset_db
ifcapable utf16 {
Index: test/testrunner.tcl
==================================================================
--- test/testrunner.tcl
+++ test/testrunner.tcl
@@ -60,29 +60,20 @@
$a0 status
where SWITCHES are:
--buildonly
--dryrun
- --explain
--jobs NUMBER-OF-JOBS
- --stop-on-coredump
- --stop-on-error
--zipvfs ZIPVFS-SOURCE-DIR
-Special values for PERMUTATION that work with plain tclsh:
-
- list - show all allowed PERMUTATION arguments.
- mdevtest - tests recommended prior to normal development check-ins.
- release - full release test with various builds.
- sdevtest - like mdevtest but using ASAN and UBSAN.
-
-Other PERMUTATION arguments must be run using testfixture, not tclsh:
-
+Interesting values for PERMUTATION are:
+
+ veryquick - a fast subset of the tcl test scripts. This is the default.
+ full - all tcl test scripts.
all - all tcl test scripts, plus a subset of test scripts rerun
with various permutations.
- full - all tcl test scripts.
- veryquick - a fast subset of the tcl test scripts. This is the default.
+ release - full release test with various builds.
If no PATTERN arguments are present, all tests specified by the PERMUTATION
are run. Otherwise, each pattern is interpreted as a glob pattern. Only
those tcl tests for which the final component of the filename matches at
least one specified pattern are run.
@@ -102,12 +93,10 @@
of sub-processes the test script uses to run tests.
The "script" command outputs the script used to build a configuration.
Add the "-msvc" option for a Windows-compatible script. For a list of
available configurations enter "$a0 script help".
-
-Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md
}]]
exit 1
}
#-------------------------------------------------------------------------
@@ -141,14 +130,10 @@
}
return $ret
}
proc default_njob {} {
- global env
- if {[info exists env(NJOB)] && $env(NJOB)>=1} {
- return $env(NJOB)
- }
set nCore [guess_number_of_cores]
if {$nCore<=2} {
set nHelper 1
} else {
set nHelper [expr int($nCore*0.5)]
@@ -171,13 +156,10 @@
set TRG(reporttime) 2000
set TRG(fuzztest) 0 ;# is the fuzztest option present.
set TRG(zipvfs) "" ;# -zipvfs option, if any
set TRG(buildonly) 0 ;# True if --buildonly option
set TRG(dryrun) 0 ;# True if --dryrun option
-set TRG(explain) 0 ;# True for the --explain option
-set TRG(stopOnError) 0 ;# Stop running at first failure
-set TRG(stopOnCore) 0 ;# Stop on a core-dump
switch -nocase -glob -- $tcl_platform(os) {
*darwin* {
set TRG(platform) osx
set TRG(make) make.sh
@@ -468,16 +450,10 @@
if {$isLast} { usage }
} elseif {($n>2 && [string match "$a*" --buildonly]) || $a=="-b"} {
set TRG(buildonly) 1
} elseif {($n>2 && [string match "$a*" --dryrun]) || $a=="-d"} {
set TRG(dryrun) 1
- } elseif {($n>2 && [string match "$a*" --explain]) || $a=="-e"} {
- set TRG(explain) 1
- } elseif {[string match "$a*" --stop-on-error]} {
- set TRG(stopOnError) 1
- } elseif {[string match "$a*" --stop-on-coredump]} {
- set TRG(stopOnCore) 1
} else {
usage
}
} else {
lappend TRG(patternlist) [string map {% *} $a]
@@ -856,21 +832,10 @@
}
}
}
-# Check to ensure that the interpreter is a full-blown "testfixture"
-# build and not just a "tclsh". If this is not the case, issue an
-# error message and exit.
-#
-proc must_be_testfixture {} {
- if {[lsearch [info commands] sqlite3_soft_heap_limit]<0} {
- puts "Use testfixture, not tclsh, for these arguments."
- exit 1
- }
-}
-
proc add_jobs_from_cmdline {patternlist} {
global TRG
if {$TRG(zipvfs)!=""} {
add_zipvfs_jobs
@@ -882,32 +847,23 @@
}
set first [lindex $patternlist 0]
switch -- $first {
all {
- must_be_testfixture
set patternlist [lrange $patternlist 1 end]
set clist [trd_all_configs]
foreach c $clist {
add_tcl_jobs "" $c $patternlist
}
}
mdevtest {
- set config_set {
- All-O0
- All-Debug
- }
- add_devtest_jobs $config_set [lrange $patternlist 1 end]
+ add_devtest_jobs {All-O0 All-Debug} [lrange $patternlist 1 end]
}
sdevtest {
- set config_set {
- All-Sanitize
- All-Debug
- }
- add_devtest_jobs $config_set [lrange $patternlist 1 end]
+ add_devtest_jobs {All-Sanitize All-Debug} [lrange $patternlist 1 end]
}
release {
set patternlist [lrange $patternlist 1 end]
foreach b [trd_builds $TRG(platform)] {
@@ -926,19 +882,11 @@
}
}
}
}
- list {
- set allperm [array names ::testspec]
- lappend allperm all mdevtest sdevtest release list
- puts "Allowed values for the PERMUTATION argument: [lsort $allperm]"
- exit 0
- }
-
default {
- must_be_testfixture
if {[info exists ::testspec($first)]} {
add_tcl_jobs "" $first [lrange $patternlist 1 end]
} else {
add_tcl_jobs "" full $patternlist
}
@@ -998,18 +946,10 @@
if {[info exists TRG(reportlength)]} {
puts -nonewline "[string repeat " " $TRG(reportlength)]\r"
}
puts "FAILED: $job(displayname) ($iJob)"
set state "failed"
- if {$TRG(stopOnError)} {
- puts "OUTPUT: $O($iJob)"
- exit 1
- }
- if {$TRG(stopOnCore) && [string first {core dumped} $O($iJob)]>0} {
- puts "OUTPUT: $O($iJob)"
- exit 1
- }
}
set tm [clock_milliseconds]
set jobtm [expr {$tm - $job(starttime)}]
@@ -1066,18 +1006,13 @@
set fd [open [file join $dir $TRG(make)] w]
puts $fd $script
close $fd
}
- # Add a batch/shell file command to set the directory used for temp
- # files to the test's working directory. Otherwise, tests that use
- # large numbers of temp files (e.g. zipvfs), might generate temp
- # filename collisions.
- if {$TRG(platform)=="win"} {
- set set_tmp_dir "SET SQLITE_TMPDIR=[file normalize $dir]"
- } else {
- set set_tmp_dir "export SQLITE_TMPDIR=\"[file normalize $dir]\""
+ set job_cmd $job(cmd)
+ if {$TRG(platform)!="win"} {
+ set job_cmd "export SQLITE_TMPDIR=\"[file normalize $dir]\"\n$job_cmd"
}
if { $TRG(dryrun) } {
mark_job_as_finished $job(jobid) "" done 0
@@ -1090,12 +1025,11 @@
} else {
set pwd [pwd]
cd $dir
set fd [open $TRG(run) w]
- puts $fd $set_tmp_dir
- puts $fd $job(cmd)
+ puts $fd $job_cmd
close $fd
set fd [open "|$TRG(runcmd) 2>@1" r]
cd $pwd
fconfigure $fd -blocking false
@@ -1207,44 +1141,17 @@
trdb eval { DELETE FROM jobs WHERE displaytype!='bld' }
}
}
}
-# Handle the --explain option. Provide a human-readable
-# explanation of all the tests that are in the trdb database jobs
-# table.
-#
-proc explain_layer {indent depid} {
- global TRG
- if {$TRG(buildonly)} {
- set showtests 0
- } else {
- set showtests 1
- }
- trdb eval {SELECT jobid, displayname, displaytype, dirname
- FROM jobs WHERE depid=$depid ORDER BY displayname} {
- if {$displaytype=="bld"} {
- puts "${indent}$displayname in $dirname"
- explain_layer "${indent} " $jobid
- } elseif {$showtests} {
- puts "${indent}[lindex $displayname end]"
- }
- }
-}
-proc explain_tests {} {
- explain_layer "" ""
-}
-
sqlite3 trdb $TRG(dbname)
trdb timeout $TRG(timeout)
set tm [lindex [time { make_new_testset }] 0]
-if {$TRG(explain)} {
- explain_tests
-} else {
- if {$TRG(nJob)>1} {
- puts "splitting work across $TRG(nJob) jobs"
- }
- puts "built testset in [expr $tm/1000]ms.."
- handle_buildonly
- run_testset
-}
+if {$TRG(nJob)>1} {
+ puts "splitting work across $TRG(nJob) jobs"
+}
+puts "built testset in [expr $tm/1000]ms.."
+
+handle_buildonly
+run_testset
trdb close
+#puts [pwd]
Index: test/testrunner_data.tcl
==================================================================
--- test/testrunner_data.tcl
+++ test/testrunner_data.tcl
@@ -106,11 +106,10 @@
set build(Sanitize) {
CC=clang -fsanitize=address,undefined -fno-sanitize-recover=undefined
-DSQLITE_ENABLE_STAT4
-DSQLITE_OMIT_LOOKASIDE=1
-DCONFIG_SLOWDOWN_FACTOR=5.0
- -DSQLITE_ENABLE_RBU
--enable-debug
--enable-all
}
set build(Stdcall) {
-DUSE_STDCALL=1
DELETED test/values.test
Index: test/values.test
==================================================================
--- test/values.test
+++ /dev/null
@@ -1,583 +0,0 @@
-# 2024 March 3
-#
-# 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.
-#
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-set testprefix values
-
-
-do_execsql_test 1.0 {
- CREATE TABLE x1(a, b, c);
-}
-
-
-explain_i {
- INSERT INTO x1(a, b, c) VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4);
-}
-do_execsql_test 1.1.1 {
- INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4);
-}
-do_execsql_test 1.1.2 {
- SELECT * FROM x1;
-} {
- 1 1 1
- 2 2 2
- 3 3 3
- 4 4 4
-}
-
-do_execsql_test 1.2.0 {
- DELETE FROM x1
-}
-do_execsql_test 1.2.1 {
- INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3) UNION ALL SELECT 4, 4, 4;
- SELECT * FROM x1;
-} {1 1 1 2 2 2 3 3 3 4 4 4}
-
-sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 4
-
-do_execsql_test 1.2.2 {
- DELETE FROM x1;
- INSERT INTO x1
- VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4), (5, 5, 5)
- UNION ALL SELECT 6, 6, 6;
- SELECT * FROM x1;
-} {1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 6 6 6}
-
-do_execsql_test 1.2.3 {
- DELETE FROM x1;
- INSERT INTO x1
- VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4)
- UNION ALL SELECT 6, 6, 6;
- SELECT * FROM x1;
-} {1 1 1 2 2 2 3 3 3 4 4 4 6 6 6}
-
-do_execsql_test 1.2.4 {
- DELETE FROM x1;
- INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3) UNION ALL SELECT 6, 6, 6;
- SELECT * FROM x1;
-} {
- 1 1 1
- 2 2 2
- 3 3 3
- 6 6 6
-}
-
-set a 4
-set b 5
-set c 6
-do_execsql_test 1.2.5 {
- DELETE FROM x1;
- INSERT INTO x1
- VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3),
- (4, 4, $a), (5, 5, $b), (6, 6, $c)
-}
-
-do_execsql_test 1.2.6 {
- SELECT * FROM x1;
-} {
- 1 1 1
- 2 2 2
- 3 3 3
- 4 4 4
- 5 5 5
- 6 6 6
-}
-
-#-------------------------------------------------------------------------
-# SQLITE_LIMIT_COMPOUND_SELECT set to 0.
-#
-reset_db
-
-do_execsql_test 2.0 {
- CREATE TABLE x1(a, b, c);
-}
-
-sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 3
-
-do_catchsql_test 2.1.1 {
- INSERT INTO x1 VALUES
- (1, 1, 1),
- (2, 2, 2),
- (3, 3, 3),
- (4, 4, 4),
- (5, 5, 5),
- (6, 6, 6),
- (7, 7, 7),
- (8, 8, 8),
- (9, 9, 9),
- (10, 10, 10, 10)
-} {1 {all VALUES must have the same number of terms}}
-
-do_catchsql_test 2.1.2 {
- INSERT INTO x1 VALUES
- (1, 1, 1),
- (2, 2, 2, 2),
- (3, 3, 3),
- (4, 4, 4),
- (5, 5, 5),
- (6, 6, 6),
- (7, 7, 7),
- (8, 8, 8),
- (9, 9, 9),
- (10, 10, 10)
-} {1 {all VALUES must have the same number of terms}}
-
-sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 0
-
-do_execsql_test 2.2 {
- INSERT INTO x1 VALUES
- (1, 1, 1),
- (2, 2, 2),
- (3, 3, 3),
- (4, 4, 4),
- (5, 5, 5),
- (6, 6, 6),
- (7, 7, 7),
- (8, 8, 8),
- (9, 9, 9),
- (10, 10, 10)
-} {}
-do_execsql_test 2.3 {
- INSERT INTO x1 VALUES
- (1, 1, 1),
- (2, 2, 2),
- (3, 3, 3),
- (4, 4, 4),
- (5, 5, 5),
- (6, 6, 6),
- (7, 7, 7),
- (8, 8, 8),
- (9, 9, 9),
- (10, 10, 10)
- UNION ALL
- SELECT 5, 12, 12
- ORDER BY 1
-} {}
-
-#-------------------------------------------------------------------------
-reset_db
-
-do_execsql_test 3.0 {
- CREATE TABLE y1(x, y);
-}
-
-do_execsql_test 3.1.1 {
- DELETE FROM y1;
- INSERT INTO y1 VALUES(1, 2), (3, 4), (row_number() OVER (), 5);
-}
-do_execsql_test 3.1.2 {
- SELECT * FROM y1;
-} {1 2 3 4 1 5}
-do_execsql_test 3.2.1 {
- DELETE FROM y1;
- INSERT INTO y1 VALUES(1, 2), (3, 4), (row_number() OVER (), 6)
- , (row_number() OVER (), 7)
-}
-do_execsql_test 3.1.2 {
- SELECT * FROM y1;
-} {1 2 3 4 1 6 1 7}
-
-#-------------------------------------------------------------------------
-reset_db
-
-do_execsql_test 4.0 {
- CREATE TABLE x1(a PRIMARY KEY, b) WITHOUT ROWID;
-}
-
-foreach {tn iLimit} {1 0 2 3} {
- sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT $iLimit
-
- do_execsql_test 4.1.1 {
- DELETE FROM x1;
- INSERT INTO x1 VALUES
- (1, 1),
- (2, (SELECT * FROM (VALUES('a'), ('b'), ('c'), ('d')) ))
- }
- do_execsql_test 4.1.2 {
- SELECT * FROM x1
- } {1 1 2 a}
-
- do_execsql_test 4.2.1 {
- DELETE FROM x1;
- INSERT INTO x1 VALUES
- (1, 1),
- (2, 2),
- (3, 3),
- (4, 4),
- (5, (SELECT * FROM (VALUES('a'), ('b'), ('c'), ('d')) ))
- }
- do_execsql_test 4.2.2 {
- SELECT * FROM x1
- } {1 1 2 2 3 3 4 4 5 a}
-
- do_execsql_test 4.3.1 {
- DELETE FROM x1;
- INSERT INTO x1 VALUES
- (1, (SELECT * FROM (VALUES('a'), ('b'), ('c'), ('d'), ('e')) ))
- }
- do_execsql_test 4.3.2 {
- SELECT * FROM x1
- } {1 a}
-}
-
-#------------------------------------------------------------------------
-reset_db
-
-do_execsql_test 5.0 {
- CREATE VIEW v1 AS VALUES(1, 2, 3), (4, 5, 6), (7, 8, 9);
-}
-do_execsql_test 5.1 {
- SELECT * FROM v1
-} {1 2 3 4 5 6 7 8 9}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 6.0 {
- CREATE TABLE t1(x);
- INSERT INTO t1 VALUES(1), (2);
-}
-
-do_execsql_test 6.1 {
- SELECT ( VALUES( x ), ( x ) ) FROM t1;
-} {1 2}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 6.0 {
- CREATE TABLE t1(x);
- INSERT INTO t1 VALUES('x'), ('y');
-}
-
-do_execsql_test 6.1 {
- SELECT * FROM t1, (VALUES(1), (2))
-} {x 1 x 2 y 1 y 2}
-
-do_execsql_test 6.2 {
- VALUES(CAST(44 AS REAL)),(55);
-} {44.0 55}
-
-#------------------------------------------------------------------------
-do_execsql_test 7.1 {
- WITH x1(a, b) AS (
- VALUES(1, 2), ('a', 'b')
- )
- SELECT * FROM x1 one, x1 two
-} {
- 1 2 1 2
- 1 2 a b
- a b 1 2
- a b a b
-}
-
-#-------------------------------------------------------------------------
-reset_db
-
-set VVV {
- ( VALUES('a', 'b'), ('c', 'd'), (123, NULL) )
-}
-set VVV2 {
- (
- SELECT 'a' AS column1, 'b' AS column2
- UNION ALL SELECT 'c', 'd' UNION ALL SELECT 123, NULL
- )
-}
-
-do_execsql_test 8.0 {
- CREATE TABLE t1(x);
- INSERT INTO t1 VALUES('d'), (NULL), (123)
-}
-foreach {tn q res} {
- 1 "SELECT * FROM t1 LEFT JOIN VVV" {
- d a b d c d d 123 {}
- {} a b {} c d {} 123 {}
- 123 a b 123 c d 123 123 {}
- }
-
- 2 "SELECT * FROM t1 LEFT JOIN VVV ON (column1=x)" {
- d {} {}
- {} {} {}
- 123 123 {}
- }
-
- 3 "SELECT * FROM t1 RIGHT JOIN VVV" {
- d a b d c d d 123 {}
- {} a b {} c d {} 123 {}
- 123 a b 123 c d 123 123 {}
- }
-
- 4 "SELECT * FROM t1 RIGHT JOIN VVV ON (column1=x)" {
- 123 123 {}
- {} a b
- {} c d
- }
-
- 5 "SELECT * FROM t1 FULL OUTER JOIN VVV ON (column1=x)" {
- d {} {}
- {} {} {}
- 123 123 {}
- {} a b
- {} c d
- }
-
- 6 "SELECT count(*) FROM VVV" { 3 }
-
- 7 "SELECT (SELECT column1 FROM VVV)" { a }
-
- 8 "SELECT * FROM VVV UNION ALL SELECT * FROM VVV" {
- a b c d 123 {}
- a b c d 123 {}
- }
-
- 9 "SELECT * FROM VVV INTERSECT SELECT * FROM VVV" {
- 123 {} a b c d
- }
-
- 10 "SELECT * FROM VVV eXCEPT SELECT * FROM VVV" { }
-
- 11 "SELECT * FROM VVV eXCEPT SELECT 'a', 'b'" { 123 {} c d }
-
-} {
- set q1 [string map [list VVV $VVV] $q]
- set q2 [string map [list VVV $VVV2] $q]
- set q3 "WITH VVV AS $VVV $q"
-
- do_execsql_test 8.1.$tn.1 $q1 $res
- do_execsql_test 8.1.$tn.2 $q2 $res
- do_execsql_test 8.1.$tn.3 $q3 $res
-}
-
-#-------------------------------------------------------------------------
-reset_db
-
-do_execsql_test 9.1 {
- VALUES(456), (123), (NULL) UNION ALL SELECT 122 ORDER BY 1
-} { {} 122 123 456 }
-
-do_execsql_test 9.2 {
- VALUES (1, 2), (3, 4), (
- ( SELECT column1 FROM ( VALUES (5, 6), (7, 8) ) ),
- ( SELECT max(column2) FROM ( VALUES (5, 1), (7, 6) ) )
- )
-} { 1 2 3 4 5 6 }
-
-do_execsql_test 10.1 {
- CREATE TABLE a2(a, b, c DEFAULT 'xyz');
-}
-do_execsql_test 10.2 {
- INSERT INTO a2(a) VALUES(3),(4);
-}
-
-#-------------------------------------------------------------------------
-reset_db
-ifcapable fts5 {
- do_execsql_test 11.0 {
- CREATE VIRTUAL TABLE ft USING fts3(x);
- }
- do_execsql_test 11.1 {
- INSERT INTO ft VALUES('one'), ('two');
- }
-}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 12.0 {
- CREATE TABLE t1(a, b);
-}
-do_execsql_test 12.1 {
- INSERT INTO t1 SELECT 1, 2 UNION ALL VALUES(3, 4), (5, 6);
-}
-do_execsql_test 12.2 {
- SELECT * FROM t1
-} {1 2 3 4 5 6}
-
-#-------------------------------------------------------------------------
-reset_db
-do_execsql_test 13.0 {
- CREATE TABLE t1(x);
- INSERT INTO t1 VALUES('xyz');
-
- SELECT (
- VALUES( (max(substr('abc', 1, 1), x)) ),
- (123),
- (456)
- )
- FROM t1;
-} {xyz}
-
-do_catchsql_test 13.1 {
- VALUES(300), (zeroblob(300) OVER win);
-} {1 {zeroblob() may not be used as a window function}}
-
-#--------------------------------------------------------------------------
-reset_db
-do_execsql_test 14.1 {
- PRAGMA encoding = utf16;
- CREATE TABLE t1(a, b);
-} {}
-
-db close
-sqlite3 db test.db
-
-do_execsql_test 14.2 {
- INSERT INTO t1 VALUES
- (17, 'craft'),
- (16, 'urtlek' IN(1,2,3));
-}
-
-#--------------------------------------------------------------------------
-#
-reset_db
-do_eqp_test 15.1 {
- VALUES(1),(2),(3),(4),(5);
-} {
- QUERY PLAN
- `--SCAN 5-ROW VALUES CLAUSE
-}
-do_execsql_test 15.2 {
- CREATE TABLE t1(a,b);
-}
-do_eqp_test 15.3 {
- INSERT INTO t1 VALUES
- (1,2),(3,4),(7,8);
-} {
- QUERY PLAN
- `--SCAN 3-ROW VALUES CLAUSE
-}
-do_eqp_test 15.4 {
- INSERT INTO t1 VALUES
- (1,2),(3,4),(7,8),
- (5,row_number()OVER());
-} {
- QUERY PLAN
- `--COMPOUND QUERY
- |--LEFT-MOST SUBQUERY
- | `--SCAN 3-ROW VALUES CLAUSE
- `--UNION ALL
- |--CO-ROUTINE (subquery-xxxxxx)
- | `--SCAN CONSTANT ROW
- `--SCAN (subquery-xxxxxx)
-}
-do_eqp_test 15.5 {
- SELECT * FROM (VALUES(1),(2),(3),(4),(5),(6)), (VALUES('a'),('b'),('c'));
-} {
- QUERY PLAN
- |--SCAN 6-ROW VALUES CLAUSE
- `--SCAN 3-ROW VALUES CLAUSE
-}
-do_execsql_test 15.6 {
- CREATE TABLE t2(x,y);
-}
-do_eqp_test 15.7 {
- SELECT * FROM t2 UNION ALL VALUES(1,2),(3,4),(5,6),(7,8);
-} {
- QUERY PLAN
- `--COMPOUND QUERY
- |--LEFT-MOST SUBQUERY
- | `--SCAN t2
- `--UNION ALL
- `--SCAN 4-ROW VALUES CLAUSE
-}
-
-#--------------------------------------------------------------------------
-# The VALUES-as-coroutine optimization can be applied to later rows of
-# a VALUES clause even if earlier rows do not qualify.
-#
-reset_db
-do_execsql_test 16.1 {
- CREATE TABLE t1(a,b);
-}
-do_execsql_test 16.2 {
- BEGIN;
- INSERT INTO t1 VALUES(1,2),(3,4),(5,6),
- (7,row_number()OVER()),
- (9,10), (11,12), (13,14), (15,16);
- SELECT * FROM t1 ORDER BY a, b;
- ROLLBACK;
-} {1 2 3 4 5 6 7 1 9 10 11 12 13 14 15 16}
-do_eqp_test 16.3 {
- INSERT INTO t1 VALUES(1,2),(3,4),(5,6),
- (7,row_number()OVER()),
- (9,10), (11,12), (13,14), (15,16);
-} {
- QUERY PLAN
- `--COMPOUND QUERY
- |--LEFT-MOST SUBQUERY
- | `--SCAN 3-ROW VALUES CLAUSE
- |--UNION ALL
- | |--CO-ROUTINE (subquery-xxxxxx)
- | | `--SCAN CONSTANT ROW
- | `--SCAN (subquery-xxxxxx)
- `--UNION ALL
- `--SCAN 4-ROW VALUES CLAUSE
-}
-do_execsql_test 16.4 {
- BEGIN;
- INSERT INTO t1 VALUES
- (1,row_number()OVER()),
- (2,3), (4,5), (6,7);
- SELECT * FROM t1 ORDER BY a, b;
- ROLLBACK;
-} {1 1 2 3 4 5 6 7}
-do_eqp_test 16.5 {
- INSERT INTO t1 VALUES
- (1,row_number()OVER()),
- (2,3), (4,5), (6,7);
-} {
- QUERY PLAN
- `--COMPOUND QUERY
- |--LEFT-MOST SUBQUERY
- | |--CO-ROUTINE (subquery-xxxxxx)
- | | `--SCAN CONSTANT ROW
- | `--SCAN (subquery-xxxxxx)
- `--UNION ALL
- `--SCAN 3-ROW VALUES CLAUSE
-}
-do_execsql_test 16.6 {
- BEGIN;
- INSERT INTO t1 VALUES
- (1,2),(3,4),
- (5,row_number()OVER()),
- (7,8),(9,10),(11,12),
- (13,row_number()OVER()),
- (15,16),(17,18),(19,20),(21,22);
- SELECT * FROM t1 ORDER BY a, b;
- ROLLBACK;
-} { 1 2 3 4 5 1 7 8 9 10 11 12 13 1 15 16 17 18 19 20 21 22}
-do_eqp_test 16.7 {
- INSERT INTO t1 VALUES
- (1,2),(3,4),
- (5,row_number()OVER()),
- (7,8),(9,10),(11,12),
- (13,row_number()OVER()),
- (15,16),(17,18),(19,20),(21,22);
-} {
- QUERY PLAN
- `--COMPOUND QUERY
- |--LEFT-MOST SUBQUERY
- | `--SCAN 2-ROW VALUES CLAUSE
- |--UNION ALL
- | |--CO-ROUTINE (subquery-xxxxxx)
- | | `--SCAN CONSTANT ROW
- | `--SCAN (subquery-xxxxxx)
- |--UNION ALL
- | `--SCAN 3-ROW VALUES CLAUSE
- |--UNION ALL
- | |--CO-ROUTINE (subquery-xxxxxx)
- | | `--SCAN CONSTANT ROW
- | `--SCAN (subquery-xxxxxx)
- `--UNION ALL
- `--SCAN 4-ROW VALUES CLAUSE
-}
-
-finish_test
DELETED test/valuesfault.test
Index: test/valuesfault.test
==================================================================
--- test/valuesfault.test
+++ /dev/null
@@ -1,37 +0,0 @@
-# 2024 March 3
-#
-# 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.
-#
-
-set testdir [file dirname $argv0]
-source $testdir/tester.tcl
-set testprefix valuesfault
-source $testdir/malloc_common.tcl
-
-
-do_execsql_test 1.0 {
- CREATE TABLE x1(a, b, c);
-}
-faultsim_save_and_close
-
-do_faultsim_test 1 -prep {
- faultsim_restore_and_reopen
- sqlite3_limit db SQLITE_LIMIT_COMPOUND_SELECT 2
-} -body {
- execsql {
- INSERT INTO x1 VALUES(1, 1, 1), (2, 2, 2), (3, 3, 3), (4, 4, 4);
- }
-} -test {
- faultsim_test_result {0 {}}
-}
-
-
-finish_test
Index: test/whereL.test
==================================================================
--- test/whereL.test
+++ test/whereL.test
@@ -47,37 +47,10 @@
QUERY PLAN
|--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
|--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
`--SCAN t3
}
-do_eqp_test 121 {
- SELECT * FROM t1, t2, t3
- WHERE t1.a=t2.a AND t2.a=t3.j AND t3.j=abs(5)
- ORDER BY t1.a;
-} {
- QUERY PLAN
- |--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
- |--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
- `--SCAN t3
-}
-
-# The sqlite3ExprIsConstant() routine does not believe that
-# the expression "coalesce(5,random())" is constant. So the
-# optimization does not apply in this case.
-#
-sqlite3_create_function db
-do_eqp_test 122 {
- SELECT * FROM t1, t2, t3
- WHERE t1.a=t2.a AND t2.a=t3.j AND t3.j=coalesce(5,random())
- ORDER BY t1.a;
-} {
- QUERY PLAN
- |--SCAN t3
- |--SEARCH t1 USING INDEX sqlite_autoindex_t1_1 (a=?)
- |--SEARCH t2 USING INDEX sqlite_autoindex_t2_1 (a=?)
- `--USE TEMP B-TREE FOR ORDER BY
-}
# Constant propagation in the face of collating sequences:
#
do_execsql_test 200 {
CREATE TABLE c3(x COLLATE binary, y COLLATE nocase, z COLLATE binary);
Index: tool/lemon.c
==================================================================
--- tool/lemon.c
+++ tool/lemon.c
@@ -57,86 +57,10 @@
** as C evolves ever closer to Ada.... To work around the latest problems
** we have to define the following variant of strlen().
*/
#define lemonStrlen(X) ((int)strlen(X))
-/*
-** Header on the linked list of memory allocations.
-*/
-typedef struct MemChunk MemChunk;
-struct MemChunk {
- MemChunk *pNext;
- size_t sz;
- /* Actually memory follows */
-};
-
-/*
-** Global linked list of all memory allocations.
-*/
-static MemChunk *memChunkList = 0;
-
-/*
-** Wrappers around malloc(), calloc(), realloc() and free().
-**
-** All memory allocations are kept on a doubly-linked list. The
-** lemon_free_all() function can be called prior to exit to clean
-** up any memory leaks.
-**
-** This is not necessary. But compilers and getting increasingly
-** fussy about memory leaks, even in command-line programs like Lemon
-** where they do not matter. So this code is provided to hush the
-** warnings.
-*/
-static void *lemon_malloc(size_t nByte){
- MemChunk *p;
- if( nByte<0 ) return 0;
- p = malloc( nByte + sizeof(MemChunk) );
- if( p==0 ){
- fprintf(stderr, "Out of memory. Failed to allocate %lld bytes.\n",
- (long long int)nByte);
- exit(1);
- }
- p->pNext = memChunkList;
- p->sz = nByte;
- memChunkList = p;
- return (void*)&p[1];
-}
-static void *lemon_calloc(size_t nElem, size_t sz){
- void *p = lemon_malloc(nElem*sz);
- memset(p, 0, nElem*sz);
- return p;
-}
-static void lemon_free(void *pOld){
- if( pOld ){
- MemChunk *p = (MemChunk*)pOld;
- p--;
- memset(pOld, 0, p->sz);
- }
-}
-static void *lemon_realloc(void *pOld, size_t nNew){
- void *pNew;
- MemChunk *p;
- if( pOld==0 ) return lemon_malloc(nNew);
- p = (MemChunk*)pOld;
- p--;
- if( p->sz>=nNew ) return pOld;
- pNew = lemon_malloc( nNew );
- memcpy(pNew, pOld, p->sz);
- return pNew;
-}
-
-/* Free all outstanding memory allocations.
-** Do this right before exiting.
-*/
-static void lemon_free_all(void){
- while( memChunkList ){
- MemChunk *pNext = memChunkList->pNext;
- free( memChunkList );
- memChunkList = pNext;
- }
-}
-
/*
** 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
@@ -571,11 +495,11 @@
struct action *newaction;
if( actionfreelist==0 ){
int i;
int amt = 100;
- actionfreelist = (struct action *)lemon_calloc(amt, sizeof(struct action));
+ actionfreelist = (struct action *)calloc(amt, sizeof(struct action));
if( actionfreelist==0 ){
fprintf(stderr,"Unable to allocate memory for a new parser action.");
exit(1);
}
for(i=0; iaAction[N].lookahead)
/* Free all memory associated with the given acttab */
void acttab_free(acttab *p){
- lemon_free( p->aAction );
- lemon_free( p->aLookahead );
- lemon_free( p );
+ free( p->aAction );
+ free( p->aLookahead );
+ free( p );
}
/* Allocate a new acttab structure */
acttab *acttab_alloc(int nsymbol, int nterminal){
- acttab *p = (acttab *) lemon_calloc( 1, sizeof(*p) );
+ acttab *p = (acttab *) calloc( 1, sizeof(*p) );
if( p==0 ){
fprintf(stderr,"Unable to allocate memory for a new acttab.");
exit(1);
}
memset(p, 0, sizeof(*p));
@@ -716,11 +640,11 @@
** state.
*/
void acttab_action(acttab *p, int lookahead, int action){
if( p->nLookahead>=p->nLookaheadAlloc ){
p->nLookaheadAlloc += 25;
- p->aLookahead = (struct lookahead_action *) lemon_realloc( p->aLookahead,
+ p->aLookahead = (struct lookahead_action *) realloc( p->aLookahead,
sizeof(p->aLookahead[0])*p->nLookaheadAlloc );
if( p->aLookahead==0 ){
fprintf(stderr,"malloc failed\n");
exit(1);
}
@@ -766,11 +690,11 @@
*/
n = p->nsymbol + 1;
if( p->nAction + n >= p->nActionAlloc ){
int oldAlloc = p->nActionAlloc;
p->nActionAlloc = p->nAction + n + p->nActionAlloc + 20;
- p->aAction = (struct lookahead_action *) lemon_realloc( p->aAction,
+ p->aAction = (struct lookahead_action *) realloc( p->aAction,
sizeof(p->aAction[0])*p->nActionAlloc);
if( p->aAction==0 ){
fprintf(stderr,"malloc failed\n");
exit(1);
}
@@ -1388,11 +1312,11 @@
static struct config *basis = 0; /* Top of list of basis configs */
static struct config **basisend = 0; /* End of list of basis configs */
/* Return a pointer to a new configuration */
PRIVATE struct config *newconfig(void){
- return (struct config*)lemon_calloc(1, sizeof(struct config));
+ return (struct config*)calloc(1, sizeof(struct config));
}
/* The configuration "old" is no longer used */
PRIVATE void deleteconfig(struct config *old)
{
@@ -1604,23 +1528,23 @@
** Add the macro defined to the azDefine array.
*/
static void handle_D_option(char *z){
char **paz;
nDefine++;
- azDefine = (char **) lemon_realloc(azDefine, sizeof(azDefine[0])*nDefine);
+ azDefine = (char **) realloc(azDefine, sizeof(azDefine[0])*nDefine);
if( azDefine==0 ){
fprintf(stderr,"out of memory\n");
exit(1);
}
- bDefineUsed = (char*)lemon_realloc(bDefineUsed, nDefine);
+ bDefineUsed = (char*)realloc(bDefineUsed, nDefine);
if( bDefineUsed==0 ){
fprintf(stderr,"out of memory\n");
exit(1);
}
bDefineUsed[nDefine-1] = 0;
paz = &azDefine[nDefine-1];
- *paz = (char *) lemon_malloc( lemonStrlen(z)+1 );
+ *paz = (char *) malloc( lemonStrlen(z)+1 );
if( *paz==0 ){
fprintf(stderr,"out of memory\n");
exit(1);
}
lemon_strcpy(*paz, z);
@@ -1630,21 +1554,21 @@
/* Rember the name of the output directory
*/
static char *outputDir = NULL;
static void handle_d_option(char *z){
- outputDir = (char *) lemon_malloc( lemonStrlen(z)+1 );
+ outputDir = (char *) malloc( lemonStrlen(z)+1 );
if( outputDir==0 ){
fprintf(stderr,"out of memory\n");
exit(1);
}
lemon_strcpy(outputDir, z);
}
static char *user_templatename = NULL;
static void handle_T_option(char *z){
- user_templatename = (char *) lemon_malloc( lemonStrlen(z)+1 );
+ user_templatename = (char *) malloc( lemonStrlen(z)+1 );
if( user_templatename==0 ){
memory_error();
}
lemon_strcpy(user_templatename, z);
}
@@ -1877,11 +1801,10 @@
fprintf(stderr,"%d parsing conflicts.\n",lem.nconflict);
}
/* return 0 on success, 1 on failure. */
exitcode = ((lem.errorcnt > 0) || (lem.nconflict > 0)) ? 1 : 0;
- lemon_free_all();
exit(exitcode);
return (exitcode);
}
/******************** From the file "msort.c" *******************************/
/*
@@ -2466,11 +2389,11 @@
}
break;
case IN_RHS:
if( x[0]=='.' ){
struct rule *rp;
- rp = (struct rule *)lemon_calloc( sizeof(struct rule) +
+ rp = (struct rule *)calloc( sizeof(struct rule) +
sizeof(struct symbol*)*psp->nrhs + sizeof(char*)*psp->nrhs, 1);
if( rp==0 ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Can't allocate enough memory for this rule.");
psp->errorcnt++;
@@ -2518,21 +2441,21 @@
}
}else if( (x[0]=='|' || x[0]=='/') && psp->nrhs>0 && ISUPPER(x[1]) ){
struct symbol *msp = psp->rhs[psp->nrhs-1];
if( msp->type!=MULTITERMINAL ){
struct symbol *origsp = msp;
- msp = (struct symbol *) lemon_calloc(1,sizeof(*msp));
+ msp = (struct symbol *) calloc(1,sizeof(*msp));
memset(msp, 0, sizeof(*msp));
msp->type = MULTITERMINAL;
msp->nsubsym = 1;
- msp->subsym = (struct symbol**)lemon_calloc(1,sizeof(struct symbol*));
+ msp->subsym = (struct symbol **) calloc(1,sizeof(struct symbol*));
msp->subsym[0] = origsp;
msp->name = origsp->name;
psp->rhs[psp->nrhs-1] = msp;
}
msp->nsubsym++;
- msp->subsym = (struct symbol **) lemon_realloc(msp->subsym,
+ msp->subsym = (struct symbol **) realloc(msp->subsym,
sizeof(struct symbol*)*msp->nsubsym);
msp->subsym[msp->nsubsym-1] = Symbol_new(&x[1]);
if( ISLOWER(x[1]) || ISLOWER(msp->subsym[0]->name[0]) ){
ErrorMsg(psp->filename,psp->tokenlineno,
"Cannot form a compound containing a non-terminal");
@@ -2744,11 +2667,11 @@
}
lemon_sprintf(zLine, "#line %d ", psp->tokenlineno);
nLine = lemonStrlen(zLine);
n += nLine + lemonStrlen(psp->filename) + nBack;
}
- *psp->declargslot = (char *) lemon_realloc(*psp->declargslot, n);
+ *psp->declargslot = (char *) realloc(*psp->declargslot, n);
zBuf = *psp->declargslot + nOld;
if( addLineMacro ){
if( nOld && zBuf[-1]!='\n' ){
*(zBuf++) = '\n';
}
@@ -2858,11 +2781,11 @@
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 **) lemon_realloc(msp->subsym,
+ 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,
@@ -3073,22 +2996,22 @@
return;
}
fseek(fp,0,2);
filesize = ftell(fp);
rewind(fp);
- filebuf = (char *)lemon_malloc( filesize+1 );
+ filebuf = (char *)malloc( filesize+1 );
if( filesize>100000000 || filebuf==0 ){
ErrorMsg(ps.filename,0,"Input file too large.");
- lemon_free(filebuf);
+ free(filebuf);
gp->errorcnt++;
fclose(fp);
return;
}
if( fread(filebuf,1,filesize,fp)!=filesize ){
ErrorMsg(ps.filename,0,"Can't read in all %d bytes of this file.",
filesize);
- lemon_free(filebuf);
+ free(filebuf);
gp->errorcnt++;
fclose(fp);
return;
}
fclose(fp);
@@ -3196,11 +3119,11 @@
*cp = 0; /* Null terminate the token */
parseonetoken(&ps); /* Parse the token */
*cp = (char)c; /* Restore the buffer */
cp = nextcp;
}
- lemon_free(filebuf); /* Release the buffer after parsing */
+ free(filebuf); /* Release the buffer after parsing */
gp->rule = ps.firstrule;
gp->errorcnt = ps.errorcnt;
}
/*************************** From the file "plink.c" *********************/
/*
@@ -3214,11 +3137,11 @@
struct plink *newlink;
if( plink_freelist==0 ){
int i;
int amt = 100;
- plink_freelist = (struct plink *)lemon_calloc( amt, sizeof(struct plink) );
+ plink_freelist = (struct plink *)calloc( amt, sizeof(struct plink) );
if( plink_freelist==0 ){
fprintf(stderr,
"Unable to allocate memory for a new follow-set propagation link.\n");
exit(1);
}
@@ -3267,11 +3190,13 @@
/*********************** From the file "report.c" **************************/
/*
** Procedures for generating reports and tables in the LEMON parser generator.
*/
-/* Generate a filename with the given suffix.
+/* Generate a filename with the given suffix. Space to hold the
+** name comes from malloc() and must be freed by the calling
+** function.
*/
PRIVATE char *file_makename(struct lemon *lemp, const char *suffix)
{
char *name;
char *cp;
@@ -3284,11 +3209,11 @@
}
sz = lemonStrlen(filename);
sz += lemonStrlen(suffix);
if( outputDir ) sz += lemonStrlen(outputDir) + 1;
sz += 5;
- name = (char*)lemon_malloc( sz );
+ name = (char*)malloc( sz );
if( name==0 ){
fprintf(stderr,"Can't allocate space for a filename.\n");
exit(1);
}
name[0] = 0;
@@ -3311,11 +3236,11 @@
const char *suffix,
const char *mode
){
FILE *fp;
- if( lemp->outname ) lemon_free(lemp->outname);
+ if( lemp->outname ) free(lemp->outname);
lemp->outname = file_makename(lemp, suffix);
fp = fopen(lemp->outname,mode);
if( fp==0 && *mode=='w' ){
fprintf(stderr,"Can't open file \"%s\".\n",lemp->outname);
lemp->errorcnt++;
@@ -3627,18 +3552,18 @@
cp = strrchr(argv0,'/');
#endif
if( cp ){
c = *cp;
*cp = 0;
- path = (char *)lemon_malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
+ path = (char *)malloc( lemonStrlen(argv0) + lemonStrlen(name) + 2 );
if( path ) lemon_sprintf(path,"%s/%s",argv0,name);
*cp = c;
}else{
pathlist = getenv("PATH");
if( pathlist==0 ) pathlist = ".:/bin:/usr/bin";
- pathbuf = (char *) lemon_malloc( lemonStrlen(pathlist) + 1 );
- path = (char *)lemon_malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
+ pathbuf = (char *) malloc( lemonStrlen(pathlist) + 1 );
+ path = (char *)malloc( lemonStrlen(pathlist)+lemonStrlen(name)+2 );
if( (pathbuf != 0) && (path!=0) ){
pathbufptr = pathbuf;
lemon_strcpy(pathbuf, pathlist);
while( *pathbuf ){
cp = strchr(pathbuf,':');
@@ -3650,11 +3575,11 @@
if( c==0 ) pathbuf[0] = 0;
else pathbuf = &cp[1];
if( access(path,modemask)==0 ) break;
}
}
- lemon_free(pathbufptr);
+ free(pathbufptr);
}
return path;
}
/* Given an action, compute the integer value for that action
@@ -3781,11 +3706,11 @@
in = fopen(tpltname,"rb");
if( in==0 ){
fprintf(stderr,"Can't open the template file \"%s\".\n",tpltname);
lemp->errorcnt++;
}
- lemon_free(toFree);
+ free(toFree);
return in;
}
/* Print a #line directive line to the output file. */
PRIVATE void tplt_linedir(FILE *out, int lineno, char *filename)
@@ -3910,11 +3835,11 @@
}
n = lemonStrlen(zText);
}
if( (int) (n+sizeof(zInt)*2+used) >= alloced ){
alloced = n + sizeof(zInt)*2 + used + 200;
- z = (char *) lemon_realloc(z, alloced);
+ z = (char *) realloc(z, alloced);
}
if( z==0 ) return empty;
while( n-- > 0 ){
c = *(zText++);
if( c=='%' && n>0 && zText[0]=='d' ){
@@ -4200,11 +4125,11 @@
unsigned hash; /* For hashing the name of a type */
const char *name; /* Name of the parser */
/* Allocate and initialize types[] and allocate stddt[] */
arraysize = lemp->nsymbol * 2;
- types = (char**)lemon_calloc( arraysize, sizeof(char*) );
+ types = (char**)calloc( arraysize, sizeof(char*) );
if( types==0 ){
fprintf(stderr,"Out of memory.\n");
exit(1);
}
for(i=0; isymbols[i];
if( sp->datatype==0 ) continue;
len = lemonStrlen(sp->datatype);
if( len>maxdtlength ) maxdtlength = len;
}
- stddt = (char*)lemon_malloc( maxdtlength*2 + 1 );
+ stddt = (char*)malloc( maxdtlength*2 + 1 );
if( stddt==0 ){
fprintf(stderr,"Out of memory.\n");
exit(1);
}
@@ -4266,11 +4191,11 @@
hash++;
if( hash>=(unsigned)arraysize ) hash = 0;
}
if( types[hash]==0 ){
sp->dtnum = hash + 1;
- types[hash] = (char*)lemon_malloc( lemonStrlen(stddt)+1 );
+ types[hash] = (char*)malloc( lemonStrlen(stddt)+1 );
if( types[hash]==0 ){
fprintf(stderr,"Out of memory.\n");
exit(1);
}
lemon_strcpy(types[hash],stddt);
@@ -4288,17 +4213,17 @@
fprintf(out," int yyinit;\n"); lineno++;
fprintf(out," %sTOKENTYPE yy0;\n",name); lineno++;
for(i=0; ierrsym && lemp->errsym->useCnt ){
fprintf(out," int yy%d;\n",lemp->errsym->dtnum); lineno++;
}
- lemon_free(stddt);
- lemon_free(types);
+ free(stddt);
+ free(types);
fprintf(out,"} YYMINORTYPE;\n"); lineno++;
*plineno = lineno;
}
/*
@@ -4523,11 +4448,11 @@
/* Generate the include code, if any */
tplt_print(out,lemp,lemp->include,&lineno);
if( mhflag ){
char *incName = file_makename(lemp, ".h");
fprintf(out,"#include \"%s\"\n", incName); lineno++;
- lemon_free(incName);
+ free(incName);
}
tplt_xfer(lemp->name,in,out,&lineno);
/* Generate #defines for all tokens */
if( lemp->tokenprefix ) prefix = lemp->tokenprefix;
@@ -4630,11 +4555,11 @@
/* Compute the action table, but do not output it yet. The action
** table must be computed before generating the YYNSTATE macro because
** we need to know how many states can be eliminated.
*/
- ax = (struct axset *) lemon_calloc(lemp->nxstate*2, sizeof(ax[0]));
+ ax = (struct axset *) calloc(lemp->nxstate*2, sizeof(ax[0]));
if( ax==0 ){
fprintf(stderr,"malloc failed\n");
exit(1);
}
for(i=0; inxstate; i++){
@@ -4688,11 +4613,11 @@
i, stp->statenum, ax[i].isTkn ? "Token" : "Var ",
ax[i].nAction, pActtab->nAction, nn);
}
#endif
}
- lemon_free(ax);
+ free(ax);
/* Mark rules that are actually used for reduce actions after all
** optimizations have been applied
*/
for(rp=lemp->rule; rp; rp=rp->next) rp->doesReduce = LEMON_FALSE;
@@ -5314,21 +5239,21 @@
}
/* Allocate a new set */
char *SetNew(void){
char *s;
- s = (char*)lemon_calloc( size, 1);
+ s = (char*)calloc( size, 1);
if( s==0 ){
memory_error();
}
return s;
}
/* Deallocate a set */
void SetFree(char *s)
{
- lemon_free(s);
+ free(s);
}
/* Add a new element to the set. Return TRUE if the element was added
** and FALSE if it was already there. */
int SetAdd(char *s, int e)
@@ -5383,11 +5308,11 @@
const char *z;
char *cpy;
if( y==0 ) return 0;
z = Strsafe_find(y);
- if( z==0 && (cpy=(char *)lemon_malloc( lemonStrlen(y)+1 ))!=0 ){
+ if( z==0 && (cpy=(char *)malloc( lemonStrlen(y)+1 ))!=0 ){
lemon_strcpy(cpy,y);
z = cpy;
Strsafe_insert(z);
}
MemoryCheck(z);
@@ -5419,17 +5344,17 @@
static struct s_x1 *x1a;
/* Allocate a new associative array */
void Strsafe_init(void){
if( x1a ) return;
- x1a = (struct s_x1*)lemon_malloc( sizeof(struct s_x1) );
+ x1a = (struct s_x1*)malloc( sizeof(struct s_x1) );
if( x1a ){
x1a->size = 1024;
x1a->count = 0;
- x1a->tbl = (x1node*)lemon_calloc(1024, sizeof(x1node) + sizeof(x1node*));
+ x1a->tbl = (x1node*)calloc(1024, sizeof(x1node) + sizeof(x1node*));
if( x1a->tbl==0 ){
- lemon_free(x1a);
+ free(x1a);
x1a = 0;
}else{
int i;
x1a->ht = (x1node**)&(x1a->tbl[1024]);
for(i=0; i<1024; i++) x1a->ht[i] = 0;
@@ -5460,11 +5385,11 @@
/* Need to make the hash table bigger */
int i,arrSize;
struct s_x1 array;
array.size = arrSize = x1a->size*2;
array.count = x1a->count;
- array.tbl = (x1node*)lemon_calloc(arrSize, sizeof(x1node)+sizeof(x1node*));
+ array.tbl = (x1node*)calloc(arrSize, sizeof(x1node) + sizeof(x1node*));
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
array.ht = (x1node**)&(array.tbl[arrSize]);
for(i=0; icount; i++){
x1node *oldnp, *newnp;
@@ -5475,11 +5400,11 @@
newnp->next = array.ht[h];
newnp->data = oldnp->data;
newnp->from = &(array.ht[h]);
array.ht[h] = newnp;
}
- /* lemon_free(x1a->tbl); // This program was originally for 16-bit machines.
+ /* free(x1a->tbl); // This program was originally for 16-bit machines.
** Don't worry about freeing memory on modern platforms. */
*x1a = array;
}
/* Insert the new data */
h = ph & (x1a->size-1);
@@ -5516,11 +5441,11 @@
{
struct symbol *sp;
sp = Symbol_find(x);
if( sp==0 ){
- sp = (struct symbol *)lemon_calloc(1, sizeof(struct symbol) );
+ sp = (struct symbol *)calloc(1, sizeof(struct symbol) );
MemoryCheck(sp);
sp->name = Strsafe(x);
sp->type = ISUPPER(*x) ? TERMINAL : NONTERMINAL;
sp->rule = 0;
sp->fallback = 0;
@@ -5587,17 +5512,17 @@
static struct s_x2 *x2a;
/* Allocate a new associative array */
void Symbol_init(void){
if( x2a ) return;
- x2a = (struct s_x2*)lemon_malloc( sizeof(struct s_x2) );
+ x2a = (struct s_x2*)malloc( sizeof(struct s_x2) );
if( x2a ){
x2a->size = 128;
x2a->count = 0;
- x2a->tbl = (x2node*)lemon_calloc(128, sizeof(x2node) + sizeof(x2node*));
+ x2a->tbl = (x2node*)calloc(128, sizeof(x2node) + sizeof(x2node*));
if( x2a->tbl==0 ){
- lemon_free(x2a);
+ free(x2a);
x2a = 0;
}else{
int i;
x2a->ht = (x2node**)&(x2a->tbl[128]);
for(i=0; i<128; i++) x2a->ht[i] = 0;
@@ -5628,11 +5553,11 @@
/* Need to make the hash table bigger */
int i,arrSize;
struct s_x2 array;
array.size = arrSize = x2a->size*2;
array.count = x2a->count;
- array.tbl = (x2node*)lemon_calloc(arrSize, sizeof(x2node)+sizeof(x2node*));
+ array.tbl = (x2node*)calloc(arrSize, sizeof(x2node) + sizeof(x2node*));
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
array.ht = (x2node**)&(array.tbl[arrSize]);
for(i=0; icount; i++){
x2node *oldnp, *newnp;
@@ -5644,11 +5569,11 @@
newnp->key = oldnp->key;
newnp->data = oldnp->data;
newnp->from = &(array.ht[h]);
array.ht[h] = newnp;
}
- /* lemon_free(x2a->tbl); // This program was originally written for 16-bit
+ /* free(x2a->tbl); // This program was originally written for 16-bit
** machines. Don't worry about freeing this trivial amount of memory
** on modern platforms. Just leak it. */
*x2a = array;
}
/* Insert the new data */
@@ -5705,11 +5630,11 @@
{
struct symbol **array;
int i,arrSize;
if( x2a==0 ) return 0;
arrSize = x2a->count;
- array = (struct symbol **)lemon_calloc(arrSize, sizeof(struct symbol *));
+ array = (struct symbol **)calloc(arrSize, sizeof(struct symbol *));
if( array ){
for(i=0; itbl[i].data;
}
return array;
}
@@ -5753,11 +5678,11 @@
/* Allocate a new state structure */
struct state *State_new()
{
struct state *newstate;
- newstate = (struct state *)lemon_calloc(1, sizeof(struct state) );
+ newstate = (struct state *)calloc(1, sizeof(struct state) );
MemoryCheck(newstate);
return newstate;
}
/* There is one instance of the following structure for each
@@ -5786,17 +5711,17 @@
static struct s_x3 *x3a;
/* Allocate a new associative array */
void State_init(void){
if( x3a ) return;
- x3a = (struct s_x3*)lemon_malloc( sizeof(struct s_x3) );
+ x3a = (struct s_x3*)malloc( sizeof(struct s_x3) );
if( x3a ){
x3a->size = 128;
x3a->count = 0;
- x3a->tbl = (x3node*)lemon_calloc(128, sizeof(x3node) + sizeof(x3node*));
+ x3a->tbl = (x3node*)calloc(128, sizeof(x3node) + sizeof(x3node*));
if( x3a->tbl==0 ){
- lemon_free(x3a);
+ free(x3a);
x3a = 0;
}else{
int i;
x3a->ht = (x3node**)&(x3a->tbl[128]);
for(i=0; i<128; i++) x3a->ht[i] = 0;
@@ -5827,11 +5752,11 @@
/* Need to make the hash table bigger */
int i,arrSize;
struct s_x3 array;
array.size = arrSize = x3a->size*2;
array.count = x3a->count;
- array.tbl = (x3node*)lemon_calloc(arrSize, sizeof(x3node)+sizeof(x3node*));
+ array.tbl = (x3node*)calloc(arrSize, sizeof(x3node) + sizeof(x3node*));
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
array.ht = (x3node**)&(array.tbl[arrSize]);
for(i=0; icount; i++){
x3node *oldnp, *newnp;
@@ -5843,11 +5768,11 @@
newnp->key = oldnp->key;
newnp->data = oldnp->data;
newnp->from = &(array.ht[h]);
array.ht[h] = newnp;
}
- lemon_free(x3a->tbl);
+ free(x3a->tbl);
*x3a = array;
}
/* Insert the new data */
h = ph & (x3a->size-1);
np = &(x3a->tbl[x3a->count++]);
@@ -5884,11 +5809,11 @@
{
struct state **array;
int i,arrSize;
if( x3a==0 ) return 0;
arrSize = x3a->count;
- array = (struct state **)lemon_calloc(arrSize, sizeof(struct state *));
+ array = (struct state **)calloc(arrSize, sizeof(struct state *));
if( array ){
for(i=0; itbl[i].data;
}
return array;
}
@@ -5926,17 +5851,17 @@
static struct s_x4 *x4a;
/* Allocate a new associative array */
void Configtable_init(void){
if( x4a ) return;
- x4a = (struct s_x4*)lemon_malloc( sizeof(struct s_x4) );
+ x4a = (struct s_x4*)malloc( sizeof(struct s_x4) );
if( x4a ){
x4a->size = 64;
x4a->count = 0;
- x4a->tbl = (x4node*)lemon_calloc(64, sizeof(x4node) + sizeof(x4node*));
+ x4a->tbl = (x4node*)calloc(64, sizeof(x4node) + sizeof(x4node*));
if( x4a->tbl==0 ){
- lemon_free(x4a);
+ free(x4a);
x4a = 0;
}else{
int i;
x4a->ht = (x4node**)&(x4a->tbl[64]);
for(i=0; i<64; i++) x4a->ht[i] = 0;
@@ -5967,12 +5892,11 @@
/* Need to make the hash table bigger */
int i,arrSize;
struct s_x4 array;
array.size = arrSize = x4a->size*2;
array.count = x4a->count;
- array.tbl = (x4node*)lemon_calloc(arrSize,
- sizeof(x4node) + sizeof(x4node*));
+ array.tbl = (x4node*)calloc(arrSize, sizeof(x4node) + sizeof(x4node*));
if( array.tbl==0 ) return 0; /* Fail due to malloc failure */
array.ht = (x4node**)&(array.tbl[arrSize]);
for(i=0; icount; i++){
x4node *oldnp, *newnp;
@@ -5983,10 +5907,13 @@
newnp->next = array.ht[h];
newnp->data = oldnp->data;
newnp->from = &(array.ht[h]);
array.ht[h] = newnp;
}
+ /* free(x4a->tbl); // This code was originall written for 16-bit machines.
+ ** on modern machines, don't worry about freeing this trival amount of
+ ** memory. */
*x4a = array;
}
/* Insert the new data */
h = ph & (x4a->size-1);
np = &(x4a->tbl[x4a->count++]);