msi: Fix WHERE IS (NOT) NULL queries.

This commit is contained in:
Mike McCormack 2006-11-07 15:07:16 +09:00 committed by Alexandre Julliard
parent 2b943bfddc
commit 50e5caeb6c
4 changed files with 54 additions and 6 deletions

View File

@ -54,6 +54,7 @@
#define EXPR_WILDCARD 9
#define EXPR_COL_NUMBER_STRING 10
#define EXPR_COL_NUMBER32 11
#define EXPR_UNARY 12
struct sql_str {
LPCWSTR data;

View File

@ -59,6 +59,7 @@ static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR colu
static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);
static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );
static struct expr * EXPR_unary( void *info, struct expr *l, UINT op );
static struct expr * EXPR_column( void *info, column_info *column );
static struct expr * EXPR_ival( void *info, int val );
static struct expr * EXPR_sval( void *info, struct sql_str * );
@ -513,13 +514,13 @@ expr:
}
| column_val TK_IS TK_NULL
{
$$ = EXPR_complex( info, $1, OP_ISNULL, NULL );
$$ = EXPR_unary( info, $1, OP_ISNULL );
if( !$$ )
YYABORT;
}
| column_val TK_IS TK_NOT TK_NULL
{
$$ = EXPR_complex( info, $1, OP_NOTNULL, NULL );
$$ = EXPR_unary( info, $1, OP_NOTNULL );
if( !$$ )
YYABORT;
}
@ -762,6 +763,19 @@ static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct e
return e;
}
static struct expr * EXPR_unary( void *info, struct expr *l, UINT op )
{
struct expr *e = parser_alloc( info, sizeof *e );
if( e )
{
e->type = EXPR_UNARY;
e->u.expr.left = l;
e->u.expr.op = op;
e->u.expr.right = NULL;
}
return e;
}
static struct expr * EXPR_column( void *info, column_info *column )
{
struct expr *e = parser_alloc( info, sizeof *e );

View File

@ -1354,6 +1354,12 @@ static void test_where(void)
MsiCloseHandle( rec );
rec = 0;
query = "SELECT * FROM `Media` WHERE `DiskPrompt` IS NULL";
r = do_query(hdb, query, &rec);
ok( r == ERROR_SUCCESS, "query failed: %d\n", r );
MsiCloseHandle( rec );
MsiCloseHandle( hdb );
DeleteFile(msifile);
}

View File

@ -99,7 +99,7 @@ static UINT WHERE_set_row( struct tagMSIVIEW *view, UINT row, MSIRECORD *rec, UI
return wv->table->ops->set_row( wv->table, row, rec, mask );
}
static INT INT_evaluate( INT lval, UINT op, INT rval )
static INT INT_evaluate_binary( INT lval, UINT op, INT rval )
{
switch( op )
{
@ -119,6 +119,16 @@ static INT INT_evaluate( INT lval, UINT op, INT rval )
return ( lval >= rval );
case OP_NE:
return ( lval != rval );
default:
ERR("Unknown operator %d\n", op );
}
return 0;
}
static INT INT_evaluate_unary( INT lval, UINT op )
{
switch( op )
{
case OP_ISNULL:
return ( !lval );
case OP_NOTNULL:
@ -211,7 +221,14 @@ static UINT WHERE_evaluate( MSIDATABASE *db, MSIVIEW *table, UINT row,
r = WHERE_evaluate( db, table, row, cond->u.expr.right, &rval, record );
if( r != ERROR_SUCCESS )
return r;
*val = INT_evaluate( lval, cond->u.expr.op, rval );
*val = INT_evaluate_binary( lval, cond->u.expr.op, rval );
return ERROR_SUCCESS;
case EXPR_UNARY:
r = table->ops->fetch_int( table, row, cond->u.expr.left->u.col_number, &tval );
if( r != ERROR_SUCCESS )
return r;
*val = INT_evaluate_unary( tval, cond->u.expr.op );
return ERROR_SUCCESS;
case EXPR_STRCMP:
@ -497,6 +514,16 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
}
break;
case EXPR_UNARY:
if ( cond->u.expr.left->type != EXPR_COLUMN )
{
*valid = FALSE;
return ERROR_INVALID_PARAMETER;
}
r = WHERE_VerifyCondition( db, table, cond->u.expr.left, valid );
if( r != ERROR_SUCCESS )
return r;
break;
case EXPR_IVAL:
*valid = 1;
cond->type = EXPR_UVAL;