📄 sql.y
字号:
YYABORT;
}
}
;
fromtable:
TK_FROM table
{
SQL_input* sql = (SQL_input*) info;
UINT r;
$$ = NULL;
r = TABLE_CreateView( sql->db, $2, &$$ );
if( r != ERROR_SUCCESS || !$$ )
YYABORT;
}
| TK_FROM table TK_COMMA table
{
SQL_input* sql = (SQL_input*) info;
UINT r;
/* only support inner joins on two tables */
r = JOIN_CreateView( sql->db, &$$, $2, $4 );
if( r != ERROR_SUCCESS )
YYABORT;
}
;
expr:
TK_LP expr TK_RP
{
$$ = $2;
if( !$$ )
YYABORT;
}
| expr TK_AND expr
{
$$ = EXPR_complex( info, $1, OP_AND, $3 );
if( !$$ )
YYABORT;
}
| expr TK_OR expr
{
$$ = EXPR_complex( info, $1, OP_OR, $3 );
if( !$$ )
YYABORT;
}
| column_val TK_EQ val
{
$$ = EXPR_complex( info, $1, OP_EQ, $3 );
if( !$$ )
YYABORT;
}
| column_val TK_GT val
{
$$ = EXPR_complex( info, $1, OP_GT, $3 );
if( !$$ )
YYABORT;
}
| column_val TK_LT val
{
$$ = EXPR_complex( info, $1, OP_LT, $3 );
if( !$$ )
YYABORT;
}
| column_val TK_LE val
{
$$ = EXPR_complex( info, $1, OP_LE, $3 );
if( !$$ )
YYABORT;
}
| column_val TK_GE val
{
$$ = EXPR_complex( info, $1, OP_GE, $3 );
if( !$$ )
YYABORT;
}
| column_val TK_NE val
{
$$ = EXPR_complex( info, $1, OP_NE, $3 );
if( !$$ )
YYABORT;
}
| column_val TK_IS TK_NULL
{
$$ = EXPR_unary( info, $1, OP_ISNULL );
if( !$$ )
YYABORT;
}
| column_val TK_IS TK_NOT TK_NULL
{
$$ = EXPR_unary( info, $1, OP_NOTNULL );
if( !$$ )
YYABORT;
}
;
val:
column_val
| const_val
;
constlist:
const_val
{
$$ = parser_alloc_column( info, NULL, NULL );
if( !$$ )
YYABORT;
$$->val = $1;
}
| const_val TK_COMMA constlist
{
$$ = parser_alloc_column( info, NULL, NULL );
if( !$$ )
YYABORT;
$$->val = $1;
$$->next = $3;
}
;
update_assign_list:
column_assignment
| column_assignment TK_COMMA update_assign_list
{
$$ = $1;
$$->next = $3;
}
;
column_assignment:
column TK_EQ const_val
{
$$ = $1;
$$->val = $3;
}
;
const_val:
number
{
$$ = EXPR_ival( info, $1 );
if( !$$ )
YYABORT;
}
| TK_MINUS number %prec TK_NEGATION
{
$$ = EXPR_ival( info, -$2 );
if( !$$ )
YYABORT;
}
| TK_STRING
{
$$ = EXPR_sval( info, &$1 );
if( !$$ )
YYABORT;
}
| TK_WILDCARD
{
$$ = EXPR_wildcard( info );
if( !$$ )
YYABORT;
}
;
column_val:
column
{
$$ = EXPR_column( info, $1 );
if( !$$ )
YYABORT;
}
;
column:
table TK_DOT id
{
$$ = parser_alloc_column( info, $1, $3 );
if( !$$ )
YYABORT;
}
| id
{
$$ = parser_alloc_column( info, NULL, $1 );
if( !$$ )
YYABORT;
}
;
table:
id
{
$$ = $1;
}
;
id:
TK_ID
{
$$ = SQL_getstring( info, &$1 );
if( !$$ )
YYABORT;
}
;
number:
TK_INTEGER
{
$$ = SQL_getint( info );
}
;
%%
static void *parser_alloc( void *info, unsigned int sz )
{
SQL_input* sql = (SQL_input*) info;
struct list *mem;
mem = msi_alloc( sizeof (struct list) + sz );
list_add_tail( sql->mem, mem );
return &mem[1];
}
static column_info *parser_alloc_column( void *info, LPCWSTR table, LPCWSTR column )
{
column_info *col;
col = parser_alloc( info, sizeof (*col) );
if( col )
{
col->table = table;
col->column = column;
col->val = NULL;
col->type = 0;
col->next = NULL;
}
return col;
}
static int sql_lex( void *SQL_lval, SQL_input *sql )
{
int token;
struct sql_str * str = SQL_lval;
do
{
sql->n += sql->len;
if( ! sql->command[sql->n] )
return 0; /* end of input */
/* TRACE("string : %s\n", debugstr_w(&sql->command[sql->n])); */
sql->len = sqliteGetToken( &sql->command[sql->n], &token );
if( sql->len==0 )
break;
str->data = &sql->command[sql->n];
str->len = sql->len;
}
while( token == TK_SPACE );
/* TRACE("token : %d (%s)\n", token, debugstr_wn(&sql->command[sql->n], sql->len)); */
return token;
}
LPWSTR SQL_getstring( void *info, struct sql_str *strdata )
{
LPCWSTR p = strdata->data;
UINT len = strdata->len;
LPWSTR str;
/* if there's quotes, remove them */
if( ( (p[0]=='`') && (p[len-1]=='`') ) ||
( (p[0]=='\'') && (p[len-1]=='\'') ) )
{
p++;
len -= 2;
}
str = parser_alloc( info, (len + 1)*sizeof(WCHAR) );
if( !str )
return str;
memcpy( str, p, len*sizeof(WCHAR) );
str[len]=0;
return str;
}
INT SQL_getint( void *info )
{
SQL_input* sql = (SQL_input*) info;
LPCWSTR p = &sql->command[sql->n];
INT i, r = 0;
for( i=0; i<sql->len; i++ )
{
if( '0' > p[i] || '9' < p[i] )
{
ERR("should only be numbers here!\n");
break;
}
r = (p[i]-'0') + r*10;
}
return r;
}
static int sql_error( const char *str )
{
return 0;
}
static struct expr * EXPR_wildcard( void *info )
{
struct expr *e = parser_alloc( info, sizeof *e );
if( e )
{
e->type = EXPR_WILDCARD;
}
return e;
}
static struct expr * EXPR_complex( void *info, struct expr *l, UINT op, struct expr *r )
{
struct expr *e = parser_alloc( info, sizeof *e );
if( e )
{
e->type = EXPR_COMPLEX;
e->u.expr.left = l;
e->u.expr.op = op;
e->u.expr.right = r;
}
return e;
}
static struct expr * EXPR_unary( void *info, struct expr *l, UINT op )
{
struct expr *e = parser_alloc( info, sizeof *e );
if( e )
{
e->type = EXPR_UNARY;
e->u.expr.left = l;
e->u.expr.op = op;
e->u.expr.right = NULL;
}
return e;
}
static struct expr * EXPR_column( void *info, column_info *column )
{
struct expr *e = parser_alloc( info, sizeof *e );
if( e )
{
e->type = EXPR_COLUMN;
e->u.sval = column->column;
}
return e;
}
static struct expr * EXPR_ival( void *info, int val )
{
struct expr *e = parser_alloc( info, sizeof *e );
if( e )
{
e->type = EXPR_IVAL;
e->u.ival = val;
}
return e;
}
static struct expr * EXPR_sval( void *info, struct sql_str *str )
{
struct expr *e = parser_alloc( info, sizeof *e );
if( e )
{
e->type = EXPR_SVAL;
e->u.sval = SQL_getstring( info, str );
}
return e;
}
static BOOL SQL_MarkPrimaryKeys( column_info *cols,
column_info *keys )
{
column_info *k;
BOOL found = TRUE;
for( k = keys; k && found; k = k->next )
{
column_info *c;
found = FALSE;
for( c = cols; c && !found; c = c->next )
{
if( lstrcmpW( k->column, c->column ) )
continue;
c->type |= MSITYPE_KEY;
found = TRUE;
}
}
return found;
}
UINT MSI_ParseSQL( MSIDATABASE *db, LPCWSTR command, MSIVIEW **phview,
struct list *mem )
{
SQL_input sql;
int r;
*phview = NULL;
sql.db = db;
sql.command = command;
sql.n = 0;
sql.len = 0;
sql.view = phview;
sql.mem = mem;
r = sql_parse(&sql);
TRACE("Parse returned %d\n", r);
if( r )
{
*sql.view = NULL;
return ERROR_BAD_QUERY_SYNTAX;
}
return ERROR_SUCCESS;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -