Resubmit of patch.
Patch separated into test and fix components.
Patch rebased.
tableName variable --> table_name
Commented code removed.
Unused variables removed
Unnecessary debug printf's removed.
Thanks for the review,
~Nate
On Thu, 1 Oct 2009, Hans Leidekker wrote:
Hi Nate,
Your patch applies with offsets, please rebase to current git.
And get rid of this warning:
db.c: In function ‘test_where_not_in_selected’:
db.c:1576: warning: unused variable ‘count’
+ 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"*/;
Please remove the commented strings.
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)
'table_name' or just 'table' would be more in keeping with the existing style.
+ printf("Returned entry: %s\n", buf);
trace() is usually used for debug printing but you might want to turn this
into a test instead, or just leave it out. And you should split off the tests
to keep the patch size down.
-Hans
From 75668d7c9eeeb49c786b021575ca7a98c3303dce Mon Sep 17 00:00:00 2001
From: Nate Gallaher <[email protected]>
Date: Sun, 18 Oct 2009 12:47:02 -0400
Subject: [PATCH] Test for bug 20227
Tests that a query on a join of two tables returns data from the correct
table. i.e.: two tables both containing the column "action" are joined
and filtered on the equality of this column. In the buggy case, all
rows of the joined table would be returned, since the first action
column is always equal to itself.
---
dlls/msi/tests/db.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 97 insertions(+), 0 deletions(-)
diff --git a/dlls/msi/tests/db.c b/dlls/msi/tests/db.c
index 019ff5e..904a974 100644
--- a/dlls/msi/tests/db.c
+++ b/dlls/msi/tests/db.c
@@ -1566,6 +1566,102 @@ static void test_binary(void)
DeleteFile( msifile );
}
+/* Test for bug 20227 */
+static void test_where_not_in_selected(void)
+{
+ MSIHANDLE hdb = 0, rec, view;
+ LPCSTR query;
+ UINT r;
+
+ 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.Condition from CATable, IESTable where "
+ "CATable.Action = IESTable.Action and CATable.Type = 32";
+ 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 );
+
+ 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 );
+
+ 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 +8301,7 @@ START_TEST(db)
test_longstrings();
test_streamtable();
test_binary();
+ test_where_not_in_selected();
test_where();
test_msiimport();
test_binary_import();
--
1.6.0.4
From 047617c993543caedbd5a7073e97d6333419790b Mon Sep 17 00:00:00 2001
From: Nate Gallaher <[email protected]>
Date: Sun, 18 Oct 2009 12:41:41 -0400
Subject: [PATCH] Add tablename tracking to VIEW_find_column.
Fixes bug 20227.
This fixes the bug where multiple columns of the same name, but
different tables are members of a join. Any attempt to refer 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/update.c | 7 ++++---
dlls/msi/where.c | 15 +++++++++------
16 files changed, 91 insertions(+), 51 deletions(-)
diff --git a/dlls/msi/alter.c b/dlls/msi/alter.c
index 0f750d0..a62b13e 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 *table_name)
{
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, table_name );
return ERROR_FUNCTION_FAILED;
}
diff --git a/dlls/msi/create.c b/dlls/msi/create.c
index 63cd373..2e13d59 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 *table_name)
{
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, table_name );
return ERROR_FUNCTION_FAILED;
}
diff --git a/dlls/msi/delete.c b/dlls/msi/delete.c
index c824d9e..210fc9e 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 *table_name)
{
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, table_name );
if( !dv->table )
return ERROR_FUNCTION_FAILED;
return dv->table->ops->get_column_info( dv->table, n, name,
- type, temporary );
+ type, temporary, table_name);
}
static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
diff --git a/dlls/msi/distinct.c b/dlls/msi/distinct.c
index 1e0cc2f..06beece 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 *table_name)
{
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, table_name );
if( !dv->table )
return ERROR_FUNCTION_FAILED;
return dv->table->ops->get_column_info( dv->table, n, name,
- type, temporary );
+ type, temporary, table_name );
}
static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
diff --git a/dlls/msi/insert.c b/dlls/msi/insert.c
index 0a1fbe6..61807e9 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 *table_name)
{
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, table_name );
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, table_name );
}
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..1aeb17c 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 *table_name )
{
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, table_name );
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,
+ table_name);
cols += table->columns;
}
diff --git a/dlls/msi/msipriv.h b/dlls/msi/msipriv.h
index 296e87d..58df7fe 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
@@ -736,7 +736,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..8d815dc 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 table_name, UINT *n )
{
LPWSTR col_name;
+ LPWSTR haystack_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, &haystack_table_name );
if( r != ERROR_SUCCESS )
return r;
x = lstrcmpW( name, col_name );
+ if( table_name )
+ x |= lstrcmpW( table_name, haystack_table_name );
msi_free( col_name );
+ msi_free( haystack_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..c4b9e80 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 *table_name)
{
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, table_name );
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, table_name );
}
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..005bcdb 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 *table_name)
{
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,
+ table_name);
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..23ae971 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 *table_name)
{
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,
+ table_name);
if (n == 0 || n > NUM_STREAMS_COLS)
return ERROR_INVALID_PARAMETER;
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index aa37670..714383d 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -1555,7 +1555,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 *table_name )
{
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
@@ -1571,6 +1572,13 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
return ERROR_FUNCTION_FAILED;
}
+ if( table_name )
+ {
+ *table_name = strdupW( tv->columns[n-1].tablename );
+ if( !*table_name )
+ return ERROR_FUNCTION_FAILED;
+ }
+
if( type )
*type = tv->columns[n-1].type;
@@ -2049,6 +2057,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)
@@ -2057,7 +2066,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/update.c b/dlls/msi/update.c
index 56d2391..c80d5a9 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* table_name )
{
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, table_name );
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, table_name );
}
static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
diff --git a/dlls/msi/where.c b/dlls/msi/where.c
index fc804a4..32f71b9 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 *table_name)
{
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, table_name );
if( !wv->table )
return ERROR_FUNCTION_FAILED;
return wv->table->ops->get_column_info( wv->table, n, name,
- type, temporary );
+ type, temporary, table_name );
}
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