mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-08 03:22:21 +03:00
Code generator tries to avoid pointless OP_IsNull and OP_Affinity opcodes.
FossilOrigin-Name: ebb0c8a3e977dc741704e733b5a5d931d9b27028
This commit is contained in:
65
src/expr.c
65
src/expr.c
@@ -1258,6 +1258,71 @@ int sqlite3ExprIsInteger(Expr *p, int *pValue){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
** Return FALSE if there is no chance that the expression can be NULL.
|
||||
**
|
||||
** If the expression might be NULL or if the expression is too complex
|
||||
** to tell return TRUE.
|
||||
**
|
||||
** This routine is used as an optimization, to skip OP_IsNull opcodes
|
||||
** when we know that a value cannot be NULL. Hence, a false positive
|
||||
** (returning TRUE when in fact the expression can never be NULL) might
|
||||
** be a small performance hit but is otherwise harmless. On the other
|
||||
** hand, a false negative (returning FALSE when the result could be NULL)
|
||||
** will likely result in an incorrect answer. So when in doubt, return
|
||||
** TRUE.
|
||||
*/
|
||||
int sqlite3ExprCanBeNull(const Expr *p){
|
||||
u8 op;
|
||||
while( p->op==TK_UPLUS || p->op==TK_MINUS ){ p = p->pLeft; }
|
||||
op = p->op;
|
||||
if( op==TK_REGISTER ) op = p->op2;
|
||||
switch( op ){
|
||||
case TK_INTEGER:
|
||||
case TK_STRING:
|
||||
case TK_FLOAT:
|
||||
case TK_BLOB:
|
||||
return 0;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if the given expression is a constant which would be
|
||||
** unchanged by OP_Affinity with the affinity given in the second
|
||||
** argument.
|
||||
**
|
||||
** This routine is used to determine if the OP_Affinity operation
|
||||
** can be omitted. When in doubt return FALSE. A false negative
|
||||
** is harmless. A false positive, however, can result in the wrong
|
||||
** answer.
|
||||
*/
|
||||
int sqlite3ExprNeedsNoAffinityChange(const Expr *p, char aff){
|
||||
u8 op;
|
||||
if( aff==SQLITE_AFF_NONE ) return 1;
|
||||
while( p->op==TK_UPLUS || p->op==TK_MINUS ){ p = p->pLeft; }
|
||||
op = p->op;
|
||||
if( op==TK_REGISTER ) op = p->op2;
|
||||
switch( op ){
|
||||
case TK_INTEGER: {
|
||||
return aff==SQLITE_AFF_INTEGER || aff==SQLITE_AFF_NUMERIC;
|
||||
}
|
||||
case TK_FLOAT: {
|
||||
return aff==SQLITE_AFF_REAL || aff==SQLITE_AFF_NUMERIC;
|
||||
}
|
||||
case TK_STRING: {
|
||||
return aff==SQLITE_AFF_TEXT;
|
||||
}
|
||||
case TK_BLOB: {
|
||||
return 1;
|
||||
}
|
||||
default: {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
** Return TRUE if the given string is a row-id column name.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user