[PATCH] Add tablename tracking to VIEW_find_column
Nate Gallaher
ngallaher at deepthought.org
Wed Sep 30 23:13:03 CDT 2009
This fixes the bug where multiple columns of the same name, but
different tables are members of a join. Any attempt to reffer to these
columns will resolve to the first available column with that name,
irregardless of any tablename modifier.
dlls/msi/alter.c | 5 +-
dlls/msi/create.c | 5 +-
dlls/msi/delete.c | 7 ++-
dlls/msi/distinct.c | 7 ++-
dlls/msi/insert.c | 19 +++++----
dlls/msi/join.c | 8 ++-
dlls/msi/msipriv.h | 8 ++--
dlls/msi/msiquery.c | 14 +++++--
dlls/msi/query.h | 8 +++-
dlls/msi/select.c | 11 +++--
dlls/msi/sql.y | 3 +-
dlls/msi/storages.c | 6 ++-
dlls/msi/streams.c | 6 ++-
dlls/msi/table.c | 13 +++++-
dlls/msi/tests/db.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++++
dlls/msi/update.c | 7 ++-
dlls/msi/where.c | 15 ++++---
17 files changed, 201 insertions(+), 51 deletions(-)
diff --git a/dlls/msi/alter.c b/dlls/msi/alter.c
index 0f750d0..427505d 100644
--- a/dlls/msi/alter.c
+++ b/dlls/msi/alter.c
@@ -183,11 +183,12 @@ static UINT ALTER_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
}
static UINT ALTER_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
MSIALTERVIEW *av = (MSIALTERVIEW*)view;
- TRACE("%p %d %p %p %p\n", av, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", av, n, name, type, temporary, tableName );
return ERROR_FUNCTION_FAILED;
}
diff --git a/dlls/msi/create.c b/dlls/msi/create.c
index 63cd373..88a502d 100644
--- a/dlls/msi/create.c
+++ b/dlls/msi/create.c
@@ -91,11 +91,12 @@ static UINT CREATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
}
static UINT CREATE_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
- TRACE("%p %d %p %p %p\n", cv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", cv, n, name, type, temporary, tableName );
return ERROR_FUNCTION_FAILED;
}
diff --git a/dlls/msi/delete.c b/dlls/msi/delete.c
index c824d9e..70cce01 100644
--- a/dlls/msi/delete.c
+++ b/dlls/msi/delete.c
@@ -127,17 +127,18 @@ static UINT DELETE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
}
static UINT DELETE_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
MSIDELETEVIEW *dv = (MSIDELETEVIEW*)view;
- TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, tableName );
if( !dv->table )
return ERROR_FUNCTION_FAILED;
return dv->table->ops->get_column_info( dv->table, n, name,
- type, temporary );
+ type, temporary, tableName);
}
static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
diff --git a/dlls/msi/distinct.c b/dlls/msi/distinct.c
index 1e0cc2f..4f21792 100644
--- a/dlls/msi/distinct.c
+++ b/dlls/msi/distinct.c
@@ -205,17 +205,18 @@ static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *
}
static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
MSIDISTINCTVIEW *dv = (MSIDISTINCTVIEW*)view;
- TRACE("%p %d %p %p %p\n", dv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", dv, n, name, type, temporary, tableName );
if( !dv->table )
return ERROR_FUNCTION_FAILED;
return dv->table->ops->get_column_info( dv->table, n, name,
- type, temporary );
+ type, temporary, tableName );
}
static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
diff --git a/dlls/msi/insert.c b/dlls/msi/insert.c
index 0a1fbe6..480d3b1 100644
--- a/dlls/msi/insert.c
+++ b/dlls/msi/insert.c
@@ -114,8 +114,8 @@ static BOOL msi_columns_in_order(MSIINSERTVIEW *iv, UINT col_count)
for (i = 1; i <= col_count; i++)
{
- iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL);
- iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL);
+ iv->sv->ops->get_column_info(iv->sv, i, &a, NULL, NULL, NULL);
+ iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL, NULL);
res = lstrcmpW(a, b);
msi_free(a);
@@ -157,13 +157,14 @@ static UINT msi_arrange_record(MSIINSERTVIEW *iv, MSIRECORD **values)
for (colidx = 1; colidx <= val_count; colidx++)
{
- r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL, NULL);
+ r = iv->sv->ops->get_column_info(iv->sv, colidx, &a, NULL, NULL, NULL);
if (r != ERROR_SUCCESS)
goto err;
for (i = 1; i <= col_count; i++)
{
- r = iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL);
+ r = iv->table->ops->get_column_info(iv->table, i, &b, NULL,
+ NULL, NULL);
if (r != ERROR_SUCCESS)
goto err;
@@ -200,7 +201,8 @@ static BOOL row_has_null_primary_keys(MSIINSERTVIEW *iv, MSIRECORD *row)
for (i = 1; i <= col_count; i++)
{
- r = iv->table->ops->get_column_info(iv->table, i, NULL, &type, NULL);
+ r = iv->table->ops->get_column_info(iv->table, i, NULL, &type,
+ NULL, NULL);
if (r != ERROR_SUCCESS)
return FALSE;
@@ -291,18 +293,19 @@ static UINT INSERT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
}
static UINT INSERT_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
MSIVIEW *sv;
- TRACE("%p %d %p %p %p\n", iv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", iv, n, name, type, temporary, tableName );
sv = iv->sv;
if( !sv )
return ERROR_FUNCTION_FAILED;
- return sv->ops->get_column_info( sv, n, name, type, temporary );
+ return sv->ops->get_column_info( sv, n, name, type, temporary, tableName );
}
static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
diff --git a/dlls/msi/join.c b/dlls/msi/join.c
index 35db2fe..2f904ae 100644
--- a/dlls/msi/join.c
+++ b/dlls/msi/join.c
@@ -194,13 +194,14 @@ static UINT JOIN_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *cols
}
static UINT JOIN_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName )
{
MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
JOINTABLE *table;
UINT cols = 0;
- TRACE("%p %d %p %p %p\n", jv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", jv, n, name, type, temporary, tableName );
if (n == 0 || n > jv->columns)
return ERROR_FUNCTION_FAILED;
@@ -209,7 +210,8 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view,
{
if (n <= cols + table->columns)
return table->view->ops->get_column_info(table->view, n - cols,
- name, type, temporary);
+ name, type, temporary,
+ tableName);
cols += table->columns;
}
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index b61d7b6..b842994 100644
--- a/dlls/msi/msipriv.h
+++ b/dlls/msi/msipriv.h
@@ -227,11 +227,11 @@ typedef struct tagMSIVIEWOPS
/*
* get_column_info - returns the name and type of a specific column
*
- * The name is HeapAlloc'ed by this function and should be freed by
- * the caller.
+ * The name and tablename is HeapAlloc'ed by this function and should be
+ * freed by the caller.
* The column information can be queried at any time.
*/
- UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type, BOOL *temporary );
+ UINT (*get_column_info)( struct tagMSIVIEW *view, UINT n, LPWSTR *name, UINT *type, BOOL *temporary, LPWSTR *tableName);
/*
* modify - not yet implemented properly
@@ -733,7 +733,7 @@ extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** );
extern UINT MSI_ViewClose( MSIQUERY* );
extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **);
extern UINT MSI_ViewModify( MSIQUERY *, MSIMODIFY, MSIRECORD * );
-extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, UINT * );
+extern UINT VIEW_find_column( MSIVIEW *, LPCWSTR, LPCWSTR, UINT * );
extern UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD **);
/* install internals */
diff --git a/dlls/msi/msiquery.c b/dlls/msi/msiquery.c
index 5a46f9b..4ddc1b0 100644
--- a/dlls/msi/msiquery.c
+++ b/dlls/msi/msiquery.c
@@ -56,9 +56,10 @@ static void MSI_CloseView( MSIOBJECTHDR *arg )
}
}
-UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n )
+UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, LPCWSTR tableName, UINT *n )
{
LPWSTR col_name;
+ LPWSTR table_name;
UINT i, count, r;
r = table->ops->get_dimensions( table, NULL, &count );
@@ -70,11 +71,15 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n )
INT x;
col_name = NULL;
- r = table->ops->get_column_info( table, i, &col_name, NULL, NULL );
+ r = table->ops->get_column_info( table, i, &col_name, NULL,
+ NULL, &table_name );
if( r != ERROR_SUCCESS )
return r;
x = lstrcmpW( name, col_name );
+ if( tableName )
+ x |= lstrcmpW( tableName, table_name );
msi_free( col_name );
+ msi_free( table_name );
if( !x )
{
*n = i;
@@ -308,7 +313,7 @@ UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
for (i = 1; i <= col_count; i++)
{
- ret = view->ops->get_column_info(view, i, NULL, &type, NULL);
+ ret = view->ops->get_column_info(view, i, NULL, &type, NULL, NULL);
if (ret)
{
ERR("Error getting column type for %d\n", i);
@@ -555,7 +560,8 @@ UINT MSI_ViewGetColumnInfo( MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec )
for( i=0; i<count; i++ )
{
name = NULL;
- r = view->ops->get_column_info( view, i+1, &name, &type, &temporary );
+ r = view->ops->get_column_info( view, i+1, &name, &type, &temporary,
+ NULL );
if( r != ERROR_SUCCESS )
continue;
if (info == MSICOLINFO_NAMES)
diff --git a/dlls/msi/query.h b/dlls/msi/query.h
index eb11a1c..a43663d 100644
--- a/dlls/msi/query.h
+++ b/dlls/msi/query.h
@@ -68,6 +68,12 @@ struct complex_expr
struct expr *right;
};
+struct ext_column
+{
+ LPCWSTR column;
+ LPCWSTR table;
+};
+
struct expr
{
int type;
@@ -77,7 +83,7 @@ struct expr
INT ival;
UINT uval;
LPCWSTR sval;
- LPCWSTR column;
+ struct ext_column column;
UINT col_number;
} u;
};
diff --git a/dlls/msi/select.c b/dlls/msi/select.c
index 8fd761e..fa59341 100644
--- a/dlls/msi/select.c
+++ b/dlls/msi/select.c
@@ -209,11 +209,12 @@ static UINT SELECT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
}
static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
MSISELECTVIEW *sv = (MSISELECTVIEW*)view;
- TRACE("%p %d %p %p %p\n", sv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", sv, n, name, type, temporary, tableName );
if( !sv->table )
return ERROR_FUNCTION_FAILED;
@@ -224,7 +225,7 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
n = sv->cols[ n - 1 ];
return sv->table->ops->get_column_info( sv->table, n, name,
- type, temporary );
+ type, temporary, tableName );
}
static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
@@ -247,7 +248,7 @@ static UINT msi_select_update(struct tagMSIVIEW *view, MSIRECORD *rec, UINT row)
{
col = sv->cols[i];
- r = SELECT_get_column_info(view, i + 1, &name, &type, NULL);
+ r = SELECT_get_column_info(view, i + 1, &name, &type, NULL, NULL);
msi_free(name);
if (r != ERROR_SUCCESS)
{
@@ -388,7 +389,7 @@ static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name )
if( sv->num_cols >= sv->max_cols )
return ERROR_FUNCTION_FAILED;
- r = VIEW_find_column( table, name, &n );
+ r = VIEW_find_column( table, name, NULL, &n );
if( r != ERROR_SUCCESS )
return r;
diff --git a/dlls/msi/sql.y b/dlls/msi/sql.y
index 969c92c..e2484df 100644
--- a/dlls/msi/sql.y
+++ b/dlls/msi/sql.y
@@ -856,7 +856,8 @@ static struct expr * EXPR_column( void *info, const column_info *column )
if( e )
{
e->type = EXPR_COLUMN;
- e->u.sval = column->column;
+ e->u.column.column = column->column;
+ e->u.column.table = column->table;
}
return e;
}
diff --git a/dlls/msi/storages.c b/dlls/msi/storages.c
index 16b323c..938ed7d 100644
--- a/dlls/msi/storages.c
+++ b/dlls/msi/storages.c
@@ -289,14 +289,16 @@ static UINT STORAGES_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *c
}
static UINT STORAGES_get_column_info(struct tagMSIVIEW *view, UINT n,
- LPWSTR *name, UINT *type, BOOL *temporary)
+ LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
LPCWSTR name_ptr = NULL;
static const WCHAR Name[] = {'N','a','m','e',0};
static const WCHAR Data[] = {'D','a','t','a',0};
- TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary);
+ TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary,
+ tableName);
if (n == 0 || n > NUM_STORAGES_COLS)
return ERROR_INVALID_PARAMETER;
diff --git a/dlls/msi/streams.c b/dlls/msi/streams.c
index 12f707e..1ebd475 100644
--- a/dlls/msi/streams.c
+++ b/dlls/msi/streams.c
@@ -255,14 +255,16 @@ static UINT STREAMS_get_dimensions(struct tagMSIVIEW *view, UINT *rows, UINT *co
}
static UINT STREAMS_get_column_info(struct tagMSIVIEW *view, UINT n,
- LPWSTR *name, UINT *type, BOOL *temporary)
+ LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
LPCWSTR name_ptr = NULL;
static const WCHAR Name[] = {'N','a','m','e',0};
static const WCHAR Data[] = {'D','a','t','a',0};
- TRACE("(%p, %d, %p, %p, %p)\n", view, n, name, type, temporary);
+ TRACE("(%p, %d, %p, %p, %p, %p)\n", view, n, name, type, temporary,
+ tableName);
if (n == 0 || n > NUM_STREAMS_COLS)
return ERROR_INVALID_PARAMETER;
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index 126769a..16377c3 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -1551,7 +1551,8 @@ static UINT TABLE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
}
static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
@@ -1567,6 +1568,13 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
return ERROR_FUNCTION_FAILED;
}
+ if( tableName )
+ {
+ *tableName = strdupW( tv->columns[n-1].tablename );
+ if( !*tableName )
+ return ERROR_FUNCTION_FAILED;
+ }
+
if( type )
*type = tv->columns[n-1].type;
@@ -2045,6 +2053,7 @@ done:
static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWSTR name)
{
UINT n, r, count;
+ MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
r = TABLE_get_dimensions(view, NULL, &count);
if (r != ERROR_SUCCESS)
@@ -2053,7 +2062,7 @@ static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWS
if (order->num_cols >= count)
return ERROR_FUNCTION_FAILED;
- r = VIEW_find_column(view, name, &n);
+ r = VIEW_find_column(view, name, tv->name, &n);
if (r != ERROR_SUCCESS)
return r;
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index 019ff5e..7227c3c 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -1566,6 +1566,115 @@ static void test_binary(void)
DeleteFile( msifile );
}
+static void test_where_not_in_selected(void)
+{
+ MSIHANDLE hdb = 0, rec, view;
+ LPCSTR query;
+ UINT r;
+ DWORD size;
+ CHAR buf[MAX_PATH];
+ UINT count;
+
+ hdb = create_db();
+ ok( hdb, "failed to create db\n");
+
+ r = run_query(hdb, 0,
+ "CREATE TABLE `IESTable` ("
+ "`Action` CHAR(64), "
+ "`Condition` CHAR(64), "
+ "`Sequence` LONG PRIMARY KEY `Sequence`)");
+ ok( r == S_OK, "Cannot create IESTable table: %d\n", r);
+
+ r = run_query(hdb, 0,
+ "CREATE TABLE `CATable` ("
+ "`Action` CHAR(64), "
+ "`Type` LONG PRIMARY KEY `Type`)");
+ ok( r == S_OK, "Cannot create CATable table: %d\n", r);
+
+ r = run_query(hdb, 0, "INSERT INTO `IESTable` "
+ "( `Action`, `Condition`, `Sequence`) "
+ "VALUES ( 'clean', 'cond4', 4)");
+ ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `IESTable` "
+ "( `Action`, `Condition`, `Sequence`) "
+ "VALUES ( 'depends', 'cond1', 1)");
+ ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `IESTable` "
+ "( `Action`, `Condition`, `Sequence`) "
+ "VALUES ( 'build', 'cond2', 2)");
+ ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `IESTable` "
+ "( `Action`, `Condition`, `Sequence`) "
+ "VALUES ( 'build2', 'cond6', 6)");
+ ok( r == S_OK, "cannot add entry to IESTable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `IESTable` "
+ "( `Action`, `Condition`, `Sequence`) "
+ "VALUES ( 'build', 'cond3', 3)");
+ ok(r == S_OK, "cannot add entry to IESTable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `CATable` "
+ "( `Action`, `Type` ) "
+ "VALUES ( 'build', 32)");
+ ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `CATable` "
+ "( `Action`, `Type` ) "
+ "VALUES ( 'depends', 64)");
+ ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `CATable` "
+ "( `Action`, `Type` ) "
+ "VALUES ( 'clean', 63)");
+ ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
+
+ r = run_query(hdb, 0, "INSERT INTO `CATable` "
+ "( `Action`, `Type` ) "
+ "VALUES ( 'build2', 34)");
+ ok(r == S_OK, "cannot add entry to CATable table:%d\n", r );
+ query = /*"Select IESTable.Action, IESTable.Condition from CATable, IESTable where "*/
+ "Select IESTable.Condition from CATable, IESTable where "
+ //"CATable.Action = IESTable.Action and (CATable.Type = 51 or CATable.Type = 32) "
+ "CATable.Action = IESTable.Action and CATable.Type = 32 "
+ /*"order by IESTable.Sequence"*/;
+ r = MsiDatabaseOpenView(hdb, query, &view);
+ ok( r == ERROR_SUCCESS, "failed to open view: %d\n", r );
+
+ r = MsiViewExecute(view, 0);
+ ok( r == ERROR_SUCCESS, "failed to execute view: %d\n", r );
+
+ r = MsiViewFetch(view, &rec);
+ ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
+
+ size = sizeof buf;
+ r = MsiRecordGetString( rec, 1, buf, &size );
+ printf("Returned entry: %s\n", buf);
+
+ ok( check_record( rec, 1, "cond2"), "wrong condition\n");
+
+ MsiCloseHandle( rec );
+ r = MsiViewFetch(view, &rec);
+ ok( r == ERROR_SUCCESS, "failed to fetch view: %d\n", r );
+
+ size = sizeof buf;
+ r = MsiRecordGetString( rec, 1, buf, &size );
+ printf("Returned entry: %s\n", buf);
+
+ ok( check_record( rec, 1, "cond3"), "wrong condition\n");
+
+ MsiCloseHandle( rec );
+ MsiViewClose(view);
+ MsiCloseHandle(view);
+
+ MsiCloseHandle( hdb );
+ DeleteFile(msifile);
+
+}
+
+
static void test_where(void)
{
MSIHANDLE hdb = 0, rec, view;
@@ -8205,6 +8314,7 @@ START_TEST(db)
test_longstrings();
test_streamtable();
test_binary();
+ test_where_not_in_selected();
test_where();
test_msiimport();
test_binary_import();
diff --git a/dlls/msi/update.c b/dlls/msi/update.c
index 56d2391..7619e10 100644
--- a/dlls/msi/update.c
+++ b/dlls/msi/update.c
@@ -155,18 +155,19 @@ static UINT UPDATE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *co
}
static UINT UPDATE_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR* tableName )
{
MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
MSIVIEW *wv;
- TRACE("%p %d %p %p %p\n", uv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", uv, n, name, type, temporary, tableName );
wv = uv->wv;
if( !wv )
return ERROR_FUNCTION_FAILED;
- return wv->ops->get_column_info( wv, n, name, type, temporary );
+ return wv->ops->get_column_info( wv, n, name, type, temporary, tableName );
}
static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
diff --git a/dlls/msi/where.c b/dlls/msi/where.c
index fc804a4..21692bc 100644
--- a/dlls/msi/where.c
+++ b/dlls/msi/where.c
@@ -490,17 +490,18 @@ static UINT WHERE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
}
static UINT WHERE_get_column_info( struct tagMSIVIEW *view,
- UINT n, LPWSTR *name, UINT *type, BOOL *temporary )
+ UINT n, LPWSTR *name, UINT *type, BOOL *temporary,
+ LPWSTR *tableName)
{
MSIWHEREVIEW *wv = (MSIWHEREVIEW*)view;
- TRACE("%p %d %p %p %p\n", wv, n, name, type, temporary );
+ TRACE("%p %d %p %p %p %p\n", wv, n, name, type, temporary, tableName );
if( !wv->table )
return ERROR_FUNCTION_FAILED;
return wv->table->ops->get_column_info( wv->table, n, name,
- type, temporary );
+ type, temporary, tableName );
}
static UINT WHERE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
@@ -597,11 +598,13 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
switch( cond->type )
{
case EXPR_COLUMN:
- r = VIEW_find_column( table, cond->u.column, &val );
+ r = VIEW_find_column( table, cond->u.column.column,
+ cond->u.column.table, &val );
if( r == ERROR_SUCCESS )
{
UINT type = 0;
- r = table->ops->get_column_info( table, val, NULL, &type, NULL );
+ r = table->ops->get_column_info( table, val, NULL, &type,
+ NULL, NULL );
if( r == ERROR_SUCCESS )
{
if (type&MSITYPE_STRING)
@@ -619,7 +622,7 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
else
{
*valid = 0;
- WARN("Couldn't find column %s\n", debugstr_w( cond->u.column ) );
+ WARN("Couldn't find column %s.%s\n", debugstr_w( cond->u.column.table ), debugstr_w( cond->u.column.column ) );
}
break;
case EXPR_COMPLEX:
--
1.6.0.4
--------------030304010000060409010607--
More information about the wine-patches
mailing list