📄 select.c
字号:
if( pOrderBy==0 || pParse->db->mallocFailed ) return 0; if( pOrderBy->nExpr>SQLITE_MAX_COLUMN ){ const char *zType = isOrder ? "ORDER" : "GROUP"; sqlite3ErrorMsg(pParse, "too many terms in %s BY clause", zType); return 1; } pEList = pSelect->pEList; if( pEList==0 ){ return 0; } for(i=0; i<pOrderBy->nExpr; i++){ int iCol; Expr *pE = pOrderBy->a[i].pExpr; iCol = matchOrderByTermToExprList(pParse, pSelect, pE, i+1, 0, pHasAgg); if( iCol<0 ){ return 1; } if( iCol>pEList->nExpr ){ const char *zType = isOrder ? "ORDER" : "GROUP"; sqlite3ErrorMsg(pParse, "%r %s BY term out of range - should be " "between 1 and %d", i+1, zType, pEList->nExpr); return 1; } if( iCol>0 ){ CollSeq *pColl = pE->pColl; int flags = pE->flags & EP_ExpCollate; sqlite3ExprDelete(pE); pE = sqlite3ExprDup(db, pEList->a[iCol-1].pExpr); pOrderBy->a[i].pExpr = pE; if( pE && pColl && flags ){ pE->pColl = pColl; pE->flags |= flags; } } } return 0;}/*** Analyze and ORDER BY or GROUP BY clause in a SELECT statement. Return** the number of errors seen.**** The processing depends on whether the SELECT is simple or compound.** For a simple SELECT statement, evry term of the ORDER BY or GROUP BY** clause needs to be an expression. If any expression is an integer** constant, then that expression is replaced by the corresponding ** expression from the result set.**** For compound SELECT statements, every expression needs to be of** type TK_COLUMN with a iTable value as given in the 4th parameter.** If any expression is an integer, that becomes the column number.** Otherwise, match the expression against result set columns from** the left-most SELECT.*/static int processCompoundOrderBy( Parse *pParse, /* Parsing context. Leave error messages here */ Select *pSelect, /* The SELECT statement containing the ORDER BY */ int iTable /* Output table for compound SELECT statements */){ int i; ExprList *pOrderBy; ExprList *pEList; sqlite3 *db; int moreToDo = 1; pOrderBy = pSelect->pOrderBy; if( pOrderBy==0 ) return 0; if( pOrderBy->nExpr>SQLITE_MAX_COLUMN ){ sqlite3ErrorMsg(pParse, "too many terms in ORDER BY clause"); return 1; } db = pParse->db; for(i=0; i<pOrderBy->nExpr; i++){ pOrderBy->a[i].done = 0; } while( pSelect->pPrior ){ pSelect = pSelect->pPrior; } while( pSelect && moreToDo ){ moreToDo = 0; for(i=0; i<pOrderBy->nExpr; i++){ int iCol = -1; Expr *pE, *pDup; if( pOrderBy->a[i].done ) continue; pE = pOrderBy->a[i].pExpr; pDup = sqlite3ExprDup(db, pE); if( !db->mallocFailed ){ assert(pDup); iCol = matchOrderByTermToExprList(pParse, pSelect, pDup, i+1, 1, 0); } sqlite3ExprDelete(pDup); if( iCol<0 ){ return 1; } pEList = pSelect->pEList; if( pEList==0 ){ return 1; } if( iCol>pEList->nExpr ){ sqlite3ErrorMsg(pParse, "%r ORDER BY term out of range - should be " "between 1 and %d", i+1, pEList->nExpr); return 1; } if( iCol>0 ){ pE->op = TK_COLUMN; pE->iTable = iTable; pE->iAgg = -1; pE->iColumn = iCol-1; pE->pTab = 0; pOrderBy->a[i].done = 1; }else{ moreToDo = 1; } } pSelect = pSelect->pNext; } for(i=0; i<pOrderBy->nExpr; i++){ if( pOrderBy->a[i].done==0 ){ sqlite3ErrorMsg(pParse, "%r ORDER BY term does not match any " "column in the result set", i+1); return 1; } } return 0;}/*** Get a VDBE for the given parser context. Create a new one if necessary.** If an error occurs, return NULL and leave a message in pParse.*/Vdbe *sqlite3GetVdbe(Parse *pParse){ Vdbe *v = pParse->pVdbe; if( v==0 ){ v = pParse->pVdbe = sqlite3VdbeCreate(pParse->db);#ifndef SQLITE_OMIT_TRACE if( v ){ sqlite3VdbeAddOp0(v, OP_Trace); }#endif } return v;}/*** Compute the iLimit and iOffset fields of the SELECT based on the** pLimit and pOffset expressions. pLimit and pOffset hold the expressions** that appear in the original SQL statement after the LIMIT and OFFSET** keywords. Or NULL if those keywords are omitted. iLimit and iOffset ** are the integer memory register numbers for counters used to compute ** the limit and offset. If there is no limit and/or offset, then ** iLimit and iOffset are negative.**** This routine changes the values of iLimit and iOffset only if** a limit or offset is defined by pLimit and pOffset. iLimit and** iOffset should have been preset to appropriate default values** (usually but not always -1) prior to calling this routine.** Only if pLimit!=0 or pOffset!=0 do the limit registers get** redefined. The UNION ALL operator uses this property to force** the reuse of the same limit and offset registers across multiple** SELECT statements.*/static void computeLimitRegisters(Parse *pParse, Select *p, int iBreak){ Vdbe *v = 0; int iLimit = 0; int iOffset; int addr1; /* ** "LIMIT -1" always shows all rows. There is some ** contraversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean ** no rows. */ if( p->pLimit ){ p->iLimit = iLimit = ++pParse->nMem; v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pLimit, iLimit); sqlite3VdbeAddOp1(v, OP_MustBeInt, iLimit); VdbeComment((v, "LIMIT counter")); sqlite3VdbeAddOp2(v, OP_IfZero, iLimit, iBreak); } if( p->pOffset ){ p->iOffset = iOffset = ++pParse->nMem; if( p->pLimit ){ pParse->nMem++; /* Allocate an extra register for limit+offset */ } v = sqlite3GetVdbe(pParse); if( v==0 ) return; sqlite3ExprCode(pParse, p->pOffset, iOffset); sqlite3VdbeAddOp1(v, OP_MustBeInt, iOffset); VdbeComment((v, "OFFSET counter")); addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iOffset); sqlite3VdbeAddOp2(v, OP_Integer, 0, iOffset); sqlite3VdbeJumpHere(v, addr1); if( p->pLimit ){ sqlite3VdbeAddOp3(v, OP_Add, iLimit, iOffset, iOffset+1); VdbeComment((v, "LIMIT+OFFSET")); addr1 = sqlite3VdbeAddOp1(v, OP_IfPos, iLimit); sqlite3VdbeAddOp2(v, OP_Integer, -1, iOffset+1); sqlite3VdbeJumpHere(v, addr1); } }}/*** Allocate a virtual index to use for sorting.*/static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){ if( pOrderBy ){ int addr; assert( pOrderBy->iECursor==0 ); pOrderBy->iECursor = pParse->nTab++; addr = sqlite3VdbeAddOp2(pParse->pVdbe, OP_OpenEphemeral, pOrderBy->iECursor, pOrderBy->nExpr+1); assert( p->addrOpenEphm[2] == -1 ); p->addrOpenEphm[2] = addr; }}#ifndef SQLITE_OMIT_COMPOUND_SELECT/*** Return the appropriate collating sequence for the iCol-th column of** the result set for the compound-select statement "p". Return NULL if** the column has no default collating sequence.**** The collating sequence for the compound select is taken from the** left-most term of the select that has a collating sequence.*/static CollSeq *multiSelectCollSeq(Parse *pParse, Select *p, int iCol){ CollSeq *pRet; if( p->pPrior ){ pRet = multiSelectCollSeq(pParse, p->pPrior, iCol); }else{ pRet = 0; } if( pRet==0 ){ pRet = sqlite3ExprCollSeq(pParse, p->pEList->a[iCol].pExpr); } return pRet;}#endif /* SQLITE_OMIT_COMPOUND_SELECT */#ifndef SQLITE_OMIT_COMPOUND_SELECT/*** This routine is called to process a query that is really the union** or intersection of two or more separate queries.**** "p" points to the right-most of the two queries. the query on the** left is p->pPrior. The left query could also be a compound query** in which case this routine will be called recursively. **** The results of the total query are to be written into a destination** of type eDest with parameter iParm.**** Example 1: Consider a three-way compound SQL statement.**** SELECT a FROM t1 UNION SELECT b FROM t2 UNION SELECT c FROM t3**** This statement is parsed up as follows:**** SELECT c FROM t3** |** `-----> SELECT b FROM t2** |** `------> SELECT a FROM t1**** The arrows in the diagram above represent the Select.pPrior pointer.** So if this routine is called with p equal to the t3 query, then** pPrior will be the t2 query. p->op will be TK_UNION in this case.**** Notice that because of the way SQLite parses compound SELECTs, the** individual selects always group from left to right.*/static int multiSelect( Parse *pParse, /* Parsing context */ Select *p, /* The right-most of SELECTs to be coded */ SelectDest *pDest, /* What to do with query results */ char *aff /* If eDest is SRT_Union, the affinity string */){ int rc = SQLITE_OK; /* Success code from a subroutine */ Select *pPrior; /* Another SELECT immediately to our left */ Vdbe *v; /* Generate code to this VDBE */ int nCol; /* Number of columns in the result set */ ExprList *pOrderBy; /* The ORDER BY clause on p */ int aSetP2[2]; /* Set P2 value of these op to number of columns */ int nSetP2 = 0; /* Number of slots in aSetP2[] used */ SelectDest dest; /* Alternative data destination */ dest = *pDest; /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs. Only ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT. */ if( p==0 || p->pPrior==0 ){ rc = 1; goto multi_select_end; } pPrior = p->pPrior; assert( pPrior->pRightmost!=pPrior ); assert( pPrior->pRightmost==p->pRightmost ); if( pPrior->pOrderBy ){ sqlite3ErrorMsg(pParse,"ORDER BY clause should come after %s not before", selectOpName(p->op)); rc = 1; goto multi_select_end; } if( pPrior->pLimit ){ sqlite3ErrorMsg(pParse,"LIMIT clause should come after %s not before", selectOpName(p->op)); rc = 1; goto multi_select_end; } /* Make sure we have a valid query engine. If not, create a new one. */ v = sqlite3GetVdbe(pParse); if( v==0 ){ rc = 1; goto multi_select_end; } /* Create the destination temporary table if necessary */ if( dest.eDest==SRT_EphemTab ){ assert( p->pEList ); assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) ); aSetP2[nSetP2++] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, 0); dest.eDest = SRT_Table; } /* Generate code for the left and right SELECT statements. */ pOrderBy = p->pOrderBy; switch( p->op ){ case TK_ALL: { if( pOrderBy==0 ){ int addr = 0; assert( !pPrior->pLimit ); pPrior->pLimit = p->pLimit; pPrior->pOffset = p->pOffset; rc = sqlite3Select(pParse, pPrior, &dest, 0, 0, 0, aff); p->pLimit = 0; p->pOffset = 0; if( rc ){ goto multi_select_end; } p->pPrior = 0; p->iLimit = pPrior->iLimit; p->iOffset = pPrior->iOffset; if( p->iLimit>=0 ){ addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit); VdbeComment((v, "Jump ahead if LIMIT reached")); } rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff); p->pPrior = pPrior; if( rc ){ goto multi_select_end; } if( addr ){ sqlite3VdbeJumpHere(v, addr); } break; } /* For UNION ALL ... ORDER BY fall through to the next case */ } case TK_EXCEPT: case TK_UNION: { int unionTab; /* Cursor number of the temporary table holding result */ int op = 0; /* One of the SRT_ operations to apply to self */ int priorOp; /* The SRT_ operation to apply to prior selects */ Expr *pLimit, *pOffset; /* Saved values of p->nLimit and p->nOffset */ int addr; SelectDest uniondest; priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union; if( dest.eDest==priorOp && pOrderBy==0 && !p->pLimit && !p->pOffset ){ /* We can reuse a temporary table generated by a SELECT to our ** right. */ unionTab = dest.iParm; }else{ /* We will need to create our own temporary table to hold the ** intermediate results. */ unionTab = pParse->nTab++; if( processCompoundOrderBy(pParse, p, unionTab) ){ rc = 1; goto multi_select_end; } addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0); if( priorOp==SRT_Table ){ assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) ); aSetP2[nSetP2++
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -