#include "query.h"\r
#include "wine/list.h"\r
#include "wine/debug.h"\r
-#include "wine/unicode.h"\r
\r
#define YYLEX_PARAM info\r
#define YYPARSE_PARAM info\r
static int SQL_lex( void *SQL_lval, SQL_input *info );\r
\r
static void *parser_alloc( void *info, unsigned int sz );\r
+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column );\r
\r
-static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, string_list *keys);\r
+static BOOL SQL_MarkPrimaryKeys( column_info *cols, column_info *keys);\r
\r
static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r );\r
-static struct expr * EXPR_column( void *info, LPWSTR column );\r
-static struct expr * EXPR_ival( void *info, struct sql_str *, int sign );\r
+static struct expr * EXPR_column( void *info, column_info *column );\r
+static struct expr * EXPR_ival( void *info, int val );\r
static struct expr * EXPR_sval( void *info, struct sql_str * );\r
static struct expr * EXPR_wildcard( void *info );\r
\r
{\r
struct sql_str str;\r
LPWSTR string;\r
- string_list *column_list;\r
- value_list *val_list;\r
+ column_info *column_list;\r
MSIVIEW *query;\r
struct expr *expr;\r
USHORT column_type;\r
- create_col_info *column_info;\r
- column_assignment update_col_info;\r
+ int integer;\r
}\r
\r
%token TK_ABORT TK_AFTER TK_AGG_FUNCTION TK_ALL TK_AND TK_AS TK_ASC\r
%nonassoc END_OF_FILE ILLEGAL SPACE UNCLOSED_STRING COMMENT FUNCTION\r
COLUMN AGG_FUNCTION.\r
\r
-%type <string> column table id\r
-%type <column_list> selcollist\r
-%type <query> query from fromtable unorderedsel selectfrom\r
+%type <string> table id\r
+%type <column_list> selcollist column column_and_type column_def table_def\r
+%type <column_list> column_assignment update_assign_list constlist\r
+%type <query> query from fromtable selectfrom unorderedsel\r
%type <query> oneupdate onedelete oneselect onequery onecreate oneinsert\r
%type <expr> expr val column_val const_val\r
%type <column_type> column_type data_type data_type_l data_count\r
-%type <column_info> column_def table_def\r
-%type <val_list> constlist\r
-%type <update_col_info> column_assignment update_assign_list\r
+%type <integer> number\r
\r
%%\r
\r
SQL_input* sql = (SQL_input*) info;\r
MSIVIEW *update = NULL; \r
\r
- UPDATE_CreateView( sql->db, &update, $2, &$4, $6 );\r
+ UPDATE_CreateView( sql->db, &update, $2, $4, $6 );\r
if( !update )\r
YYABORT;\r
$$ = update;\r
;\r
\r
column_def:\r
- column_def TK_COMMA column column_type\r
+ column_def TK_COMMA column_and_type\r
{\r
- create_col_info *ci;\r
+ column_info *ci;\r
\r
for( ci = $1; ci->next; ci = ci->next )\r
;\r
\r
- ci->next = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );\r
- if( !ci->next )\r
- {\r
- /* FIXME: free $1 */\r
- YYABORT;\r
- }\r
- ci->next->colname = $3;\r
- ci->next->type = $4;\r
- ci->next->next = NULL;\r
-\r
+ ci->next = $3;\r
$$ = $1;\r
}\r
- | column column_type\r
+ | column_and_type\r
{\r
- $$ = HeapAlloc( GetProcessHeap(), 0, sizeof *$$ );\r
- if( ! $$ )\r
- YYABORT;\r
- $$->colname = $1;\r
+ $$ = $1;\r
+ }\r
+ ;\r
+\r
+column_and_type:\r
+ column column_type\r
+ {\r
+ $$ = $1;\r
$$->type = $2;\r
- $$->next = NULL;\r
}\r
;\r
\r
;\r
\r
data_count:\r
- TK_INTEGER\r
+ number\r
{\r
- SQL_input* sql = (SQL_input*) info;\r
- int val = SQL_getint(sql);\r
- if( ( val > 255 ) || ( val < 0 ) )\r
+ if( ( $1 > 255 ) || ( $1 < 0 ) )\r
YYABORT;\r
- $$ = val;\r
+ $$ = $1;\r
}\r
;\r
\r
\r
selcollist:\r
column \r
- { \r
- string_list *list;\r
-\r
- list = HeapAlloc( GetProcessHeap(), 0, sizeof *list );\r
- if( !list )\r
- YYABORT;\r
- list->string = $1;\r
- list->next = NULL;\r
-\r
- $$ = list;\r
- TRACE("Collist %s\n",debugstr_w($$->string));\r
- }\r
| column TK_COMMA selcollist\r
{ \r
- string_list *list;\r
-\r
- list = HeapAlloc( GetProcessHeap(), 0, sizeof *list );\r
- if( !list )\r
- YYABORT;\r
- list->string = $1;\r
- list->next = $3;\r
-\r
- $$ = list;\r
- TRACE("From table: %s\n",debugstr_w($$->string));\r
+ $1->next = $3;\r
}\r
| TK_STAR\r
{\r
constlist:\r
const_val\r
{\r
- value_list *vals;\r
-\r
- vals = parser_alloc( info, sizeof *vals );\r
- if( !vals )\r
+ $$ = parser_alloc_column( info, NULL, NULL );\r
+ if( !$$ )\r
YYABORT;\r
- vals->val = $1;\r
- vals->next = NULL;\r
- $$ = vals;\r
+ $$->val = $1;\r
}\r
| const_val TK_COMMA constlist\r
{\r
- value_list *vals;\r
-\r
- vals = parser_alloc( info, sizeof *vals );\r
- if( !vals )\r
+ $$ = parser_alloc_column( info, NULL, NULL );\r
+ if( !$$ )\r
YYABORT;\r
- vals->val = $1;\r
- vals->next = $3;\r
- $$ = vals;\r
+ $$->val = $1;\r
+ $$->next = $3;\r
}\r
;\r
\r
column_assignment\r
| column_assignment TK_COMMA update_assign_list\r
{\r
- $1.col_list->next = $3.col_list;\r
- $1.val_list->next = $3.val_list;\r
$$ = $1;\r
+ $$->next = $3;\r
}\r
;\r
\r
column_assignment:\r
column TK_EQ const_val\r
{\r
- $$.col_list = HeapAlloc( GetProcessHeap(), 0, sizeof *$$.col_list );\r
- if( !$$.col_list )\r
- YYABORT;\r
- $$.col_list->string = $1;\r
- $$.col_list->next = NULL;\r
- $$.val_list = HeapAlloc( GetProcessHeap(), 0, sizeof *$$.val_list );\r
- if( !$$.val_list )\r
- YYABORT;\r
- $$.val_list->val = $3;\r
- $$.val_list->next = 0;\r
+ $$ = $1;\r
+ $$->val = $3;\r
}\r
;\r
\r
const_val:\r
- TK_INTEGER\r
+ number\r
{\r
- $$ = EXPR_ival( info, &$1, 1 );\r
+ $$ = EXPR_ival( info, $1 );\r
if( !$$ )\r
YYABORT;\r
}\r
- | TK_MINUS TK_INTEGER\r
+ | TK_MINUS number\r
{\r
- $$ = EXPR_ival( info, &$2, -1 );\r
+ $$ = EXPR_ival( info, -$2 );\r
if( !$$ )\r
YYABORT;\r
}\r
column:\r
table TK_DOT id\r
{\r
- $$ = $3; /* FIXME */\r
+ $$ = parser_alloc_column( info, $1, $3 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
| id\r
{\r
- $$ = $1;\r
+ $$ = parser_alloc_column( info, NULL, $1 );\r
+ if( !$$ )\r
+ YYABORT;\r
}\r
;\r
\r
}\r
;\r
\r
+number:\r
+ TK_INTEGER\r
+ {\r
+ $$ = SQL_getint( info );\r
+ }\r
+ ;\r
+\r
%%\r
\r
static void *parser_alloc( void *info, unsigned int sz )\r
return &mem[1];\r
}\r
\r
+static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column )\r
+{\r
+ column_info *col;\r
+\r
+ col = parser_alloc( info, sizeof (*col) );\r
+ if( col )\r
+ {\r
+ col->table = table;\r
+ col->column = column;\r
+ col->val = NULL;\r
+ col->type = 0;\r
+ col->next = NULL;\r
+ }\r
+\r
+ return col;\r
+}\r
+\r
int SQL_lex( void *SQL_lval, SQL_input *sql )\r
{\r
int token;\r
{\r
SQL_input* sql = (SQL_input*) info;\r
LPCWSTR p = &sql->command[sql->n];\r
+ INT i, r = 0;\r
+\r
+ for( i=0; i<sql->len; i++ )\r
+ {\r
+ if( '0' > p[i] || '9' < p[i] )\r
+ {\r
+ ERR("should only be numbers here!\n");\r
+ break;\r
+ }\r
+ r = (p[i]-'0') + r*10;\r
+ }\r
\r
- return atoiW( p );\r
+ return r;\r
}\r
\r
int SQL_error( const char *str )\r
return e;\r
}\r
\r
-static struct expr * EXPR_column( void *info, LPWSTR column )\r
+static struct expr * EXPR_column( void *info, column_info *column )\r
{\r
struct expr *e = parser_alloc( info, sizeof *e );\r
if( e )\r
{\r
e->type = EXPR_COLUMN;\r
- e->u.sval = column;\r
+ e->u.sval = column->column;\r
}\r
return e;\r
}\r
\r
-static struct expr * EXPR_ival( void *info, struct sql_str *str, int sign )\r
+static struct expr * EXPR_ival( void *info, int val )\r
{\r
struct expr *e = parser_alloc( info, sizeof *e );\r
if( e )\r
{\r
e->type = EXPR_IVAL;\r
- e->u.ival = atoiW( str->data ) * sign;\r
+ e->u.ival = val;\r
}\r
return e;\r
}\r
return e;\r
}\r
\r
-static BOOL SQL_MarkPrimaryKeys( create_col_info *cols, string_list *keys)\r
+static BOOL SQL_MarkPrimaryKeys( column_info *cols,\r
+ column_info *keys )\r
{\r
- string_list *k;\r
+ column_info *k;\r
BOOL found = TRUE;\r
\r
for( k = keys; k && found; k = k->next )\r
{\r
- create_col_info *c;\r
+ column_info *c;\r
\r
found = FALSE;\r
for( c = cols; c && !found; c = c->next )\r
{\r
- if( lstrcmpW( k->string, c->colname ) )\r
+ if( lstrcmpW( k->column, c->column ) )\r
continue;\r
c->type |= MSITYPE_KEY;\r
found = TRUE;\r