📄 expr.c
字号:
sqliteSetNString(&pParse->zErrMsg, "wrong number of arguments to function ", -1, zId, nId, "()", 2, 0); pParse->nErr++; nErr++; } if( is_agg ) pExpr->op = TK_AGG_FUNCTION; if( is_agg && 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 ){ if( is_type_of ){ pExpr->op = TK_STRING; if( sqliteExprType(pExpr->pList->a[0].pExpr)==SQLITE_SO_NUM ){ pExpr->token.z = "numeric"; pExpr->token.n = 7; }else{ pExpr->token.z = "text"; pExpr->token.n = 4; } } }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: 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_INTEGER: { int iVal = atoi(pExpr->token.z); char zBuf[30]; sprintf(zBuf,"%d",iVal); if( strlen(zBuf)!=pExpr->token.n || strncmp(pExpr->token.z,zBuf,pExpr->token.n)!=0 ){ /* If the integer value cannot be represented exactly in 32 bits, ** then code it as a string instead. */ sqliteVdbeAddOp(v, OP_String, 0, 0); }else{ sqliteVdbeAddOp(v, OP_Integer, iVal, 0); } sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n); break; } case TK_FLOAT: { sqliteVdbeAddOp(v, OP_String, 0, 0); assert( pExpr->token.z ); sqliteVdbeChangeP3(v, -1, pExpr->token.z, pExpr->token.n); break; } case TK_STRING: { int addr = sqliteVdbeAddOp(v, OP_String, 0, 0); assert( pExpr->token.z ); sqliteVdbeChangeP3(v, addr, pExpr->token.z, pExpr->token.n); sqliteVdbeDequoteP3(v, addr); break; } case TK_NULL: { sqliteVdbeAddOp(v, OP_String, 0, 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_UPLUS: { Expr *pLeft = pExpr->pLeft; if( pLeft && pLeft->op==TK_INTEGER ){ sqliteVdbeAddOp(v, OP_Integer, atoi(pLeft->token.z), 0); sqliteVdbeChangeP3(v, -1, pLeft->token.z, pLeft->token.n); }else if( pLeft && pLeft->op==TK_FLOAT ){ sqliteVdbeAddOp(v, OP_String, 0, 0); sqliteVdbeChangeP3(v, -1, pLeft->token.z, pLeft->token.n); }else{ sqliteExprCode(pParse, pExpr->pLeft); } 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 ){ 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: { int i; 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 ); for(i=0; i<nExpr; i++){ sqliteExprCode(pParse, pList->a[i].pExpr); } sqliteVdbeAddOp(v, OP_Function, nExpr, 0); sqliteVdbeChangeP3(v, -1, (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, 1, 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_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 ){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -