mariadb/storage/innobase/pars/pars0grm.y
aivanov@mysql.com 780f80be16 Applied innodb-5.1-ss475 snapshot.
* Fix BUG#15650: "DELETE with LEFT JOIN crashes server with innodb_locks_unsafe_for binlog"
* Fix BUG#17134: "Partitions: uncommitted changes are visible"
* Fix BUG#17992: "Partitions: InnoDB, somehow rotten table after UPDATE"
  row0ins.c: MySQL's partitioned table code does not set preduilt->sql_stat_start right
  if it does an insert in the same statement after doing a search first in the same
  partition table. We now write trx id always to the buffer, not just when flag
  sql_stat_start is on. This will waste CPU time very sightly.
* Fix BUG#18077: "InnoDB uses full explicit table locks in stored FUNCTION"
* Fix BUG#18238: "When locks exhaust the buffer pool, InnoDB does not roll back the trx"
* Fix BUG#18252" "Disk space leak in updates of InnoDB BLOB rows in 5.0 and 5.1"
* Fix BUG#18283: "When InnoDB returns error 'lock table full', MySQL can write to binlog too much"
* Fix BUG#18350: "Use consistent read in CREATE ... SELECT ... if innodb_locks_unsafe_for_binlog"
* Fix BUG#18384: "InnoDB memory leak on duplicate key errors in 5.0 if row has many columns"
* Fix BUG#18934: "InnoDB crashes when table uses column names like DB_ROW_ID"
  Refuse tables that use reserved column names.
* InnoDB's SQL parser:
  - Add support for UNSIGNED types, EXIT keyword, quoted identifiers, user-function callbacks
    for processing results of FETCH statements, bound literals, DATA_VARCHAR for bound literals.
  - Allow bound literals of type non-INTEGER to be of length 0.
  - Add make_flex.sh and update lexer/parser generation documentation.
  - Add comment clarifying the difference between 'alias' and 'indirection' fields in sym_node_t.
  - Remove never reached duplicate code in pars_set_dfield_type().
  - Rewrite pars_info datatypes and APIs, add a few helper functions.
  - Since the functions definitions in pars_info_t are accessed after pars_sql() returns
    in the query graph execution stage, we can't free pars_info_t in pars_sql(). Instead,
    make pars_sql() transfer ownership of pars_info_t to the created query graph, and
    make que_graph_free() free it if needed.
  - Allow access to system columns like DB_ROW_ID.
* Use bound literals in row_truncate_table_for_mysql, row_drop_table_for_mysql,
  row_discard_tablespace_for_mysql, and row_rename_table_for_mysql.
* Setting an isolation level of the transaction to read committed weakens the locks for
  this session similarly like the option innodb_locks_unsafe_for binlog. This patch removes
  alnost all gap locking (used in next-key locking) and makes MySQL to release the row locks
  on the rows which does not belong to result set. Additionally, nonlocking selects on
  INSERT INTO SELECT, UPDATE ... (SELECT ...), and CREATE ... SELECT ... use a nonlocking
  consistent read. If a binlog is used, then binlog format should be set to row based
  binloging to make the execution of the complex SQL statements.
* Disable the statistic variables btr_search_n_hash_fail and n_hash_succ, n_hash_fail,
  n_patt_succ, and n_searches of btr_search_t in builds without #ifdef UNIV_SEARCH_PERF_STAT.
* Make innodb.test faster. Group all consistent read test cases to a one test case and
  wait their lock timeout after all have been send to the server. Decrease amount of rows
  inserted in a certain test - this has no effect on the effectiveness of the test and
  reduces the running time by ~10 sec. Remove temporary work-arounds from innodb.result
  now that ALTER TABLE DROP FOREIGN KEY works once again.
* Make innodb_unsafe_binlog.test faster. Grout all consistent read test cases to a one
  test case amd wait their lock timeout after all have been sent to the server. Remove
  unnecessary option --loose_innodb_lock_wait_timeout.
* Print dictionary memory size in SHOW INNODB STATUS.
* Fix memory leaks in row_create_table_for_mysql() in rare corner cases.
* Remove code related to clustered tables. They were never implemented, and the
  implementation would be challenging with ROW_FORMAT=COMPACT. Remove the table types
  DICT_TABLE_CLUSTER_MEMBER and DICT_TABLE_CLUSTER and all related tests and functions.
  dict_table_t: Remove mix_id, mix_len, mix_id_len, mix_id_buf, and cluster_name.
  plan_t: Remove mixed_index.
  dict_create_sys_tables_tuple(): Set MIX_ID=0, MIX_LEN=0, CLUSTER_NAME=NULL when
  inserting into SYS_TABLES.
  dict_tree_check_search_tuple(): Enclose in #ifdef UNIV_DEBUG.
* Move calling of thr_local_free() from trx_free_for_mysql() to
  innobase_close_connection().
2006-04-23 12:48:31 +04:00

616 lines
15 KiB
Text

/******************************************************
SQL parser: input file for the GNU Bison parser generator
(c) 1997 Innobase Oy
Created 12/14/1997 Heikki Tuuri
Published under the GPL version 2
Look from pars0lex.l for instructions how to generate the C files for
the InnoDB parser.
*******************************************************/
%{
/* The value of the semantic attribute is a pointer to a query tree node
que_node_t */
#include "univ.i"
#include <math.h> /* Can't be before univ.i */
#include "pars0pars.h"
#include "mem0mem.h"
#include "que0types.h"
#include "que0que.h"
#include "row0sel.h"
#define YYSTYPE que_node_t*
/* #define __STDC__ */
int
yylex(void);
%}
%token PARS_INT_LIT
%token PARS_FLOAT_LIT
%token PARS_STR_LIT
%token PARS_FIXBINARY_LIT
%token PARS_BLOB_LIT
%token PARS_NULL_LIT
%token PARS_ID_TOKEN
%token PARS_AND_TOKEN
%token PARS_OR_TOKEN
%token PARS_NOT_TOKEN
%token PARS_GE_TOKEN
%token PARS_LE_TOKEN
%token PARS_NE_TOKEN
%token PARS_PROCEDURE_TOKEN
%token PARS_IN_TOKEN
%token PARS_OUT_TOKEN
%token PARS_BINARY_TOKEN
%token PARS_BLOB_TOKEN
%token PARS_INT_TOKEN
%token PARS_INTEGER_TOKEN
%token PARS_FLOAT_TOKEN
%token PARS_CHAR_TOKEN
%token PARS_IS_TOKEN
%token PARS_BEGIN_TOKEN
%token PARS_END_TOKEN
%token PARS_IF_TOKEN
%token PARS_THEN_TOKEN
%token PARS_ELSE_TOKEN
%token PARS_ELSIF_TOKEN
%token PARS_LOOP_TOKEN
%token PARS_WHILE_TOKEN
%token PARS_RETURN_TOKEN
%token PARS_SELECT_TOKEN
%token PARS_SUM_TOKEN
%token PARS_COUNT_TOKEN
%token PARS_DISTINCT_TOKEN
%token PARS_FROM_TOKEN
%token PARS_WHERE_TOKEN
%token PARS_FOR_TOKEN
%token PARS_DDOT_TOKEN
%token PARS_CONSISTENT_TOKEN
%token PARS_READ_TOKEN
%token PARS_ORDER_TOKEN
%token PARS_BY_TOKEN
%token PARS_ASC_TOKEN
%token PARS_DESC_TOKEN
%token PARS_INSERT_TOKEN
%token PARS_INTO_TOKEN
%token PARS_VALUES_TOKEN
%token PARS_UPDATE_TOKEN
%token PARS_SET_TOKEN
%token PARS_DELETE_TOKEN
%token PARS_CURRENT_TOKEN
%token PARS_OF_TOKEN
%token PARS_CREATE_TOKEN
%token PARS_TABLE_TOKEN
%token PARS_INDEX_TOKEN
%token PARS_UNIQUE_TOKEN
%token PARS_CLUSTERED_TOKEN
%token PARS_DOES_NOT_FIT_IN_MEM_TOKEN
%token PARS_ON_TOKEN
%token PARS_ASSIGN_TOKEN
%token PARS_DECLARE_TOKEN
%token PARS_CURSOR_TOKEN
%token PARS_SQL_TOKEN
%token PARS_OPEN_TOKEN
%token PARS_FETCH_TOKEN
%token PARS_CLOSE_TOKEN
%token PARS_NOTFOUND_TOKEN
%token PARS_TO_CHAR_TOKEN
%token PARS_TO_NUMBER_TOKEN
%token PARS_TO_BINARY_TOKEN
%token PARS_BINARY_TO_NUMBER_TOKEN
%token PARS_SUBSTR_TOKEN
%token PARS_REPLSTR_TOKEN
%token PARS_CONCAT_TOKEN
%token PARS_INSTR_TOKEN
%token PARS_LENGTH_TOKEN
%token PARS_SYSDATE_TOKEN
%token PARS_PRINTF_TOKEN
%token PARS_ASSERT_TOKEN
%token PARS_RND_TOKEN
%token PARS_RND_STR_TOKEN
%token PARS_ROW_PRINTF_TOKEN
%token PARS_COMMIT_TOKEN
%token PARS_ROLLBACK_TOKEN
%token PARS_WORK_TOKEN
%token PARS_UNSIGNED_TOKEN
%token PARS_EXIT_TOKEN
%token PARS_FUNCTION_TOKEN
%left PARS_AND_TOKEN PARS_OR_TOKEN
%left PARS_NOT_TOKEN
%left '=' '<' '>' PARS_GE_TOKEN PARS_LE_TOKEN
%left '-' '+'
%left '*' '/'
%left NEG /* negation--unary minus */
%left '%'
/* Grammar follows */
%%
statement:
procedure_definition ';'
| stored_procedure_call
| predefined_procedure_call ';'
| while_statement ';'
| for_statement ';'
| exit_statement ';'
| if_statement ';'
| return_statement ';'
| assignment_statement ';'
| select_statement ';'
| insert_statement ';'
| row_printf_statement ';'
| delete_statement_searched ';'
| delete_statement_positioned ';'
| update_statement_searched ';'
| update_statement_positioned ';'
| open_cursor_statement ';'
| fetch_statement ';'
| close_cursor_statement ';'
| commit_statement ';'
| rollback_statement ';'
| create_table ';'
| create_index ';'
;
statement_list:
statement { $$ = que_node_list_add_last(NULL, $1); }
| statement_list statement
{ $$ = que_node_list_add_last($1, $2); }
;
exp:
PARS_ID_TOKEN { $$ = $1;}
| function_name '(' exp_list ')'
{ $$ = pars_func($1, $3); }
| PARS_INT_LIT { $$ = $1;}
| PARS_FLOAT_LIT { $$ = $1;}
| PARS_STR_LIT { $$ = $1;}
| PARS_FIXBINARY_LIT { $$ = $1;}
| PARS_BLOB_LIT { $$ = $1;}
| PARS_NULL_LIT { $$ = $1;}
| PARS_SQL_TOKEN { $$ = $1;}
| exp '+' exp { $$ = pars_op('+', $1, $3); }
| exp '-' exp { $$ = pars_op('-', $1, $3); }
| exp '*' exp { $$ = pars_op('*', $1, $3); }
| exp '/' exp { $$ = pars_op('/', $1, $3); }
| '-' exp %prec NEG { $$ = pars_op('-', $2, NULL); }
| '(' exp ')' { $$ = $2; }
| exp '=' exp { $$ = pars_op('=', $1, $3); }
| exp '<' exp { $$ = pars_op('<', $1, $3); }
| exp '>' exp { $$ = pars_op('>', $1, $3); }
| exp PARS_GE_TOKEN exp { $$ = pars_op(PARS_GE_TOKEN, $1, $3); }
| exp PARS_LE_TOKEN exp { $$ = pars_op(PARS_LE_TOKEN, $1, $3); }
| exp PARS_NE_TOKEN exp { $$ = pars_op(PARS_NE_TOKEN, $1, $3); }
| exp PARS_AND_TOKEN exp{ $$ = pars_op(PARS_AND_TOKEN, $1, $3); }
| exp PARS_OR_TOKEN exp { $$ = pars_op(PARS_OR_TOKEN, $1, $3); }
| PARS_NOT_TOKEN exp { $$ = pars_op(PARS_NOT_TOKEN, $2, NULL); }
| PARS_ID_TOKEN '%' PARS_NOTFOUND_TOKEN
{ $$ = pars_op(PARS_NOTFOUND_TOKEN, $1, NULL); }
| PARS_SQL_TOKEN '%' PARS_NOTFOUND_TOKEN
{ $$ = pars_op(PARS_NOTFOUND_TOKEN, $1, NULL); }
;
function_name:
PARS_TO_CHAR_TOKEN { $$ = &pars_to_char_token; }
| PARS_TO_NUMBER_TOKEN { $$ = &pars_to_number_token; }
| PARS_TO_BINARY_TOKEN { $$ = &pars_to_binary_token; }
| PARS_BINARY_TO_NUMBER_TOKEN
{ $$ = &pars_binary_to_number_token; }
| PARS_SUBSTR_TOKEN { $$ = &pars_substr_token; }
| PARS_CONCAT_TOKEN { $$ = &pars_concat_token; }
| PARS_INSTR_TOKEN { $$ = &pars_instr_token; }
| PARS_LENGTH_TOKEN { $$ = &pars_length_token; }
| PARS_SYSDATE_TOKEN { $$ = &pars_sysdate_token; }
| PARS_RND_TOKEN { $$ = &pars_rnd_token; }
| PARS_RND_STR_TOKEN { $$ = &pars_rnd_str_token; }
;
question_mark_list:
/* Nothing */
| '?'
| question_mark_list ',' '?'
;
stored_procedure_call:
'{' PARS_ID_TOKEN '(' question_mark_list ')' '}'
{ $$ = pars_stored_procedure_call($2); }
;
predefined_procedure_call:
predefined_procedure_name '(' exp_list ')'
{ $$ = pars_procedure_call($1, $3); }
;
predefined_procedure_name:
PARS_REPLSTR_TOKEN { $$ = &pars_replstr_token; }
| PARS_PRINTF_TOKEN { $$ = &pars_printf_token; }
| PARS_ASSERT_TOKEN { $$ = &pars_assert_token; }
;
user_function_call:
PARS_ID_TOKEN '(' ')' { $$ = $1; }
;
table_list:
PARS_ID_TOKEN { $$ = que_node_list_add_last(NULL, $1); }
| table_list ',' PARS_ID_TOKEN
{ $$ = que_node_list_add_last($1, $3); }
;
variable_list:
/* Nothing */ { $$ = NULL; }
| PARS_ID_TOKEN { $$ = que_node_list_add_last(NULL, $1); }
| variable_list ',' PARS_ID_TOKEN
{ $$ = que_node_list_add_last($1, $3); }
;
exp_list:
/* Nothing */ { $$ = NULL; }
| exp { $$ = que_node_list_add_last(NULL, $1);}
| exp_list ',' exp { $$ = que_node_list_add_last($1, $3); }
;
select_item:
exp { $$ = $1; }
| PARS_COUNT_TOKEN '(' '*' ')'
{ $$ = pars_func(&pars_count_token,
que_node_list_add_last(NULL,
sym_tab_add_int_lit(
pars_sym_tab_global, 1))); }
| PARS_COUNT_TOKEN '(' PARS_DISTINCT_TOKEN PARS_ID_TOKEN ')'
{ $$ = pars_func(&pars_count_token,
que_node_list_add_last(NULL,
pars_func(&pars_distinct_token,
que_node_list_add_last(
NULL, $4)))); }
| PARS_SUM_TOKEN '(' exp ')'
{ $$ = pars_func(&pars_sum_token,
que_node_list_add_last(NULL,
$3)); }
;
select_item_list:
/* Nothing */ { $$ = NULL; }
| select_item { $$ = que_node_list_add_last(NULL, $1); }
| select_item_list ',' select_item
{ $$ = que_node_list_add_last($1, $3); }
;
select_list:
'*' { $$ = pars_select_list(&pars_star_denoter,
NULL); }
| select_item_list PARS_INTO_TOKEN variable_list
{ $$ = pars_select_list($1, $3); }
| select_item_list { $$ = pars_select_list($1, NULL); }
;
search_condition:
/* Nothing */ { $$ = NULL; }
| PARS_WHERE_TOKEN exp { $$ = $2; }
;
for_update_clause:
/* Nothing */ { $$ = NULL; }
| PARS_FOR_TOKEN PARS_UPDATE_TOKEN
{ $$ = &pars_update_token; }
;
consistent_read_clause:
/* Nothing */ { $$ = NULL; }
| PARS_CONSISTENT_TOKEN PARS_READ_TOKEN
{ $$ = &pars_consistent_token; }
;
order_direction:
/* Nothing */ { $$ = &pars_asc_token; }
| PARS_ASC_TOKEN { $$ = &pars_asc_token; }
| PARS_DESC_TOKEN { $$ = &pars_desc_token; }
;
order_by_clause:
/* Nothing */ { $$ = NULL; }
| PARS_ORDER_TOKEN PARS_BY_TOKEN PARS_ID_TOKEN order_direction
{ $$ = pars_order_by($3, $4); }
;
select_statement:
PARS_SELECT_TOKEN select_list
PARS_FROM_TOKEN table_list
search_condition
for_update_clause
consistent_read_clause
order_by_clause { $$ = pars_select_statement($2, $4, $5,
$6, $7, $8); }
;
insert_statement_start:
PARS_INSERT_TOKEN PARS_INTO_TOKEN
PARS_ID_TOKEN { $$ = $3; }
;
insert_statement:
insert_statement_start PARS_VALUES_TOKEN '(' exp_list ')'
{ $$ = pars_insert_statement($1, $4, NULL); }
| insert_statement_start select_statement
{ $$ = pars_insert_statement($1, NULL, $2); }
;
column_assignment:
PARS_ID_TOKEN '=' exp { $$ = pars_column_assignment($1, $3); }
;
column_assignment_list:
column_assignment { $$ = que_node_list_add_last(NULL, $1); }
| column_assignment_list ',' column_assignment
{ $$ = que_node_list_add_last($1, $3); }
;
cursor_positioned:
PARS_WHERE_TOKEN
PARS_CURRENT_TOKEN PARS_OF_TOKEN
PARS_ID_TOKEN { $$ = $4; }
;
update_statement_start:
PARS_UPDATE_TOKEN PARS_ID_TOKEN
PARS_SET_TOKEN
column_assignment_list { $$ = pars_update_statement_start(FALSE,
$2, $4); }
;
update_statement_searched:
update_statement_start
search_condition { $$ = pars_update_statement($1, NULL, $2); }
;
update_statement_positioned:
update_statement_start
cursor_positioned { $$ = pars_update_statement($1, $2, NULL); }
;
delete_statement_start:
PARS_DELETE_TOKEN PARS_FROM_TOKEN
PARS_ID_TOKEN { $$ = pars_update_statement_start(TRUE,
$3, NULL); }
;
delete_statement_searched:
delete_statement_start
search_condition { $$ = pars_update_statement($1, NULL, $2); }
;
delete_statement_positioned:
delete_statement_start
cursor_positioned { $$ = pars_update_statement($1, $2, NULL); }
;
row_printf_statement:
PARS_ROW_PRINTF_TOKEN select_statement
{ $$ = pars_row_printf_statement($2); }
;
assignment_statement:
PARS_ID_TOKEN PARS_ASSIGN_TOKEN exp
{ $$ = pars_assignment_statement($1, $3); }
;
elsif_element:
PARS_ELSIF_TOKEN
exp PARS_THEN_TOKEN statement_list
{ $$ = pars_elsif_element($2, $4); }
;
elsif_list:
elsif_element { $$ = que_node_list_add_last(NULL, $1); }
| elsif_list elsif_element
{ $$ = que_node_list_add_last($1, $2); }
;
else_part:
/* Nothing */ { $$ = NULL; }
| PARS_ELSE_TOKEN statement_list
{ $$ = $2; }
| elsif_list { $$ = $1; }
;
if_statement:
PARS_IF_TOKEN exp PARS_THEN_TOKEN statement_list
else_part
PARS_END_TOKEN PARS_IF_TOKEN
{ $$ = pars_if_statement($2, $4, $5); }
;
while_statement:
PARS_WHILE_TOKEN exp PARS_LOOP_TOKEN statement_list
PARS_END_TOKEN PARS_LOOP_TOKEN
{ $$ = pars_while_statement($2, $4); }
;
for_statement:
PARS_FOR_TOKEN PARS_ID_TOKEN PARS_IN_TOKEN
exp PARS_DDOT_TOKEN exp
PARS_LOOP_TOKEN statement_list
PARS_END_TOKEN PARS_LOOP_TOKEN
{ $$ = pars_for_statement($2, $4, $6, $8); }
;
exit_statement:
PARS_EXIT_TOKEN { $$ = pars_exit_statement(); }
;
return_statement:
PARS_RETURN_TOKEN { $$ = pars_return_statement(); }
;
open_cursor_statement:
PARS_OPEN_TOKEN PARS_ID_TOKEN
{ $$ = pars_open_statement(
ROW_SEL_OPEN_CURSOR, $2); }
;
close_cursor_statement:
PARS_CLOSE_TOKEN PARS_ID_TOKEN
{ $$ = pars_open_statement(
ROW_SEL_CLOSE_CURSOR, $2); }
;
fetch_statement:
PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN variable_list
{ $$ = pars_fetch_statement($2, $4, NULL); }
| PARS_FETCH_TOKEN PARS_ID_TOKEN PARS_INTO_TOKEN user_function_call
{ $$ = pars_fetch_statement($2, NULL, $4); }
;
column_def:
PARS_ID_TOKEN type_name opt_column_len opt_unsigned opt_not_null
{ $$ = pars_column_def($1, $2, $3, $4, $5); }
;
column_def_list:
column_def { $$ = que_node_list_add_last(NULL, $1); }
| column_def_list ',' column_def
{ $$ = que_node_list_add_last($1, $3); }
;
opt_column_len:
/* Nothing */ { $$ = NULL; }
| '(' PARS_INT_LIT ')'
{ $$ = $2; }
;
opt_unsigned:
/* Nothing */ { $$ = NULL; }
| PARS_UNSIGNED_TOKEN
{ $$ = &pars_int_token;
/* pass any non-NULL pointer */ }
;
opt_not_null:
/* Nothing */ { $$ = NULL; }
| PARS_NOT_TOKEN PARS_NULL_LIT
{ $$ = &pars_int_token;
/* pass any non-NULL pointer */ }
;
not_fit_in_memory:
/* Nothing */ { $$ = NULL; }
| PARS_DOES_NOT_FIT_IN_MEM_TOKEN
{ $$ = &pars_int_token;
/* pass any non-NULL pointer */ }
;
create_table:
PARS_CREATE_TOKEN PARS_TABLE_TOKEN
PARS_ID_TOKEN '(' column_def_list ')'
not_fit_in_memory { $$ = pars_create_table($3, $5, $7); }
;
column_list:
PARS_ID_TOKEN { $$ = que_node_list_add_last(NULL, $1); }
| column_list ',' PARS_ID_TOKEN
{ $$ = que_node_list_add_last($1, $3); }
;
unique_def:
/* Nothing */ { $$ = NULL; }
| PARS_UNIQUE_TOKEN { $$ = &pars_unique_token; }
;
clustered_def:
/* Nothing */ { $$ = NULL; }
| PARS_CLUSTERED_TOKEN { $$ = &pars_clustered_token; }
;
create_index:
PARS_CREATE_TOKEN unique_def
clustered_def
PARS_INDEX_TOKEN
PARS_ID_TOKEN PARS_ON_TOKEN PARS_ID_TOKEN
'(' column_list ')' { $$ = pars_create_index($2, $3, $5, $7, $9); }
;
commit_statement:
PARS_COMMIT_TOKEN PARS_WORK_TOKEN
{ $$ = pars_commit_statement(); }
;
rollback_statement:
PARS_ROLLBACK_TOKEN PARS_WORK_TOKEN
{ $$ = pars_rollback_statement(); }
;
type_name:
PARS_INT_TOKEN { $$ = &pars_int_token; }
| PARS_INTEGER_TOKEN { $$ = &pars_int_token; }
| PARS_CHAR_TOKEN { $$ = &pars_char_token; }
| PARS_BINARY_TOKEN { $$ = &pars_binary_token; }
| PARS_BLOB_TOKEN { $$ = &pars_blob_token; }
;
parameter_declaration:
PARS_ID_TOKEN PARS_IN_TOKEN type_name
{ $$ = pars_parameter_declaration($1,
PARS_INPUT, $3); }
| PARS_ID_TOKEN PARS_OUT_TOKEN type_name
{ $$ = pars_parameter_declaration($1,
PARS_OUTPUT, $3); }
;
parameter_declaration_list:
/* Nothing */ { $$ = NULL; }
| parameter_declaration { $$ = que_node_list_add_last(NULL, $1); }
| parameter_declaration_list ',' parameter_declaration
{ $$ = que_node_list_add_last($1, $3); }
;
variable_declaration:
PARS_ID_TOKEN type_name ';'
{ $$ = pars_variable_declaration($1, $2); }
;
variable_declaration_list:
/* Nothing */
| variable_declaration
| variable_declaration_list variable_declaration
;
cursor_declaration:
PARS_DECLARE_TOKEN PARS_CURSOR_TOKEN PARS_ID_TOKEN
PARS_IS_TOKEN select_statement ';'
{ $$ = pars_cursor_declaration($3, $5); }
;
function_declaration:
PARS_DECLARE_TOKEN PARS_FUNCTION_TOKEN PARS_ID_TOKEN ';'
{ $$ = pars_function_declaration($3); }
;
declaration:
cursor_declaration
| function_declaration
;
declaration_list:
/* Nothing */
| declaration
| declaration_list declaration
;
procedure_definition:
PARS_PROCEDURE_TOKEN PARS_ID_TOKEN '(' parameter_declaration_list ')'
PARS_IS_TOKEN
variable_declaration_list
declaration_list
PARS_BEGIN_TOKEN
statement_list
PARS_END_TOKEN { $$ = pars_procedure_definition($2, $4,
$10); }
;
%%