Mike McCormack : msi: Fix WHERE IS (NOT) NULL queries.
Alexandre Julliard
julliard at wine.codeweavers.com
Tue Nov 7 10:16:43 CST 2006
Module: wine
Branch: master
Commit: 50e5caeb6c4d13548ac07eea469714147ed7288e
URL: http://source.winehq.org/git/wine.git/?a=commit;h=50e5caeb6c4d13548ac07eea469714147ed7288e
Author: Mike McCormack <mike at codeweavers.com>
Date: Tue Nov 7 15:07:16 2006 +0900
msi: Fix WHERE IS (NOT) NULL queries.
---
dlls/msi/query.h | 1 +
dlls/msi/sql.y | 18 ++++++++++++++++--
dlls/msi/tests/db.c | 6 ++++++
dlls/msi/where.c | 35 +++++++++++++++++++++++++++++++----
4 files changed, 54 insertions(+), 6 deletions(-)
diff --git a/dlls/msi/query.h b/dlls/msi/query.h
index 360f4b5..86773ad 100644
--- a/dlls/msi/query.h
+++ b/dlls/msi/query.h
@@ -54,6 +54,7 @@ #define EXPR_STRCMP 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;
diff --git a/dlls/msi/sql.y b/dlls/msi/sql.y
index c005611..17cb957 100644
--- a/dlls/msi/sql.y
+++ b/dlls/msi/sql.y
@@ -59,6 +59,7 @@ static column_info *parser_alloc_column(
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
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 );
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index 1bca0d3..7360238 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -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);
}
diff --git a/dlls/msi/where.c b/dlls/msi/where.c
index 6fd2f88..a30ebcb 100644
--- a/dlls/msi/where.c
+++ b/dlls/msi/where.c
@@ -99,7 +99,7 @@ static UINT WHERE_set_row( struct tagMSI
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
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
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:
@@ -224,7 +241,7 @@ static UINT WHERE_evaluate( MSIDATABASE
default:
ERR("Invalid expression type\n");
break;
- }
+ }
return ERROR_SUCCESS;
@@ -497,6 +514,16 @@ static UINT WHERE_VerifyCondition( MSIDA
}
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;
@@ -512,7 +539,7 @@ static UINT WHERE_VerifyCondition( MSIDA
ERR("Invalid expression type\n");
*valid = 0;
break;
- }
+ }
return ERROR_SUCCESS;
}
More information about the wine-cvs
mailing list