mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Merge recent enhancements from trunk.
FossilOrigin-Name: 39d55579376906f212271ce9b2d367e3ad029fb173f22c7253312b467970208a
This commit is contained in:
56
src/select.c
56
src/select.c
@@ -84,7 +84,10 @@ struct SortCtx {
|
||||
|
||||
/*
|
||||
** Delete all the content of a Select structure. Deallocate the structure
|
||||
** itself only if bFree is true.
|
||||
** itself depending on the value of bFree
|
||||
**
|
||||
** If bFree==1, call sqlite3DbFree() on the p object.
|
||||
** If bFree==0, Leave the first Select object unfreed
|
||||
*/
|
||||
static void clearSelect(sqlite3 *db, Select *p, int bFree){
|
||||
while( p ){
|
||||
@@ -188,6 +191,20 @@ void sqlite3SelectDelete(sqlite3 *db, Select *p){
|
||||
if( OK_IF_ALWAYS_TRUE(p) ) clearSelect(db, p, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
** Delete all the substructure for p, but keep p allocated. Redefine
|
||||
** p to be a single SELECT where every column of the result set has a
|
||||
** value of NULL.
|
||||
*/
|
||||
void sqlite3SelectReset(Parse *pParse, Select *p){
|
||||
if( ALWAYS(p) ){
|
||||
clearSelect(pParse->db, p, 0);
|
||||
memset(&p->iLimit, 0, sizeof(Select) - offsetof(Select,iLimit));
|
||||
p->pEList = sqlite3ExprListAppend(pParse, 0,
|
||||
sqlite3ExprAlloc(pParse->db,TK_NULL,0,0));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return a pointer to the right-most SELECT statement in a compound.
|
||||
*/
|
||||
@@ -296,7 +313,8 @@ static int tableAndColumnIndex(
|
||||
int N, /* Number of tables in pSrc->a[] to search */
|
||||
const char *zCol, /* Name of the column we are looking for */
|
||||
int *piTab, /* Write index of pSrc->a[] here */
|
||||
int *piCol /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
|
||||
int *piCol, /* Write index of pSrc->a[*piTab].pTab->aCol[] here */
|
||||
int bIgnoreHidden /* True to ignore hidden columns */
|
||||
){
|
||||
int i; /* For looping over tables in pSrc */
|
||||
int iCol; /* Index of column matching zCol */
|
||||
@@ -304,7 +322,9 @@ static int tableAndColumnIndex(
|
||||
assert( (piTab==0)==(piCol==0) ); /* Both or neither are NULL */
|
||||
for(i=0; i<N; i++){
|
||||
iCol = columnIndex(pSrc->a[i].pTab, zCol);
|
||||
if( iCol>=0 ){
|
||||
if( iCol>=0
|
||||
&& (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0)
|
||||
){
|
||||
if( piTab ){
|
||||
*piTab = i;
|
||||
*piCol = iCol;
|
||||
@@ -469,10 +489,11 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
|
||||
int iLeft; /* Matching left table */
|
||||
int iLeftCol; /* Matching column in the left table */
|
||||
|
||||
if( IsHiddenColumn(&pRightTab->aCol[j]) ) continue;
|
||||
zName = pRightTab->aCol[j].zName;
|
||||
if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol) ){
|
||||
if( tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 1) ){
|
||||
addWhereTerm(pParse, pSrc, iLeft, iLeftCol, i+1, j,
|
||||
isOuter, &p->pWhere);
|
||||
isOuter, &p->pWhere);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -512,7 +533,7 @@ static int sqliteProcessJoin(Parse *pParse, Select *p){
|
||||
zName = pList->a[j].zName;
|
||||
iRightCol = columnIndex(pRightTab, zName);
|
||||
if( iRightCol<0
|
||||
|| !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol)
|
||||
|| !tableAndColumnIndex(pSrc, i+1, zName, &iLeft, &iLeftCol, 0)
|
||||
){
|
||||
sqlite3ErrorMsg(pParse, "cannot join using column %s - column "
|
||||
"not present in both tables", zName);
|
||||
@@ -2711,9 +2732,9 @@ static int multiSelect(
|
||||
** it is that we currently need.
|
||||
*/
|
||||
assert( unionTab==dest.iSDParm || dest.eDest!=priorOp );
|
||||
if( dest.eDest!=priorOp ){
|
||||
assert( p->pEList || db->mallocFailed );
|
||||
if( dest.eDest!=priorOp && db->mallocFailed==0 ){
|
||||
int iCont, iBreak, iStart;
|
||||
assert( p->pEList );
|
||||
iBreak = sqlite3VdbeMakeLabel(pParse);
|
||||
iCont = sqlite3VdbeMakeLabel(pParse);
|
||||
computeLimitRegisters(pParse, p, iBreak);
|
||||
@@ -2809,6 +2830,7 @@ static int multiSelect(
|
||||
}
|
||||
#endif
|
||||
}
|
||||
if( pParse->nErr ) goto multi_select_end;
|
||||
|
||||
/* Compute collating sequences used by
|
||||
** temporary tables needed to implement the compound select.
|
||||
@@ -3600,6 +3622,7 @@ static void substSelect(
|
||||
** (3b) the FROM clause of the subquery may not contain a virtual
|
||||
** table and
|
||||
** (3c) the outer query may not be an aggregate.
|
||||
** (3d) the outer query may not be DISTINCT.
|
||||
**
|
||||
** (4) The subquery can not be DISTINCT.
|
||||
**
|
||||
@@ -3650,6 +3673,7 @@ static void substSelect(
|
||||
** (17d1) aggregate, or
|
||||
** (17d2) DISTINCT, or
|
||||
** (17d3) a join.
|
||||
** (17e) the subquery may not contain window functions
|
||||
**
|
||||
** The parent and sub-query may contain WHERE clauses. Subject to
|
||||
** rules (11), (13) and (14), they may also contain ORDER BY,
|
||||
@@ -3796,8 +3820,11 @@ static int flattenSubquery(
|
||||
*/
|
||||
if( (pSubitem->fg.jointype & JT_OUTER)!=0 ){
|
||||
isLeftJoin = 1;
|
||||
if( pSubSrc->nSrc>1 || isAgg || IsVirtual(pSubSrc->a[0].pTab) ){
|
||||
/* (3a) (3c) (3b) */
|
||||
if( pSubSrc->nSrc>1 /* (3a) */
|
||||
|| isAgg /* (3b) */
|
||||
|| IsVirtual(pSubSrc->a[0].pTab) /* (3c) */
|
||||
|| (p->selFlags & SF_Distinct)!=0 /* (3d) */
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -3831,6 +3858,7 @@ static int flattenSubquery(
|
||||
if( (pSub1->selFlags & (SF_Distinct|SF_Aggregate))!=0 /* (17b) */
|
||||
|| (pSub1->pPrior && pSub1->op!=TK_ALL) /* (17a) */
|
||||
|| pSub1->pSrc->nSrc<1 /* (17c) */
|
||||
|| pSub1->pWin /* (17e) */
|
||||
){
|
||||
return 0;
|
||||
}
|
||||
@@ -4956,7 +4984,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
|
||||
/* Process NATURAL keywords, and ON and USING clauses of joins.
|
||||
*/
|
||||
if( db->mallocFailed || sqliteProcessJoin(pParse, p) ){
|
||||
if( pParse->nErr || db->mallocFailed || sqliteProcessJoin(pParse, p) ){
|
||||
return WRC_Abort;
|
||||
}
|
||||
|
||||
@@ -5062,7 +5090,7 @@ static int selectExpander(Walker *pWalker, Select *p){
|
||||
|
||||
if( i>0 && zTName==0 ){
|
||||
if( (pFrom->fg.jointype & JT_NATURAL)!=0
|
||||
&& tableAndColumnIndex(pTabList, i, zName, 0, 0)
|
||||
&& tableAndColumnIndex(pTabList, i, zName, 0, 0, 1)
|
||||
){
|
||||
/* In a NATURAL join, omit the join columns from the
|
||||
** table to the right of the join */
|
||||
@@ -5733,7 +5761,9 @@ int sqlite3Select(
|
||||
}
|
||||
|
||||
#ifndef SQLITE_OMIT_WINDOWFUNC
|
||||
if( sqlite3WindowRewrite(pParse, p) ){
|
||||
rc = sqlite3WindowRewrite(pParse, p);
|
||||
if( rc ){
|
||||
assert( db->mallocFailed || pParse->nErr>0 );
|
||||
goto select_end;
|
||||
}
|
||||
#if SELECTTRACE_ENABLED
|
||||
|
||||
Reference in New Issue
Block a user