📄 expr.c
字号:
int is_agg = 0; /* True if is an aggregate function */ int i; int nId; /* Number of characters in function name */ const char *zId; /* The function name. */ FuncDef *pDef; getFunctionName(pExpr, &zId, &nId); pDef = sqliteFindFunction(pParse->db, zId, nId, n, 0); if( pDef==0 ){ pDef = sqliteFindFunction(pParse->db, zId, nId, -1, 0); if( pDef==0 ){ no_such_func = 1; }else{ wrong_num_args = 1; } }else{ is_agg = pDef->xFunc==0; } if( is_agg && !allowAgg ){ sqliteErrorMsg(pParse, "misuse of aggregate function %.*s()", nId, zId); nErr++; is_agg = 0; }else if( no_such_func ){ sqliteErrorMsg(pParse, "no such function: %.*s", nId, zId); nErr++; }else if( wrong_num_args ){ sqliteErrorMsg(pParse,"wrong number of arguments to function %.*s()", nId, zId); nErr++; } if( is_agg ){ pExpr->op = TK_AGG_FUNCTION; if( pIsAgg ) *pIsAgg = 1; } for(i=0; nErr==0 && i<n; i++){ nErr = sqliteExprCheck(pParse, pExpr->pList->a[i].pExpr, allowAgg && !is_agg, pIsAgg); } if( pDef==0 ){ /* Already reported an error */ }else if( pDef->dataType>=0 ){ if( pDef->dataType<n ){ pExpr->dataType = sqliteExprType(pExpr->pList->a[pDef->dataType].pExpr); }else{ pExpr->dataType = SQLITE_SO_NUM; } }else if( pDef->dataType==SQLITE_ARGS ){ pDef->dataType = SQLITE_SO_TEXT; for(i=0; i<n; i++){ if( sqliteExprType(pExpr->pList->a[i].pExpr)==SQLITE_SO_NUM ){ pExpr->dataType = SQLITE_SO_NUM; break; } } }else if( pDef->dataType==SQLITE_NUMERIC ){ pExpr->dataType = SQLITE_SO_NUM; }else{ pExpr->dataType = SQLITE_SO_TEXT; } } default: { if( pExpr->pLeft ){ nErr = sqliteExprCheck(pParse, pExpr->pLeft, allowAgg, pIsAgg); } if( nErr==0 && pExpr->pRight ){ nErr = sqliteExprCheck(pParse, pExpr->pRight, allowAgg, pIsAgg); } if( nErr==0 && pExpr->pList ){ int n = pExpr->pList->nExpr; int i; for(i=0; nErr==0 && i<n; i++){ Expr *pE2 = pExpr->pList->a[i].pExpr; nErr = sqliteExprCheck(pParse, pE2, allowAgg, pIsAgg); } } break; } } return nErr;}/*** Return either SQLITE_SO_NUM or SQLITE_SO_TEXT to indicate whether the** given expression should sort as numeric values or as text.**** The sqliteExprResolveIds() and sqliteExprCheck() routines must have** both been called on the expression before it is passed to this routine.*/int sqliteExprType(Expr *p){ if( p==0 ) return SQLITE_SO_NUM; while( p ) switch( p->op ){ case TK_PLUS: case TK_MINUS: case TK_STAR: case TK_SLASH: case TK_AND: case TK_OR: case TK_ISNULL: case TK_NOTNULL: case TK_NOT: case TK_UMINUS: case TK_UPLUS: case TK_BITAND: case TK_BITOR: case TK_BITNOT: case TK_LSHIFT: case TK_RSHIFT: case TK_REM: case TK_INTEGER: case TK_FLOAT: case TK_IN: case TK_BETWEEN: case TK_GLOB: case TK_LIKE: return SQLITE_SO_NUM; case TK_STRING: case TK_NULL: case TK_CONCAT: case TK_VARIABLE: return SQLITE_SO_TEXT; case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: if( sqliteExprType(p->pLeft)==SQLITE_SO_NUM ){ return SQLITE_SO_NUM; } p = p->pRight; break; case TK_AS: p = p->pLeft; break; case TK_COLUMN: case TK_FUNCTION: case TK_AGG_FUNCTION: return p->dataType; case TK_SELECT: assert( p->pSelect ); assert( p->pSelect->pEList ); assert( p->pSelect->pEList->nExpr>0 ); p = p->pSelect->pEList->a[0].pExpr; break; case TK_CASE: { if( p->pRight && sqliteExprType(p->pRight)==SQLITE_SO_NUM ){ return SQLITE_SO_NUM; } if( p->pList ){ int i; ExprList *pList = p->pList; for(i=1; i<pList->nExpr; i+=2){ if( sqliteExprType(pList->a[i].pExpr)==SQLITE_SO_NUM ){ return SQLITE_SO_NUM; } } } return SQLITE_SO_TEXT; } default: assert( p->op==TK_ABORT ); /* Can't Happen */ break; } return SQLITE_SO_NUM;}/*** Generate code into the current Vdbe to evaluate the given** expression and leave the result on the top of stack.*/void sqliteExprCode(Parse *pParse, Expr *pExpr){ Vdbe *v = pParse->pVdbe; int op; if( v==0 || pExpr==0 ) return; switch( pExpr->op ){ case TK_PLUS: op = OP_Add; break; case TK_MINUS: op = OP_Subtract; break; case TK_STAR: op = OP_Multiply; break; case TK_SLASH: op = OP_Divide; break; case TK_AND: op = OP_And; break; case TK_OR: op = OP_Or; break; case TK_LT: op = OP_Lt; break; case TK_LE: op = OP_Le; break; case TK_GT: op = OP_Gt; break; case TK_GE: op = OP_Ge; break; case TK_NE: op = OP_Ne; break; case TK_EQ: op = OP_Eq; break; case TK_ISNULL: op = OP_IsNull; break; case TK_NOTNULL: op = OP_NotNull; break; case TK_NOT: op = OP_Not; break; case TK_UMINUS: op = OP_Negative; break; case TK_BITAND: op = OP_BitAnd; break; case TK_BITOR: op = OP_BitOr; break; case TK_BITNOT: op = OP_BitNot; break; case TK_LSHIFT: op = OP_ShiftLeft; break; case TK_RSHIFT: op = OP_ShiftRight; break; case TK_REM: op = OP_Remainder; break; default: break; } switch( pExpr->op ){ case TK_COLUMN: { if( pParse->useAgg ){ sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); }else if( pExpr->iColumn>=0 ){ sqliteVdbeAddOp(v, OP_Column, pExpr->iTable, pExpr->iColumn); }else{ sqliteVdbeAddOp(v, OP_Recno, pExpr->iTable, 0); } break; } case TK_STRING: case TK_FLOAT: case TK_INTEGER: { if( pExpr->op==TK_INTEGER && sqliteFitsIn32Bits(pExpr->token.z) ){ sqliteVdbeAddOp(v, OP_Integer, atoi(pExpr->token.z), 0); }else{ sqliteVdbeAddOp(v, OP_String, 0, 0); } assert( pExpr->token.z ); sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n); sqliteVdbeDequoteP3(v, -1); break; } case TK_NULL: { sqliteVdbeAddOp(v, OP_String, 0, 0); break; } case TK_VARIABLE: { sqliteVdbeAddOp(v, OP_Variable, pExpr->iTable, 0); break; } case TK_LT: case TK_LE: case TK_GT: case TK_GE: case TK_NE: case TK_EQ: { if( pParse->db->file_format>=4 && sqliteExprType(pExpr)==SQLITE_SO_TEXT ){ op += 6; /* Convert numeric opcodes to text opcodes */ } /* Fall through into the next case */ } case TK_AND: case TK_OR: case TK_PLUS: case TK_STAR: case TK_MINUS: case TK_REM: case TK_BITAND: case TK_BITOR: case TK_SLASH: { sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pRight); sqliteVdbeAddOp(v, op, 0, 0); break; } case TK_LSHIFT: case TK_RSHIFT: { sqliteExprCode(pParse, pExpr->pRight); sqliteExprCode(pParse, pExpr->pLeft); sqliteVdbeAddOp(v, op, 0, 0); break; } case TK_CONCAT: { sqliteExprCode(pParse, pExpr->pLeft); sqliteExprCode(pParse, pExpr->pRight); sqliteVdbeAddOp(v, OP_Concat, 2, 0); break; } case TK_UMINUS: { assert( pExpr->pLeft ); if( pExpr->pLeft->op==TK_FLOAT || pExpr->pLeft->op==TK_INTEGER ){ Token *p = &pExpr->pLeft->token; char *z = sqliteMalloc( p->n + 2 ); sprintf(z, "-%.*s", p->n, p->z); if( pExpr->pLeft->op==TK_INTEGER && sqliteFitsIn32Bits(z) ){ sqliteVdbeAddOp(v, OP_Integer, atoi(z), 0); }else{ sqliteVdbeAddOp(v, OP_String, 0, 0); } sqliteVdbeChangeP3(v, -1, z, p->n+1); sqliteFree(z); break; } /* Fall through into TK_NOT */ } case TK_BITNOT: case TK_NOT: { sqliteExprCode(pParse, pExpr->pLeft); sqliteVdbeAddOp(v, op, 0, 0); break; } case TK_ISNULL: case TK_NOTNULL: { int dest; sqliteVdbeAddOp(v, OP_Integer, 1, 0); sqliteExprCode(pParse, pExpr->pLeft); dest = sqliteVdbeCurrentAddr(v) + 2; sqliteVdbeAddOp(v, op, 1, dest); sqliteVdbeAddOp(v, OP_AddImm, -1, 0); break; } case TK_AGG_FUNCTION: { sqliteVdbeAddOp(v, OP_AggGet, 0, pExpr->iAgg); break; } case TK_GLOB: case TK_LIKE: case TK_FUNCTION: { ExprList *pList = pExpr->pList; int nExpr = pList ? pList->nExpr : 0; FuncDef *pDef; int nId; const char *zId; getFunctionName(pExpr, &zId, &nId); pDef = sqliteFindFunction(pParse->db, zId, nId, nExpr, 0); assert( pDef!=0 ); nExpr = sqliteExprCodeExprList(pParse, pList, pDef->includeTypes); sqliteVdbeOp3(v, OP_Function, nExpr, 0, (char*)pDef, P3_POINTER); break; } case TK_SELECT: { sqliteVdbeAddOp(v, OP_MemLoad, pExpr->iColumn, 0); break; } case TK_IN: { int addr; sqliteVdbeAddOp(v, OP_Integer, 1, 0); sqliteExprCode(pParse, pExpr->pLeft); addr = sqliteVdbeCurrentAddr(v); sqliteVdbeAddOp(v, OP_NotNull, -1, addr+4); sqliteVdbeAddOp(v, OP_Pop, 2, 0); sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeAddOp(v, OP_Goto, 0, addr+6); if( pExpr->pSelect ){ sqliteVdbeAddOp(v, OP_Found, pExpr->iTable, addr+6); }else{ sqliteVdbeAddOp(v, OP_SetFound, pExpr->iTable, addr+6); } sqliteVdbeAddOp(v, OP_AddImm, -1, 0); break; } case TK_BETWEEN: { sqliteExprCode(pParse, pExpr->pLeft); sqliteVdbeAddOp(v, OP_Dup, 0, 0); sqliteExprCode(pParse, pExpr->pList->a[0].pExpr); sqliteVdbeAddOp(v, OP_Ge, 0, 0); sqliteVdbeAddOp(v, OP_Pull, 1, 0); sqliteExprCode(pParse, pExpr->pList->a[1].pExpr); sqliteVdbeAddOp(v, OP_Le, 0, 0); sqliteVdbeAddOp(v, OP_And, 0, 0); break; } case TK_UPLUS: case TK_AS: { sqliteExprCode(pParse, pExpr->pLeft); break; } case TK_CASE: { int expr_end_label; int jumpInst; int addr; int nExpr; int i; assert(pExpr->pList); assert((pExpr->pList->nExpr % 2) == 0); assert(pExpr->pList->nExpr > 0); nExpr = pExpr->pList->nExpr; expr_end_label = sqliteVdbeMakeLabel(v); if( pExpr->pLeft ){ sqliteExprCode(pParse, pExpr->pLeft); } for(i=0; i<nExpr; i=i+2){ sqliteExprCode(pParse, pExpr->pList->a[i].pExpr); if( pExpr->pLeft ){ sqliteVdbeAddOp(v, OP_Dup, 1, 1); jumpInst = sqliteVdbeAddOp(v, OP_Ne, 1, 0); sqliteVdbeAddOp(v, OP_Pop, 1, 0); }else{ jumpInst = sqliteVdbeAddOp(v, OP_IfNot, 1, 0); } sqliteExprCode(pParse, pExpr->pList->a[i+1].pExpr); sqliteVdbeAddOp(v, OP_Goto, 0, expr_end_label); addr = sqliteVdbeCurrentAddr(v); sqliteVdbeChangeP2(v, jumpInst, addr); } if( pExpr->pLeft ){ sqliteVdbeAddOp(v, OP_Pop, 1, 0); } if( pExpr->pRight ){ sqliteExprCode(pParse, pExpr->pRight); }else{ sqliteVdbeAddOp(v, OP_String, 0, 0); } sqliteVdbeResolveLabel(v, expr_end_label); break; } case TK_RAISE: { if( !pParse->trigStack ){ sqliteErrorMsg(pParse, "RAISE() may only be used within a trigger-program"); pParse->nErr++; return; } if( pExpr->iColumn == OE_Rollback || pExpr->iColumn == OE_Abort || pExpr->iColumn == OE_Fail ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -