Compare commits

...

12 Commits

Author SHA1 Message Date
drh ee3686eb50 Version 3.32.3
FossilOrigin-Name: 7ebdfa80be8e8e73324b8d66b3460222eb74c7e9dfd655b48d6ca7e1933cc8fd
2020-06-18 14:00:33 +00:00
drh 1ec2f06788 Fix an assert() that could fail when operating on a database with a corrupt schema.
FossilOrigin-Name: b69b9c0628feac9f1ecc53e4411377168ee0ecc82dc2d80de4270d37b218022c
2020-06-18 13:16:19 +00:00
drh d40a11dc22 Fix an assert() in fts3 that could fail when processing a corrupt record.
FossilOrigin-Name: ea71fb7fabcce71af05af14a8eaba3693f6bc859a18ab9f107eaac51260853fe
2020-06-17 17:27:42 +00:00
drh c780c380da Merge miscellaneous fixes from trunk into the 3.32 branch.
FossilOrigin-Name: d55b8e7993997e6bd75396479c822947a1254b62c28c4bbb71b4ff4f1410a802
2020-06-17 12:37:26 +00:00
dan ecaa9539a8 Ensure that aggregate functions that (a) are part of SELECT statements with
no FROM clause and (b) have one or more scalar sub-selects as arguments are
assigned to the correct aggregate context.
Fix for ticket [7c6d876f84e6e7e2]

FossilOrigin-Name: dafd2466a10f68acbe129010216f017a5fcfc048ffbc0da806d04f04e58cfcbb
2020-06-10 11:18:28 +00:00
dan 38113e6890 Ensure that the "push-down" optimization does not push constraints down into compound queries if any of the component queries uses window functions.
FossilOrigin-Name: d31850fe50420cb0d2c48f19741b889700c52d0d0273967eb4b81571a4ee63a7
2020-06-10 11:01:58 +00:00
dan b410111f45 Disable AggInfo consistency checks when unwinding after an OOM.
FossilOrigin-Name: 7e2833fb2be8e7df5b25b8db73aed60ec81780bbd3e4f11a43b5eacbd5bd01a7
2020-06-10 11:01:21 +00:00
drh 2b6bfa68d9 Increase the version number to 3.32.3.
FossilOrigin-Name: a376ec6942734e5d35c6a2c07bde9010ed4b56e412623e2121efd76017595a4f
2020-06-08 12:51:03 +00:00
drh 2aebad17f7 When an Expr object is changed and that Expr is referenced by an AggInfo, then
also update the AggInfo.  Also, persist all AggInfo objects until the Parse
object is destroyed.  This is a new fix for ticket [c8d3b9f0a750a529].

FossilOrigin-Name: 44a58d6cb135a1040807093e27e3d4bdcfd5fd2c2b52e9af1e5f01c26b321d82
2020-06-08 12:49:53 +00:00
drh fc6d946586 Version 3.32.2
FossilOrigin-Name: ec02243ea6ce33b090870ae55ab8aa2534b54d216d45c4aa2fdbb00e86861e8c
2020-06-04 12:58:43 +00:00
drh 996e330613 Fix for ticket [810dc8038872e212].
FossilOrigin-Name: 9cfefef591dc555e41fe267e5a5b128f82038d01f8c44480ede16be4a923863f
2020-06-03 22:57:15 +00:00
drh 6b9f94d1c6 Version number to 3.32.2
FossilOrigin-Name: 4454b27fc594c2600a2d5aa9f421f2e1e4c3017dda828c071b3ccb11ff46d6d5
2020-06-03 22:47:05 +00:00
24 changed files with 744 additions and 1960 deletions
+1 -1
View File
@@ -1 +1 @@
3.32.1
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.1.
# 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.1'
PACKAGE_STRING='sqlite 3.32.1'
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.1 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.1:";;
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.1
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.1, 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.1, 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.1
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 @@
0c1fcf4711a2e66c813aed38cf41cd3e2123ee8eb6db98118086764c4ba83350
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);
+3 -1
View File
@@ -702,6 +702,8 @@ int sqlite3VdbeExec(
goto no_mem;
}
assert( p->rc==SQLITE_OK || (p->rc&0xff)==SQLITE_BUSY );
testcase( p->rc!=SQLITE_OK );
p->rc = SQLITE_OK;
assert( p->bIsReader || p->readOnly!=0 );
p->iCurrentTime = 0;
assert( p->explain==0 );
@@ -2074,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