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