📄 expr.c
字号:
/*** 2001 September 15**** The author disclaims copyright to this source code. In place of** a legal notice, here is a blessing:**** May you do good and not evil.** May you find forgiveness for yourself and forgive others.** May you share freely, never taking more than you give.***************************************************************************** This file contains routines used for analyzing expressions and** for generating VDBE code that evaluates expressions in SQLite.**** $Id: expr.c,v 1.392 2008/08/29 02:14:03 drh Exp $*/#include "sqliteInt.h"#include <ctype.h>/*** Return the 'affinity' of the expression pExpr if any.**** If pExpr is a column, a reference to a column via an 'AS' alias,** or a sub-select with a column as the return value, then the ** affinity of that column is returned. Otherwise, 0x00 is returned,** indicating no affinity for the expression.**** i.e. the WHERE clause expresssions in the following statements all** have an affinity:**** CREATE TABLE t1(a);** SELECT * FROM t1 WHERE a;** SELECT a AS b FROM t1 WHERE b;** SELECT * FROM t1 WHERE (select a from t1);*/char sqlite3ExprAffinity(Expr *pExpr){ int op = pExpr->op; if( op==TK_SELECT ){ return sqlite3ExprAffinity(pExpr->pSelect->pEList->a[0].pExpr); }#ifndef SQLITE_OMIT_CAST if( op==TK_CAST ){ return sqlite3AffinityType(&pExpr->token); }#endif if( (op==TK_COLUMN || op==TK_REGISTER) && pExpr->pTab!=0 ){ /* op==TK_REGISTER && pExpr->pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ int j = pExpr->iColumn; if( j<0 ) return SQLITE_AFF_INTEGER; assert( pExpr->pTab && j<pExpr->pTab->nCol ); return pExpr->pTab->aCol[j].affinity; } return pExpr->affinity;}/*** Set the collating sequence for expression pExpr to be the collating** sequence named by pToken. Return a pointer to the revised expression.** The collating sequence is marked as "explicit" using the EP_ExpCollate** flag. An explicit collating sequence will override implicit** collating sequences.*/Expr *sqlite3ExprSetColl(Parse *pParse, Expr *pExpr, Token *pCollName){ char *zColl = 0; /* Dequoted name of collation sequence */ CollSeq *pColl; sqlite3 *db = pParse->db; zColl = sqlite3NameFromToken(db, pCollName); if( pExpr && zColl ){ pColl = sqlite3LocateCollSeq(pParse, zColl, -1); if( pColl ){ pExpr->pColl = pColl; pExpr->flags |= EP_ExpCollate; } } sqlite3DbFree(db, zColl); return pExpr;}/*** Return the default collation sequence for the expression pExpr. If** there is no default collation type, return 0.*/CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ CollSeq *pColl = 0; Expr *p = pExpr; while( p ){ int op; pColl = p->pColl; if( pColl ) break; op = p->op; if( (op==TK_COLUMN || op==TK_REGISTER) && p->pTab!=0 ){ /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ const char *zColl; int j = p->iColumn; if( j>=0 ){ sqlite3 *db = pParse->db; zColl = p->pTab->aCol[j].zColl; pColl = sqlite3FindCollSeq(db, ENC(db), zColl, -1, 0); pExpr->pColl = pColl; } break; } if( op!=TK_CAST && op!=TK_UPLUS ){ break; } p = p->pLeft; } if( sqlite3CheckCollSeq(pParse, pColl) ){ pColl = 0; } return pColl;}/*** pExpr is an operand of a comparison operator. aff2 is the** type affinity of the other operand. This routine returns the** type affinity that should be used for the comparison operator.*/char sqlite3CompareAffinity(Expr *pExpr, char aff2){ char aff1 = sqlite3ExprAffinity(pExpr); if( aff1 && aff2 ){ /* Both sides of the comparison are columns. If one has numeric ** affinity, use that. Otherwise use no affinity. */ if( sqlite3IsNumericAffinity(aff1) || sqlite3IsNumericAffinity(aff2) ){ return SQLITE_AFF_NUMERIC; }else{ return SQLITE_AFF_NONE; } }else if( !aff1 && !aff2 ){ /* Neither side of the comparison is a column. Compare the ** results directly. */ return SQLITE_AFF_NONE; }else{ /* One side is a column, the other is not. Use the columns affinity. */ assert( aff1==0 || aff2==0 ); return (aff1 + aff2); }}/*** pExpr is a comparison operator. Return the type affinity that should** be applied to both operands prior to doing the comparison.*/static char comparisonAffinity(Expr *pExpr){ char aff; assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || pExpr->op==TK_NE ); assert( pExpr->pLeft ); aff = sqlite3ExprAffinity(pExpr->pLeft); if( pExpr->pRight ){ aff = sqlite3CompareAffinity(pExpr->pRight, aff); } else if( pExpr->pSelect ){ aff = sqlite3CompareAffinity(pExpr->pSelect->pEList->a[0].pExpr, aff); } else if( !aff ){ aff = SQLITE_AFF_NONE; } return aff;}/*** pExpr is a comparison expression, eg. '=', '<', IN(...) etc.** idx_affinity is the affinity of an indexed column. Return true** if the index with affinity idx_affinity may be used to implement** the comparison in pExpr.*/int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity){ char aff = comparisonAffinity(pExpr); switch( aff ){ case SQLITE_AFF_NONE: return 1; case SQLITE_AFF_TEXT: return idx_affinity==SQLITE_AFF_TEXT; default: return sqlite3IsNumericAffinity(idx_affinity); }}/*** Return the P5 value that should be used for a binary comparison** opcode (OP_Eq, OP_Ge etc.) used to compare pExpr1 and pExpr2.*/static u8 binaryCompareP5(Expr *pExpr1, Expr *pExpr2, int jumpIfNull){ u8 aff = (char)sqlite3ExprAffinity(pExpr2); aff = sqlite3CompareAffinity(pExpr1, aff) | jumpIfNull; return aff;}/*** Return a pointer to the collation sequence that should be used by** a binary comparison operator comparing pLeft and pRight.**** If the left hand expression has a collating sequence type, then it is** used. Otherwise the collation sequence for the right hand expression** is used, or the default (BINARY) if neither expression has a collating** type.**** Argument pRight (but not pLeft) may be a null pointer. In this case,** it is not considered.*/CollSeq *sqlite3BinaryCompareCollSeq( Parse *pParse, Expr *pLeft, Expr *pRight){ CollSeq *pColl; assert( pLeft ); if( pLeft->flags & EP_ExpCollate ){ assert( pLeft->pColl ); pColl = pLeft->pColl; }else if( pRight && pRight->flags & EP_ExpCollate ){ assert( pRight->pColl ); pColl = pRight->pColl; }else{ pColl = sqlite3ExprCollSeq(pParse, pLeft); if( !pColl ){ pColl = sqlite3ExprCollSeq(pParse, pRight); } } return pColl;}/*** Generate the operands for a comparison operation. Before** generating the code for each operand, set the EP_AnyAff** flag on the expression so that it will be able to used a** cached column value that has previously undergone an** affinity change.*/static void codeCompareOperands( Parse *pParse, /* Parsing and code generating context */ Expr *pLeft, /* The left operand */ int *pRegLeft, /* Register where left operand is stored */ int *pFreeLeft, /* Free this register when done */ Expr *pRight, /* The right operand */ int *pRegRight, /* Register where right operand is stored */ int *pFreeRight /* Write temp register for right operand there */){ while( pLeft->op==TK_UPLUS ) pLeft = pLeft->pLeft; pLeft->flags |= EP_AnyAff; *pRegLeft = sqlite3ExprCodeTemp(pParse, pLeft, pFreeLeft); while( pRight->op==TK_UPLUS ) pRight = pRight->pLeft; pRight->flags |= EP_AnyAff; *pRegRight = sqlite3ExprCodeTemp(pParse, pRight, pFreeRight);}/*** Generate code for a comparison operator.*/static int codeCompare( Parse *pParse, /* The parsing (and code generating) context */ Expr *pLeft, /* The left operand */ Expr *pRight, /* The right operand */ int opcode, /* The comparison opcode */ int in1, int in2, /* Register holding operands */ int dest, /* Jump here if true. */ int jumpIfNull /* If true, jump if either operand is NULL */){ int p5; int addr; CollSeq *p4; p4 = sqlite3BinaryCompareCollSeq(pParse, pLeft, pRight); p5 = binaryCompareP5(pLeft, pRight, jumpIfNull); addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1, (void*)p4, P4_COLLSEQ); sqlite3VdbeChangeP5(pParse->pVdbe, p5); if( (p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_NONE ){ sqlite3ExprCacheAffinityChange(pParse, in1, 1); sqlite3ExprCacheAffinityChange(pParse, in2, 1); } return addr;}#if SQLITE_MAX_EXPR_DEPTH>0/*** Check that argument nHeight is less than or equal to the maximum** expression depth allowed. If it is not, leave an error message in** pParse.*/int sqlite3ExprCheckHeight(Parse *pParse, int nHeight){ int rc = SQLITE_OK; int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; if( nHeight>mxHeight ){ sqlite3ErrorMsg(pParse, "Expression tree is too large (maximum depth %d)", mxHeight ); rc = SQLITE_ERROR; } return rc;}/* The following three functions, heightOfExpr(), heightOfExprList()** and heightOfSelect(), are used to determine the maximum height** of any expression tree referenced by the structure passed as the** first argument.**** If this maximum height is greater than the current value pointed** to by pnHeight, the second parameter, then set *pnHeight to that** value.*/static void heightOfExpr(Expr *p, int *pnHeight){ if( p ){ if( p->nHeight>*pnHeight ){ *pnHeight = p->nHeight; } }}static void heightOfExprList(ExprList *p, int *pnHeight){ if( p ){ int i; for(i=0; i<p->nExpr; i++){ heightOfExpr(p->a[i].pExpr, pnHeight); } }}static void heightOfSelect(Select *p, int *pnHeight){ if( p ){ heightOfExpr(p->pWhere, pnHeight); heightOfExpr(p->pHaving, pnHeight); heightOfExpr(p->pLimit, pnHeight); heightOfExpr(p->pOffset, pnHeight); heightOfExprList(p->pEList, pnHeight); heightOfExprList(p->pGroupBy, pnHeight); heightOfExprList(p->pOrderBy, pnHeight); heightOfSelect(p->pPrior, pnHeight); }}/*** Set the Expr.nHeight variable in the structure passed as an ** argument. An expression with no children, Expr.pList or ** Expr.pSelect member has a height of 1. Any other expression** has a height equal to the maximum height of any other ** referenced Expr plus one.*/static void exprSetHeight(Expr *p){ int nHeight = 0; heightOfExpr(p->pLeft, &nHeight); heightOfExpr(p->pRight, &nHeight); heightOfExprList(p->pList, &nHeight); heightOfSelect(p->pSelect, &nHeight); p->nHeight = nHeight + 1;}/*** Set the Expr.nHeight variable using the exprSetHeight() function. If** the height is greater than the maximum allowed expression depth,** leave an error in pParse.*/void sqlite3ExprSetHeight(Parse *pParse, Expr *p){ exprSetHeight(p); sqlite3ExprCheckHeight(pParse, p->nHeight);}/*** Return the maximum height of any expression tree referenced** by the select statement passed as an argument.*/int sqlite3SelectExprHeight(Select *p){ int nHeight = 0; heightOfSelect(p, &nHeight); return nHeight;}#else #define exprSetHeight(y)#endif /* SQLITE_MAX_EXPR_DEPTH>0 *//*** Construct a new expression node and return a pointer to it. Memory** for this node is obtained from sqlite3_malloc(). The calling function** is responsible for making sure the node eventually gets freed.*/Expr *sqlite3Expr( sqlite3 *db, /* Handle for sqlite3DbMallocZero() (may be null) */ int op, /* Expression opcode */ Expr *pLeft, /* Left operand */ Expr *pRight, /* Right operand */ const Token *pToken /* Argument token */){ Expr *pNew; pNew = sqlite3DbMallocZero(db, sizeof(Expr)); if( pNew==0 ){ /* When malloc fails, delete pLeft and pRight. Expressions passed to ** this function must always be allocated with sqlite3Expr() for this ** reason. */ sqlite3ExprDelete(db, pLeft); sqlite3ExprDelete(db, pRight); return 0; } pNew->op = op; pNew->pLeft = pLeft; pNew->pRight = pRight; pNew->iAgg = -1; pNew->span.z = (u8*)""; if( pToken ){ assert( pToken->dyn==0 ); pNew->span = pNew->token = *pToken; }else if( pLeft ){ if( pRight ){ if( pRight->span.dyn==0 && pLeft->span.dyn==0 ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -