Commit 0093007b authored by Mike McCormack's avatar Mike McCormack Committed by Alexandre Julliard

Track memory allocations in the SQL parser.

parent 7f99aa83
...@@ -201,20 +201,10 @@ static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode, ...@@ -201,20 +201,10 @@ static UINT CREATE_modify( struct tagMSIVIEW *view, MSIMODIFY eModifyMode,
static UINT CREATE_delete( struct tagMSIVIEW *view ) static UINT CREATE_delete( struct tagMSIVIEW *view )
{ {
MSICREATEVIEW *cv = (MSICREATEVIEW*)view; MSICREATEVIEW *cv = (MSICREATEVIEW*)view;
create_col_info *col;
TRACE("%p\n", cv ); TRACE("%p\n", cv );
col = cv->col_info;
while( col )
{
create_col_info *t = col;
col = col->next;
HeapFree( GetProcessHeap(), 0, t->colname );
HeapFree( GetProcessHeap(), 0, t );
}
msiobj_release( &cv->db->hdr ); msiobj_release( &cv->db->hdr );
HeapFree( GetProcessHeap(), 0, cv->name );
HeapFree( GetProcessHeap(), 0, cv ); HeapFree( GetProcessHeap(), 0, cv );
return ERROR_SUCCESS; return ERROR_SUCCESS;
...@@ -250,7 +240,7 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table, ...@@ -250,7 +240,7 @@ UINT CREATE_CreateView( MSIDATABASE *db, MSIVIEW **view, LPWSTR table,
cv->view.ops = &create_ops; cv->view.ops = &create_ops;
msiobj_addref( &db->hdr ); msiobj_addref( &db->hdr );
cv->db = db; cv->db = db;
cv->name = table; /* FIXME: strdupW it? */ cv->name = table;
cv->col_info = col_info; cv->col_info = col_info;
cv->bIsTemp = temp; cv->bIsTemp = temp;
*view = (MSIVIEW*) cv; *view = (MSIVIEW*) cv;
......
...@@ -233,7 +233,6 @@ static UINT INSERT_delete( struct tagMSIVIEW *view ) ...@@ -233,7 +233,6 @@ static UINT INSERT_delete( struct tagMSIVIEW *view )
sv = iv->sv; sv = iv->sv;
if( sv ) if( sv )
sv->ops->delete( sv ); sv->ops->delete( sv );
delete_value_list( iv->vals );
msiobj_release( &iv->db->hdr ); msiobj_release( &iv->db->hdr );
HeapFree( GetProcessHeap(), 0, iv ); HeapFree( GetProcessHeap(), 0, iv );
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "objbase.h" #include "objbase.h"
#include "objidl.h" #include "objidl.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "wine/list.h"
#define MSI_DATASIZEMASK 0x00ff #define MSI_DATASIZEMASK 0x00ff
#define MSITYPE_VALID 0x0100 #define MSITYPE_VALID 0x0100
...@@ -77,6 +78,7 @@ typedef struct tagMSIQUERY ...@@ -77,6 +78,7 @@ typedef struct tagMSIQUERY
MSIVIEW *view; MSIVIEW *view;
UINT row; UINT row;
MSIDATABASE *db; MSIDATABASE *db;
struct list mem;
} MSIQUERY; } MSIQUERY;
/* maybe we can use a Variant instead of doing it ourselves? */ /* maybe we can use a Variant instead of doing it ourselves? */
......
...@@ -41,10 +41,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi); ...@@ -41,10 +41,16 @@ WINE_DEFAULT_DEBUG_CHANNEL(msi);
void MSI_CloseView( MSIOBJECTHDR *arg ) void MSI_CloseView( MSIOBJECTHDR *arg )
{ {
MSIQUERY *query = (MSIQUERY*) arg; MSIQUERY *query = (MSIQUERY*) arg;
struct list *ptr, *t;
if( query->view && query->view->ops->delete ) if( query->view && query->view->ops->delete )
query->view->ops->delete( query->view ); query->view->ops->delete( query->view );
msiobj_release( &query->db->hdr ); msiobj_release( &query->db->hdr );
LIST_FOR_EACH_SAFE( ptr, t, &query->mem )
{
HeapFree( GetProcessHeap(), 0, ptr );
}
} }
UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n ) UINT VIEW_find_column( MSIVIEW *table, LPCWSTR name, UINT *n )
...@@ -120,8 +126,9 @@ UINT MSI_DatabaseOpenViewW(MSIDATABASE *db, ...@@ -120,8 +126,9 @@ UINT MSI_DatabaseOpenViewW(MSIDATABASE *db,
query->row = 0; query->row = 0;
query->db = db; query->db = db;
query->view = NULL; query->view = NULL;
list_init( &query->mem );
r = MSI_ParseSQL( db, szQuery, &query->view ); r = MSI_ParseSQL( db, szQuery, &query->view, &query->mem );
if( r == ERROR_SUCCESS ) if( r == ERROR_SUCCESS )
{ {
msiobj_addref( &query->hdr ); msiobj_addref( &query->hdr );
......
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "msi.h" #include "msi.h"
#include "msiquery.h" #include "msiquery.h"
#include "msipriv.h" #include "msipriv.h"
#include "wine/list.h"
#define OP_EQ 1 #define OP_EQ 1
...@@ -105,7 +106,8 @@ typedef struct _column_assignment ...@@ -105,7 +106,8 @@ typedef struct _column_assignment
} column_assignment; } column_assignment;
UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phView); UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
struct list *mem );
UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view ); UINT TABLE_CreateView( MSIDATABASE *db, LPCWSTR name, MSIVIEW **view );
...@@ -131,10 +133,6 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **, LPWSTR table, ...@@ -131,10 +133,6 @@ UINT UPDATE_CreateView( MSIDATABASE *db, MSIVIEW **, LPWSTR table,
UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table ); UINT DELETE_CreateView( MSIDATABASE *db, MSIVIEW **view, MSIVIEW *table );
void delete_expr( struct expr *e );
void delete_string_list( string_list *sl );
void delete_value_list( value_list *vl );
int sqliteGetToken(const WCHAR *z, int *tokenType); int sqliteGetToken(const WCHAR *z, int *tokenType);
#endif /* __WINE_MSI_QUERY_H */ #endif /* __WINE_MSI_QUERY_H */
...@@ -30,6 +30,7 @@ ...@@ -30,6 +30,7 @@
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
#include "query.h" #include "query.h"
#include "wine/list.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/unicode.h" #include "wine/unicode.h"
...@@ -46,20 +47,22 @@ typedef struct tag_SQL_input ...@@ -46,20 +47,22 @@ typedef struct tag_SQL_input
LPCWSTR command; LPCWSTR command;
DWORD n, len; DWORD n, len;
MSIVIEW **view; /* view structure for the resulting query */ MSIVIEW **view; /* view structure for the resulting query */
struct list *mem;
} SQL_input; } SQL_input;
static LPWSTR SQL_getstring( struct sql_str *str ); static LPWSTR SQL_getstring( void *info, struct sql_str *str );
static INT SQL_getint( SQL_input *sql ); static INT SQL_getint( void *info );
static int SQL_lex( void *SQL_lval, SQL_input *info); static int SQL_lex( void *SQL_lval, SQL_input *info );
static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, static void *parser_alloc( void *info, unsigned int sz );
string_list *keys);
static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r ); static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, string_list *keys);
static struct expr * EXPR_column( LPWSTR );
static struct expr * EXPR_ival( struct sql_str *, int sign); static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );
static struct expr * EXPR_sval( struct sql_str *); static struct expr * EXPR_column( void *info, LPWSTR column );
static struct expr * EXPR_wildcard(); static struct expr * EXPR_ival( void *info, struct sql_str *, int sign );
static struct expr * EXPR_sval( void *info, struct sql_str * );
static struct expr * EXPR_wildcard( void *info );
%} %}
...@@ -435,70 +438,72 @@ expr: ...@@ -435,70 +438,72 @@ expr:
TK_LP expr TK_RP TK_LP expr TK_RP
{ {
$$ = $2; $$ = $2;
if( !$$ )
YYABORT;
} }
| column_val TK_EQ column_val | column_val TK_EQ column_val
{ {
$$ = EXPR_complex( $1, OP_EQ, $3 ); $$ = EXPR_complex( info, $1, OP_EQ, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| expr TK_AND expr | expr TK_AND expr
{ {
$$ = EXPR_complex( $1, OP_AND, $3 ); $$ = EXPR_complex( info, $1, OP_AND, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| expr TK_OR expr | expr TK_OR expr
{ {
$$ = EXPR_complex( $1, OP_OR, $3 ); $$ = EXPR_complex( info, $1, OP_OR, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_EQ val | column_val TK_EQ val
{ {
$$ = EXPR_complex( $1, OP_EQ, $3 ); $$ = EXPR_complex( info, $1, OP_EQ, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_GT val | column_val TK_GT val
{ {
$$ = EXPR_complex( $1, OP_GT, $3 ); $$ = EXPR_complex( info, $1, OP_GT, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_LT val | column_val TK_LT val
{ {
$$ = EXPR_complex( $1, OP_LT, $3 ); $$ = EXPR_complex( info, $1, OP_LT, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_LE val | column_val TK_LE val
{ {
$$ = EXPR_complex( $1, OP_LE, $3 ); $$ = EXPR_complex( info, $1, OP_LE, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_GE val | column_val TK_GE val
{ {
$$ = EXPR_complex( $1, OP_GE, $3 ); $$ = EXPR_complex( info, $1, OP_GE, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_NE val | column_val TK_NE val
{ {
$$ = EXPR_complex( $1, OP_NE, $3 ); $$ = EXPR_complex( info, $1, OP_NE, $3 );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_IS TK_NULL | column_val TK_IS TK_NULL
{ {
$$ = EXPR_complex( $1, OP_ISNULL, NULL ); $$ = EXPR_complex( info, $1, OP_ISNULL, NULL );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
| column_val TK_IS TK_NOT TK_NULL | column_val TK_IS TK_NOT TK_NULL
{ {
$$ = EXPR_complex( $1, OP_NOTNULL, NULL ); $$ = EXPR_complex( info, $1, OP_NOTNULL, NULL );
if( !$$ ) if( !$$ )
YYABORT; YYABORT;
} }
...@@ -514,24 +519,22 @@ constlist: ...@@ -514,24 +519,22 @@ constlist:
{ {
value_list *vals; value_list *vals;
vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals ); vals = parser_alloc( info, sizeof *vals );
if( vals ) if( !vals )
{ YYABORT;
vals->val = $1; vals->val = $1;
vals->next = NULL; vals->next = NULL;
}
$$ = vals; $$ = vals;
} }
| const_val TK_COMMA constlist | const_val TK_COMMA constlist
{ {
value_list *vals; value_list *vals;
vals = HeapAlloc( GetProcessHeap(), 0, sizeof *vals ); vals = parser_alloc( info, sizeof *vals );
if( vals ) if( !vals )
{ YYABORT;
vals->val = $1; vals->val = $1;
vals->next = $3; vals->next = $3;
}
$$ = vals; $$ = vals;
} }
; ;
...@@ -565,26 +568,26 @@ column_assignment: ...@@ -565,26 +568,26 @@ column_assignment:
const_val: const_val:
TK_INTEGER TK_INTEGER
{ {
$$ = EXPR_ival( &$1, 1 ); $$ = EXPR_ival( info, &$1, 1 );
} }
| TK_MINUS TK_INTEGER | TK_MINUS TK_INTEGER
{ {
$$ = EXPR_ival( &$2, -1 ); $$ = EXPR_ival( info, &$2, -1 );
} }
| TK_STRING | TK_STRING
{ {
$$ = EXPR_sval( &$1 ); $$ = EXPR_sval( info, &$1 );
} }
| TK_WILDCARD | TK_WILDCARD
{ {
$$ = EXPR_wildcard(); $$ = EXPR_wildcard( info );
} }
; ;
column_val: column_val:
column column
{ {
$$ = EXPR_column( $1 ); $$ = EXPR_column( info, $1 );
} }
; ;
...@@ -609,13 +612,25 @@ table: ...@@ -609,13 +612,25 @@ table:
id: id:
TK_ID TK_ID
{ {
$$ = SQL_getstring( &$1 ); $$ = SQL_getstring( info, &$1 );
if( !$$ )
YYABORT;
} }
; ;
%% %%
int SQL_lex( void *SQL_lval, SQL_input *sql) static void *parser_alloc( void *info, unsigned int sz )
{
SQL_input* sql = (SQL_input*) info;
struct list *mem;
mem = HeapAlloc( GetProcessHeap(), 0, sizeof (struct list) + sz );
list_add_tail( sql->mem, mem );
return &mem[1];
}
int SQL_lex( void *SQL_lval, SQL_input *sql )
{ {
int token; int token;
struct sql_str * str = SQL_lval; struct sql_str * str = SQL_lval;
...@@ -640,7 +655,7 @@ int SQL_lex( void *SQL_lval, SQL_input *sql) ...@@ -640,7 +655,7 @@ int SQL_lex( void *SQL_lval, SQL_input *sql)
return token; return token;
} }
LPWSTR SQL_getstring( struct sql_str *strdata) LPWSTR SQL_getstring( void *info, struct sql_str *strdata )
{ {
LPCWSTR p = strdata->data; LPCWSTR p = strdata->data;
UINT len = strdata->len; UINT len = strdata->len;
...@@ -653,30 +668,31 @@ LPWSTR SQL_getstring( struct sql_str *strdata) ...@@ -653,30 +668,31 @@ LPWSTR SQL_getstring( struct sql_str *strdata)
p++; p++;
len -= 2; len -= 2;
} }
str = HeapAlloc( GetProcessHeap(), 0, (len + 1)*sizeof(WCHAR)); str = parser_alloc( info, (len + 1)*sizeof(WCHAR) );
if(!str ) if( !str )
return str; return str;
memcpy(str, p, len*sizeof(WCHAR) ); memcpy( str, p, len*sizeof(WCHAR) );
str[len]=0; str[len]=0;
return str; return str;
} }
INT SQL_getint( SQL_input *sql ) INT SQL_getint( void *info )
{ {
SQL_input* sql = (SQL_input*) info;
LPCWSTR p = &sql->command[sql->n]; LPCWSTR p = &sql->command[sql->n];
return atoiW( p ); return atoiW( p );
} }
int SQL_error(const char *str) int SQL_error( const char *str )
{ {
return 0; return 0;
} }
static struct expr * EXPR_wildcard() static struct expr * EXPR_wildcard( void *info )
{ {
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e ); struct expr *e = parser_alloc( info, sizeof *e );
if( e ) if( e )
{ {
e->type = EXPR_WILDCARD; e->type = EXPR_WILDCARD;
...@@ -684,9 +700,9 @@ static struct expr * EXPR_wildcard() ...@@ -684,9 +700,9 @@ static struct expr * EXPR_wildcard()
return e; return e;
} }
static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r ) static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r )
{ {
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e ); struct expr *e = parser_alloc( info, sizeof *e );
if( e ) if( e )
{ {
e->type = EXPR_COMPLEX; e->type = EXPR_COMPLEX;
...@@ -697,20 +713,20 @@ static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r ) ...@@ -697,20 +713,20 @@ static struct expr * EXPR_complex( struct expr *l, UINT op, struct expr *r )
return e; return e;
} }
static struct expr * EXPR_column( LPWSTR str ) static struct expr * EXPR_column( void *info, LPWSTR column )
{ {
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e ); struct expr *e = parser_alloc( info, sizeof *e );
if( e ) if( e )
{ {
e->type = EXPR_COLUMN; e->type = EXPR_COLUMN;
e->u.sval = str; e->u.sval = column;
} }
return e; return e;
} }
static struct expr * EXPR_ival( struct sql_str *str , int sign) static struct expr * EXPR_ival( void *info, struct sql_str *str, int sign )
{ {
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e ); struct expr *e = parser_alloc( info, sizeof *e );
if( e ) if( e )
{ {
e->type = EXPR_IVAL; e->type = EXPR_IVAL;
...@@ -719,55 +735,18 @@ static struct expr * EXPR_ival( struct sql_str *str , int sign) ...@@ -719,55 +735,18 @@ static struct expr * EXPR_ival( struct sql_str *str , int sign)
return e; return e;
} }
static struct expr * EXPR_sval( struct sql_str *str ) static struct expr * EXPR_sval( void *info, struct sql_str *str )
{ {
struct expr *e = HeapAlloc( GetProcessHeap(), 0, sizeof *e ); struct expr *e = parser_alloc( info, sizeof *e );
if( e ) if( e )
{ {
e->type = EXPR_SVAL; e->type = EXPR_SVAL;
e->u.sval = SQL_getstring( str ); e->u.sval = SQL_getstring( info, str );
} }
return e; return e;
} }
void delete_expr( struct expr *e ) static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, string_list *keys)
{
if( !e )
return;
if( e->type == EXPR_COMPLEX )
{
delete_expr( e->u.expr.left );
delete_expr( e->u.expr.right );
}
else if( e->type == EXPR_SVAL )
HeapFree( GetProcessHeap(), 0, e->u.sval );
HeapFree( GetProcessHeap(), 0, e );
}
void delete_string_list( string_list *sl )
{
while( sl )
{
string_list *t = sl->next;
HeapFree( GetProcessHeap(), 0, sl->string );
HeapFree( GetProcessHeap(), 0, sl );
sl = t;
}
}
void delete_value_list( value_list *vl )
{
while( vl )
{
value_list *t = vl->next;
delete_expr( vl->val );
HeapFree( GetProcessHeap(), 0, vl );
vl = t;
}
}
static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
string_list *keys )
{ {
string_list *k; string_list *k;
BOOL found = TRUE; BOOL found = TRUE;
...@@ -789,7 +768,8 @@ static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, ...@@ -789,7 +768,8 @@ static BOOL SQL_MarkPrimaryKeys( create_col_info *cols,
return found; return found;
} }
UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview ) UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
struct list *mem )
{ {
SQL_input sql; SQL_input sql;
int r; int r;
...@@ -801,6 +781,7 @@ UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview ) ...@@ -801,6 +781,7 @@ UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview )
sql.n = 0; sql.n = 0;
sql.len = 0; sql.len = 0;
sql.view = phview; sql.view = phview;
sql.mem = mem;
r = SQL_parse(&sql); r = SQL_parse(&sql);
......
...@@ -171,7 +171,6 @@ static UINT UPDATE_delete( struct tagMSIVIEW *view ) ...@@ -171,7 +171,6 @@ static UINT UPDATE_delete( struct tagMSIVIEW *view )
wv = uv->wv; wv = uv->wv;
if( wv ) if( wv )
wv->ops->delete( wv ); wv->ops->delete( wv );
delete_value_list( uv->vals );
msiobj_release( &uv->db->hdr ); msiobj_release( &uv->db->hdr );
HeapFree( GetProcessHeap(), 0, uv ); HeapFree( GetProcessHeap(), 0, uv );
......
...@@ -334,9 +334,6 @@ static UINT WHERE_delete( struct tagMSIVIEW *view ) ...@@ -334,9 +334,6 @@ static UINT WHERE_delete( struct tagMSIVIEW *view )
wv->reorder = NULL; wv->reorder = NULL;
wv->row_count = 0; wv->row_count = 0;
if( wv->cond )
delete_expr( wv->cond );
msiobj_release( &wv->db->hdr ); msiobj_release( &wv->db->hdr );
HeapFree( GetProcessHeap(), 0, wv ); HeapFree( GetProcessHeap(), 0, wv );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment