msi: Add tablename tracking to VIEW_find_column.
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.
This commit is contained in:
parent
c6af1f5cd4
commit
cc366e1282
|
@ -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,
|
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;
|
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;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
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;
|
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;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
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;
|
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 )
|
if( !dv->table )
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
return dv->table->ops->get_column_info( dv->table, n, name,
|
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,
|
static UINT DELETE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
||||||
|
|
|
@ -205,17 +205,18 @@ static UINT DISTINCT_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT DISTINCT_get_column_info( struct tagMSIVIEW *view,
|
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;
|
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 )
|
if( !dv->table )
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
return dv->table->ops->get_column_info( dv->table, n, name,
|
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,
|
static UINT DISTINCT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
||||||
|
|
|
@ -114,8 +114,8 @@ static BOOL msi_columns_in_order(MSIINSERTVIEW *iv, UINT col_count)
|
||||||
|
|
||||||
for (i = 1; i <= col_count; i++)
|
for (i = 1; i <= col_count; i++)
|
||||||
{
|
{
|
||||||
iv->sv->ops->get_column_info(iv->sv, i, &a, 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);
|
iv->table->ops->get_column_info(iv->table, i, &b, NULL, NULL, NULL);
|
||||||
|
|
||||||
res = lstrcmpW(a, b);
|
res = lstrcmpW(a, b);
|
||||||
msi_free(a);
|
msi_free(a);
|
||||||
|
@ -157,13 +157,14 @@ static UINT msi_arrange_record(MSIINSERTVIEW *iv, MSIRECORD **values)
|
||||||
|
|
||||||
for (colidx = 1; colidx <= val_count; colidx++)
|
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)
|
if (r != ERROR_SUCCESS)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
for (i = 1; i <= col_count; i++)
|
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)
|
if (r != ERROR_SUCCESS)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
|
@ -200,7 +201,8 @@ static BOOL row_has_null_primary_keys(MSIINSERTVIEW *iv, MSIRECORD *row)
|
||||||
|
|
||||||
for (i = 1; i <= col_count; i++)
|
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)
|
if (r != ERROR_SUCCESS)
|
||||||
return FALSE;
|
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,
|
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;
|
MSIINSERTVIEW *iv = (MSIINSERTVIEW*)view;
|
||||||
MSIVIEW *sv;
|
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;
|
sv = iv->sv;
|
||||||
if( !sv )
|
if( !sv )
|
||||||
return ERROR_FUNCTION_FAILED;
|
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)
|
static UINT INSERT_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, MSIRECORD *rec, UINT row)
|
||||||
|
|
|
@ -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,
|
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;
|
MSIJOINVIEW *jv = (MSIJOINVIEW*)view;
|
||||||
JOINTABLE *table;
|
JOINTABLE *table;
|
||||||
UINT cols = 0;
|
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)
|
if (n == 0 || n > jv->columns)
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
@ -209,7 +210,8 @@ static UINT JOIN_get_column_info( struct tagMSIVIEW *view,
|
||||||
{
|
{
|
||||||
if (n <= cols + table->columns)
|
if (n <= cols + table->columns)
|
||||||
return table->view->ops->get_column_info(table->view, n - cols,
|
return table->view->ops->get_column_info(table->view, n - cols,
|
||||||
name, type, temporary);
|
name, type, temporary,
|
||||||
|
table_name);
|
||||||
|
|
||||||
cols += table->columns;
|
cols += table->columns;
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,11 +228,11 @@ typedef struct tagMSIVIEWOPS
|
||||||
/*
|
/*
|
||||||
* get_column_info - returns the name and type of a specific column
|
* 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 name and tablename is HeapAlloc'ed by this function and should be
|
||||||
* the caller.
|
* freed by the caller.
|
||||||
* The column information can be queried at any time.
|
* 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
|
* modify - not yet implemented properly
|
||||||
|
@ -737,7 +737,7 @@ extern UINT MSI_ViewFetch( MSIQUERY*, MSIRECORD ** );
|
||||||
extern UINT MSI_ViewClose( MSIQUERY* );
|
extern UINT MSI_ViewClose( MSIQUERY* );
|
||||||
extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **);
|
extern UINT MSI_ViewGetColumnInfo(MSIQUERY *, MSICOLINFO, MSIRECORD **);
|
||||||
extern UINT MSI_ViewModify( MSIQUERY *, MSIMODIFY, 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 **);
|
extern UINT msi_view_get_row(MSIDATABASE *, MSIVIEW *, UINT, MSIRECORD **);
|
||||||
|
|
||||||
/* install internals */
|
/* install internals */
|
||||||
|
|
|
@ -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 col_name;
|
||||||
|
LPWSTR haystack_table_name;
|
||||||
UINT i, count, r;
|
UINT i, count, r;
|
||||||
|
|
||||||
r = table->ops->get_dimensions( table, NULL, &count );
|
r = table->ops->get_dimensions( table, NULL, &count );
|
||||||
|
@ -70,11 +71,15 @@ UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n )
|
||||||
INT x;
|
INT x;
|
||||||
|
|
||||||
col_name = NULL;
|
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 )
|
if( r != ERROR_SUCCESS )
|
||||||
return r;
|
return r;
|
||||||
x = lstrcmpW( name, col_name );
|
x = lstrcmpW( name, col_name );
|
||||||
|
if( table_name )
|
||||||
|
x |= lstrcmpW( table_name, haystack_table_name );
|
||||||
msi_free( col_name );
|
msi_free( col_name );
|
||||||
|
msi_free( haystack_table_name );
|
||||||
if( !x )
|
if( !x )
|
||||||
{
|
{
|
||||||
*n = i;
|
*n = i;
|
||||||
|
@ -306,7 +311,7 @@ UINT msi_view_get_row(MSIDATABASE *db, MSIVIEW *view, UINT row, MSIRECORD **rec)
|
||||||
|
|
||||||
for (i = 1; i <= col_count; i++)
|
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)
|
if (ret)
|
||||||
{
|
{
|
||||||
ERR("Error getting column type for %d\n", i);
|
ERR("Error getting column type for %d\n", i);
|
||||||
|
@ -553,7 +558,8 @@ UINT MSI_ViewGetColumnInfo( MSIQUERY *query, MSICOLINFO info, MSIRECORD **prec )
|
||||||
for( i=0; i<count; i++ )
|
for( i=0; i<count; i++ )
|
||||||
{
|
{
|
||||||
name = NULL;
|
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 )
|
if( r != ERROR_SUCCESS )
|
||||||
continue;
|
continue;
|
||||||
if (info == MSICOLINFO_NAMES)
|
if (info == MSICOLINFO_NAMES)
|
||||||
|
|
|
@ -68,6 +68,12 @@ struct complex_expr
|
||||||
struct expr *right;
|
struct expr *right;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ext_column
|
||||||
|
{
|
||||||
|
LPCWSTR column;
|
||||||
|
LPCWSTR table;
|
||||||
|
};
|
||||||
|
|
||||||
struct expr
|
struct expr
|
||||||
{
|
{
|
||||||
int type;
|
int type;
|
||||||
|
@ -77,7 +83,7 @@ struct expr
|
||||||
INT ival;
|
INT ival;
|
||||||
UINT uval;
|
UINT uval;
|
||||||
LPCWSTR sval;
|
LPCWSTR sval;
|
||||||
LPCWSTR column;
|
struct ext_column column;
|
||||||
UINT col_number;
|
UINT col_number;
|
||||||
} u;
|
} u;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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,
|
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;
|
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 )
|
if( !sv->table )
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
@ -224,7 +225,7 @@ static UINT SELECT_get_column_info( struct tagMSIVIEW *view,
|
||||||
n = sv->cols[ n - 1 ];
|
n = sv->cols[ n - 1 ];
|
||||||
|
|
||||||
return sv->table->ops->get_column_info( sv->table, n, name,
|
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)
|
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];
|
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);
|
msi_free(name);
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -388,7 +389,7 @@ static UINT SELECT_AddColumn( MSISELECTVIEW *sv, LPCWSTR name )
|
||||||
if( sv->num_cols >= sv->max_cols )
|
if( sv->num_cols >= sv->max_cols )
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
r = VIEW_find_column( table, name, &n );
|
r = VIEW_find_column( table, name, NULL, &n );
|
||||||
if( r != ERROR_SUCCESS )
|
if( r != ERROR_SUCCESS )
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -856,7 +856,8 @@ static struct expr * EXPR_column( void *info, const column_info *column )
|
||||||
if( e )
|
if( e )
|
||||||
{
|
{
|
||||||
e->type = EXPR_COLUMN;
|
e->type = EXPR_COLUMN;
|
||||||
e->u.sval = column->column;
|
e->u.column.column = column->column;
|
||||||
|
e->u.column.table = column->table;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
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;
|
LPCWSTR name_ptr = NULL;
|
||||||
|
|
||||||
static const WCHAR Name[] = {'N','a','m','e',0};
|
static const WCHAR Name[] = {'N','a','m','e',0};
|
||||||
static const WCHAR Data[] = {'D','a','t','a',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)
|
if (n == 0 || n > NUM_STORAGES_COLS)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
|
@ -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,
|
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;
|
LPCWSTR name_ptr = NULL;
|
||||||
|
|
||||||
static const WCHAR Name[] = {'N','a','m','e',0};
|
static const WCHAR Name[] = {'N','a','m','e',0};
|
||||||
static const WCHAR Data[] = {'D','a','t','a',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)
|
if (n == 0 || n > NUM_STREAMS_COLS)
|
||||||
return ERROR_INVALID_PARAMETER;
|
return ERROR_INVALID_PARAMETER;
|
||||||
|
|
|
@ -1582,7 +1582,8 @@ static UINT TABLE_get_dimensions( struct tagMSIVIEW *view, UINT *rows, UINT *col
|
||||||
}
|
}
|
||||||
|
|
||||||
static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
|
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;
|
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
|
||||||
|
|
||||||
|
@ -1598,6 +1599,13 @@ static UINT TABLE_get_column_info( struct tagMSIVIEW *view,
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( table_name )
|
||||||
|
{
|
||||||
|
*table_name = strdupW( tv->columns[n-1].tablename );
|
||||||
|
if( !*table_name )
|
||||||
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if( type )
|
if( type )
|
||||||
*type = tv->columns[n-1].type;
|
*type = tv->columns[n-1].type;
|
||||||
|
|
||||||
|
@ -2118,6 +2126,7 @@ done:
|
||||||
static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWSTR name)
|
static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWSTR name)
|
||||||
{
|
{
|
||||||
UINT n, r, count;
|
UINT n, r, count;
|
||||||
|
MSITABLEVIEW *tv = (MSITABLEVIEW*)view;
|
||||||
|
|
||||||
r = TABLE_get_dimensions(view, NULL, &count);
|
r = TABLE_get_dimensions(view, NULL, &count);
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
|
@ -2126,7 +2135,7 @@ static UINT order_add_column(struct tagMSIVIEW *view, MSIORDERINFO *order, LPCWS
|
||||||
if (order->num_cols >= count)
|
if (order->num_cols >= count)
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
r = VIEW_find_column(view, name, &n);
|
r = VIEW_find_column(view, name, tv->name, &n);
|
||||||
if (r != ERROR_SUCCESS)
|
if (r != ERROR_SUCCESS)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
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;
|
MSIUPDATEVIEW *uv = (MSIUPDATEVIEW*)view;
|
||||||
MSIVIEW *wv;
|
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;
|
wv = uv->wv;
|
||||||
if( !wv )
|
if( !wv )
|
||||||
return ERROR_FUNCTION_FAILED;
|
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,
|
static UINT UPDATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
|
||||||
|
|
|
@ -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,
|
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;
|
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 )
|
if( !wv->table )
|
||||||
return ERROR_FUNCTION_FAILED;
|
return ERROR_FUNCTION_FAILED;
|
||||||
|
|
||||||
return wv->table->ops->get_column_info( wv->table, n, name,
|
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,
|
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 )
|
switch( cond->type )
|
||||||
{
|
{
|
||||||
case EXPR_COLUMN:
|
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 )
|
if( r == ERROR_SUCCESS )
|
||||||
{
|
{
|
||||||
UINT type = 0;
|
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( r == ERROR_SUCCESS )
|
||||||
{
|
{
|
||||||
if (type&MSITYPE_STRING)
|
if (type&MSITYPE_STRING)
|
||||||
|
@ -619,7 +622,7 @@ static UINT WHERE_VerifyCondition( MSIDATABASE *db, MSIVIEW *table, struct expr
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*valid = 0;
|
*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;
|
break;
|
||||||
case EXPR_COMPLEX:
|
case EXPR_COMPLEX:
|
||||||
|
|
Loading…
Reference in New Issue