Snapshot of upstream SQLite 3.32.3

This commit is contained in:
Stephen Lombardo
2020-06-19 10:52:08 -04:00
parent c6a9d85534
commit ed8f99586a
24 changed files with 742 additions and 1960 deletions
+1 -1
View File
@@ -1 +1 @@
3.32.2
3.32.3
Vendored
+9 -9
View File
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for sqlite 3.32.2.
# Generated by GNU Autoconf 2.69 for sqlite 3.32.3.
#
#
# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
PACKAGE_VERSION='3.32.2'
PACKAGE_STRING='sqlite 3.32.2'
PACKAGE_VERSION='3.32.3'
PACKAGE_STRING='sqlite 3.32.3'
PACKAGE_BUGREPORT=''
PACKAGE_URL=''
@@ -1467,7 +1467,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
\`configure' configures sqlite 3.32.2 to adapt to many kinds of systems.
\`configure' configures sqlite 3.32.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1532,7 +1532,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
short | recursive ) echo "Configuration of sqlite 3.32.2:";;
short | recursive ) echo "Configuration of sqlite 3.32.3:";;
esac
cat <<\_ACEOF
@@ -1659,7 +1659,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
sqlite configure 3.32.2
sqlite configure 3.32.3
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2078,7 +2078,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by sqlite $as_me 3.32.2, which was
It was created by sqlite $as_me 3.32.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -12243,7 +12243,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
This file was extended by sqlite $as_me 3.32.2, which was
This file was extended by sqlite $as_me 3.32.3, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -12309,7 +12309,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
sqlite config.status 3.32.2
sqlite config.status 3.32.3
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
+6 -3
View File
@@ -2267,6 +2267,9 @@ static int fts3PoslistMerge(
*/
fts3GetDeltaVarint(&p1, &i1);
fts3GetDeltaVarint(&p2, &i2);
if( i1<2 || i2<2 ){
break;
}
do {
fts3PutDeltaVarint(&p, &iPrev, (i1<i2) ? i1 : i2);
iPrev -= 2;
@@ -2335,7 +2338,7 @@ static int fts3PoslistPhraseMerge(
/* Never set both isSaveLeft and isExact for the same invocation. */
assert( isSaveLeft==0 || isExact==0 );
assert( p!=0 && *p1!=0 && *p2!=0 );
assert_fts3_nc( p!=0 && *p1!=0 && *p2!=0 );
if( *p1==POS_COLUMN ){
p1++;
p1 += fts3GetVarint32(p1, &iCol1);
@@ -4520,7 +4523,7 @@ void sqlite3Fts3DoclistNext(
assert( nDoclist>0 );
assert( *pbEof==0 );
assert( p || *piDocid==0 );
assert_fts3_nc( p || *piDocid==0 );
assert( !p || (p>=aDoclist && p<=&aDoclist[nDoclist]) );
if( p==0 ){
@@ -5170,7 +5173,7 @@ static void fts3EvalInvalidatePoslist(Fts3Phrase *pPhrase){
**
** Parameter nNear is passed the NEAR distance of the expression (5 in
** the example above). When this function is called, *paPoslist points to
** the position list, and *pnToken is the number of phrase tokens in, the
** the position list, and *pnToken is the number of phrase tokens in the
** phrase on the other side of the NEAR operator to pPhrase. For example,
** if pPhrase refers to the "def ghi" phrase, then *paPoslist points to
** the position list associated with phrase "abc".
+22 -1872
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1 +1 @@
ec02243ea6ce33b090870ae55ab8aa2534b54d216d45c4aa2fdbb00e86861e8c
7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd
+4 -2
View File
@@ -200,16 +200,18 @@ static int hasSharedCacheTableLock(
** table. */
if( isIndex ){
HashElem *p;
int bSeen = 0;
for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){
Index *pIdx = (Index *)sqliteHashData(p);
if( pIdx->tnum==(int)iRoot ){
if( iTab ){
if( bSeen ){
/* Two or more indexes share the same root page. There must
** be imposter tables. So just return true. The assert is not
** useful in that case. */
return 1;
}
iTab = pIdx->pTable->tnum;
bSeen = 1;
}
}
}else{
@@ -1751,7 +1753,7 @@ static int freeSpace(MemPage *pPage, u16 iStart, u16 iSize){
nFrag = iFreeBlk - iEnd;
if( iEnd>iFreeBlk ) return SQLITE_CORRUPT_PAGE(pPage);
iEnd = iFreeBlk + get2byte(&data[iFreeBlk+2]);
if( NEVER(iEnd > pPage->pBt->usableSize) ){
if( iEnd > pPage->pBt->usableSize ){
return SQLITE_CORRUPT_PAGE(pPage);
}
iSize = iEnd - iStart;
+11 -2
View File
@@ -207,12 +207,21 @@ void sqlite3FinishCoding(Parse *pParse){
*/
sqlite3AutoincrementBegin(pParse);
/* Code constant expressions that where factored out of inner loops */
/* Code constant expressions that where factored out of inner loops.
**
** The pConstExpr list might also contain expressions that we simply
** want to keep around until the Parse object is deleted. Such
** expressions have iConstExprReg==0. Do not generate code for
** those expressions, of course.
*/
if( pParse->pConstExpr ){
ExprList *pEL = pParse->pConstExpr;
pParse->okConstFactor = 0;
for(i=0; i<pEL->nExpr; i++){
sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg);
int iReg = pEL->a[i].u.iConstExprReg;
if( iReg>0 ){
sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg);
}
}
}
+85 -4
View File
@@ -52,7 +52,12 @@ char sqlite3ExprAffinity(const Expr *pExpr){
op = pExpr->op;
if( op==TK_SELECT ){
assert( pExpr->flags&EP_xIsSelect );
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
if( ALWAYS(pExpr->x.pSelect)
&& pExpr->x.pSelect->pEList
&& ALWAYS(pExpr->x.pSelect->pEList->a[0].pExpr)
){
return sqlite3ExprAffinity(pExpr->x.pSelect->pEList->a[0].pExpr);
}
}
if( op==TK_REGISTER ) op = pExpr->op2;
#ifndef SQLITE_OMIT_CAST
@@ -2043,8 +2048,10 @@ static int exprNodeIsConstant(Walker *pWalker, Expr *pExpr){
/* Fall through */
case TK_IF_NULL_ROW:
case TK_REGISTER:
case TK_DOT:
testcase( pExpr->op==TK_REGISTER );
testcase( pExpr->op==TK_IF_NULL_ROW );
testcase( pExpr->op==TK_DOT );
pWalker->eCode = 0;
return WRC_Abort;
case TK_VARIABLE:
@@ -5650,10 +5657,25 @@ int sqlite3ExprCoveredByIndex(
*/
struct SrcCount {
SrcList *pSrc; /* One particular FROM clause in a nested query */
int iSrcInner; /* Smallest cursor number in this context */
int nThis; /* Number of references to columns in pSrcList */
int nOther; /* Number of references to columns in other FROM clauses */
};
/*
** xSelect callback for sqlite3FunctionUsesThisSrc(). If this is the first
** SELECT with a FROM clause encountered during this iteration, set
** SrcCount.iSrcInner to the cursor number of the leftmost object in
** the FROM cause.
*/
static int selectSrcCount(Walker *pWalker, Select *pSel){
struct SrcCount *p = pWalker->u.pSrcCount;
if( p->iSrcInner==0x7FFFFFFF && ALWAYS(pSel->pSrc) && pSel->pSrc->nSrc ){
pWalker->u.pSrcCount->iSrcInner = pSel->pSrc->a[0].iCursor;
}
return WRC_Continue;
}
/*
** Count the number of references to columns.
*/
@@ -5674,7 +5696,7 @@ static int exprSrcCount(Walker *pWalker, Expr *pExpr){
}
if( i<nSrc ){
p->nThis++;
}else if( nSrc==0 || pExpr->iTable<pSrc->a[0].iCursor ){
}else if( pExpr->iTable<p->iSrcInner ){
/* In a well-formed parse tree (no name resolution errors),
** TK_COLUMN nodes with smaller Expr.iTable values are in an
** outer context. Those are the only ones to count as "other" */
@@ -5696,9 +5718,10 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
assert( pExpr->op==TK_AGG_FUNCTION );
memset(&w, 0, sizeof(w));
w.xExprCallback = exprSrcCount;
w.xSelectCallback = sqlite3SelectWalkNoop;
w.xSelectCallback = selectSrcCount;
w.u.pSrcCount = &cnt;
cnt.pSrc = pSrcList;
cnt.iSrcInner = (pSrcList&&pSrcList->nSrc)?pSrcList->a[0].iCursor:0x7FFFFFFF;
cnt.nThis = 0;
cnt.nOther = 0;
sqlite3WalkExprList(&w, pExpr->x.pList);
@@ -5710,6 +5733,64 @@ int sqlite3FunctionUsesThisSrc(Expr *pExpr, SrcList *pSrcList){
return cnt.nThis>0 || cnt.nOther==0;
}
/*
** This is a Walker expression node callback.
**
** For Expr nodes that contain pAggInfo pointers, make sure the AggInfo
** object that is referenced does not refer directly to the Expr. If
** it does, make a copy. This is done because the pExpr argument is
** subject to change.
**
** The copy is stored on pParse->pConstExpr with a register number of 0.
** This will cause the expression to be deleted automatically when the
** Parse object is destroyed, but the zero register number means that it
** will not generate any code in the preamble.
*/
static int agginfoPersistExprCb(Walker *pWalker, Expr *pExpr){
if( ALWAYS(!ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced))
&& pExpr->pAggInfo!=0
){
AggInfo *pAggInfo = pExpr->pAggInfo;
int iAgg = pExpr->iAgg;
Parse *pParse = pWalker->pParse;
sqlite3 *db = pParse->db;
assert( pExpr->op==TK_AGG_COLUMN || pExpr->op==TK_AGG_FUNCTION );
if( pExpr->op==TK_AGG_COLUMN ){
assert( iAgg>=0 && iAgg<pAggInfo->nColumn );
if( pAggInfo->aCol[iAgg].pExpr==pExpr ){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aCol[iAgg].pExpr = pExpr;
pParse->pConstExpr =
sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
}
}
}else{
assert( iAgg>=0 && iAgg<pAggInfo->nFunc );
if( pAggInfo->aFunc[iAgg].pExpr==pExpr ){
pExpr = sqlite3ExprDup(db, pExpr, 0);
if( pExpr ){
pAggInfo->aFunc[iAgg].pExpr = pExpr;
pParse->pConstExpr =
sqlite3ExprListAppend(pParse, pParse->pConstExpr, pExpr);
}
}
}
}
return WRC_Continue;
}
/*
** Initialize a Walker object so that will persist AggInfo entries referenced
** by the tree that is walked.
*/
void sqlite3AggInfoPersistWalkerInit(Walker *pWalker, Parse *pParse){
memset(pWalker, 0, sizeof(*pWalker));
pWalker->pParse = pParse;
pWalker->xExprCallback = agginfoPersistExprCb;
pWalker->xSelectCallback = sqlite3SelectWalkNoop;
}
/*
** Add a new element to the pAggInfo->aCol[] array. Return the index of
** the new element. Return a negative number if malloc fails.
@@ -5740,7 +5821,7 @@ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){
&i
);
return i;
}
}
/*
** This is the xExprCallback for a tree walker. It is used to
+15
View File
@@ -529,11 +529,26 @@ int sqlite3SchemaToIndex(sqlite3 *db, Schema *pSchema){
return i;
}
/*
** Deallocate a single AggInfo object
*/
static void agginfoFree(sqlite3 *db, AggInfo *p){
sqlite3DbFree(db, p->aCol);
sqlite3DbFree(db, p->aFunc);
sqlite3DbFree(db, p);
}
/*
** Free all memory allocations in the pParse object
*/
void sqlite3ParserReset(Parse *pParse){
sqlite3 *db = pParse->db;
AggInfo *pThis = pParse->pAggList;
while( pThis ){
AggInfo *pNext = pThis->pNext;
agginfoFree(db, pThis);
pThis = pNext;
}
sqlite3DbFree(db, pParse->aLabel);
sqlite3ExprListDelete(db, pParse->pConstExpr);
if( db ){
+100 -54
View File
@@ -2717,9 +2717,7 @@ static int multiSelect(
selectOpName(p->op)));
rc = sqlite3Select(pParse, p, &uniondest);
testcase( rc!=SQLITE_OK );
/* Query flattening in sqlite3Select() might refill p->pOrderBy.
** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
sqlite3ExprListDelete(db, p->pOrderBy);
assert( p->pOrderBy==0 );
pDelete = p->pPrior;
p->pPrior = pPrior;
p->pOrderBy = 0;
@@ -3792,6 +3790,7 @@ static int flattenSubquery(
Expr *pWhere; /* The WHERE clause */
struct SrcList_item *pSubitem; /* The subquery */
sqlite3 *db = pParse->db;
Walker w; /* Walker to persist agginfo data */
/* Check to see if flattening is permitted. Return 0 if not.
*/
@@ -4105,7 +4104,7 @@ static int flattenSubquery(
** We look at every expression in the outer query and every place we see
** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
*/
if( pSub->pOrderBy ){
if( pSub->pOrderBy && (pParent->selFlags & SF_NoopOrderBy)==0 ){
/* At this point, any non-zero iOrderByCol values indicate that the
** ORDER BY column expression is identical to the iOrderByCol'th
** expression returned by SELECT statement pSub. Since these values
@@ -4129,7 +4128,13 @@ static int flattenSubquery(
if( isLeftJoin>0 ){
sqlite3SetJoinExpr(pWhere, iNewParent);
}
pParent->pWhere = sqlite3ExprAnd(pParse, pWhere, pParent->pWhere);
if( pWhere ){
if( pParent->pWhere ){
pParent->pWhere = sqlite3PExpr(pParse, TK_AND, pWhere, pParent->pWhere);
}else{
pParent->pWhere = pWhere;
}
}
if( db->mallocFailed==0 ){
SubstContext x;
x.pParse = pParse;
@@ -4166,6 +4171,8 @@ static int flattenSubquery(
/* Finially, delete what is left of the subquery and return
** success.
*/
sqlite3AggInfoPersistWalkerInit(&w, pParse);
sqlite3WalkSelect(&w,pSub1);
sqlite3SelectDelete(db, pSub1);
#if SELECTTRACE_ENABLED
@@ -4426,11 +4433,14 @@ static int pushDownWhereTerms(
){
Expr *pNew;
int nChng = 0;
Select *pSel;
if( pWhere==0 ) return 0;
if( pSubq->selFlags & SF_Recursive ) return 0; /* restriction (2) */
#ifndef SQLITE_OMIT_WINDOWFUNC
if( pSubq->pWin ) return 0; /* restriction (6) */
for(pSel=pSubq; pSel; pSel=pSel->pPrior){
if( pSel->pWin ) return 0; /* restriction (6) */
}
#endif
#ifdef SQLITE_DEBUG
@@ -4630,6 +4640,14 @@ static int convertCompoundSelectToSubquery(Walker *pWalker, Select *p){
for(pX=p; pX && (pX->op==TK_ALL || pX->op==TK_SELECT); pX=pX->pPrior){}
if( pX==0 ) return WRC_Continue;
a = p->pOrderBy->a;
#ifndef SQLITE_OMIT_WINDOWFUNC
/* If iOrderByCol is already non-zero, then it has already been matched
** to a result column of the SELECT statement. This occurs when the
** SELECT is rewritten for window-functions processing and then passed
** to sqlite3SelectPrep() and similar a second time. The rewriting done
** by this function is not required in this case. */
if( a[0].u.x.iOrderByCol ) return WRC_Continue;
#endif
for(i=p->pOrderBy->nExpr-1; i>=0; i--){
if( a[i].pExpr->flags & EP_Collate ) break;
}
@@ -5750,10 +5768,10 @@ int sqlite3Select(
Expr *pWhere; /* The WHERE clause. May be NULL */
ExprList *pGroupBy; /* The GROUP BY clause. May be NULL */
Expr *pHaving; /* The HAVING clause. May be NULL */
AggInfo *pAggInfo = 0; /* Aggregate information */
int rc = 1; /* Value to return from this function */
DistinctCtx sDistinct; /* Info on how to code the DISTINCT keyword */
SortCtx sSort; /* Info on how to code the ORDER BY clause */
AggInfo sAggInfo; /* Information used by aggregate queries */
int iEnd; /* Address of the end of the query */
sqlite3 *db; /* The database connection */
ExprList *pMinMaxOrderBy = 0; /* Added ORDER BY for min/max queries */
@@ -5765,7 +5783,6 @@ int sqlite3Select(
return 1;
}
if( sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0) ) return 1;
memset(&sAggInfo, 0, sizeof(sAggInfo));
#if SELECTTRACE_ENABLED
SELECTTRACE(1,pParse,p, ("begin processing:\n", pParse->addrExplain));
if( sqlite3SelectTrace & 0x100 ){
@@ -5787,6 +5804,7 @@ int sqlite3Select(
sqlite3ExprListDelete(db, p->pOrderBy);
p->pOrderBy = 0;
p->selFlags &= ~SF_Distinct;
p->selFlags |= SF_NoopOrderBy;
}
sqlite3SelectPrep(pParse, p, 0);
if( pParse->nErr || db->mallocFailed ){
@@ -6355,14 +6373,20 @@ int sqlite3Select(
** sAggInfo for all TK_AGG_FUNCTION nodes in expressions of the
** SELECT statement.
*/
pAggInfo = sqlite3DbMallocZero(db, sizeof(*pAggInfo) );
if( pAggInfo==0 ){
goto select_end;
}
pAggInfo->pNext = pParse->pAggList;
pParse->pAggList = pAggInfo;
memset(&sNC, 0, sizeof(sNC));
sNC.pParse = pParse;
sNC.pSrcList = pTabList;
sNC.uNC.pAggInfo = &sAggInfo;
sNC.uNC.pAggInfo = pAggInfo;
VVA_ONLY( sNC.ncFlags = NC_UAggInfo; )
sAggInfo.mnReg = pParse->nMem+1;
sAggInfo.nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
sAggInfo.pGroupBy = pGroupBy;
pAggInfo->mnReg = pParse->nMem+1;
pAggInfo->nSortingColumn = pGroupBy ? pGroupBy->nExpr : 0;
pAggInfo->pGroupBy = pGroupBy;
sqlite3ExprAnalyzeAggList(&sNC, pEList);
sqlite3ExprAnalyzeAggList(&sNC, sSort.pOrderBy);
if( pHaving ){
@@ -6375,14 +6399,14 @@ int sqlite3Select(
}
sqlite3ExprAnalyzeAggregates(&sNC, pHaving);
}
sAggInfo.nAccumulator = sAggInfo.nColumn;
if( p->pGroupBy==0 && p->pHaving==0 && sAggInfo.nFunc==1 ){
minMaxFlag = minMaxQuery(db, sAggInfo.aFunc[0].pExpr, &pMinMaxOrderBy);
pAggInfo->nAccumulator = pAggInfo->nColumn;
if( p->pGroupBy==0 && p->pHaving==0 && pAggInfo->nFunc==1 ){
minMaxFlag = minMaxQuery(db, pAggInfo->aFunc[0].pExpr, &pMinMaxOrderBy);
}else{
minMaxFlag = WHERE_ORDERBY_NORMAL;
}
for(i=0; i<sAggInfo.nFunc; i++){
Expr *pExpr = sAggInfo.aFunc[i].pExpr;
for(i=0; i<pAggInfo->nFunc; i++){
Expr *pExpr = pAggInfo->aFunc[i].pExpr;
assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
sNC.ncFlags |= NC_InAggFunc;
sqlite3ExprAnalyzeAggList(&sNC, pExpr->x.pList);
@@ -6394,22 +6418,22 @@ int sqlite3Select(
#endif
sNC.ncFlags &= ~NC_InAggFunc;
}
sAggInfo.mxReg = pParse->nMem;
pAggInfo->mxReg = pParse->nMem;
if( db->mallocFailed ) goto select_end;
#if SELECTTRACE_ENABLED
if( sqlite3SelectTrace & 0x400 ){
int ii;
SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", &sAggInfo));
SELECTTRACE(0x400,pParse,p,("After aggregate analysis %p:\n", pAggInfo));
sqlite3TreeViewSelect(0, p, 0);
for(ii=0; ii<sAggInfo.nColumn; ii++){
for(ii=0; ii<pAggInfo->nColumn; ii++){
sqlite3DebugPrintf("agg-column[%d] iMem=%d\n",
ii, sAggInfo.aCol[ii].iMem);
sqlite3TreeViewExpr(0, sAggInfo.aCol[ii].pExpr, 0);
ii, pAggInfo->aCol[ii].iMem);
sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pExpr, 0);
}
for(ii=0; ii<sAggInfo.nFunc; ii++){
for(ii=0; ii<pAggInfo->nFunc; ii++){
sqlite3DebugPrintf("agg-func[%d]: iMem=%d\n",
ii, sAggInfo.aFunc[ii].iMem);
sqlite3TreeViewExpr(0, sAggInfo.aFunc[ii].pExpr, 0);
ii, pAggInfo->aFunc[ii].iMem);
sqlite3TreeViewExpr(0, pAggInfo->aFunc[ii].pExpr, 0);
}
}
#endif
@@ -6434,10 +6458,11 @@ int sqlite3Select(
** that we do not need it after all, the OP_SorterOpen instruction
** will be converted into a Noop.
*/
sAggInfo.sortingIdx = pParse->nTab++;
pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pGroupBy,0,sAggInfo.nColumn);
pAggInfo->sortingIdx = pParse->nTab++;
pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pGroupBy,
0, pAggInfo->nColumn);
addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen,
sAggInfo.sortingIdx, sAggInfo.nSortingColumn,
pAggInfo->sortingIdx, pAggInfo->nSortingColumn,
0, (char*)pKeyInfo, P4_KEYINFO);
/* Initialize memory locations used by GROUP BY aggregate processing
@@ -6492,8 +6517,8 @@ int sqlite3Select(
nGroupBy = pGroupBy->nExpr;
nCol = nGroupBy;
j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
if( sAggInfo.aCol[i].iSorterColumn>=j ){
for(i=0; i<pAggInfo->nColumn; i++){
if( pAggInfo->aCol[i].iSorterColumn>=j ){
nCol++;
j++;
}
@@ -6501,8 +6526,8 @@ int sqlite3Select(
regBase = sqlite3GetTempRange(pParse, nCol);
sqlite3ExprCodeExprList(pParse, pGroupBy, regBase, 0, 0);
j = nGroupBy;
for(i=0; i<sAggInfo.nColumn; i++){
struct AggInfo_col *pCol = &sAggInfo.aCol[i];
for(i=0; i<pAggInfo->nColumn; i++){
struct AggInfo_col *pCol = &pAggInfo->aCol[i];
if( pCol->iSorterColumn>=j ){
int r1 = j + regBase;
sqlite3ExprCodeGetColumnOfTable(v,
@@ -6512,16 +6537,16 @@ int sqlite3Select(
}
regRecord = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterInsert, sAggInfo.sortingIdx, regRecord);
sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord);
sqlite3ReleaseTempReg(pParse, regRecord);
sqlite3ReleaseTempRange(pParse, regBase, nCol);
sqlite3WhereEnd(pWInfo);
sAggInfo.sortingIdxPTab = sortPTab = pParse->nTab++;
pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++;
sortOut = sqlite3GetTempReg(pParse);
sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol);
sqlite3VdbeAddOp2(v, OP_SorterSort, sAggInfo.sortingIdx, addrEnd);
sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd);
VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v);
sAggInfo.useSortingIdx = 1;
pAggInfo->useSortingIdx = 1;
}
/* If the index or temporary table used by the GROUP BY sort
@@ -6545,14 +6570,14 @@ int sqlite3Select(
*/
addrTopOfLoop = sqlite3VdbeCurrentAddr(v);
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_SorterData, sAggInfo.sortingIdx,
sqlite3VdbeAddOp3(v, OP_SorterData, pAggInfo->sortingIdx,
sortOut, sortPTab);
}
for(j=0; j<pGroupBy->nExpr; j++){
if( groupBySort ){
sqlite3VdbeAddOp3(v, OP_Column, sortPTab, j, iBMem+j);
}else{
sAggInfo.directMode = 1;
pAggInfo->directMode = 1;
sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
}
}
@@ -6582,14 +6607,14 @@ int sqlite3Select(
** the current row
*/
sqlite3VdbeJumpHere(v, addr1);
updateAccumulator(pParse, iUseFlag, &sAggInfo);
updateAccumulator(pParse, iUseFlag, pAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
VdbeComment((v, "indicate data in accumulator"));
/* End of the loop
*/
if( groupBySort ){
sqlite3VdbeAddOp2(v, OP_SorterNext, sAggInfo.sortingIdx, addrTopOfLoop);
sqlite3VdbeAddOp2(v, OP_SorterNext, pAggInfo->sortingIdx, addrTopOfLoop);
VdbeCoverage(v);
}else{
sqlite3WhereEnd(pWInfo);
@@ -6622,7 +6647,7 @@ int sqlite3Select(
VdbeCoverage(v);
VdbeComment((v, "Groupby result generator entry point"));
sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
finalizeAggFunctions(pParse, &sAggInfo);
finalizeAggFunctions(pParse, pAggInfo);
sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
selectInnerLoop(pParse, p, -1, &sSort,
&sDistinct, pDest,
@@ -6633,7 +6658,7 @@ int sqlite3Select(
/* Generate a subroutine that will reset the group-by accumulator
*/
sqlite3VdbeResolveLabel(v, addrReset);
resetAccumulator(pParse, &sAggInfo);
resetAccumulator(pParse, pAggInfo);
sqlite3VdbeAddOp2(v, OP_Integer, 0, iUseFlag);
VdbeComment((v, "indicate accumulator empty"));
sqlite3VdbeAddOp1(v, OP_Return, regReset);
@@ -6641,7 +6666,7 @@ int sqlite3Select(
} /* endif pGroupBy. Begin aggregate queries without GROUP BY: */
else {
Table *pTab;
if( (pTab = isSimpleCount(p, &sAggInfo))!=0 ){
if( (pTab = isSimpleCount(p, pAggInfo))!=0 ){
/* If isSimpleCount() returns a pointer to a Table structure, then
** the SQL statement is of the form:
**
@@ -6696,7 +6721,7 @@ int sqlite3Select(
if( pKeyInfo ){
sqlite3VdbeChangeP4(v, -1, (char *)pKeyInfo, P4_KEYINFO);
}
sqlite3VdbeAddOp2(v, OP_Count, iCsr, sAggInfo.aFunc[0].iMem);
sqlite3VdbeAddOp2(v, OP_Count, iCsr, pAggInfo->aFunc[0].iMem);
sqlite3VdbeAddOp1(v, OP_Close, iCsr);
explainSimpleCount(pParse, pTab, pBest);
}else{
@@ -6711,12 +6736,16 @@ int sqlite3Select(
** first row visited by the aggregate, so that they are updated at
** least once even if the FILTER clause means the min() or max()
** function visits zero rows. */
if( sAggInfo.nAccumulator ){
for(i=0; i<sAggInfo.nFunc; i++){
if( ExprHasProperty(sAggInfo.aFunc[i].pExpr, EP_WinFunc) ) continue;
if( sAggInfo.aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ) break;
if( pAggInfo->nAccumulator ){
for(i=0; i<pAggInfo->nFunc; i++){
if( ExprHasProperty(pAggInfo->aFunc[i].pExpr, EP_WinFunc) ){
continue;
}
if( pAggInfo->aFunc[i].pFunc->funcFlags&SQLITE_FUNC_NEEDCOLL ){
break;
}
}
if( i==sAggInfo.nFunc ){
if( i==pAggInfo->nFunc ){
regAcc = ++pParse->nMem;
sqlite3VdbeAddOp2(v, OP_Integer, 0, regAcc);
}
@@ -6727,7 +6756,7 @@ int sqlite3Select(
** of output.
*/
assert( p->pGroupBy==0 );
resetAccumulator(pParse, &sAggInfo);
resetAccumulator(pParse, pAggInfo);
/* If this query is a candidate for the min/max optimization, then
** minMaxFlag will have been previously set to either
@@ -6743,7 +6772,7 @@ int sqlite3Select(
if( pWInfo==0 ){
goto select_end;
}
updateAccumulator(pParse, regAcc, &sAggInfo);
updateAccumulator(pParse, regAcc, pAggInfo);
if( regAcc ) sqlite3VdbeAddOp2(v, OP_Integer, 1, regAcc);
if( sqlite3WhereIsOrdered(pWInfo)>0 ){
sqlite3VdbeGoto(v, sqlite3WhereBreakLabel(pWInfo));
@@ -6751,7 +6780,7 @@ int sqlite3Select(
(minMaxFlag==WHERE_ORDERBY_MIN?"min":"max")));
}
sqlite3WhereEnd(pWInfo);
finalizeAggFunctions(pParse, &sAggInfo);
finalizeAggFunctions(pParse, pAggInfo);
}
sSort.pOrderBy = 0;
@@ -6790,8 +6819,25 @@ int sqlite3Select(
*/
select_end:
sqlite3ExprListDelete(db, pMinMaxOrderBy);
sqlite3DbFree(db, sAggInfo.aCol);
sqlite3DbFree(db, sAggInfo.aFunc);
#ifdef SQLITE_DEBUG
if( pAggInfo && !db->mallocFailed ){
for(i=0; i<pAggInfo->nColumn; i++){
Expr *pExpr = pAggInfo->aCol[i].pExpr;
assert( pExpr!=0 || db->mallocFailed );
if( pExpr==0 ) continue;
assert( pExpr->pAggInfo==pAggInfo );
assert( pExpr->iAgg==i );
}
for(i=0; i<pAggInfo->nFunc; i++){
Expr *pExpr = pAggInfo->aFunc[i].pExpr;
assert( pExpr!=0 || db->mallocFailed );
if( pExpr==0 ) continue;
assert( pExpr->pAggInfo==pAggInfo );
assert( pExpr->iAgg==i );
}
}
#endif
#if SELECTTRACE_ENABLED
SELECTTRACE(0x1,pParse,p,("end processing\n"));
if( (sqlite3SelectTrace & 0x2000)!=0 && ExplainQueryPlanParent(pParse)==0 ){
+16 -4
View File
@@ -2506,11 +2506,11 @@ struct AggInfo {
ExprList *pGroupBy; /* The group by clause */
struct AggInfo_col { /* For each column used in source tables */
Table *pTab; /* Source table */
int iTable; /* Cursor number of the source table */
int iColumn; /* Column number within the source table */
int iSorterColumn; /* Column number in the sorting index */
int iMem; /* Memory location that acts as accumulator */
Expr *pExpr; /* The original expression */
int iTable; /* Cursor number of the source table */
int iMem; /* Memory location that acts as accumulator */
i16 iColumn; /* Column number within the source table */
i16 iSorterColumn; /* Column number in the sorting index */
} *aCol;
int nColumn; /* Number of used entries in aCol[] */
int nAccumulator; /* Number of columns that show through to the output.
@@ -2523,8 +2523,17 @@ struct AggInfo {
int iDistinct; /* Ephemeral table used to enforce DISTINCT */
} *aFunc;
int nFunc; /* Number of entries in aFunc[] */
#ifdef SQLITE_DEBUG
int iAggMagic; /* Magic number when valid */
#endif
AggInfo *pNext; /* Next in list of them all */
};
/*
** Value for AggInfo.iAggMagic when the structure is valid
*/
#define AggInfoMagic 0x2059e99e
/*
** The datatype ynVar is a signed integer, either 16-bit or 32-bit.
** Usually it is 16-bits. But if SQLITE_MAX_VARIABLE_NUMBER is greater
@@ -3105,6 +3114,7 @@ struct Select {
#define SF_WhereBegin 0x0080000 /* Really a WhereBegin() call. Debug Only */
#define SF_WinRewrite 0x0100000 /* Window function rewrite accomplished */
#define SF_View 0x0200000 /* SELECT statement is a view */
#define SF_NoopOrderBy 0x0400000 /* ORDER BY is ignored for this query */
/*
** The results of a SELECT can be distributed in several ways, as defined
@@ -3321,6 +3331,7 @@ struct Parse {
Parse *pToplevel; /* Parse structure for main program (or NULL) */
Table *pTriggerTab; /* Table triggers are being coded for */
Parse *pParentParse; /* Parent parser if this parser is nested */
AggInfo *pAggList; /* List of all AggInfo objects */
int addrCrTab; /* Address of OP_CreateBtree opcode on CREATE TABLE */
u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */
u32 oldmask; /* Mask of old.* columns referenced */
@@ -4287,6 +4298,7 @@ int sqlite3ExprCompareSkip(Expr*, Expr*, int);
int sqlite3ExprListCompare(ExprList*, ExprList*, int);
int sqlite3ExprImpliesExpr(Parse*,Expr*, Expr*, int);
int sqlite3ExprImpliesNonNullRow(Expr*,int);
void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*);
void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*);
void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*);
int sqlite3ExprCoveredByIndex(Expr*, int iCur, Index *pIdx);
+1 -1
View File
@@ -2076,7 +2076,7 @@ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */
if( (flags1 | flags3)&MEM_Str ){
if( (flags1 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
applyNumericAffinity(pIn1,0);
assert( flags3==pIn3->flags );
testcase( flags3==pIn3->flags );
flags3 = pIn3->flags;
}
if( (flags3 & (MEM_Int|MEM_IntReal|MEM_Real|MEM_Str))==MEM_Str ){
+4 -1
View File
@@ -956,12 +956,16 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
Window *pMWin = p->pWin; /* Master window object */
Window *pWin; /* Window object iterator */
Table *pTab;
Walker w;
u32 selFlags = p->selFlags;
pTab = sqlite3DbMallocZero(db, sizeof(Table));
if( pTab==0 ){
return sqlite3ErrorToParser(db, SQLITE_NOMEM);
}
sqlite3AggInfoPersistWalkerInit(&w, pParse);
sqlite3WalkSelect(&w, p);
p->pSrc = 0;
p->pWhere = 0;
@@ -1042,7 +1046,6 @@ int sqlite3WindowRewrite(Parse *pParse, Select *p){
p->pSrc = sqlite3SrcListAppend(pParse, 0, 0, 0);
if( p->pSrc ){
Table *pTab2;
Walker w;
p->pSrc->a[0].pSelect = pSub;
sqlite3SrcListAssignCursors(pParse, p->pSrc);
pSub->selFlags |= SF_Expanded;
+47
View File
@@ -17,6 +17,7 @@
set testdir [file dirname $argv0]
source $testdir/tester.tcl
set testprefix aggnested
do_test aggnested-1.1 {
db eval {
@@ -259,6 +260,52 @@ do_execsql_test aggnested-4.4 {
SELECT max((SELECT a FROM (SELECT count(*) AS a FROM ty) AS s)) FROM tx;
} {3}
#--------------------------------------------------------------------------
#
reset_db
do_execsql_test 5.0 {
CREATE TABLE x1(a, b);
INSERT INTO x1 VALUES(1, 2);
CREATE TABLE x2(x);
INSERT INTO x2 VALUES(NULL), (NULL), (NULL);
}
# At one point, aggregate "total()" in the query below was being processed
# as part of the outer SELECT, not as part of the sub-select with no FROM
# clause.
do_execsql_test 5.1 {
SELECT ( SELECT total( (SELECT b FROM x1) ) ) FROM x2;
} {2.0 2.0 2.0}
do_execsql_test 5.2 {
SELECT ( SELECT total( (SELECT 2 FROM x1) ) ) FROM x2;
} {2.0 2.0 2.0}
do_execsql_test 5.3 {
CREATE TABLE t1(a);
CREATE TABLE t2(b);
}
do_execsql_test 5.4 {
SELECT(
SELECT max(b) LIMIT (
SELECT total( (SELECT a FROM t1) )
)
)
FROM t2;
} {{}}
do_execsql_test 5.5 {
CREATE TABLE a(b);
WITH c AS(SELECT a)
SELECT(SELECT(SELECT group_concat(b, b)
LIMIT(SELECT 0.100000 *
AVG(DISTINCT(SELECT 0 FROM a ORDER BY b, b, b))))
FROM a GROUP BY b,
b, b) FROM a EXCEPT SELECT b FROM a ORDER BY b,
b, b;
}
+84
View File
@@ -1182,5 +1182,89 @@ do_catchsql_test 14.2 {
ALTER TABLE t1 RENAME TO alkjalkjdfiiiwuer987lkjwer82mx97sf98788s9789s;
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
do_test 15.0 {
sqlite3 db {}
db deserialize [decode_hexdb {
| size 28672 pagesize 4096 filename crash-3afa1ca9e9c1bd.db
| page 1 offset 0
| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3.
| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07 .....@ ........
| 32: 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 04 ................
| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................
| 96: 00 00 00 00 0d 00 00 00 06 0e 88 00 0f b8 0f 6d ...............m
| 112: 0f 3a 0f 0b 0e d5 0e 88 01 00 00 00 00 00 00 00 .:..............
| 3712: 00 00 00 00 00 00 00 00 4b 06 06 17 25 25 01 5b ........K...%%.[
| 3728: 74 61 62 6c 65 73 71 6c 69 74 65 5f 73 74 61 74 tablesqlite_stat
| 3744: 31 73 71 6c 69 74 65 5f 73 74 61 74 31 07 43 52 1sqlite_stat1.CR
| 3760: 45 41 54 45 20 54 41 42 4c 45 20 73 71 6c 69 74 EATE TABLE sqlit
| 3776: 65 5f 73 74 61 74 31 28 74 62 6c 2c 69 64 78 2c e_stat1(tbl,idx,
| 3792: 73 74 61 74 29 34 05 06 17 13 11 01 53 69 6e 64 stat)4......Sind
| 3808: 65 78 63 31 63 63 31 06 43 52 45 41 54 45 20 55 exc1cc1.CREATE U
| 3824: 4e 49 51 55 45 20 49 4e 44 45 58 20 63 31 63 20 NIQUE INDEX c1c
| 3840: 4f 4e 20 63 31 28 63 2c 20 62 29 2d 04 06 17 13 ON c1(c, b)-....
| 3856: 11 01 45 69 6e 64 65 78 63 31 64 63 31 05 43 52 ..Eindexc1dc1.CR
| 3872: 45 41 54 45 20 49 4e 44 45 58 20 63 31 64 20 4f EATE INDEX c1d O
| 3888: 4e 20 63 31 28 64 2c 20 62 29 31 03 06 17 13 11 N c1(d, b)1.....
| 3904: 01 4d 69 6e 64 65 78 62 31 63 62 31 05 43 52 45 .Mindexb1cb1.CRE
| 3920: 41 54 45 20 55 4e 49 51 55 45 20 49 4e 44 45 58 ATE UNIQUE INDEX
| 3936: 20 62 31 63 20 4f 4e 20 62 31 28 63 29 49 02 06 b1c ON b1(c)I..
| 3952: 17 11 11 0f 7f 74 61 62 6c 65 63 31 63 31 03 43 .....tablec1c1.C
| 3968: 52 45 41 54 45 20 54 41 42 4c 45 20 63 31 28 61 REATE TABLE c1(a
| 3984: 20 49 4e 54 20 50 52 49 4d 41 52 59 20 4b 45 59 INT PRIMARY KEY
| 4000: 2c 20 62 2c 20 63 2c 20 64 29 20 57 49 54 48 4f , b, c, d) WITHO
| 4016: 55 54 20 52 4f 57 49 44 46 01 06 17 11 11 01 79 UT ROWIDF......y
| 4032: 74 61 62 6c 65 62 31 62 31 02 43 52 45 41 54 45 tableb1b1.CREATE
| 4048: 20 54 41 42 4c 45 20 62 31 28 61 20 49 4e 54 20 TABLE b1(a INT
| 4064: 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 62 2c 20 PRIMARY KEY, b,
| 4080: 63 29 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 c) WITHOUT ROWID
| page 2 offset 4096
| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f e2 ................
| 16: 0f da 00 00 00 01 00 00 00 00 00 00 00 00 00 00 ................
| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 06 ................
| 4048: 67 07 07 04 01 0f 01 06 66 06 07 04 01 0f 01 05 g.......f.......
| 4064: 65 05 07 04 01 0f 01 04 64 04 07 04 01 0f 01 03 e.......d.......
| 4080: 63 03 07 04 01 0f 01 02 62 0f 05 04 09 0f 09 61 c.......b......a
| page 3 offset 8192
| 0: 0a 00 00 00 07 0f bd 00 0f f9 0f ef 0f e5 0f db ................
| 16: 0f d1 0f c7 0f bd 00 00 00 00 01 00 00 00 00 00 ................
| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 09 05 01 ................
| 4032: 0f 01 01 07 61 07 07 09 05 01 0f 01 01 06 61 06 ....a.........a.
| 4048: 06 09 05 01 0f 01 01 05 61 05 05 09 05 01 0f 01 ........a.......
| 4064: 01 04 61 04 04 09 05 01 0f 01 01 03 61 03 03 09 ..a.........a...
| 4080: 05 01 0f 01 01 02 61 0f 02 06 05 09 0f 09 09 61 ......a........a
| page 4 offset 12288
| 0: 0a 00 00 00 07 0f d8 00 0f fc 0f f0 0f ea 0f e4 ................
| 16: 0f de 0f d8 0f f6 00 00 00 00 00 00 00 00 00 00 ................
| 4048: 00 00 00 00 00 00 00 00 05 03 01 01 07 07 05 03 ................
| 4064: 01 01 06 06 05 03 01 01 05 05 05 03 01 01 04 04 ................
| 4080: 05 03 01 01 03 03 05 03 01 01 0f 02 03 03 09 09 ................
| page 5 offset 16384
| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f f2 0f ea 0f 00 ................
| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07 ................
| 4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05 a.......a.......
| 4064: 61 05 07 04 01 1f 01 04 61 04 07 04 01 0f 01 03 a.......a.......
| 4080: 61 03 07 04 01 0f 01 02 61 02 05 04 09 0f 09 61 a.......a......a
| page 6 offset 20480
| 0: 0a 00 00 00 07 0f ca 00 0f fa 0f ea 0f e2 00 00 ................
| 4032: 00 00 00 00 00 00 00 00 00 00 07 04 01 0f 01 07 ................
| 4048: 61 07 07 04 01 0f 01 06 61 06 07 04 01 0f 01 05 a.......a.......
| 4064: 61 05 07 04 01 0f 01 04 61 04 07 04 01 0f 01 03 a.......a.......
| 4080: 61 03 07 04 01 0f 01 0f 61 02 05 04 09 0f 09 61 a.......a......a
| page 7 offset 24576
| 0: 0d 00 00 00 05 0f 1c 00 0f f0 0f e0 0f d3 0f c5 ................
| 16: 0f b8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
| 4016: 00 00 00 00 00 00 00 00 0b 05 04 11 11 13 62 31 ..............b1
| 4032: 62 31 37 20 31 0c 04 04 11 13 13 62 31 62 31 63 b17 1......b1b1c
| 4048: 37 20 31 0b 03 04 11 11 13 63 31 63 31 37 20 31 7 1......c1c17 1
| 4064: 0e 02 04 11 13 07 63 31 63 31 64 37 20 31 20 31 ......c1c1d7 1 1
| 4080: 0e 01 04 11 13 17 63 31 63 31 63 37 20 31 00 00 ......c1c1c7 1..
| end crash-3afa1ca9e9c1bd.db
}]} {}
do_execsql_test 15.1 {
UPDATE c1 SET c= NOT EXISTS(SELECT 1 FROM c1 ORDER BY (SELECT 1 FROM c1 ORDER BY a)) +10 WHERE d BETWEEN 4 AND 7;
} {}
finish_test
+1 -1
View File
@@ -16,6 +16,7 @@ source $testdir/tester.tcl
ifcapable !fts3 { finish_test ; return }
set ::testprefix fts3corrupt2
sqlite3_fts3_may_be_corrupt 1
set data [list]
lappend data {*}{
@@ -107,5 +108,4 @@ foreach c {50 100 150 200 250} {
finish_test
+60 -3
View File
@@ -5849,8 +5849,6 @@ do_catchsql_test 37.1 {
#-------------------------------------------------------------------------
#
reset_db
reset_db
do_test 38.0 {
sqlite3 db {}
@@ -6061,9 +6059,68 @@ do_execsql_test 38.1 {
UPDATE t1 SET b=a;
}
do_catchsql_test 38.1 {
do_catchsql_test 38.2 {
SELECT b FROM t1 WHERE a MATCH 'e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*e*'
} {1 {database disk image is malformed}}
#-------------------------------------------------------------------------
reset_db
set saved $sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1
do_execsql_test 39.0 {
CREATE VIRTUAL TABLE t0 USING fts3(
col0 INTEGER PRIMARY KEY,
col1 VARCHAR(8),
col2 BINARY,
col3 BINARY
);
INSERT INTO t0_content VALUES(1,1,'1234','aaaa','bbbb');
INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',X'000131030782000103323334050101010200000461616161050101020200000462626262050101030200');
}
do_test 39.1 {
catch {
db eval { SELECT rowid FROM t0 WHERE t0 MATCH '1 NEAR 1' }
}
} 0
do_test 39.2 {
catch {
db eval {
SELECT matchinfo(t0,'yxy') FROM t0 WHERE t0 MATCH x'2b0a312b0a312a312a2a0b5d0a0b0b0a312a0a0b0b0a312a0b310a392a0b0a27312a2a0b5d0a312a0b310a31315d0b310a312a316d2a0b313b15bceaa50a312a0b0a27312a2a0b5d0a312a0b310a312b0b2a310a312a0b2a0b2a0b2e5d0a0bff313336e34a2a312a0b0a3c310b0a0b4b4b0b4b2a4bec40322b2a0b310a0a312a0a0a0a0a0a0a0a0a0b310a312a2a2a0b5d0a0b0b0a312a0b310a312a0b0a4e4541530b310a5df5ced70a0a0a0a0a4f520a0a0a0a0a0a0a312a0b0a4e4541520b310a5d616161610a0a0a0a4f520a0a0a0a0a0a312b0a312a312a0a0a0a0a0a0a004a0b0a310b220a0b0a310a4a22310a0b0a7e6fe0e0e030e0e0e0e0e01176e02000e0e0e0e0e01131320226310a0b0a310a4a22310a0b0a310a766f8b8b4ee0e0300ae0090909090909090909090909090909090909090909090909090909090909090947aaaa540b09090909090909090909090909090909090909090909090909090909090909fae0e0f2f22164e0e0f273e07fefefef7d6dfafafafa6d6d6d6d';
}
}
} 0
set sqlite_fts3_enable_parentheses $saved
#-------------------------------------------------------------------------
reset_db
set saved $sqlite_fts3_enable_parentheses
set sqlite_fts3_enable_parentheses 1
do_execsql_test 40.1 {
CREATE VIRTUAL TABLE t0 USING fts3(col0 INTEGER PRIMARY KEY, col1, col2 ,col3 );
INSERT INTO t0_segdir VALUES(0,0,0,0,'0 42',
X'0001310301020001033233340500010102000004616161bc050101020200000462626262050101030200'
);
}
do_execsql_test 40.2 {
SELECT 0==matchinfo(t0,'sx') FROM t0 WHERE t0 MATCH '1* 2 3 4 5 6 OR 1';
} 0
set sqlite_fts3_enable_parentheses $saved
#-------------------------------------------------------------------------
reset_db
do_execsql_test 41.1 {
CREATE VIRTUAL TABLE t1 USING fts3(a,b,c);
INSERT INTO t1_segdir VALUES(0,0,0,0,'0 835',X'000130120106000106000106001f030001030001030000083230313630363039090107000107000107000001340901050001050001050000013509010400010400010400010730303030303030091c0400010400010400000662696e6172793c0301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000008636f3870696c657209010200010200010200000664627374617409070300010300010300010465627567090402000102000102000006656e61626c653f07020001020001020001020001020001020001020001020001020001030001010002020001020001020001020001120001020001020001020001020001020001087874656e73696f6e091f0400010400010400000466747334090a0300010300010400030135090d03000103000103000003676363090103000103000103000106656f706f6c790910030001030001030000056a736f6e310913030001030001030000046c6f6164091f030001030001030000036d6178091c02000102000102000105656d6f7279091c03000103000103000304737973350916030001030001030000066e6f636173653c02010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020000046f6d6974091f020001020001020000057274726565091903000103000103000302696d3c010102020003010202000301020200030102020003010202000301020200030102020003010202000301020200030102020003010202000301020200000a746872656164736166650922020001020001020000047674616209070400010400010400000178b401010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200010101020001010102000101010200');
}
do_execsql_test 41.2 {
SELECT offsets(t1) FROM t1 WHERE t1 MATCH 'rtree ner "json1^enable"';
}
finish_test
BIN
View File
Binary file not shown.
+29
View File
@@ -172,4 +172,33 @@ do_execsql_test istrue-710 {
SELECT 0.0 IS FALSE COLLATE BINARY;
} {1 1 1 1 1 1 1 1 1}
# 2020-06-12 bug report from Chromium
# https://bugs.chromium.org/p/chromium/issues/detail?id=1094247
do_catchsql_test istrue-800 {
SELECT 9 IN (false.false);
} {1 {no such column: false.false}}
do_execsql_test istrue-810 {
CREATE TABLE t8(a INT, true INT, false INT, d INT);
INSERT INTO t8(a,true,false,d) VALUES(5,6,7,8),(4,3,2,1),('a','b','c','d');
SELECT * FROM t8 ORDER BY false;
} {4 3 2 1 5 6 7 8 a b c d}
do_catchsql_test istrue-820 {
SELECT 9 IN (false.false) FROM t8;
} {1 {no such column: false.false}}
do_execsql_test istrue-830 {
CREATE TABLE false(true INT, false INT, x INT CHECK (5 IN (false.false)));
} {}
do_execsql_test istrue-840 {
INSERT INTO False VALUES(4,5,6);
} {}
do_catchsql_test istrue-841 {
INSERT INTO False VALUES(5,6,7);
} {1 {CHECK constraint failed: false}}
do_execsql_test istrue-850 {
SELECT 9 IN (false.false) FROM false;
} {0}
do_execsql_test istrue-851 {
SELECT 5 IN (false.false) FROM false;
} {1}
finish_test
+9
View File
@@ -314,4 +314,13 @@ do_execsql_test select3-9.100 {
SELECT * FROM t0 GROUP BY c0;
} {1.0 1.0}
reset_db
do_execsql_test select3.10.100 {
CREATE TABLE t1(a, b);
CREATE TABLE t2(c, d);
SELECT max(t1.a),
(SELECT 'xyz' FROM (SELECT * FROM t2 WHERE 0) WHERE t1.b=1)
FROM t1;
} {{} {}}
finish_test
+21
View File
@@ -1446,5 +1446,26 @@ do_execsql_test 6.1 {
SELECT * FROM (SELECT a FROM t1 UNION SELECT b FROM t2) WHERE a=a;
} {12345}
# 2020-06-15 ticket 8f157e8010b22af0
#
reset_db
do_execsql_test 7.1 {
CREATE TABLE t1(c1); INSERT INTO t1 VALUES(12),(123),(1234),(NULL),('abc');
CREATE TABLE t2(c2); INSERT INTO t2 VALUES(44),(55),(123);
CREATE TABLE t3(c3,c4); INSERT INTO t3 VALUES(66,1),(123,2),(77,3);
CREATE VIEW t4 AS SELECT c3 FROM t3;
CREATE VIEW t5 AS SELECT c3 FROM t3 ORDER BY c4;
}
do_execsql_test 7.2 {
SELECT * FROM t1, t2 WHERE c1=(SELECT 123 INTERSECT SELECT c2 FROM t4) AND c1=123;
} {123 123}
do_execsql_test 7.3 {
SELECT * FROM t1, t2 WHERE c1=(SELECT 123 INTERSECT SELECT c2 FROM t5) AND c1=123;
} {123 123}
do_execsql_test 7.4 {
CREATE TABLE a(b);
CREATE VIEW c(d) AS SELECT b FROM a ORDER BY b;
SELECT sum(d) OVER( PARTITION BY(SELECT 0 FROM c JOIN a WHERE b =(SELECT b INTERSECT SELECT d FROM c) AND b = 123)) FROM c;
} {}
finish_test
+11
View File
@@ -317,4 +317,15 @@ do_execsql_test 9.10 {
SELECT coalesce(max(quote(a)),10) FROM t1 GROUP BY a;
} {NULL '' 'X'}
# 2020-06-14: assert() changed back into testcase()
# ticket 9fb26d37cefaba40
#
reset_db
do_execsql_test 10.1 {
CREATE TABLE a(b TEXT); INSERT INTO a VALUES(0),(4),(9);
CREATE TABLE c(d NUM);
CREATE VIEW f(g, h) AS SELECT b, 0 FROM a UNION SELECT d, d FROM c;
SELECT g = g FROM f GROUP BY h;
} {1}
finish_test
+203
View File
@@ -1743,5 +1743,208 @@ do_execsql_test 53.0 {
WHERE a.c);
} {4 4 4 4}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 54.1 {
CREATE TABLE t1(a VARCHAR(20), b FLOAT);
INSERT INTO t1 VALUES('1',10.0);
}
do_catchsql_test 54.2 {
SELECT * FROM (
SELECT sum(b) OVER() AS c FROM t1
UNION
SELECT b AS c FROM t1
) WHERE c>10;
} {0 {}}
do_execsql_test 54.3 {
INSERT INTO t1 VALUES('2',5.0);
INSERT INTO t1 VALUES('3',15.0);
}
do_catchsql_test 54.4 {
SELECT * FROM (
SELECT sum(b) OVER() AS c FROM t1
UNION
SELECT b AS c FROM t1
) WHERE c>10;
} {0 {15.0 30.0}}
# 2020-06-05 ticket c8d3b9f0a750a529
reset_db
do_execsql_test 55.1 {
CREATE TABLE a(b);
SELECT
(SELECT b FROM a
GROUP BY b
HAVING (SELECT COUNT()OVER() + lead(b)OVER(ORDER BY SUM(DISTINCT b) + b))
)
FROM a
UNION
SELECT 99
ORDER BY 1;
} {99}
#------------------------------------------------------------------------
reset_db
do_execsql_test 56.1 {
CREATE TABLE t1(a, b INTEGER);
CREATE TABLE t2(c, d);
}
do_catchsql_test 56.2 {
SELECT avg(b) FROM t1
UNION ALL
SELECT min(c) OVER () FROM t2
ORDER BY nosuchcolumn;
} {1 {1st ORDER BY term does not match any column in the result set}}
reset_db
do_execsql_test 57.1 {
CREATE TABLE t4(a, b, c, d, e);
}
do_catchsql_test 57.2 {
SELECT b FROM t4
UNION
SELECT a FROM t4
ORDER BY (
SELECT sum(x) OVER() FROM (
SELECT c AS x FROM t4
UNION
SELECT d FROM t4
ORDER BY (SELECT e FROM t4)
)
);
} {1 {1st ORDER BY term does not match any column in the result set}}
# 2020-06-06 various dbsqlfuzz finds and
# ticket 0899cf62f597d7e7
#
reset_db
do_execsql_test 57.1 {
CREATE TABLE t1(a, b, c);
INSERT INTO t1 VALUES(NULL,NULL,NULL);
SELECT
sum(a),
min(b) OVER (),
count(c) OVER (ORDER BY b)
FROM t1;
} {{} {} 0}
do_execsql_test 57.2 {
CREATE TABLE v0 ( v1 INTEGER PRIMARY KEY ) ;
INSERT INTO v0 VALUES ( 10 ) ;
SELECT DISTINCT v1, lead(v1) OVER() FROM v0 GROUP BY v1 ORDER BY 2;
} {10 {}}
do_catchsql_test 57.3 {
DROP TABLE t1;
CREATE TABLE t1(a);
INSERT INTO t1(a) VALUES(22);
CREATE TABLE t3(y);
INSERT INTO t3(y) VALUES(5),(11),(-9);
SELECT (
SELECT max(y) OVER( ORDER BY (SELECT x FROM (SELECT sum(y) AS x FROM t1)))
)
FROM t3;
} {1 {misuse of aggregate: sum()}}
# 2020-06-06 ticket 1f6f353b684fc708
reset_db
do_execsql_test 58.1 {
CREATE TABLE a(a, b, c);
INSERT INTO a VALUES(1, 2, 3);
INSERT INTO a VALUES(4, 5, 6);
SELECT sum(345+b) OVER (ORDER BY b),
sum(avg(678)) OVER (ORDER BY c) FROM a;
} {347 678.0}
# 2020-06-06 ticket e5504e987e419fb0
do_catchsql_test 59.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(x INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES (123);
SELECT
ntile( (SELECT sum(x)) ) OVER(ORDER BY x),
min(x) OVER(ORDER BY x)
FROM t1;
} {1 {misuse of aggregate: sum()}}
# 2020-06-07 ticket f7d890858f361402
do_execsql_test 60.1 {
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (x INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES (99);
SELECT EXISTS(SELECT count(*) OVER() FROM t1 ORDER BY sum(x) OVER());
} {1}
# 2020-06-07 test case generated by dbsqlfuzz showing how an AggInfo
# object might be referenced after the sqlite3Select() call that created
# it returns. This proves the need to persist all AggInfo objects until
# the Parse object is destroyed.
#
reset_db
do_execsql_test 61.1 {
CREATE TABLE t1(a);
INSERT INTO t1 VALUES(5),(NULL),('seventeen');
SELECT (SELECT max(x)OVER(ORDER BY x) % min(x)OVER(ORDER BY CASE x WHEN 889 THEN x WHEN x THEN x END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST((SELECT (SELECT max(x)OVER(ORDER BY x) / min(x)OVER(ORDER BY CASE x WHEN 889 THEN 299 WHEN -true THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a IN(SELECT (SELECT max(x) & sum ( a )OVER(ORDER BY CASE x WHEN -8 THEN 299 WHEN 863 THEN 863 END)) FROM (SELECT (SELECT sum(CAST(a AS )) FROM t1) AS x FROM t1)) AS t1 )) FROM t1) AS x FROM t1)) AS x )) FROM t1) AS x FROM t1)) AS real)) FROM t1) AS x FROM t1);
} {{} {} {}}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 62.1 {
CREATE TABLE t1(a VARCHAR(20), b FLOAT);
INSERT INTO t1 VALUES('1',10.0);
}
do_execsql_test 62.2 {
SELECT * FROM (
SELECT sum(b) OVER() AS c FROM t1
UNION
SELECT b AS c FROM t1
) WHERE c>10;
}
do_execsql_test 62.3 {
INSERT INTO t1 VALUES('2',5.0);
INSERT INTO t1 VALUES('3',15.0);
}
do_execsql_test 62.4 {
SELECT * FROM (
SELECT sum(b) OVER() AS c FROM t1
UNION
SELECT b AS c FROM t1
) WHERE c>10;
} {15.0 30.0}
#-------------------------------------------------------------------------
reset_db
do_execsql_test 63.1 {
CREATE TABLE t1(b, x);
CREATE TABLE t2(c, d);
CREATE TABLE t3(e, f);
}
do_execsql_test 63.2 {
SELECT max(b) OVER(
ORDER BY SUM(
(SELECT c FROM t2 UNION SELECT x ORDER BY c)
)
) FROM t1;
} {{}}
do_execsql_test 63.3 {
SELECT sum(b) over(
ORDER BY (
SELECT max(b) OVER(
ORDER BY sum(
(SELECT x AS c UNION SELECT 1234 ORDER BY c)
)
) AS e
ORDER BY e
)
)
FROM t1;
} {{}}
finish_test
+2 -2
View File
@@ -255,7 +255,7 @@ do_execsql_test 8.2 {
do_catchsql_test 8.3 {
SELECT min( max((SELECT x FROM v1)) ) OVER()
} {1 {misuse of aggregate: max()}}
} {0 0}
do_execsql_test 8.4 {
SELECT(
@@ -263,6 +263,6 @@ do_execsql_test 8.4 {
SELECT sum( avg((SELECT x FROM v1)) ) OVER()
)
FROM v1;
} {0.0}
} {0.0 0.0}
finish_test