/* Copyright (C) 2000-2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

/* sql_yacc.yy */

%{

#include <stdio.h>
#include "MyxSQLTreeItem.h"


typedef void* YYSTYPE;
#define YYSTYPE_IS_DECLARED

#ifdef __cplusplus
extern "C" {
#endif

extern int yylex(void **yylval);
void *tree;

#ifdef __cplusplus
}
#endif

extern void yyerror(const char *);

%}

%pure_parser					/* We have threads */
/*
  Currently there is 287 shift/reduce conflict. We should not introduce
  new conflicts any more.
*/
%expect 276

/*
   Comments for TOKENS.
   For each token, please include in the same line a comment that contains
   the following tags:
   SQL-2003-R : Reserved keyword as per SQL-2003
   SQL-2003-N : Non Reserved keyword as per SQL-2003
   SQL-1999-R : Reserved keyword as per SQL-1999
   SQL-1999-N : Non Reserved keyword as per SQL-1999
   MYSQL      : MySQL extention (unspecified)
   MYSQL-FUNC : MySQL extention, function
   INTERNAL   : Not a real token, lex optimization
   OPERATOR   : SQL operator
   FUTURE-USE : Reserved for futur use

   This makes the code grep-able, and helps maintenance.
*/

%token  ABORT_SYM                     /* INTERNAL (used in lex) */
%token  ACCESSIBLE_SYM
%token  ACTION                        /* SQL-2003-N */
%token  ADD                           /* SQL-2003-R */
%token  ADDDATE_SYM                   /* MYSQL-FUNC */
%token  AFTER_SYM                     /* SQL-2003-N */
%token  AGAINST
%token  AGGREGATE_SYM
%token  ALGORITHM_SYM
%token  ALL                           /* SQL-2003-R */
%token  ALTER                         /* SQL-2003-R */
%token  ANALYZE_SYM
%token  AND_AND_SYM                   /* OPERATOR */
%token  AND_SYM                       /* SQL-2003-R */
%token  ANY_SYM                       /* SQL-2003-R */
%token  AS                            /* SQL-2003-R */
%token  ASC                           /* SQL-2003-N */
%token  ASCII_SYM                     /* MYSQL-FUNC */
%token  ASENSITIVE_SYM                /* FUTURE-USE */
%token  AT_SYM                        /* SQL-2003-R */
%token  AUTHORS_SYM
%token  AUTOEXTEND_SIZE_SYM
%token  AUTO_INC
%token  AVG_ROW_LENGTH
%token  AVG_SYM                       /* SQL-2003-N */
%token  BACKUP_SYM
%token  BEFORE_SYM                    /* SQL-2003-N */
%token  BEGIN_SYM                     /* SQL-2003-R */
%token  BETWEEN_SYM                   /* SQL-2003-R */
%token  BIGINT                        /* SQL-2003-R */
%token  BINARY                        /* SQL-2003-R */
%token  BINLOG_SYM
%token  BIN_NUM
%token  BIT_AND                       /* MYSQL-FUNC */
%token  BIT_OR                        /* MYSQL-FUNC */
%token  BIT_SYM                       /* MYSQL-FUNC */
%token  BIT_XOR                       /* MYSQL-FUNC */
%token  BLOB_SYM                      /* SQL-2003-R */
%token  BOOLEAN_SYM                   /* SQL-2003-R */
%token  BOOL_SYM
%token  BOTH                          /* SQL-2003-R */
%token  BTREE_SYM
%token  BY                            /* SQL-2003-R */
%token  BYTE_SYM
%token  CACHE_SYM
%token  CALL_SYM                      /* SQL-2003-R */
%token  CASCADE                       /* SQL-2003-N */
%token  CASCADED                      /* SQL-2003-R */
%token  CASE_SYM                      /* SQL-2003-R */
%token  CAST_SYM                      /* SQL-2003-R */
%token  CHAIN_SYM                     /* SQL-2003-N */
%token  CHANGE
%token  CHANGED
%token  CHARSET
%token  CHAR_SYM                      /* SQL-2003-R */
%token  CHECKSUM_SYM
%token  CHECK_SYM                     /* SQL-2003-R */
%token  CIPHER_SYM
%token  CLIENT_SYM
%token  CLOSE_SYM                     /* SQL-2003-R */
%token  COALESCE                      /* SQL-2003-N */
%token  CODE_SYM
%token  COLLATE_SYM                   /* SQL-2003-R */
%token  COLLATION_SYM                 /* SQL-2003-N */
%token  COLUMNS
%token  COLUMN_SYM                    /* SQL-2003-R */
%token  COMMENT_SYM
%token  COMMITTED_SYM                 /* SQL-2003-N */
%token  COMMIT_SYM                    /* SQL-2003-R */
%token  COMPACT_SYM
%token  COMPLETION_SYM
%token  COMPRESSED_SYM
%token  CONCURRENT
%token  CONDITION_SYM                 /* SQL-2003-N */
%token  CONNECTION_SYM
%token  CONSISTENT_SYM
%token  CONSTRAINT                    /* SQL-2003-R */
%token  CONTAINS_SYM                  /* SQL-2003-N */
%token  CONTINUE_SYM                  /* SQL-2003-R */
%token  CONTRIBUTORS_SYM
%token  CONVERT_SYM                   /* SQL-2003-N */
%token  COUNT_SYM                     /* SQL-2003-N */
%token  CREATE                        /* SQL-2003-R */
%token  CROSS                         /* SQL-2003-R */
%token  CUBE_SYM                      /* SQL-2003-R */
%token  CURDATE                       /* MYSQL-FUNC */
%token  CURRENT_USER                  /* SQL-2003-R */
%token  CURSOR_SYM                    /* SQL-2003-R */
%token  CURTIME                       /* MYSQL-FUNC */
%token  DATABASE
%token  DATABASES
%token  DATAFILE_SYM
%token  DATA_SYM                      /* SQL-2003-N */
%token  DATETIME
%token  DATE_ADD_INTERVAL             /* MYSQL-FUNC */
%token  DATE_SUB_INTERVAL             /* MYSQL-FUNC */
%token  DATE_SYM                      /* SQL-2003-R */
%token  DAY_HOUR_SYM
%token  DAY_MICROSECOND_SYM
%token  DAY_MINUTE_SYM
%token  DAY_SECOND_SYM
%token  DAY_SYM                       /* SQL-2003-R */
%token  DEALLOCATE_SYM                /* SQL-2003-R */
%token  DECIMAL_NUM
%token  DECIMAL_SYM                   /* SQL-2003-R */
%token  DECLARE_SYM                   /* SQL-2003-R */
%token  DEFAULT                       /* SQL-2003-R */
%token  DEFINER_SYM
%token  DELAYED_SYM
%token  DELAY_KEY_WRITE_SYM
%token  DELETE_SYM                    /* SQL-2003-R */
%token  DESC                          /* SQL-2003-N */
%token  DESCRIBE                      /* SQL-2003-R */
%token  DES_KEY_FILE
%token  DETERMINISTIC_SYM             /* SQL-2003-R */
%token  DIRECTORY_SYM
%token  DISABLE_SYM
%token  DISCARD
%token  DISK_SYM
%token  DISTINCT                      /* SQL-2003-R */
%token  DIV_SYM
%token  DOUBLE_SYM                    /* SQL-2003-R */
%token  DO_SYM
%token  DROP                          /* SQL-2003-R */
%token  DUAL_SYM
%token  DUMPFILE
%token  DUPLICATE_SYM
%token  DYNAMIC_SYM                   /* SQL-2003-R */
%token  EACH_SYM                      /* SQL-2003-R */
%token  ELSE                          /* SQL-2003-R */
%token  ELSEIF_SYM
%token  ENABLE_SYM
%token  ENCLOSED
%token  END                           /* SQL-2003-R */
%token  ENDS_SYM
%token  END_OF_INPUT                  /* INTERNAL */
%token  ENGINES_SYM
%token  ENGINE_SYM
%token  ENUM
%token  EQ                            /* OPERATOR */
%token  EQUAL_SYM                     /* OPERATOR */
%token  ERRORS
%token  ESCAPED
%token  ESCAPE_SYM                    /* SQL-2003-R */
%token  EVENTS_SYM
%token  EVENT_SYM
%token  EVERY_SYM                     /* SQL-2003-N */
%token  EXECUTE_SYM                   /* SQL-2003-R */
%token  EXISTS                        /* SQL-2003-R */
%token  EXIT_SYM
%token  EXPANSION_SYM
%token  EXTENDED_SYM
%token  EXTENT_SIZE_SYM
%token  EXTRACT_SYM                   /* SQL-2003-N */
%token  FALSE_SYM                     /* SQL-2003-R */
%token  FAST_SYM
%token  FETCH_SYM                     /* SQL-2003-R */
%token  FILE_SYM
%token  FIRST_SYM                     /* SQL-2003-N */
%token  FIXED_SYM
%token  FLOAT_NUM
%token  FLOAT_SYM                     /* SQL-2003-R */
%token  FLUSH_SYM
%token  FORCE_SYM
%token  FOREIGN                       /* SQL-2003-R */
%token  FOR_SYM                       /* SQL-2003-R */
%token  FOUND_SYM                     /* SQL-2003-R */
%token  FRAC_SECOND_SYM
%token  FROM
%token  FULL                          /* SQL-2003-R */
%token  FULLTEXT_SYM
%token  FUNCTION_SYM                  /* SQL-2003-R */
%token  GE
%token  GEOMETRYCOLLECTION
%token  GEOMETRY_SYM
%token  GET_FORMAT                    /* MYSQL-FUNC */
%token  GLOBAL_SYM                    /* SQL-2003-R */
%token  GRANT                         /* SQL-2003-R */
%token  GRANTS
%token  GROUP_SYM                     /* SQL-2003-R */
%token  GROUP_CONCAT_SYM
%token  GT_SYM                        /* OPERATOR */
%token  HANDLER_SYM
%token  HASH_SYM
%token  HAVING                        /* SQL-2003-R */
%token  HELP_SYM
%token  HEX_NUM
%token  HIGH_PRIORITY
%token  HOST_SYM
%token  HOSTS_SYM
%token  HOUR_MICROSECOND_SYM
%token  HOUR_MINUTE_SYM
%token  HOUR_SECOND_SYM
%token  HOUR_SYM                      /* SQL-2003-R */
%token  IDENT
%token  IDENTIFIED_SYM
%token  IDENT_QUOTED
%token  IF
%token  IGNORE_SYM
%token  IMPORT
%token  INDEXES
%token  INDEX_SYM
%token  INFILE
%token  INITIAL_SIZE_SYM
%token  INNER_SYM                     /* SQL-2003-R */
%token  INNOBASE_SYM
%token  INOUT_SYM                     /* SQL-2003-R */
%token  INSENSITIVE_SYM               /* SQL-2003-R */
%token  INSERT                        /* SQL-2003-R */
%token  INSERT_METHOD
%token  INSTALL_SYM
%token  INTERVAL_SYM                  /* SQL-2003-R */
%token  INTO                          /* SQL-2003-R */
%token  INT_SYM                       /* SQL-2003-R */
%token  INVOKER_SYM
%token  IN_SYM                        /* SQL-2003-R */
%token  IS                            /* SQL-2003-R */
%token  ISOLATION                     /* SQL-2003-R */
%token  ISSUER_SYM
%token  ITERATE_SYM
%token  JOIN_SYM                      /* SQL-2003-R */
%token  KEYS
%token  KEY_BLOCK_SIZE
%token  KEY_SYM                       /* SQL-2003-N */
%token  KILL_SYM
%token  LANGUAGE_SYM                  /* SQL-2003-R */
%token  LAST_SYM                      /* SQL-2003-N */
%token  LE                            /* OPERATOR */
%token  LEADING                       /* SQL-2003-R */
%token  LEAVES
%token  LEAVE_SYM
%token  LEFT                          /* SQL-2003-R */
%token  LESS_SYM
%token  LEVEL_SYM
%token  LEX_HOSTNAME
%token  LIKE                          /* SQL-2003-R */
%token  LIMIT
%token  LINEAR_SYM
%token  LINES
%token  LINESTRING
%token  LIST_SYM
%token  LOAD
%token  LOCAL_SYM                     /* SQL-2003-R */
%token  LOCATOR_SYM                   /* SQL-2003-N */
%token  LOCKS_SYM
%token  LOCK_SYM
%token  LOGFILE_SYM
%token  LOGS_SYM
%token  LONGBLOB
%token  LONGTEXT
%token  LONG_NUM
%token  LONG_SYM
%token  LOOP_SYM
%token  LOW_PRIORITY
%token  LT                            /* OPERATOR */
%token  MASTER_CONNECT_RETRY_SYM
%token  MASTER_HOST_SYM
%token  MASTER_LOG_FILE_SYM
%token  MASTER_LOG_POS_SYM
%token  MASTER_PASSWORD_SYM
%token  MASTER_PORT_SYM
%token  MASTER_SERVER_ID_SYM
%token  MASTER_SSL_CAPATH_SYM
%token  MASTER_SSL_CA_SYM
%token  MASTER_SSL_CERT_SYM
%token  MASTER_SSL_CIPHER_SYM
%token  MASTER_SSL_KEY_SYM
%token  MASTER_SSL_SYM
%token  MASTER_SSL_VERIFY_SERVER_CERT_SYM
%token  MASTER_SYM
%token  MASTER_USER_SYM
%token  MATCH                         /* SQL-2003-R */
%token  MAX_CONNECTIONS_PER_HOUR
%token  MAX_QUERIES_PER_HOUR
%token  MAX_ROWS
%token  MAX_SIZE_SYM
%token  MAX_SYM                       /* SQL-2003-N */
%token  MAX_UPDATES_PER_HOUR
%token  MAX_USER_CONNECTIONS_SYM
%token  MAX_VALUE_SYM                 /* SQL-2003-N */
%token  MEDIUMBLOB
%token  MEDIUMINT
%token  MEDIUMTEXT
%token  MEDIUM_SYM
%token  MEMORY_SYM
%token  MERGE_SYM                     /* SQL-2003-R */
%token  MICROSECOND_SYM               /* MYSQL-FUNC */
%token  MIGRATE_SYM
%token  MINUTE_MICROSECOND_SYM
%token  MINUTE_SECOND_SYM
%token  MINUTE_SYM                    /* SQL-2003-R */
%token  MIN_ROWS
%token  MIN_SYM                       /* SQL-2003-N */
%token  MODE_SYM
%token  MODIFIES_SYM                  /* SQL-2003-R */
%token  MODIFY_SYM
%token  MOD_SYM                       /* SQL-2003-N */
%token  MONTH_SYM                     /* SQL-2003-R */
%token  MULTILINESTRING
%token  MULTIPOINT
%token  MULTIPOLYGON
%token  MUTEX_SYM
%token  NAMES_SYM                     /* SQL-2003-N */
%token  NAME_SYM                      /* SQL-2003-N */
%token  NATIONAL_SYM                  /* SQL-2003-R */
%token  NATURAL                       /* SQL-2003-R */
%token  NCHAR_STRING
%token  NCHAR_SYM                     /* SQL-2003-R */
%token  NDBCLUSTER_SYM
%token  NE                            /* OPERATOR */
%token  NEG
%token  NEW_SYM                       /* SQL-2003-R */
%token  NEXT_SYM                      /* SQL-2003-N */
%token  NODEGROUP_SYM
%token  NONE_SYM                      /* SQL-2003-R */
%token  NOT2_SYM
%token  NOT_SYM                       /* SQL-2003-R */
%token  NOW_SYM
%token  NO_SYM                        /* SQL-2003-R */
%token  NO_WAIT_SYM
%token  NO_WRITE_TO_BINLOG
%token  NULL_SYM                      /* SQL-2003-R */
%token  NUM
%token  NUMERIC_SYM                   /* SQL-2003-R */
%token  NVARCHAR_SYM
%token  OFFSET_SYM
%token  OLD_PASSWORD
%token  ON                            /* SQL-2003-R */
%token  ONE_SHOT_SYM
%token  ONE_SYM
%token  OPEN_SYM                      /* SQL-2003-R */
%token  OPTIMIZE
%token  OPTIONS_SYM
%token  OPTION                        /* SQL-2003-N */
%token  OPTIONALLY
%token  OR2_SYM
%token  ORDER_SYM                     /* SQL-2003-R */
%token  OR_OR_SYM                     /* OPERATOR */
%token  OR_SYM                        /* SQL-2003-R */
%token  OUTER
%token  OUTFILE
%token  OUT_SYM                       /* SQL-2003-R */
%token  OWNER_SYM
%token  PACK_KEYS_SYM
%token  PARAM_MARKER
%token  PARSER_SYM
%token  PARTIAL                       /* SQL-2003-N */
%token  PARTITIONING_SYM
%token  PARTITIONS_SYM
%token  PARTITION_SYM                 /* SQL-2003-R */
%token  PASSWORD
%token  PHASE_SYM
%token  PLUGINS_SYM
%token  PLUGIN_SYM
%token  POINT_SYM
%token  POLYGON
%token  PORT_SYM
%token  POSITION_SYM                  /* SQL-2003-N */
%token  PRECISION                     /* SQL-2003-R */
%token  PREPARE_SYM                   /* SQL-2003-R */
%token  PRESERVE_SYM
%token  PREV_SYM
%token  PRIMARY_SYM                   /* SQL-2003-R */
%token  PRIVILEGES                    /* SQL-2003-N */
%token  PROCEDURE                     /* SQL-2003-R */
%token  PROCESS
%token  PROCESSLIST_SYM
%token  PURGE
%token  QUARTER_SYM
%token  QUERY_SYM
%token  QUICK
%token  RANGE_SYM                     /* SQL-2003-R */
%token  READS_SYM                     /* SQL-2003-R */
%token  READ_ONLY_SYM
%token  READ_SYM                      /* SQL-2003-N */
%token  READ_WRITE_SYM
%token  REAL                          /* SQL-2003-R */
%token  REBUILD_SYM
%token  RECOVER_SYM
%token  REDOFILE_SYM
%token  REDO_BUFFER_SIZE_SYM
%token  REDUNDANT_SYM
%token  REFERENCES                    /* SQL-2003-R */
%token  REGEXP
%token  RELAY_LOG_FILE_SYM
%token  RELAY_LOG_POS_SYM
%token  RELAY_THREAD
%token  RELEASE_SYM                   /* SQL-2003-R */
%token  RELOAD
%token  REMOVE_SYM
%token  RENAME
%token  REORGANIZE_SYM
%token  REPAIR
%token  REPEATABLE_SYM                /* SQL-2003-N */
%token  REPEAT_SYM                    /* MYSQL-FUNC */
%token  REPLACE                       /* MYSQL-FUNC */
%token  REPLICATION
%token  REQUIRE_SYM
%token  RESET_SYM
%token  RESOURCES
%token  RESTORE_SYM
%token  RESTRICT
%token  RESUME_SYM
%token  RETURNS_SYM                   /* SQL-2003-R */
%token  RETURN_SYM                    /* SQL-2003-R */
%token  REVOKE                        /* SQL-2003-R */
%token  RIGHT                         /* SQL-2003-R */
%token  ROLLBACK_SYM                  /* SQL-2003-R */
%token  ROLLUP_SYM                    /* SQL-2003-R */
%token  ROUTINE_SYM                   /* SQL-2003-N */
%token  ROWS_SYM                      /* SQL-2003-R */
%token  ROW_FORMAT_SYM
%token  ROW_SYM                       /* SQL-2003-R */
%token  RTREE_SYM
%token  SAVEPOINT_SYM                 /* SQL-2003-R */
%token  SCHEDULE_SYM
%token  SECOND_MICROSECOND_SYM
%token  SECOND_SYM                    /* SQL-2003-R */
%token  SECURITY_SYM                  /* SQL-2003-N */
%token  SELECT_SYM                    /* SQL-2003-R */
%token  SENSITIVE_SYM                 /* FUTURE-USE */
%token  SEPARATOR_SYM
%token  SERIALIZABLE_SYM              /* SQL-2003-N */
%token  SERIAL_SYM
%token  SESSION_SYM                   /* SQL-2003-N */
%token  SERVER_SYM
%token  SERVER_OPTIONS
%token  SET                           /* SQL-2003-R */
%token  SET_VAR
%token  SHARE_SYM
%token  SHIFT_LEFT                    /* OPERATOR */
%token  SHIFT_RIGHT                   /* OPERATOR */
%token  SHOW
%token  SHUTDOWN
%token  SIGNED_SYM
%token  SIMPLE_SYM                    /* SQL-2003-N */
%token  SLAVE
%token  SMALLINT                      /* SQL-2003-R */
%token  SNAPSHOT_SYM
%token  SOCKET_SYM
%token  SONAME_SYM
%token  SOUNDS_SYM
%token  SPATIAL_SYM
%token  SPECIFIC_SYM                  /* SQL-2003-R */
%token  SQLEXCEPTION_SYM              /* SQL-2003-R */
%token  SQLSTATE_SYM                  /* SQL-2003-R */
%token  SQLWARNING_SYM                /* SQL-2003-R */
%token  SQL_BIG_RESULT
%token  SQL_BUFFER_RESULT
%token  SQL_CACHE_SYM
%token  SQL_CALC_FOUND_ROWS
%token  SQL_NO_CACHE_SYM
%token  SQL_SMALL_RESULT
%token  SQL_SYM                       /* SQL-2003-R */
%token  SQL_THREAD
%token  SSL_SYM
%token  STARTING
%token  STARTS_SYM
%token  START_SYM                     /* SQL-2003-R */
%token  STATUS_SYM
%token  STDDEV_SAMP_SYM               /* SQL-2003-N */
%token  STD_SYM
%token  STOP_SYM
%token  STORAGE_SYM
%token  STRAIGHT_JOIN
%token  STRING_SYM
%token  SUBDATE_SYM
%token  SUBJECT_SYM
%token  SUBPARTITIONS_SYM
%token  SUBPARTITION_SYM
%token  SUBSTRING                     /* SQL-2003-N */
%token  SUM_SYM                       /* SQL-2003-N */
%token  SUPER_SYM
%token  SUSPEND_SYM
%token  SYSDATE
%token  TABLES
%token  TABLESPACE
%token  TABLE_REF_PRIORITY
%token  TABLE_SYM                     /* SQL-2003-R */
%token  TEMPORARY                     /* SQL-2003-N */
%token  TEMPTABLE_SYM
%token  TERMINATED
%token  TEXT_STRING
%token  TEXT_SYM
%token  THAN_SYM
%token  THEN_SYM                      /* SQL-2003-R */
%token  TIMESTAMP                     /* SQL-2003-R */
%token  TIMESTAMP_ADD
%token  TIMESTAMP_DIFF
%token  TIME_SYM                      /* SQL-2003-R */
%token  TINYBLOB
%token  TINYINT
%token  TINYTEXT
%token  TO_SYM                        /* SQL-2003-R */
%token  TRAILING                      /* SQL-2003-R */
%token  TRANSACTION_SYM
%token  TRIGGERS_SYM
%token  TRIGGER_SYM                   /* SQL-2003-R */
%token  TRIM                          /* SQL-2003-N */
%token  TRUE_SYM                      /* SQL-2003-R */
%token  TRUNCATE_SYM
%token  TYPES_SYM
%token  TYPE_SYM                      /* SQL-2003-N */
%token  UDF_RETURNS_SYM
%token  ULONGLONG_NUM
%token  UNCOMMITTED_SYM               /* SQL-2003-N */
%token  UNDEFINED_SYM
%token  UNDERSCORE_CHARSET
%token  UNDOFILE_SYM
%token  UNDO_BUFFER_SIZE_SYM
%token  UNDO_SYM                      /* FUTURE-USE */
%token  UNICODE_SYM
%token  UNINSTALL_SYM
%token  UNION_SYM                     /* SQL-2003-R */
%token  UNIQUE_SYM
%token  UNKNOWN_SYM                   /* SQL-2003-R */
%token  UNLOCK_SYM
%token  UNSIGNED
%token  UNTIL_SYM
%token  UPDATE_SYM                    /* SQL-2003-R */
%token  UPGRADE_SYM
%token  USAGE                         /* SQL-2003-N */
%token  USER                          /* SQL-2003-R */
%token  USE_FRM
%token  USE_SYM
%token  USING                         /* SQL-2003-R */
%token  UTC_DATE_SYM
%token  UTC_TIMESTAMP_SYM
%token  UTC_TIME_SYM
%token  VALUES                        /* SQL-2003-R */
%token  VALUE_SYM                     /* SQL-2003-R */
%token  VARBINARY
%token  VARCHAR                       /* SQL-2003-R */
%token  VARIABLES
%token  VARIANCE_SYM
%token  VARYING                       /* SQL-2003-R */
%token  VAR_SAMP_SYM
%token  VIEW_SYM                      /* SQL-2003-N */
%token  WAIT_SYM
%token  WARNINGS
%token  WEEK_SYM
%token  WHEN_SYM                      /* SQL-2003-R */
%token  WHERE                         /* SQL-2003-R */
%token  WHILE_SYM
%token  WITH                          /* SQL-2003-R */
%token  WORK_SYM                      /* SQL-2003-N */
%token  WRAPPER_SYM
%token  WRITE_SYM                     /* SQL-2003-N */
%token  X509_SYM
%token  XA_SYM
%token  XOR
%token  YEAR_MONTH_SYM
%token  YEAR_SYM                      /* SQL-2003-R */
%token  ZEROFILL

%left   JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT
/* A dummy token to force the priority of table_ref production in a join. */
%left   TABLE_REF_PRIORITY
%left   SET_VAR
%left	OR_OR_SYM OR_SYM OR2_SYM XOR
%left	AND_SYM AND_AND_SYM
%left	BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE
%left	EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM
%left	'|'
%left	'&'
%left	SHIFT_LEFT SHIFT_RIGHT
%left	'-' '+'
%left	'*' '/' '%' DIV_SYM MOD_SYM
%left   '^'
%left	NEG '~'
%right	NOT_SYM NOT2_SYM
%right	BINARY COLLATE_SYM

%%


query:
      END_OF_INPUT { $$= NULL; }
    | verb_clause END_OF_INPUT
      {
        tree= $$= $1;
      }
    ;

verb_clause:
	  statement { $$= $1; }
	| begin { $$= $1; }
	;

/* Verb clauses, except begin */
statement:
	  alter { $$= $1; }
	| analyze { $$= $1; }
	| backup { $$= $1; }
	| binlog_base64_event { $$= $1; }
	| call { $$= $1; }
	| change { $$= $1; }
	| check { $$= $1; }
	| checksum { $$= $1; }
	| commit { $$= $1; }
	| create { $$= $1; }
	| deallocate { $$= $1; }
	| delete { $$= $1; }
	| describe { $$= $1; }
	| do { $$= $1; }
	| drop { $$= $1; }
	| execute { $$= $1; }
	| flush { $$= $1; }
	| grant { $$= $1; }
	| handler { $$= $1; }
	| help { $$= $1; }
	| insert { $$= $1; }
	| install { $$= $1; }
	| kill { $$= $1; }
	| load { $$= $1; }
	| lock { $$= $1; }
	| optimize { $$= $1; }
	| keycache { $$= $1; }
	| partition_entry { $$= $1; }
	| preload { $$= $1; }
	| prepare { $$= $1; }
	| purge { $$= $1; }
	| release { $$= $1; }
	| rename { $$= $1; }
	| repair { $$= $1; }
	| replace { $$= $1; }
	| reset { $$= $1; }
	| restore { $$= $1; }
	| revoke { $$= $1; }
	| rollback { $$= $1; }
	| savepoint { $$= $1; }
	| select { $$= $1; }
	| set { $$= $1; }
	| show { $$= $1; }
	| slave { $$= $1; }
	| start { $$= $1; }
	| truncate { $$= $1; }
	| uninstall { $$= $1; }
	| unlock { $$= $1; }
	| update { $$= $1; }
	| use { $$= $1; }
	| xa { $$= $1; }
  ;

deallocate:
    deallocate_or_drop PREPARE_SYM ident 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("prepare", "prepare"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("deallocate", "", p);
    }
  ;

deallocate_or_drop:
	  DEALLOCATE_SYM
	  {
	    $$= new_simple_tree_item("deallocate", "deallocate");
	  }
	| DROP
	  {
	    $$= new_simple_tree_item("drop", "drop");
	  }
	;

prepare:
    PREPARE_SYM ident FROM prepare_src 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("from", "from"));
      tree_item_list_add(p, $4);
      $$= new_tree_item("prepare", "", p);
    }
  ;

prepare_src:
    TEXT_STRING_sys 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("prepare_src", "", p);
    }
  | '@' ident_or_text 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("at", "@"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("prepare_src", "", p);
    }
  ;

execute:
    EXECUTE_SYM ident execute_using
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      $$= new_tree_item("execute", "", p);
    }
  ;

execute_using:
    /* nothing */
    {
      $$= NULL;
    }
  | USING execute_var_list
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("using", "using"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("execute_using", "", p);
    }
  ;

execute_var_list:
    execute_var_list ',' execute_var_ident
    {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("execute_var_list", "", p);
    }
  | execute_var_ident
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("execute_var_list", "", p);
    }
  ;

execute_var_ident: 
    '@' ident_or_text 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("at", "@"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("execute_var_ident", "", p);
    }
  ;

/* help */

help:
    HELP_SYM ident_or_text 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      $$= new_tree_item("help", "", p);
    }
  ;

/* change master */

change:
    CHANGE MASTER_SYM TO_SYM master_defs 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master", "master"));
      tree_item_list_add(p, new_simple_tree_item("to", "to"));
      tree_item_list_add(p, $4);
      $$= new_tree_item("change", "", p);
    }
  ;

master_defs:
    master_def
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("master_defs", "", p);
    }
  | master_defs ',' master_def
    {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_defs", "", p);
    }
  ;

master_def:
    MASTER_HOST_SYM EQ TEXT_STRING_sys 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_host", "master_host"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_USER_SYM EQ TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_user", "master_user"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_PASSWORD_SYM EQ TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_password", "master_password"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_PORT_SYM EQ ulong_num
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_port", "master_port"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_CONNECT_RETRY_SYM EQ ulong_num
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_connect_retry", "master_connect_retry"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_SSL_SYM EQ ulong_num
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_ssl", "master_ssl"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_ssl_ca", "master_ssl_ca"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_ssl_capath", "master_ssl_capath"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_ssl_cert", "master_ssl_cert"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_ssl_cipher", "master_ssl_cipher"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_ssl_key", "master_ssl_key"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | MASTER_SSL_VERIFY_SERVER_CERT_SYM EQ ulong_num/*1*/
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, set_item_name($1, "MASTER_SSL_VERIFY_SERVER_CERT_SYM"));
      tree_item_list_add(p, set_item_name($2, "EQ"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_def", "", p);
    }
  | master_file_def
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("master_def", "", p);
    }
  ;

master_file_def:
    MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_log_file", "master_log_file"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_file_def", "", p);
    }
  | MASTER_LOG_POS_SYM EQ ulonglong_num
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master_log_pos", "master_log_pos"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_file_def", "", p);
    }
  | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("relay_log_file", "relay_log_file"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_file_def", "", p);
    }
  | RELAY_LOG_POS_SYM EQ ulong_num
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("relay_log_pos", "relay_log_pos"));
      tree_item_list_add(p, new_simple_tree_item("eq", "="));
      tree_item_list_add(p, $3);
      $$= new_tree_item("master_file_def", "", p);
    }
  ;

/* create a table */

create:
	  CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident create2
    {
      void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }      
      tree_item_list_add(p, new_simple_tree_item("table", "table"));
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      tree_item_list_add(p, $5);
      tree_item_list_add_all(p, $6);
      delete_tree_item($6);
      $$= new_tree_item("create", "create", p);
    }
	| CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON table_ident '(' key_list ')' key_options/*2*/
	  {
      void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, new_simple_tree_item("index", "index"));
      tree_item_list_add(p, $4);
      if($5 != NULL)
      {
        tree_item_list_add(p, $5);
      }
      tree_item_list_add(p, new_simple_tree_item("on", "on"));
      tree_item_list_add(p, $7);
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $9);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      tree_item_list_add(p, $11);
      $$= new_tree_item("create", "create", p);
    }
	| CREATE DATABASE opt_if_not_exists ident opt_create_database_options
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("database", "database"));
        if($3 != NULL)
        {
          tree_item_list_add(p, $3);
        }
        tree_item_list_add(p, $4);
        if($5 != NULL)
        {
          tree_item_list_add(p, $5);
        }
        $$= new_tree_item("create", "create", p);
      }
    | CREATE view_or_trigger_or_sp_or_event/*1*/
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "CREATE"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("create", "create", p);
      }
    | CREATE USER clear_privileges grant_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("user", "user"));
        tree_item_list_add(p, $4);
        $$= new_tree_item("create", "create", p);
      }
    | CREATE LOGFILE_SYM GROUP_SYM logfile_group_info/*1*/
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "CREATE"));
        tree_item_list_add(p, set_item_name($3, "LOGFILE_SYM"));
        tree_item_list_add(p, set_item_name($3, "GROUP_SYM"));
        tree_item_list_add(p, $4);
        $$= new_tree_item("create", "create", p);
      }
    | CREATE TABLESPACE tablespace_info/*1*/
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "CREATE"));
        tree_item_list_add(p, set_item_name($3, "TABLESPACE"));
        tree_item_list_add(p, $3);
        $$= new_tree_item("create", "create", p);
      }
    | CREATE server_def/*1*/
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "CREATE"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("create", "create", p);
      }
    ;

server_def:/*3*/
      SERVER_SYM ident_or_text FOREIGN DATA_SYM WRAPPER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')'
    ;

server_options_list:/*3*/
      server_option
    | server_options_list ',' server_option
    ;

server_option:/*3*/
      USER TEXT_STRING_sys
    | HOST_SYM TEXT_STRING_sys
    | DATABASE TEXT_STRING_sys
    | OWNER_SYM TEXT_STRING_sys
    | PASSWORD TEXT_STRING_sys
    | SOCKET_SYM TEXT_STRING_sys
    | PORT_SYM ulong_num
    ;

event_tail:/*3*/
      EVENT_SYM opt_if_not_exists sp_name ON SCHEDULE_SYM ev_schedule_time opt_ev_on_completion opt_ev_status opt_ev_comment DO_SYM ev_sql_stmt
    ;

ev_schedule_time:/*3*/
      EVERY_SYM expr interval ev_starts ev_ends
    | AT_SYM expr
    ;

opt_ev_status:/*3*/
     
    | ENABLE_SYM
    | DISABLE_SYM ON SLAVE
    | DISABLE_SYM
    ;

ev_starts:/*3*/
     
    | STARTS_SYM expr
    ;

ev_ends:/*3*/
     
    | ENDS_SYM expr
    ;

opt_ev_on_completion:/*3*/
     
    | ev_on_completion
    ;

ev_on_completion:/*3*/
      ON COMPLETION_SYM PRESERVE_SYM
    | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
    ;

opt_ev_comment:/*3*/
     
    | COMMENT_SYM TEXT_STRING_sys
    ;

ev_sql_stmt:/*3*/
      ev_sql_stmt_inner
    ;

ev_sql_stmt_inner:/*3*/
      sp_proc_stmt_statement
    | sp_proc_stmt_return
    | sp_proc_stmt_if
    | case_stmt_specification
    | sp_labeled_control
    | sp_proc_stmt_unlabeled
    | sp_proc_stmt_leave
    | sp_proc_stmt_iterate
    | sp_proc_stmt_open
    | sp_proc_stmt_fetch
    | sp_proc_stmt_close
    ;

clear_privileges:
    /* Nothing */
    {
    }
    ;

sp_name:
	  ident '.' ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item(".", "."));
      tree_item_list_add(p, $3);
      $$= new_tree_item("sp_name", "", p);
    }
	| ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("sp_name", "", p);
    }
	;

create_function_tail:
	  RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("returns", "returns"));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("soname", "soname"));
      tree_item_list_add(p, $4);
      $$= new_tree_item("create_function_tail", "", p);
    }
	| '(' sp_fdparam_list ')' RETURNS_SYM type sp_c_chistics sp_proc_stmt
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      tree_item_list_add(p, new_simple_tree_item("returns", "returns"));
      tree_item_list_add(p, $5);
      tree_item_list_add(p, $6);
      tree_item_list_add(p, $7);
      $$= new_tree_item("create_function_tail", "", p);
    }
	;

sp_a_chistics:
	  /* Empty */ 
	  {
	    $$= NULL;
	  }
	| sp_a_chistics sp_chistic 
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	      delete_tree_item($1);
	    }
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_a_chistics", "", p);
	  }
	;

sp_c_chistics:
	  /* Empty */ 
	  {
	    $$= NULL;
	  }
	| sp_c_chistics sp_c_chistic 
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add_all(p, $1);
	      delete_tree_item($1);
	    }
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_c_chistics", "", p);
	  }
	;

/* Characteristics for both create and alter */
sp_chistic:
	  COMMENT_SYM TEXT_STRING_sys 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("comment", "comment"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_chistic", "", p);
	  }
	| LANGUAGE_SYM SQL_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("language", "language"));
      tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    $$= new_tree_item("sp_chistic", "", p);
	  }
	| NO_SYM SQL_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("no", "no"));
      tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    $$= new_tree_item("sp_chistic", "", p);
	  }
	| CONTAINS_SYM SQL_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("contains", "contains"));
      tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    $$= new_tree_item("sp_chistic", "", p);
	  }
	| READS_SYM SQL_SYM DATA_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("reads", "reads"));
      tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    tree_item_list_add(p, new_simple_tree_item("data", "data"));
	    $$= new_tree_item("sp_chistic", "", p);
	  }
	| MODIFIES_SYM SQL_SYM DATA_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("modifies", "modifies"));
      tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    tree_item_list_add(p, new_simple_tree_item("data", "data"));
	    $$= new_tree_item("sp_chistic", "", p);
	  }
	| sp_suid 
	  {
	  }
	;

/* Create characteristics */
sp_c_chistic:
	  sp_chistic            
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    $$= new_tree_item("sp_c_chistic", "", p);
	  }
	| DETERMINISTIC_SYM     
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("deterministic", "deterministic"));
	    $$= new_tree_item("sp_c_chistic", "", p);
	  }
	| not DETERMINISTIC_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("deterministic", "deterministic"));
	    $$= new_tree_item("sp_c_chistic", "", p);
	  }
	;

sp_suid:
	  SQL_SYM SECURITY_SYM DEFINER_SYM 
	  {
	    void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    tree_item_list_add(p, new_simple_tree_item("security", "security"));
	    tree_item_list_add(p, new_simple_tree_item("definer", "definer"));
	    $$= new_tree_item("sp_suid", "", p);
	  }
	| SQL_SYM SECURITY_SYM INVOKER_SYM 
	  {
	    void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    tree_item_list_add(p, new_simple_tree_item("security", "security"));
	    tree_item_list_add(p, new_simple_tree_item("invoker", "invoker"));
	    $$= new_tree_item("sp_suid", "", p);
	  }
	;

call:
	  CALL_SYM sp_name opt_sp_cparam_list 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "CALL_SYM"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
	    $$= new_tree_item("call", "", p);
	  }
	;

/* CALL parameters */
opt_sp_cparam_list:
	  /* Empty */
	  {
	    $$= NULL;
	  }
	| '(' opt_sp_cparams ')'/*2*/
	  {
	    $$= $2;
	  }
	;

opt_sp_cparams:/*3*/
     
    | sp_cparams
    ;

sp_cparams:
	  sp_cparams ',' expr 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("sp_cparams", "", p);
	  }
	| expr 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_cparams", "", p);
	  }
	;

/* Stored FUNCTION parameter declaration list */
sp_fdparam_list:
	  /* Empty */
	  {
	    $$= NULL;
	  }
	| sp_fdparams
	  {
	    $$= $1;
	  }
	;

sp_fdparams:
	  sp_fdparams ',' sp_fdparam
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("sp_fdparams", "", p);
	  }
	| sp_fdparam
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_fdparams", "", p);
	  }
	;

sp_init_param:/*3*/
	  {
	    $$= NULL;
	  }
    ;

sp_fdparam:
	  ident sp_init_param type /*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("sp_fdparam", "", p);
	  }
	;

/* Stored PROCEDURE parameter declaration list */
sp_pdparam_list:
	  /* Empty */
	  {
	    $$= NULL;
	  }
	| sp_pdparams
	  {
	    $$= $1;
	  }
	;

sp_pdparams:
	  sp_pdparams ',' sp_pdparam
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("sp_pdparams", "", p);
	  }
	| sp_pdparam
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_pdparams", "", p);
	  }
	;

sp_pdparam:
	  sp_opt_inout sp_init_param ident type /*2*/
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("sp_pdparam", "", p);
	  }
	;

sp_opt_inout:
	  /* Empty */ 
	  {
	    $$= NULL;
	  }
	| IN_SYM      
	  {
	    $$= new_simple_tree_item("in", "in");
	  }
	| OUT_SYM     
	  {
	    $$= new_simple_tree_item("out", "out");
	  }
	| INOUT_SYM   
	  {
	    $$= new_simple_tree_item("inout", "inout");
	  }
	;

sp_proc_stmts:
	  /* Empty */ 
	  {
	    $$= NULL;
	  }
	| sp_proc_stmts sp_proc_stmt ';'
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add_all(p, $1);
	      delete_tree_item($1);
	    }
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("semicol", ";"));
	    $$= new_tree_item("sp_proc_stmts", "", p);
	  }
	;

sp_proc_stmts1:
	  sp_proc_stmt ';' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(";", ";"));
	    $$= new_tree_item("sp_proc_stmts1", "", p);
	  }
	| sp_proc_stmts1 sp_proc_stmt ';'
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item(";", ";"));
	    $$= new_tree_item("sp_proc_stmts1", "", p);
	  }
	;

sp_decls:
	  /* Empty */ 
	  {
	    $$= NULL;
	  }
	| sp_decls sp_decl ';'
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add_all(p, $1);
	      delete_tree_item($1);
	    }
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("semicol", ";"));
	    $$= new_tree_item("sp_decls", "", p);
	  }
	;

sp_decl:
    DECLARE_SYM sp_decl_idents type sp_opt_default
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("declare", "declare"));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      $$= new_tree_item("sp_decl", "", p);
    }
	| DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("declare", "declare"));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("condition", "condition"));
      tree_item_list_add(p, new_simple_tree_item("for", "for"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("sp_decl", "", p);
    }
	| DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM sp_hcond_list sp_proc_stmt
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("declare", "declare"));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("handler", "handler"));
      tree_item_list_add(p, new_simple_tree_item("for", "for"));
      tree_item_list_add(p, $5);
      tree_item_list_add(p, $6);
      $$= new_tree_item("sp_decl", "", p);
    }
	| DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("declare", "declare"));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("cursor", "cursor"));
      tree_item_list_add(p, new_simple_tree_item("for", "for"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("sp_decl", "", p);
    }
	;

sp_cursor_stmt:
	  statement
	  {
      $$= $1;
    }
	;

sp_handler_type:
	  EXIT_SYM      
	  {
	    $$= new_simple_tree_item("exit", "exit");
	  }
	| CONTINUE_SYM  
	  {
	    $$= new_simple_tree_item("continue", "continue");
	  }
/*	| UNDO_SYM      { $$= NULL; } */
	;

sp_hcond_list:
	  sp_hcond_element
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("sp_hcond_list", "", p);
    }
	| sp_hcond_list ',' sp_hcond_element
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("sp_hcond_list", "", p);
    }
	;

sp_hcond_element:/*3*/
    sp_hcond
    ;

sp_cond:
	  ulong_num
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("sp_cond", "", p);
    }
	| SQLSTATE_SYM opt_value TEXT_STRING_literal
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("sqlstate", "sqlstate"));
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, $3);
      $$= new_tree_item("sp_cond", "", p);
    }
	;

opt_value:
	  /* Empty */  
	  {
	    $$= NULL;
	  }
	| VALUE_SYM    
	  {
	    $$= new_simple_tree_item("value", "value");
	  }
	;

sp_hcond:
	  sp_cond
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("sp_hcond_element", "", p);
    }
	| ident			/* CONDITION name */
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("sp_hcond_element", "", p);
    }
	| SQLWARNING_SYM	/* SQLSTATEs 01??? */
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("sqlwarning", "sqlwarning"));
      $$= new_tree_item("sp_hcond_element", "", p);
    }
	| not FOUND_SYM		/* SQLSTATEs 02??? */
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("found", "found"));
      $$= new_tree_item("sp_hcond_element", "", p);
    }
	| SQLEXCEPTION_SYM	/* All other SQLSTATEs */
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("sqlexception", "sqlexception"));
      $$= new_tree_item("sp_hcond_element", "", p);
    }
	;

sp_decl_idents:
	  ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("sp_decl_idents", "", p);
    }
	| sp_decl_idents ',' ident
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("sp_decl_idents", "", p);
    }
	;

sp_opt_default:
	  /* Empty */ 
	  {
	    $$= NULL;
	  }
  | DEFAULT expr 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("default", "default"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("sp_opt_default", "", p);
    }
	;

sp_proc_stmt:
	  sp_proc_stmt_statement/*4*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  }
    | sp_proc_stmt_return/*4*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  }
	| sp_proc_stmt_if/*4*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  }
	| case_stmt_specification/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
	| sp_labeled_control/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
	| sp_proc_stmt_unlabeled/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
    | sp_proc_stmt_leave/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
    | sp_proc_stmt_iterate/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
    | sp_proc_stmt_open/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
    | sp_proc_stmt_fetch/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
    | sp_proc_stmt_close/*4*/
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt", "", p);
	  } 
    ;
    
sp_proc_stmt_if:/*5*/
      IF sp_if END IF
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("if", "if"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("end", "end"));
	    tree_item_list_add(p, new_simple_tree_item("if", "if"));
	    $$= new_tree_item("sp_proc_stmt_if", "", p);
      }
    ;

sp_proc_stmt_statement:/*5*/
      statement
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt_statement", "", p);
	  }
    ;

sp_proc_stmt_return:/*5*/
      RETURN_SYM expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("return", "return"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_proc_stmt_return", "", p);
	  }
    ;

sp_proc_stmt_unlabeled:/*5*/
      sp_unlabeled_control
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("sp_proc_stmt_unlabeled", "", p);
	  }
    ;

sp_proc_stmt_leave:/*5*/
      LEAVE_SYM label_ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("leave", "leave"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_proc_stmt_leave", "", p);
	  }
    ;

sp_proc_stmt_iterate:/*5*/
      ITERATE_SYM label_ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("iterate", "iterate"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_proc_stmt_iterate", "", p);
	  }
    ;

sp_proc_stmt_open:/*5*/
      OPEN_SYM ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("open", "open"));
	    tree_item_list_add(p, set_item_name($2, "ident"));
	    $$= new_tree_item("sp_proc_stmt_open", "", p);
	  }
    ;

sp_proc_stmt_fetch:/*5*/
      FETCH_SYM sp_opt_fetch_noise ident INTO sp_fetch_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("fetch", "fetch"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("into", "into"));
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("sp_proc_stmt_fetch", "", p);
	  }
	;

sp_proc_stmt_close:/*5*/
      CLOSE_SYM ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("close", "close"));
	    tree_item_list_add(p, set_item_name($2, "ident"));
	    $$= new_tree_item("sp_proc_stmt_close", "", p);
	  }
	;

sp_opt_fetch_noise:
	  /* Empty */
	  {
	    $$= NULL;
	  }
	| NEXT_SYM FROM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("next", "next"));
	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
	    $$= new_tree_item("sp_opt_fetch_noise", "", p);
	  }
	| FROM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
	    $$= new_tree_item("sp_opt_fetch_noise", "", p);
	  }
	;

sp_fetch_list:
	  ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("sp_fetch_list", "", p);
    }
	| sp_fetch_list ',' ident
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("sp_fetch_list", "", p);
    }
	;

sp_if:
    expr THEN_SYM sp_proc_stmts1 sp_elseifs
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("then", "then"));
      tree_item_list_add(p, $3);
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      $$= new_tree_item("sp_if", "", p);
    }
	;

sp_elseifs:
	  /* Empty */
	  {
	    $$= NULL;
	  }
	| ELSEIF_SYM sp_if
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("elseif", "elseif"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_if", "", p);
	  }
	| ELSE sp_proc_stmts1
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("else", "else"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("sp_if", "", p);
	  }
	;

case_stmt_specification:/*3*/
      simple_case_stmt
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("case_stmt_specification", "", p);
      }
    | searched_case_stmt
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("case_stmt_specification", "", p);
      }
    ;

simple_case_stmt:/*3*/
      CASE_SYM expr simple_when_clause_list else_clause_opt END CASE_SYM
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("case", "case"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("end", "end"));
	    tree_item_list_add(p, new_simple_tree_item("case", "case"));
	    $$= new_tree_item("simple_case_stmt", "", p);
      }
    ;

searched_case_stmt:/*3*/
      CASE_SYM searched_when_clause_list else_clause_opt END CASE_SYM
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("case", "case"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("end", "end"));
	    tree_item_list_add(p, new_simple_tree_item("case", "case"));
	    $$= new_tree_item("searched_case_stmt", "", p);
      }
    ;

simple_when_clause_list:/*3*/
      simple_when_clause
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("simple_when_clause_list", "", p);
      }
    | simple_when_clause_list simple_when_clause
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("simple_when_clause_list", "", p);
      }
    ;

searched_when_clause_list:/*3*/
      searched_when_clause
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("searched_when_clause_list", "", p);
      }
    | searched_when_clause_list searched_when_clause
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("searched_when_clause_list", "", p);
      }
    ;

simple_when_clause:/*3*/
      WHEN_SYM expr THEN_SYM sp_proc_stmts1
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("when", "when"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("then", "then"));
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("simple_when_clause", "", p);
      }
    ;

searched_when_clause:/*3*/
      WHEN_SYM expr THEN_SYM sp_proc_stmts1
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("when", "when"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("then", "then"));
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("searched_when_clause", "", p);
      }
    ;

else_clause_opt:
      /* Empty  */
      {
        $$= NULL;
      }
    | ELSE sp_proc_stmts1
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("else", "else"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("else_clause_opt", "", p);
      }
    ;
    
sp_labeled_control:
	  label_ident ':' sp_unlabeled_control sp_opt_label
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("column", ":"));
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("sp_labeled_control", "", p);
	  }
	;

sp_opt_label:
      /* Empty  */  
      {
        $$= NULL;
      }
    | label_ident   
      {
        $$= $1;
      }
	;

sp_unlabeled_control:
	  BEGIN_SYM sp_decls sp_proc_stmts END
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("begin", "begin"));
        tree_item_list_add(p, $2);
        if($3 != NULL)
        {
          tree_item_list_add(p, $3);
        }
        tree_item_list_add(p, new_simple_tree_item("end", "end"));
        $$= new_tree_item("sp_unlabeled_control", "", p);
      }
	| LOOP_SYM sp_proc_stmts1 END LOOP_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("loop", "loop"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, new_simple_tree_item("end", "end"));
        tree_item_list_add(p, new_simple_tree_item("loop", "loop"));
        $$= new_tree_item("sp_unlabeled_control", "", p);
      }
    | WHILE_SYM expr DO_SYM sp_proc_stmts1 END WHILE_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("while", "while"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, new_simple_tree_item("do", "do"));
        tree_item_list_add(p, $4);
        tree_item_list_add(p, new_simple_tree_item("end", "end"));
        tree_item_list_add(p, new_simple_tree_item("while", "while"));
        $$= new_tree_item("sp_unlabeled_control", "", p);
      }
    | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM expr END REPEAT_SYM
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("repeat", "repeat"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, new_simple_tree_item("until", "until"));
        tree_item_list_add(p, $4);
        tree_item_list_add(p, new_simple_tree_item("end", "end"));
        tree_item_list_add(p, new_simple_tree_item("repeat", "repeat"));
        $$= new_tree_item("sp_unlabeled_control", "", p);
      }
	;

trg_action_time:
    BEFORE_SYM 
    {
      $$= new_simple_tree_item("before", "before");
    }
  | AFTER_SYM 
    {
      $$= new_simple_tree_item("after", "after");
    }
  ;

trg_event:
    INSERT 
    {
      $$= new_simple_tree_item("insert", "insert");
    }
  | UPDATE_SYM
    {
      $$= new_simple_tree_item("update", "update");
    }
  | DELETE_SYM
    {
      $$= new_simple_tree_item("delete", "delete");
    }
  ;

change_tablespace_access:/*3*/
      tablespace_name ts_access_mode
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        $$= new_tree_item("change_tablespace_access", "", p);
      }
    ;

change_tablespace_info:/*3*/
      tablespace_name CHANGE ts_datafile change_ts_option_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item("change", "change"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("change_tablespace_info", "", p);
      }
    ;

tablespace_info:/*3*/
      tablespace_name ADD ts_datafile opt_logfile_group_name tablespace_option_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item("add", "add"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("tablespace_info", "", p);
      }
    ;

opt_logfile_group_name:/*3*/
      /* Empty  */  
      {
        $$= NULL;
      }
    | USE_SYM LOGFILE_SYM GROUP_SYM ident
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("use", "use"));
        tree_item_list_add(p, new_simple_tree_item("logfile", "logfile"));
        tree_item_list_add(p, new_simple_tree_item("group", "group"));
        tree_item_list_add(p, $4);
        $$= new_tree_item("opt_logfile_group_name", "", p);
      }
    ;

alter_tablespace_info:/*3*/
      tablespace_name ADD ts_datafile alter_tablespace_option_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item("add", "add"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("alter_tablespace_info", "", p);
      }
    | tablespace_name DROP ts_datafile alter_tablespace_option_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item("drop", "drop"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("alter_tablespace_info", "", p);
      }
    ;

logfile_group_info:/*3*/
      logfile_group_name add_log_file logfile_group_option_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("logfile_group_info", "", p);
      }
    ;

alter_logfile_group_info:/*3*/
      logfile_group_name add_log_file alter_logfile_group_option_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("alter_logfile_group_info", "", p);
      }
    ;

add_log_file: /*3*/
      ADD lg_undofile
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("add", "add"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("add_log_file", "", p);
      }
    | ADD lg_redofile
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("add", "add"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("add_log_file", "", p);
      }
    ;

change_ts_option_list:/*3*/
      change_ts_options
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("change_ts_option_list", "", p);
      }
    ;

change_ts_options:/*3*/
      change_ts_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("change_ts_options", "", p);
      }
    | change_ts_options change_ts_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        $$= new_tree_item("change_ts_options", "", p);
      }
    | change_ts_options ',' change_ts_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item(",", ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("change_ts_options", "", p);
      }
    ;

change_ts_option:/*3*/
      opt_ts_initial_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("change_ts_option", "", p);
      }
    | opt_ts_autoextend_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("change_ts_option", "", p);
      }
    | opt_ts_max_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("change_ts_option", "", p);
      }
    ;

tablespace_option_list:/*3*/
      tablespace_options
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option_list", "", p);
      }
    ;

tablespace_options:/*3*/
      tablespace_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_options", "", p);
      }
    | tablespace_options tablespace_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        $$= new_tree_item("tablespace_options", "", p);
      }
    | tablespace_options ',' tablespace_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item(",", ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("tablespace_options", "", p);
      }
    ;

tablespace_option:/*3*/
      opt_ts_initial_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    | opt_ts_autoextend_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    | opt_ts_max_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    | opt_ts_extent_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    | opt_ts_nodegroup
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    | opt_ts_engine
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    | ts_wait
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    | opt_ts_comment
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_option", "", p);
      }
    ;

alter_tablespace_option_list:/*3*/
      alter_tablespace_options
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_tablespace_option_list", "", p);
      }
    ;

alter_tablespace_options:/*3*/
      alter_tablespace_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_tablespace_options", "", p);
      }
    | alter_tablespace_options alter_tablespace_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        $$= new_tree_item("alter_tablespace_options", "", p);
      }
    | alter_tablespace_options ',' alter_tablespace_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item(",", ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("alter_tablespace_options", "", p);
      }
    ;

alter_tablespace_option:/*3*/
      opt_ts_initial_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_tablespace_option", "", p);
      }
    | opt_ts_autoextend_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_tablespace_option", "", p);
      }
    | opt_ts_max_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_tablespace_option", "", p);
      }
    | opt_ts_engine
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_tablespace_option", "", p);
      }
    | ts_wait
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_tablespace_option", "", p);
      }
    ;

logfile_group_option_list:/*3*/
      logfile_group_options
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option_list", "", p);
      }
    ;

logfile_group_options:/*3*/
      logfile_group_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_options", "", p);
      }
    | logfile_group_options logfile_group_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        $$= new_tree_item("logfile_group_options", "", p);
      }
    | logfile_group_options ',' logfile_group_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item(",", ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("logfile_group_options", "", p);
      }
    ;

logfile_group_option:/*3*/
      opt_ts_initial_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option", "", p);
      }
    | opt_ts_undo_buffer_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option", "", p);
      }
    | opt_ts_redo_buffer_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option", "", p);
      }
    | opt_ts_nodegroup
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option", "", p);
      }
    | opt_ts_engine
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option", "", p);
      }
    | ts_wait
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option", "", p);
      }
    | opt_ts_comment
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_option", "", p);
      }
    ;

alter_logfile_group_option_list:/*3*/
      alter_logfile_group_options
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_logfile_group_option_list", "", p);
      }
    ;

alter_logfile_group_options:/*3*/
      alter_logfile_group_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_logfile_group_options", "", p);
      }
    | alter_logfile_group_options alter_logfile_group_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        $$= new_tree_item("alter_logfile_group_options", "", p);
      }
    | alter_logfile_group_options ',' alter_logfile_group_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item(",", ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("alter_logfile_group_options", "", p);
      }
    ;

alter_logfile_group_option:/*3*/
      opt_ts_initial_size
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_logfile_group_option", "", p);
      }
    | opt_ts_engine
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_logfile_group_option", "", p);
      }
    | ts_wait
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("alter_logfile_group_option", "", p);
      }
    ;

ts_datafile:/*3*/
      DATAFILE_SYM TEXT_STRING_sys
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("datafile", "datafile"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("ts_datafile", "", p);
      }
    ;

lg_undofile:/*3*/
      UNDOFILE_SYM TEXT_STRING_sys
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("undofile", "undofile"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("lg_undofile", "", p);
      }
    ;

lg_redofile:/*3*/
      REDOFILE_SYM TEXT_STRING_sys
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("redofile", "redofile"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("lg_redofile", "", p);
      }
    ;

tablespace_name:/*3*/
      ident
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("tablespace_name", "", p);
      }
    ;

logfile_group_name:/*3*/
      ident
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("logfile_group_name", "", p);
      }
    ;

ts_access_mode:/*3*/
      READ_ONLY_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "read_only"));
        $$= new_tree_item("ts_access_mode", "", p);
      }
    | READ_WRITE_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "read_write"));
        $$= new_tree_item("ts_access_mode", "", p);
      }
    | NOT_SYM ACCESSIBLE_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "not"));
        tree_item_list_add(p, set_item_name($2, "accessible"));
        $$= new_tree_item("ts_access_mode", "", p);
      }
    ;

opt_ts_initial_size:/*3*/
      INITIAL_SIZE_SYM opt_equal size_number
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "initial_size"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_initial_size", "", p);
      }
    ;

opt_ts_autoextend_size:/*3*/
      AUTOEXTEND_SIZE_SYM opt_equal size_number
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "autoextend_size"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_autoextend_size", "", p);
      }
    ;

opt_ts_max_size:/*3*/
      MAX_SIZE_SYM opt_equal size_number
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "max_size"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_max_size", "", p);
      }
    ;

opt_ts_extent_size:/*3*/
      EXTENT_SIZE_SYM opt_equal size_number
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "extent_size"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_extent_size", "", p);
      }
    ;

opt_ts_undo_buffer_size:/*3*/
      UNDO_BUFFER_SIZE_SYM opt_equal size_number
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "undo_buffer_size"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_undo_buffer_size", "", p);
      }
    ;

opt_ts_redo_buffer_size:/*3*/
      REDO_BUFFER_SIZE_SYM opt_equal size_number
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "redo_buffer_size"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_redo_buffer_size", "", p);
      }
    ;

opt_ts_nodegroup:/*3*/
      NODEGROUP_SYM opt_equal real_ulong_num
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "node_group"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_nodegroup", "", p);
      }
    ;

opt_ts_comment:/*3*/
      COMMENT_SYM opt_equal TEXT_STRING_sys
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "comment"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_ts_comment", "", p);
      }
    ;

opt_ts_engine:/*3*/
    opt_storage ENGINE_SYM opt_equal storage_engines
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, set_item_name($2, "engine"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("opt_ts_engine", "", p);
      }
    ;

opt_ts_wait:/*3*/
      /* Empty  */  
      {
        $$= NULL;
      }
    | ts_wait
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("opt_ts_wait", "", p);
      }
    ;

ts_wait:/*3*/
      WAIT_SYM
	  {
        $$= set_item_name($1, "wait");
      }
    | NO_WAIT_SYM
	  {
        $$= set_item_name($1, "no_wait");
      }
    ;

size_number:/*3*/
      real_ulong_num
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("size_number", "", p);
      }
    | IDENT
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("size_number", "", p);
      }
    ;

create2:
    '(' create2a 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add_all(p, $2);
      delete_tree_item($2);
      $$= new_tree_item("create2", "", p);
    }
  | opt_create_table_options opt_partitioning create3 /*2*/
    {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, $2);
      tree_item_list_add_all(p, $3);
      delete_tree_item($3);
      $$= new_tree_item("create2", "", p);
    }
  | LIKE table_ident 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("like", "like"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("create2", "", p);
    }
  | '(' LIKE table_ident ')'
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, new_simple_tree_item("like", "like"));
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("create2", "", p);
    }
  ;

create2a:
      field_list ')' opt_create_table_options opt_partitioning create3 /*2*/
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item("rp", ")"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        if($5 != NULL)
        {
          tree_item_list_add_all(p, $5);
          delete_tree_item($5);
        }
        $$= new_tree_item("create2a", "", p);
      }
	| opt_partitioning create_select ')' union_opt 
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        tree_item_list_add(p, new_simple_tree_item("rp", ")"));
        if($4 != NULL)
        {
          tree_item_list_add(p, $4);
        }
        $$= new_tree_item("create2a", "", p);
	  }
    ;

create3:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| opt_duplicate opt_as create_select union_clause 
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("create3", "", p);
	  }
	| opt_duplicate opt_as '(' create_select ')' union_opt 
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    if($6 != NULL)
	    {
	      tree_item_list_add(p, $6);
	    }
	    $$= new_tree_item("create3", "", p);
	  }
  ;

opt_partitioning:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | partitioning
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= set_item_name($1, "opt_partitioning");
      }
    ;
    
partitioning:/*3*/
      PARTITION_SYM partition
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "PARTITION_SYM"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("partitioning", "", p);
      }
    ;

partition_entry:/*3*/
      PARTITION_SYM partition
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "PARTITION_SYM"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("partition_entry", "", p);
      }
    ;

partition:/*3*/
      BY part_type_def opt_no_parts opt_sub_part part_defs
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "BY"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
        $$= new_tree_item("partition", "", p);
      }
    ;

part_type_def:/*3*/
      opt_linear KEY_SYM '(' part_field_list ')'
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, set_item_name($2, "KEY_SYM"));
        tree_item_list_add(p, set_item_name($3, "("));
        tree_item_list_add(p, $4);
        tree_item_list_add(p, set_item_name($5, ")"));
        $$= new_tree_item("part_type_def", "", p);
      }
    | opt_linear HASH_SYM part_func
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, set_item_name($2, "HASH_SYM"));
        tree_item_list_add(p, $3);
        $$= new_tree_item("part_type_def", "", p);
      }
    | RANGE_SYM part_func
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "RANGE_SYM"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("part_type_def", "", p);
      }
    | LIST_SYM part_func
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "LIST_SYM"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("part_type_def", "", p);
      }
    ;
    
opt_linear:/*3*/
 	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | LINEAR_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "LINEAR_SYM"));
        $$= set_item_name($1, "opt_linear");
      }
    ;
    
part_field_list:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | part_field_item_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_field_list", "", p);
      }
    ;
    
part_field_item_list:/*3*/
      part_field_item
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_field_item_list", "", p);
      }
    | part_field_item_list ',' part_field_item
	  {
        void *p= new_tree_item_list();
        tree_item_list_add_all(p, $1);
        delete_tree_item($1);
        tree_item_list_add(p, set_item_name($1, ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("part_field_item_list", "", p);
      }
    ;
    
part_field_item:/*3*/
      ident
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_field_item", "", p);
      }
    ;
    
part_func:/*3*/
      '(' remember_name part_func_expr remember_end ')'
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "("));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, set_item_name($5, ")"));
        $$= new_tree_item("part_func", "", p);
      }
    ;
    
sub_part_func:/*3*/
      '(' remember_name part_func_expr remember_end ')'
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "("));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, set_item_name($5, ")"));
        $$= new_tree_item("sub_part_func", "", p);
      }
    ;
    
opt_no_parts:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | PARTITIONS_SYM real_ulong_num
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "PARTITIONS_SYM"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("opt_no_parts", "", p);
      }
    ;
    
opt_sub_part:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | SUBPARTITION_SYM BY opt_linear HASH_SYM sub_part_func opt_no_subparts
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "SUBPARTITION_SYM"));
        tree_item_list_add(p, set_item_name($2, "BY"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, set_item_name($4, "HASH_SYMY"));
        tree_item_list_add(p, $5);
        tree_item_list_add(p, $6);
        $$= new_tree_item("opt_sub_part", "", p);
      }
    | SUBPARTITION_SYM BY opt_linear KEY_SYM '(' sub_part_field_list ')' opt_no_subparts
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "SUBPARTITION_SYM"));
        tree_item_list_add(p, set_item_name($2, "BY"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, set_item_name($4, "KEY_SYM"));
        tree_item_list_add(p, set_item_name($5, "("));
        tree_item_list_add(p, $6);
        tree_item_list_add(p, set_item_name($7, ")"));
        tree_item_list_add(p, $8);
        $$= new_tree_item("opt_sub_part", "", p);
      }
    ;
    
sub_part_field_list:/*3*/
      sub_part_field_item
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("sub_part_field_list", "", p);
      }
    | sub_part_field_list ',' sub_part_field_item
	  {
        void *p= new_tree_item_list();
        tree_item_list_add_all(p, $1);
        delete_tree_item($1);
        tree_item_list_add(p, set_item_name($2, ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("sub_part_field_list", "", p);
      }
    ;

sub_part_field_item:/*3*/
      ident
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("sub_part_field_item", "", p);
      }
    ;
    
part_func_expr:/*3*/
      bit_expr
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_func_expr", "", p);
      }
    ;
    
opt_no_subparts:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
      | SUBPARTITIONS_SYM real_ulong_num
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "SUBPARTITIONS_SYM"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("opt_no_subparts", "", p);
      }
    ;
    
part_defs:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | '(' part_def_list ')'
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "("));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, set_item_name($3, ")"));
        $$= new_tree_item("part_defs", "", p);
      }
    ;
    
part_def_list:/*3*/
      part_definition
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_def_list", "", p);
      }
    | part_def_list ',' part_definition
	  {
        void *p= new_tree_item_list();
        tree_item_list_add_all(p, $1);
        delete_tree_item($1);
        tree_item_list_add(p, set_item_name($2, ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("part_def_list", "", p);
      }
    ;
    
part_definition:/*3*/
      PARTITION_SYM part_name opt_part_values opt_part_options opt_sub_partition
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "PARTITION_SYM"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
        $$= new_tree_item("part_definition", "", p);
      }
    ;
    
part_name:/*3*/
      ident
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_name", "", p);
      }
    ;
    
opt_part_values:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | VALUES LESS_SYM THAN_SYM part_func_max
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "VALUES"));
        tree_item_list_add(p, set_item_name($2, "LESS_SYM"));
        tree_item_list_add(p, set_item_name($3, "THAN_SYM"));
        tree_item_list_add(p, $4);
        $$= new_tree_item("opt_part_values", "", p);
      }
    | VALUES IN_SYM '(' part_list_func ')'
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "VALUES"));
        tree_item_list_add(p, set_item_name($2, "IN_SYM"));
        tree_item_list_add(p, set_item_name($3, "("));
        tree_item_list_add(p, $4);
        tree_item_list_add(p, set_item_name($5, ")"));
        $$= new_tree_item("opt_part_values", "", p);
      }
    ;
    
part_func_max:/*3*/
      max_value_sym
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_func_max", "", p);
      }
    | part_range_func
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_func_max", "", p);
      }
    ;
    
max_value_sym:/*3*/
      MAX_VALUE_SYM
	  {
        $$= set_item_name($1, "max_value_sym");
      }
    | '(' MAX_VALUE_SYM ')'
	  {
        $$= set_item_name($2, "max_value_sym");
      }
    ;
    
part_range_func:/*3*/
      '(' part_bit_expr ')'
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $2);
        $$= new_tree_item("part_range_func", "", p);
      }
    ;
    
part_list_func:/*3*/
      part_list_item
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_list_func", "", p);
      }
    | part_list_func ',' part_list_item
	  {
        void *p= new_tree_item_list();
        tree_item_list_add_all(p, $1);
        delete_tree_item($1);
        tree_item_list_add(p, set_item_name($2, ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("part_list_func", "", p);
      }
    ;
    
part_list_item:/*3*/
      part_bit_expr
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_list_item", "", p);
      }
    ;
    
part_bit_expr:/*3*/
      bit_expr
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("part_bit_expr", "", p);
      }
    ;
    
opt_sub_partition:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | '(' sub_part_list ')'
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "("));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, set_item_name($3, ")"));
        $$= new_tree_item("opt_sub_partition", "", p);
      }
    ;
    
sub_part_list:/*3*/
      sub_part_definition
    | sub_part_list ',' sub_part_definition
	  {
        void *p= new_tree_item_list();
        tree_item_list_add_all(p, $1);
        delete_tree_item($1);
        tree_item_list_add(p, set_item_name($2, ","));
        tree_item_list_add(p, $3);
        $$= new_tree_item("sub_part_list", "", p);
      }
    ;

sub_part_definition:/*3*/
      SUBPARTITION_SYM sub_name opt_part_options
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "SUBPARTITION_SYM"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("sub_part_definition", "", p);
      }
    ;
    
sub_name:/*3*/
      ident_or_text
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("sub_name", "", p);
      }
    ;
    
opt_part_options:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | opt_part_option_list
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("opt_part_options", "", p);
      }
    ;
    
opt_part_option_list:/*3*/
      opt_part_option_list opt_part_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
        $$= new_tree_item("opt_part_option_list", "", p);
      }
    | opt_part_option
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        $$= new_tree_item("opt_part_option_list", "", p);
      }
    ;

opt_part_option:/*3*/
      TABLESPACE opt_equal ident_or_text
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "TABLESPACE"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_part_option", "", p);
      }
    | opt_storage ENGINE_SYM opt_equal storage_engines
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, set_item_name($2, "ENGINE_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("opt_part_option", "", p);
      }
    | NODEGROUP_SYM opt_equal real_ulong_num
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "NODEGROUP_SYM"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_part_option", "", p);
      }
    | MAX_ROWS opt_equal real_ulonglong_num
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "MAX_ROWS"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_part_option", "", p);
      }
    | MIN_ROWS opt_equal real_ulonglong_num
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "MIN_ROWS"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_part_option", "", p);
      }
    | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "DATA_SYM"));
        tree_item_list_add(p, set_item_name($2, "DIRECTORY_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("opt_part_option", "", p);
      }
    | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "INDEX_SYM"));
        tree_item_list_add(p, set_item_name($2, "DIRECTORY_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("opt_part_option", "", p);
      }
    | COMMENT_SYM opt_equal TEXT_STRING_sys
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "COMMENT_SYM"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        $$= new_tree_item("opt_part_option", "", p);
      }
    ;

create_select:
    SELECT_SYM select_options select_item_list opt_select_from
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("select", "select"));
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, $3);
      tree_item_list_add(p, $4);
      $$= new_tree_item("create_select", "", p);
    }
  ;

opt_as:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| AS
	  {
	    $$= new_simple_tree_item("as", "as");
	  }
	;

opt_create_database_options:
	  /* empty */			
	  {
	    $$= NULL;
	  }
	| create_database_options	
	  {
	    $$= $1;
	  }
	;

create_database_options:
	  create_database_option					
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("create_database_options", "", p);
	  }
	| create_database_options create_database_option	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("create_database_options", "", p);
	  }
	;

create_database_option:
	  default_collation   
	  {
	    $$= $1;
	  }
	| default_charset   
	  {
	    $$= $1;
	  }
	;

opt_table_options:
	  /* empty */	 
	  {
	    $$= NULL;
	  }
	| table_options  
	  {
	    $$= $1;
	  };

table_options:
	  table_option	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("table_options", "", p);
	  }
	  /* in original 5.x it was 'table_option table_options' but this should probably cause conflicts if more than one option? */
	| table_option table_options
	  {
	    void *p= new_tree_item_list_reuse($2);
	    delete_tree_item($2);
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("table_options", "", p);
	  }
	;

table_option:
	  TEMPORARY	
	  {
	    $$= new_simple_tree_item("temporary", "temporary");
	  }
	;

opt_if_not_exists:
	  /* empty */	 
	  {
	    $$= NULL;
	  }
	| IF not EXISTS	 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("if", "if"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("exists", "exists"));
	    $$= new_tree_item("opt_if_not_exists", "", p);
	  }
	;

opt_create_table_options:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| create_table_options
	  {
	    $$= $1;
	  }
	;

create_table_options_space_separated:
	  create_table_option
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("create_table_options_space_separated", "", p);
	  }
	| create_table_option create_table_options_space_separated
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add_all(p, $2);
	    delete_tree_item($2);
	    $$= new_tree_item("create_table_options_space_separated", "", p);
	  }
	;

create_table_options:
	  create_table_option
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("create_table_options", "", p);
	  }
	| create_table_option create_table_options
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add_all(p, $2);
	    delete_tree_item($2);
	    $$= new_tree_item("create_table_options", "", p);
	  }
	| create_table_option ',' create_table_options
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add_all(p, $3);
	    delete_tree_item($3);
	    $$= new_tree_item("create_table_options", "", p);
    }
	;

create_table_option:
	  ENGINE_SYM opt_equal storage_engines    
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("engine", "engine"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| TYPE_SYM opt_equal storage_engines
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("type", "type"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| MAX_ROWS opt_equal ulonglong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("max_rows", "max_rows"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| MIN_ROWS opt_equal ulonglong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("min_rows", "min_rows"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| AVG_ROW_LENGTH opt_equal ulong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("avg_row_length", "avg_row_length"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| PASSWORD opt_equal TEXT_STRING_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("password", "password"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| COMMENT_SYM opt_equal TEXT_STRING_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("comment", "comment"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| AUTO_INC opt_equal ulonglong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("auto_increment", "auto_increment"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
  | PACK_KEYS_SYM opt_equal ulong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("pack_keys", "pack_keys"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
  | PACK_KEYS_SYM opt_equal DEFAULT
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("pack_keys", "pack_keys"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, new_simple_tree_item("default", "default"));
	    $$= new_tree_item("create_table_option", "", p);
	  }
  
	| CHECKSUM_SYM opt_equal ulong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("checksum", "checksum"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| DELAY_KEY_WRITE_SYM opt_equal ulong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("delay_key_write", "delay_key_write"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| ROW_FORMAT_SYM opt_equal row_types
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("row_format", "row_format"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| UNION_SYM opt_equal '(' table_list ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("union", "union"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| default_charset
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| default_collation
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| INSERT_METHOD opt_equal merge_insert_types
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("insert_method", "insert_method"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("data", "data"));
	    tree_item_list_add(p, new_simple_tree_item("directory", "directory"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("index", "index"));
	    tree_item_list_add(p, new_simple_tree_item("directory", "directory"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("create_table_option", "", p);
	  }
    | TABLESPACE ident/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "TABLESPACE"));
        tree_item_list_add(p, $2);
	    $$= new_tree_item("create_table_option", "", p);
	  }
    | STORAGE_SYM DISK_SYM/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "STORAGE_SYM"));
	    tree_item_list_add(p, set_item_name($2, "DISK_SYM"));
	    $$= new_tree_item("create_table_option", "", p);
	  }
    | STORAGE_SYM MEMORY_SYM/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "STORAGE_SYM"));
	    tree_item_list_add(p, set_item_name($2, "MEMORY_SYM"));
	    $$= new_tree_item("create_table_option", "", p);
	  }
	| CONNECTION_SYM opt_equal TEXT_STRING_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("connection", "connection"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
    | KEY_BLOCK_SIZE opt_equal ulong_num/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "KEY_BLOCK_SIZE"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
	    $$= new_tree_item("create_table_option", "", p);
	  }
  ;

default_charset:
    opt_default charset opt_equal charset_name_or_default
    {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, $2);
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      $$= new_tree_item("default_charset", "", p);
    }
  ;

default_collation:
    opt_default COLLATE_SYM opt_equal collation_name_or_default
    {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, new_simple_tree_item("collate", "collate"));
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      $$= new_tree_item("default_collation", "", p);
    }
  ;

storage_engines:
	  ident_or_text 
	  {
	    $$= $1;
	  }
	;

known_storage_engines:/*3*/
      ident_or_text
    {      
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("known_storage_engines", "", p);
    }
    ;
    
row_types:
	  DEFAULT 
	  {
	    $$= new_simple_tree_item("default", "default");
	  }
	| FIXED_SYM
	  {
	    $$= new_simple_tree_item("fixed", "fixed");
	  }
	| DYNAMIC_SYM
	  {
	    $$= new_simple_tree_item("dynamic", "dynamic");
	  }
	| COMPRESSED_SYM
	  {
	    $$= new_simple_tree_item("compressed", "compressed");
	  }
	| REDUNDANT_SYM
	  {
	    $$= new_simple_tree_item("redundant", "redundant");
	  }
	| COMPACT_SYM
	  {
	    $$= new_simple_tree_item("compact", "compact");
	  }
	;

merge_insert_types:
    NO_SYM        
    {
      $$= new_simple_tree_item("no", "no");
    }
  | FIRST_SYM
    {
      $$= new_simple_tree_item("first", "first");
    }
  | LAST_SYM
    {
      $$= new_simple_tree_item("last", "last");
    }
  ;

opt_select_from:
	  opt_limit_clause 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("opt_select_from", "", p);
	  }
	| select_from select_lock_type
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_select_from", "", p);
	  }
	;

udf_func_type:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| AGGREGATE_SYM 
	  {
	    $$= new_simple_tree_item("aggregate", "aggregate");
	  }
	;

udf_type:
	  STRING_SYM 
	  {
	    $$= new_simple_tree_item("string", "string");
	  }
	| REAL 
	  {
	    $$= new_simple_tree_item("real", "real");
	  }
  | DECIMAL_SYM 
    {
      $$= new_simple_tree_item("decimal", "decimal");
    }
	| INT_SYM 
	  {
	    $$= new_simple_tree_item("int", "int");
	  }
	;

field_list:
	  field_list_item
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("field_list", "", p);
	  }
	| field_list ',' field_list_item
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("field_list", "", p);
	  }
	;

field_list_item:
	  column_def
	  {
	    $$= $1;
	  }
  | key_def
    {
      $$= $1;
    }
  ;

column_def:
	  field_spec opt_check_constraint
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("column_def", "", p);
	  }
	| field_spec references 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("column_def", "", p);
	  }
	;

key_def:
	  key_type opt_ident key_alg '(' key_list ')' key_options/*2*/
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $5);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      tree_item_list_add(p, $7);
      $$= new_tree_item("key_def", "", p);
    }
	| opt_constraint constraint_key_type opt_ident key_alg '(' key_list ')' key_options
	  {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, $2);  
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $6);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      tree_item_list_add(p, $8);
      $$= new_tree_item("key_def", "", p);
    }
	| opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
	  {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, new_simple_tree_item("foreign", "foreign"));
      tree_item_list_add(p, new_simple_tree_item("key", "key"));
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $6);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      tree_item_list_add(p, $8);
      $$= new_tree_item("key_def", "", p);
    }
	| constraint opt_check_constraint
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      $$= new_tree_item("key_def", "", p);
    }
	| opt_constraint check_constraint
	  {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, $2);
      $$= new_tree_item("key_def", "", p);
    }
	;

opt_check_constraint:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| check_constraint
	  {
	    $$= $1;
	  }
	;

check_constraint:
	  CHECK_SYM expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("check", "check"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("check_constraint", "", p);
	  }
	;

opt_constraint:
	  /* empty */		
	  {
	    $$= NULL;
	  }
	| constraint		
	  {
	    $$= $1;
	  }
	;

constraint:
	  CONSTRAINT opt_ident	
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("constraint", "constraint"));
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      $$= new_tree_item("constraint", "", p);	  
	  }
	;

field_spec:
	  field_ident type opt_attribute
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("field_spec", "", p);
    }
  ;

type:
	  int_type opt_len field_options	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| real_type opt_precision field_options
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| FLOAT_SYM float_options field_options
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("float", "float"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| BIT_SYM			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("bit", "bit"));
	    $$= new_tree_item("type", "", p);
	  }
	| BIT_SYM '(' NUM ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("bit", "bit"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("type", "", p);
	  }
	| BOOL_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("bool", "bool"));
	    $$= new_tree_item("type", "", p);
	  }
	| BOOLEAN_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("boolean", "boolean"));
	    $$= new_tree_item("type", "", p);
	  }
	| char '(' NUM ')' opt_binary	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      if($5 != NULL)
      {
        tree_item_list_add(p, $5);
      }
	    $$= new_tree_item("type", "", p);
	  }
	| char opt_binary		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
	    $$= new_tree_item("type", "", p);
	  }
	| nchar '(' NUM ')' opt_bin_mod	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| nchar opt_bin_mod	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| BINARY '(' NUM ')' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("binary", "binary"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("type", "", p);
	  }
	| BINARY 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("binary", "binary"));
	    $$= new_tree_item("type", "", p);
	  }
	| varchar '(' NUM ')' opt_binary 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| nvarchar '(' NUM ')' opt_bin_mod 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| VARBINARY '(' NUM ')' 	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("varbinary", "varbinary"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("type", "", p);
	  }
	| YEAR_SYM opt_len field_options 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("year", "year"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| DATE_SYM			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("date", "date"));
	    $$= new_tree_item("type", "", p);
	  }
	| TIME_SYM			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("time", "time"));
	    $$= new_tree_item("type", "", p);
	  }
	| TIMESTAMP opt_len 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("timestamp", "timestamp"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| DATETIME			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("datetime", "datetime"));
	    $$= new_tree_item("type", "", p);
	  }
	| TINYBLOB
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("tinyblob", "tinyblob"));
	    $$= new_tree_item("type", "", p);
	  }
	| BLOB_SYM opt_len		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("blob", "blob"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| spatial_type 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("type", "", p);
	  }
	| MEDIUMBLOB 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("mediumblob", "mediumblob"));
	    $$= new_tree_item("type", "", p);
	  }
	| LONGBLOB	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("longblob", "longblob"));
	    $$= new_tree_item("type", "", p);
	  }
	| LONG_SYM VARBINARY		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("long", "long"));
	    tree_item_list_add(p, new_simple_tree_item("varbinary", "varbinary"));
	    $$= new_tree_item("type", "", p);
	  }
	| LONG_SYM varchar opt_binary	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("long", "long"));
	    tree_item_list_add_all(p, $2);
	    delete_tree_item($2);
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| TINYTEXT opt_binary		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("tinytext", "tinytext"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| TEXT_SYM opt_len opt_binary	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("text", "text"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| MEDIUMTEXT opt_binary		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("mediumtext", "mediumtext"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| LONGTEXT opt_binary		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("longtext", "longtext"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| DECIMAL_SYM float_options field_options 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("decimal", "decimal"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| NUMERIC_SYM float_options field_options 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("numeric", "numeric"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| FIXED_SYM float_options field_options 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("fixed", "fixed"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| ENUM '(' string_list ')' opt_binary 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("enum", "enum"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| SET '(' string_list ')' opt_binary 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("set", "set"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| LONG_SYM opt_binary	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("long", "long"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("type", "", p);
	  }
	| SERIAL_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("serial", "serial"));
	    $$= new_tree_item("type", "", p);
	  }
	;

spatial_type:
	  GEOMETRY_SYM	      
	  {
	    $$= new_simple_tree_item("geometry", "geometry");
	  }
	| GEOMETRYCOLLECTION  
	  {
	    $$= new_simple_tree_item("geometrycollection", "geometrycollection");
	  }
	| POINT_SYM           
	  {
	    $$= new_simple_tree_item("point", "point");
	  }
	| MULTIPOINT          
	  {
	    $$= new_simple_tree_item("multipoint", "multipoint");
	  }
	| LINESTRING          
	  {
	    $$= new_simple_tree_item("linestring", "linestring");
	  }
	| MULTILINESTRING     
	  {
	    $$= new_simple_tree_item("multilinestring", "multilinestring");
	  }
	| POLYGON             
	  {
	    $$= new_simple_tree_item("polygon", "polygon");
	  }
	| MULTIPOLYGON        
	  {
	    $$= new_simple_tree_item("multipolygon", "multipolygon");
	  }
	;

char:
	  CHAR_SYM 
	  {
	    $$= set_item_name($1, "char");
	  }
	;

nchar:
	  NCHAR_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("nchar", "nchar"));
	    $$= new_tree_item("nchar", "", p);
	  }
	| NATIONAL_SYM CHAR_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("national", "national"));
	    tree_item_list_add(p, new_simple_tree_item("char", "char"));
	    $$= new_tree_item("nchar", "", p);
	  }
	;

varchar:
	  char VARYING 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("varying", "varying"));
	    $$= new_tree_item("varchar", "", p);
	  }
	| VARCHAR 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("varchar", "varchar"));
	    $$= new_tree_item("varchar", "", p);
	  }
	;

nvarchar:
	  NATIONAL_SYM VARCHAR
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("national", "national"));
	    tree_item_list_add(p, new_simple_tree_item("varchar", "varchar"));
	    $$= new_tree_item("nvarchar", "", p);
	  }
	| NVARCHAR_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("nvarchar", "nvarchar"));
	    $$= new_tree_item("nvarchar", "", p);
	  }
	| NCHAR_SYM VARCHAR 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("nchar", "nchar"));
	    tree_item_list_add(p, new_simple_tree_item("varchar", "varchar"));
	    $$= new_tree_item("nvarchar", "", p);
	  }
	| NATIONAL_SYM CHAR_SYM VARYING 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("national", "national"));
	    tree_item_list_add(p, new_simple_tree_item("char", "char"));
	    tree_item_list_add(p, new_simple_tree_item("varying", "varying"));
	    $$= new_tree_item("nvarchar", "", p);
	  }
	| NCHAR_SYM VARYING 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("nchar", "nchar"));
	    tree_item_list_add(p, new_simple_tree_item("varying", "varying"));
	    $$= new_tree_item("nvarchar", "", p);
	  }
	;

int_type:
	  INT_SYM
	  {
	    $$= new_simple_tree_item("int", "int");
	  }
	| TINYINT
	  {
	    $$= new_simple_tree_item("tinyint", "tinyint");
	  }
	| SMALLINT	
	  {
	    $$= new_simple_tree_item("smallint", "smallint");
	  }
	| MEDIUMINT
	  {
	    $$= new_simple_tree_item("mediumint", "mediumint");
	  }
	| BIGINT
	  {
	    $$= new_simple_tree_item("bigint", "bigint");	  
	  }
	;

real_type:
	  REAL		
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("real", "real"));
      $$= new_tree_item("real_type", "", p);
    }
	| DOUBLE_SYM	
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("double", "double"));
      $$= new_tree_item("real_type", "", p);
	  }
	| DOUBLE_SYM PRECISION 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("double", "double"));
      tree_item_list_add(p, new_simple_tree_item("precision", "precision"));
      $$= new_tree_item("real_type", "", p);
	  }
	;


float_options:
    /* empty */		
    {
      $$= NULL;
    }
  | '(' NUM ')'		
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, set_item_name($2, "num"));
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("float_options", "", p);
    }
	| precision		
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      $$= new_tree_item("float_options", "", p);
	  }
	;

precision:
	  '(' NUM ',' NUM ')'
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, set_item_name($2, "num"));
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, set_item_name($4, "num"));
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("precision", "", p);
    }
  ;

field_options:
	  /* empty */		
	  {
	    $$= NULL;
	  }
	| field_opt_list	
	  {
	    $$= $1;
	  }
	;

field_opt_list:
	  field_opt_list field_option 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("field_opt_list", "", p);
	  }
	| field_option 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("field_opt_list", "", p);
	  }
	;

field_option:
	  SIGNED_SYM	
	  {
	    $$= new_simple_tree_item("signed", "signed");
	  }
	| UNSIGNED	
	  {
	    $$= new_simple_tree_item("unsigned", "unsigned");
	  }
	| ZEROFILL	
	  {
	    $$= new_simple_tree_item("zerofill", "zerofill");
	  }
	;

opt_len:
	  /* empty */	
	  /* use default length */
	  {
	    $$= NULL;
	  } 
	| '(' NUM ')'	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($2, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("opt_len", "", p);
	  }
	;

opt_precision:
	/* empty */	
	{
	  $$= NULL;
	}
| precision	
  {
    $$= $1;
  }
;

opt_attribute:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| opt_attribute_list 
	  {
	    $$= $1;
	  }
	;

opt_attribute_list:
	  opt_attribute_list attribute 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_attribute_list", "", p);
	  }
	| attribute
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("opt_attribute_list", "", p);
	  }
	;

attribute:
	  NULL_SYM	  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("null", "null"));
	    $$= new_tree_item("attribute", "", p);
	  }
	| not NULL_SYM	  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("null", "null"));
	    $$= new_tree_item("attribute", "", p);
	  }
	| DEFAULT now_or_signed_literal 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("default", "default"));
	    tree_item_list_add_all(p, $2);
	    delete_tree_item($2);
	    $$= new_tree_item("attribute", "", p);
	  }
	| ON UPDATE_SYM NOW_SYM optional_braces 
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    tree_item_list_add(p, new_simple_tree_item("update", "update"));
	    tree_item_list_add(p, new_simple_tree_item("now", "now"));
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("attribute", "", p);
    }
	| AUTO_INC
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("auto_increment", "auto_increment"));
	    $$= new_tree_item("attribute", "", p);
	  }
	| SERIAL_SYM DEFAULT VALUE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("serial", "serial"));
	    tree_item_list_add(p, new_simple_tree_item("default", "default"));
	    tree_item_list_add(p, new_simple_tree_item("value", "value"));
	    $$= new_tree_item("attribute", "", p);
    }
	| opt_primary KEY_SYM 
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL) {
	      tree_item_list_add_all(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("key", "key"));
	    $$= new_tree_item("attribute", "", p);
    }
	| UNIQUE_SYM	  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("unique", "unique"));
	    $$= new_tree_item("attribute", "", p);
    }
	| UNIQUE_SYM KEY_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("unique", "unique"));
	    tree_item_list_add(p, new_simple_tree_item("key", "key"));
	    $$= new_tree_item("attribute", "", p);
    }
	| COMMENT_SYM TEXT_STRING_sys 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("comment", "comment"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("attribute", "", p);
	  }
	| COLLATE_SYM collation_name
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("collate", "collate"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("attribute", "", p);
    }
	;

now_or_signed_literal:
    NOW_SYM optional_braces 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("now", "now"));
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      $$= new_tree_item("now_or_signed_literal", "", p);
    }
  | signed_literal 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("now_or_signed_literal", "", p);
    }
  ;

charset:
	  CHAR_SYM SET	
	  {
	    void *p = new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("character", "character"));
	    tree_item_list_add(p, new_simple_tree_item("set", "set"));
	    $$= new_tree_item("charset", "charset", p);
	  }
	| CHARSET	
	  {
	    void *p = new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("charset", "charset"));
	    $$= new_tree_item("charset", "charset", p);
	  }
	;

charset_name:
	  ident_or_text
	  {
      $$= $1;
    }
	| BINARY 
	  {
	    $$= new_simple_tree_item("binary", "binary");
	  }
	;

charset_name_or_default:
	  charset_name 
	  {
	    $$= $1;
	  }
	| DEFAULT 
	  {
	    $$= new_simple_tree_item("default", "default");
	  }
	;

opt_load_data_charset:/*3*/
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | charset charset_name_or_default
      {
	    void *p = new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_load_data_charset", "", p);
      }
    ;

old_or_new_charset_name:
	  ident_or_text 
	  {
	    $$= $1;
	  }
	| BINARY 
	  {
	    $$= new_simple_tree_item("binary", "binary");
	  }
	;

old_or_new_charset_name_or_default:
	  old_or_new_charset_name 
	  {
	    $$= $1;
	  }
	| DEFAULT    
	  {
	    $$= new_simple_tree_item("default", "default");
	  } 
	;

collation_name:
	  ident_or_text 
	  {
	    $$= $1;
	  }
  ;

opt_collate:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| COLLATE_SYM collation_name_or_default 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("collate", "collate"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_collate", "", p);
	  }
	;

collation_name_or_default:
	  collation_name 
	  {
	    $$= $1;
	  }
	| DEFAULT
	  {
	    $$= new_simple_tree_item("default", "default");
	  }
	;

opt_default:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| DEFAULT	
	  {
	    $$= new_simple_tree_item("default", "default");
	  }
	;

opt_binary:
	  /* empty */			
	  {
	    $$= NULL;
	  }
	| ASCII_SYM opt_bin_mod		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("ascii", "ascii"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("opt_binary", "", p);
	  }
	| BYTE_SYM			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("byte", "byte"));
	    $$= new_tree_item("opt_binary", "", p);
	  }
	| UNICODE_SYM opt_bin_mod
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("unicode", "unicode"));
      if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }	    
	    $$= new_tree_item("opt_binary", "", p);
    } 
	| charset charset_name opt_bin_mod	
	  {
	    void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }	    
	    $$= new_tree_item("opt_binary", "", p);
	  }
  | BINARY opt_bin_charset 
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("binary", "binary"));
      if($2 != NULL)
	    {
	      tree_item_list_add_all(p, $2);
	      delete_tree_item($2);
	    }	    
	    $$= new_tree_item("opt_binary", "", p);
    }
  ;

opt_bin_mod:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| BINARY 
	  {
	    $$= new_simple_tree_item("binary", "binary");
	  }
	;

opt_bin_charset:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| ASCII_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("ascii", "ascii"));
	    $$= new_tree_item("opt_bin_charset", "", p);
	  }
	| UNICODE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("unicode", "unicode"));
	    $$= new_tree_item("opt_bin_charset", "", p);
    }
	| charset charset_name	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_bin_charset", "", p);
	  }
  ;

opt_primary:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| PRIMARY_SYM
	  {
	    $$= new_simple_tree_item("primary", "primary");
	  }
	;

references:
	  REFERENCES table_ident opt_ref_list
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("references", "references"));
      tree_item_list_add(p, $2);
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      $$= new_tree_item("references", "", p);
    }
  ;

opt_ref_list:
	  /* empty */ opt_on_delete 
	  {
	    $$= $1; 
	  }
	| '(' ref_list ')' opt_on_delete 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      $$= new_tree_item("opt_ref_list", "", p);
	  }
	;

ref_list:
	ref_list ',' ident	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("ref_list", "", p);
	  }
	| ident			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("ref_list", "", p);
	  }
	;

opt_on_delete:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| opt_on_delete_list 
	  {
	    $$= $1;
	  }
	;

opt_on_delete_list:
	  opt_on_delete_list opt_on_delete_item 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_on_delete_list", "", p);
	  }
	| opt_on_delete_item 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("opt_on_delete_list", "", p);
	  }
	;

opt_on_delete_item:
	  ON DELETE_SYM delete_option   
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    tree_item_list_add(p, new_simple_tree_item("delete", "delete"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("opt_on_delete_item", "", p);
	  }
	| ON UPDATE_SYM delete_option 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    tree_item_list_add(p, new_simple_tree_item("update", "update"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("opt_on_delete_item", "", p);
	  }
	| MATCH FULL	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("match", "match"));
	    tree_item_list_add(p, new_simple_tree_item("full", "full"));
	    $$= new_tree_item("opt_on_delete_item", "", p);
	  }
	| MATCH PARTIAL 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("match", "match"));
	    tree_item_list_add(p, new_simple_tree_item("partial", "partial"));
	    $$= new_tree_item("opt_on_delete_item", "", p);
	  }
	| MATCH SIMPLE_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("match", "match"));
	    tree_item_list_add(p, new_simple_tree_item("simple", "simple"));
	    $$= new_tree_item("opt_on_delete_item", "", p);
	  }
	;

delete_option:
	  RESTRICT	 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("restrict", "restrict"));
	    $$= new_tree_item("delete_option", "", p);
	  }
	| CASCADE	 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("cascade", "cascade"));
	    $$= new_tree_item("delete_option", "", p);
	  }
	| SET NULL_SYM   
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("set", "set"));
	    tree_item_list_add(p, new_simple_tree_item("null", "null"));
	    $$= new_tree_item("delete_option", "", p);
	  }
	| NO_SYM ACTION  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("no", "no"));
	    tree_item_list_add(p, new_simple_tree_item("action", "action"));
	    $$= new_tree_item("delete_option", "", p);
	  }
	| SET DEFAULT    
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("set", "set"));
	    tree_item_list_add(p, new_simple_tree_item("default", "default"));
	    $$= new_tree_item("delete_option", "", p);
	  }
	;

key_type:
	  key_or_index			    
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("key_type", "", p);
	  }
	| FULLTEXT_SYM opt_key_or_index	    
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("fulltext", "fulltext"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("key_type", "", p);
	  }
	| SPATIAL_SYM opt_key_or_index
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("spatial", "spatial"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("key_type", "", p);
	  }
	;

constraint_key_type:
	  PRIMARY_SYM KEY_SYM  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("primary", "primary"));
	    tree_item_list_add(p, new_simple_tree_item("key", "key"));
	    $$= new_tree_item("constraint_key_type", "", p);
	  }
	| UNIQUE_SYM opt_key_or_index 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("unique", "unique"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("constraint_key_type", "", p);
	  }
	;

key_or_index:
	  KEY_SYM 
	  {
	    $$= new_simple_tree_item("key", "key");
	  }
	| INDEX_SYM 
	  {
	    $$= new_simple_tree_item("index", "index");
	  }
	;

opt_key_or_index:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| key_or_index
	  {
	    $$= $1;
	  }
	;

keys_or_index:
	  KEYS 
	  {
	    $$= new_simple_tree_item("keys", "keys");
	  }
	| INDEX_SYM 
	  {
	    $$= new_simple_tree_item("index", "index");
	  }
	| INDEXES 
	  {
	    $$= new_simple_tree_item("indexes", "indexes");
	  }
	;

opt_unique_or_fulltext:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| UNIQUE_SYM	
	  {
	    $$= new_simple_tree_item("unique", "unique");
	  }
	| FULLTEXT_SYM	
	  {
	    $$= new_simple_tree_item("fulltext", "fulltext");
	  }
	| SPATIAL_SYM
	  {
	    $$= new_simple_tree_item("spatial", "spatial");
      }
  ;

init_key_options:/*3*/
	  /* empty */		   
	  {
	    $$= NULL;
	  }
    ;

key_alg:
      init_key_options/*1*/
      {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
	    $$= new_tree_item("key_alg", "", p);
      }
    | init_key_options key_using_alg/*4*/
      {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
	    $$= new_tree_item("key_alg", "", p);
      }
    ;

key_options:/*5*/
	  /* empty */		   
	  {
	    $$= NULL;
	  }
    | key_opts
      {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
	    $$= new_tree_item("key_options", "", p);
      }
    ;

key_opts:/*5*/
      key_opt
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("key_opts", "", p);
	  }
    | key_opts key_opt
	  {
	    void *p= new_tree_item_list_reuse($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("key_opts", "", p);
	  }
    ;
    
key_using_alg:/*5*/
	  USING btree_or_rtree 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("using", "using"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("key_alg", "", p);
	  }
	| TYPE_SYM btree_or_rtree  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("type", "type"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("key_using_alg", "", p);
	  }
	;

key_opt:/*5*/
      key_using_alg
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("key_opt", "", p);
	  }
    | KEY_BLOCK_SIZE opt_equal ulong_num
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "KEY_BLOCK_SIZE"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("key_opt", "", p);
	  }
    | WITH PARSER_SYM IDENT_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "WITH"));
	    tree_item_list_add(p, set_item_name($1, "PARSER_SYM"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("key_opt", "", p);
	  }
    ;
    
btree_or_rtree:
	  BTREE_SYM	
	  {
	    $$= new_simple_tree_item("btree", "btree");
	  }
	| RTREE_SYM
	  {
	    $$= new_simple_tree_item("rtree", "rtree");
    }
	| HASH_SYM	
	  {
	    $$= new_simple_tree_item("hash", "hash");
	  }
	;

key_list:
	  key_list ',' key_part order_dir 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("key_list", "", p);
	  }
	| key_part order_dir		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("key_list", "", p);
	  }
	;

key_part:
	  ident			
	  {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("key_part", "", p);
	  }
	| ident '(' NUM ')'	
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, set_item_name($3, "num"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("key_part", "", p);
    }
  ;

opt_ident:
	  /* empty */
	  /* Defaultlength */
    {
      $$= NULL;
    }	
	| field_ident	
	  {
	    $$= $1;
	  }
	;

opt_component:
  /* empty */      { $$= NULL; }
  | '.' ident      { $$= NULL; };

string_list:
	  text_string			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("string_list", "", p);
	  }
	| string_list ',' text_string	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("string_list", "", p);
	  }
	;

/*
** Alter table
*/

alter:
	  ALTER opt_ignore TABLE_SYM table_ident alter_commands/*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("table", "table"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("alter", "", p);
	  }
	| ALTER DATABASE ident_or_empty opt_create_database_options
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("database", "database"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("alter", "", p);
    }
	| ALTER PROCEDURE sp_name sp_a_chistics
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("procedure", "procedure"));
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("alter", "", p);
    }
	| ALTER FUNCTION_SYM sp_name sp_a_chistics
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("function", "function"));
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("alter", "", p);
    }
    | ALTER view_algorithm definer view_tail/*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
	    tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
	    $$= new_tree_item("alter", "", p);
	  }
    | ALTER definer view_tail/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
	    $$= new_tree_item("alter", "", p);
	  }
    | ALTER definer EVENT_SYM sp_name ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_status opt_ev_comment opt_ev_sql_stmt/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
        tree_item_list_add(p, $2);
	    tree_item_list_add(p, set_item_name($3, "EVENT_SYM"));
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
        tree_item_list_add(p, $6);
        tree_item_list_add(p, $7);
        tree_item_list_add(p, $8);
        tree_item_list_add(p, $9);
	    $$= new_tree_item("alter", "", p);
	  }
    | ALTER TABLESPACE alter_tablespace_info/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
	    tree_item_list_add(p, set_item_name($2, "TABLESPACE"));
        tree_item_list_add(p, $3);
	    $$= new_tree_item("alter", "", p);
	  }
    | ALTER LOGFILE_SYM GROUP_SYM alter_logfile_group_info/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
	    tree_item_list_add(p, set_item_name($2, "LOGFILE_SYM"));
	    tree_item_list_add(p, set_item_name($3, "GROUP_SYM"));
        tree_item_list_add(p, $4);
	    $$= new_tree_item("alter", "", p);
	  }
    | ALTER TABLESPACE change_tablespace_info/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
	    tree_item_list_add(p, set_item_name($2, "TABLESPACE"));
        tree_item_list_add(p, $3);
	    $$= new_tree_item("alter", "", p);
	  }
    | ALTER TABLESPACE change_tablespace_access/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
	    tree_item_list_add(p, set_item_name($2, "TABLESPACE"));
        tree_item_list_add(p, $3);
	    $$= new_tree_item("alter", "", p);
	  }
    | ALTER SERVER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')'/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ALTER"));
	    tree_item_list_add(p, set_item_name($2, "SERVER_SYM"));
        tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, "OPTIONS_SYM"));
	    tree_item_list_add(p, set_item_name($5, "("));
        tree_item_list_add(p, $6);
	    tree_item_list_add(p, set_item_name($7, ")"));
	    $$= new_tree_item("alter", "", p);
	  }
	;

ev_alter_on_schedule_completion:/*3*/
	  /* empty */  
	  {
	    $$= NULL;
	  }
    | ON SCHEDULE_SYM ev_schedule_time
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ON"));
	    tree_item_list_add(p, set_item_name($2, "SCHEDULE_SYM"));
        tree_item_list_add(p, $3);
	    $$= new_tree_item("ev_alter_on_schedule_completion", "", p);
	  }
    | ev_on_completion
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
	    $$= new_tree_item("ev_alter_on_schedule_completion", "", p);
	  }
    | ON SCHEDULE_SYM ev_schedule_time ev_on_completion
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ON"));
	    tree_item_list_add(p, set_item_name($2, "SCHEDULE_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
	    $$= new_tree_item("ev_alter_on_schedule_completion", "", p);
	  }
    ;

opt_ev_rename_to:/*3*/
	  /* empty */
	  {
	    $$= NULL;
	  }
    | RENAME TO_SYM sp_name
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "RENAME"));
	    tree_item_list_add(p, set_item_name($2, "TO_SYM"));
        tree_item_list_add(p, $3);
	    $$= new_tree_item("opt_ev_rename_to", "", p);
	  }
    ;
    
opt_ev_sql_stmt:/*3*/
	  /* empty */
	  {
	    $$= NULL;
	  }
    | DO_SYM ev_sql_stmt
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "DO_SYM"));
        tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_ev_sql_stmt", "", p);
	  }
    ;
    
ident_or_empty:
	  /* empty */  
	  {
	    $$= NULL;
	  }
	| ident      
	  {
	    $$= $1;
	  }
	;

alter_commands:
	| DISCARD TABLESPACE 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("discard", "discard"));
	    tree_item_list_add(p, new_simple_tree_item("tablespace", "tablespace"));
	    $$= new_tree_item("alter_list", "", p);
	  }
	| IMPORT TABLESPACE 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("import", "import"));
	    tree_item_list_add(p, new_simple_tree_item("tablespace", "tablespace"));
	    $$= new_tree_item("alter_list", "", p);
	  }
    | alter_list opt_partitioning/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | alter_list remove_partitioning/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | remove_partitioning/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | partitioning/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | add_partition_rule/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | DROP PARTITION_SYM alt_part_name_list/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, $2);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | REBUILD_SYM PARTITION_SYM opt_no_write_to_binlog all_or_alt_part_name_list/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "REBUILD_SYM"));
        tree_item_list_add(p, set_item_name($2, "PARTITION_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | OPTIMIZE PARTITION_SYM opt_no_write_to_binlog all_or_alt_part_name_list opt_no_write_to_binlog opt_mi_check_type/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "OPTIMIZE"));
        tree_item_list_add(p, set_item_name($2, "PARTITION_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
        tree_item_list_add(p, $6);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | ANALYZE_SYM PARTITION_SYM opt_no_write_to_binlog all_or_alt_part_name_list opt_mi_check_type/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "ANALYZE_SYM"));
        tree_item_list_add(p, set_item_name($2, "PARTITION_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list opt_mi_check_type/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "CHECK_SYM"));
        tree_item_list_add(p, set_item_name($2, "PARTITION_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | REPAIR PARTITION_SYM opt_no_write_to_binlog all_or_alt_part_name_list opt_mi_repair_type/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "REPAIR"));
        tree_item_list_add(p, set_item_name($2, "PARTITION_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | COALESCE PARTITION_SYM opt_no_write_to_binlog real_ulong_num/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "COALESCE"));
        tree_item_list_add(p, set_item_name($2, "PARTITION_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
	    $$= new_tree_item("alter_list", "", p);
	  }
    | reorg_partition_rule/*1*/
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_list", "", p);
	  }
    ;
    
remove_partitioning:/*3*/
      REMOVE_SYM PARTITIONING_SYM
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "REMOVE_SYM"));
        tree_item_list_add(p, set_item_name($2, "PARTITIONING_SYM"));
	    $$= new_tree_item("remove_partitioning", "", p);
	  }
    ;
    
all_or_alt_part_name_list:/*3*/
      ALL
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "ALL"));
  	    $$= new_tree_item("all_or_alt_part_name_list", "", p);
	  }
    | alt_part_name_list
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
  	    $$= new_tree_item("all_or_alt_part_name_list", "", p);
	  }
    ;
    
add_partition_rule:/*3*/
      ADD PARTITION_SYM opt_no_write_to_binlog add_part_extra
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "ADD"));
        tree_item_list_add(p, set_item_name($2, "PARTITION_SYM"));
        tree_item_list_add(p, $3);
  	    $$= new_tree_item("add_partition_rule", "", p);
	  }
    ;
    
add_part_extra:/*3*/
 	  /* empty */
	  {
	    $$= NULL;
	  }
    | '(' part_def_list ')'
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "("));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, set_item_name($3, ")"));
  	    $$= new_tree_item("add_part_extra", "", p);
	  }
    | PARTITIONS_SYM real_ulong_num
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "PARTITIONS_SYM"));
        tree_item_list_add(p, $2);
  	    $$= new_tree_item("add_part_extra", "", p);
	  }
    ;
    
reorg_partition_rule:/*3*/
      REORGANIZE_SYM PARTITION_SYM opt_no_write_to_binlog reorg_parts_rule
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "REORGANIZE_SYM"));
        tree_item_list_add(p, set_item_name($2, "PARTITIONS_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
  	    $$= new_tree_item("reorg_partition_rule", "", p);
	  }
    ;

reorg_parts_rule:/*3*/
 	  /* empty */
	  {
	    $$= NULL;
	  }
    | alt_part_name_list INTO '(' part_def_list ')'
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, set_item_name($2, "INTO"));
        tree_item_list_add(p, set_item_name($3, "("));
        tree_item_list_add(p, $4);
        tree_item_list_add(p, set_item_name($5, ")"));
  	    $$= new_tree_item("reorg_parts_rule", "", p);
	  }
    ;

alt_part_name_list:/*3*/
      alt_part_name_item
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
  	    $$= new_tree_item("reorg_parts_rule", "", p);
	  }
    | alt_part_name_list ',' alt_part_name_item
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
  	    $$= new_tree_item("alt_part_name_list", "", p);
	  }
    ;

alt_part_name_item:/*3*/
      ident
	  {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
  	    $$= new_tree_item("alt_part_name_item", "", p);
	  }
    ;

alter_list:/*5*/
    alter_list_item 
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_list", "", p);
    }
	| alter_list ',' alter_list_item 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("alter_list", "", p);
	  }
	;

add_column:
	  ADD opt_column
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("add", "add"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("alter_list_item", "", p);
    }
  ;

alter_list_item:
	  add_column column_def opt_place
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("alter_list_item", "", p);
	  }
	| ADD key_def
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("add", "add"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| add_column '(' field_list ')'
    {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| CHANGE opt_column field_ident field_spec opt_place
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("change", "change"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("alter_list_item", "", p);
    }
  | MODIFY_SYM opt_column field_ident type opt_attribute opt_place
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("modify", "modify"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| DROP opt_column field_ident opt_restrict
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("drop", "drop"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| DROP FOREIGN KEY_SYM opt_ident
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("drop", "drop"));
	    tree_item_list_add(p, new_simple_tree_item("foreign", "foreign"));
	    tree_item_list_add(p, new_simple_tree_item("key", "key"));
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| DROP PRIMARY_SYM KEY_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("drop", "drop"));
	    tree_item_list_add(p, new_simple_tree_item("primary", "primary"));
	    tree_item_list_add(p, new_simple_tree_item("key", "key"));
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| DROP key_or_index field_ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("drop", "drop"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| DISABLE_SYM KEYS
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("disable", "disable"));
	    tree_item_list_add(p, new_simple_tree_item("keys", "keys"));
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| ENABLE_SYM KEYS
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("enable", "enable"));
	    tree_item_list_add(p, new_simple_tree_item("keys", "keys"));
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| ALTER opt_column field_ident SET DEFAULT signed_literal
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("alter", "alter"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("set", "set"));
	    tree_item_list_add(p, new_simple_tree_item("default", "default"));
	    tree_item_list_add(p, $6);
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| ALTER opt_column field_ident DROP DEFAULT
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("alter", "alter"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("drop", "drop"));
	    tree_item_list_add(p, new_simple_tree_item("default", "default"));
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| RENAME opt_to table_ident
	  {
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("convert", "convert"));
	    tree_item_list_add(p, new_simple_tree_item("to", "to"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("alter_list_item", "", p);
    }
  | create_table_options_space_separated
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| FORCE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("force", "force"));
	    $$= new_tree_item("alter_list_item", "", p);
    }
	| alter_order_clause/*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_list_item", "", p);
    }
  ;

opt_column:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| COLUMN_SYM	
	  {
	    $$= new_simple_tree_item("column", "column");
	  }
	;

opt_ignore:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| IGNORE_SYM	
	  {
	    $$= new_simple_tree_item("ignore", "ignore");
	  }
	;

opt_restrict:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| RESTRICT	
	  {
	    $$= new_simple_tree_item("restrict", "restrict");
	  }
	| CASCADE	
	  {
	    $$= new_simple_tree_item("cascade", "cascade");
	  }
	;

opt_place:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| AFTER_SYM ident 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("after", "after"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_place", "", p);
	  }
	| FIRST_SYM	  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("first", "first"));
	    $$= new_tree_item("opt_place", "", p);
	  }
	;

opt_to:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| TO_SYM	
	  {
	    $$= new_simple_tree_item("to", "to");
	  }
	| EQ
	  {
	    $$= new_simple_tree_item("eq", "eq");
	  }
	| AS
	  {
	    $$= new_simple_tree_item("as", "as");
	  }
	;

/*
  SLAVE START and SLAVE STOP are deprecated. We keep them for compatibility.
*/

slave:
	  START_SYM SLAVE slave_thread_opts slave_until
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("start", "start"));
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("slave", "", p);
    }
  | STOP_SYM SLAVE slave_thread_opts
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("stop", "stop"));
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("slave", "", p);
    }
	| SLAVE START_SYM slave_thread_opts slave_until
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    tree_item_list_add(p, new_simple_tree_item("start", "start"));
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("slave", "", p);
    }
	| SLAVE STOP_SYM slave_thread_opts
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    tree_item_list_add(p, new_simple_tree_item("stop", "stop"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("slave", "", p);
    }
  ;

start:
	  START_SYM TRANSACTION_SYM start_transaction_opts
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("start", "start"));
	    tree_item_list_add(p, new_simple_tree_item("transaction", "transaction"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("start", "", p);
    }
	;

start_transaction_opts:
    /*empty*/ 
    {
      $$= NULL;
    }
  | WITH CONSISTENT_SYM SNAPSHOT_SYM
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("with", "with"));
	    tree_item_list_add(p, new_simple_tree_item("consistent", "consistent"));
	    tree_item_list_add(p, new_simple_tree_item("snapshot", "snapshot"));
	    $$= new_tree_item("start_transaction_opts", "", p);
    }
    ;

slave_thread_opts:
	  slave_thread_opt_list
    {
      $$= $1;
    }
	;

slave_thread_opt_list:
	  slave_thread_opt
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    } 
	    $$= new_tree_item("slave_thread_opt_list", "", p);
	  }
	| slave_thread_opt_list ',' slave_thread_opt
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("slave_thread_opt_list", "", p);
	  }
	;

slave_thread_opt:
	  /*empty*/	
	  {
	    $$= NULL;
	  }
	| SQL_THREAD	
	  {
	    $$= new_simple_tree_item("sql_thread", "sql_thread");
	  }
	| RELAY_THREAD 	
	  {
	    $$= new_simple_tree_item("relay_thread", "relay_thread");
	  }
	;

slave_until:
	  /*empty*/	
	  {
	    $$= NULL;
	  }
	| UNTIL_SYM slave_until_opts
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("until", "until"));
    }
	;

slave_until_opts:
    master_file_def
    {
	    void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
	    $$= new_tree_item("slave_thread_opt_list", "", p);
    }
  | slave_until_opts ',' master_file_def 
    {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
	    $$= new_tree_item("slave_until_opts", "", p);
    }
  ;

restore:
	  RESTORE_SYM table_or_tables table_list FROM TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("from", "from"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("restore", "", p);
    }
  ;

backup:
	  BACKUP_SYM table_or_tables table_list TO_SYM TEXT_STRING_sys
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("to", "to"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("backup", "", p);
    }
  ;

checksum:
    CHECKSUM_SYM table_or_tables table_list opt_checksum_type
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      $$= new_tree_item("checksum", "", p);
    }
	;

opt_checksum_type:
    /* nothing */  
    {
      $$= NULL;
    }
	| QUICK        
	  {
	    $$= new_simple_tree_item("quick", "quick");
	  }
	| EXTENDED_SYM 
	  {
	    $$= new_simple_tree_item("extended", "extended");
	  }
  ;

repair:
	  REPAIR opt_no_write_to_binlog table_or_tables table_list opt_mi_repair_type
	  {
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("repair", "", p);
	  }
	;

opt_mi_repair_type:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| mi_repair_types 
	  {
	    $$= $1;
	  }
	;

mi_repair_types:
	  mi_repair_type 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("mi_repair_types", "", p);
	  }
	| mi_repair_type mi_repair_types 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add_all(p, $2);
	    delete_tree_item($2);
	    $$= new_tree_item("mi_repair_types", "", p);
	  }
	;

mi_repair_type:
	  QUICK          
	  {
	    $$= new_simple_tree_item("quick", "quick");
	  }
	| EXTENDED_SYM
	  {
	    $$= new_simple_tree_item("extended", "extended");
	  }
  | USE_FRM      
    {
      $$= new_simple_tree_item("use_frm", "use_frm");
    }
  ;

analyze:
	  ANALYZE_SYM opt_no_write_to_binlog table_or_tables table_list opt_mi_check_type
	  {
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("analyze", "", p);
	  }
	;

binlog_base64_event:
      BINLOG_SYM TEXT_STRING_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "BINLOG_SYM"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("binlog_base64_event", "", p);
	  }
    ;

check:
	  CHECK_SYM table_or_tables table_list opt_mi_check_type
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("check", "", p);
	  }
	;

opt_mi_check_type:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| mi_check_types 
	  {
	    $$= $1;
	  }
	;

mi_check_types:
	  mi_check_type 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("mi_check_types", "", p);
	  }
	| mi_check_type mi_check_types 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add_all(p, $2);
	    delete_tree_item($2);
	    $$= new_tree_item("mi_check_types", "", p);
	  }
	;

mi_check_type:
	  QUICK      
	  {
	    $$= new_simple_tree_item("quick", "quick");
	  }
	| FAST_SYM 
	  {
	    $$= new_simple_tree_item("fast", "fast");
	  }
	| MEDIUM_SYM 
	  {
	    $$= new_simple_tree_item("medium", "medium");
	  }
	| EXTENDED_SYM 
	  {
	    $$= new_simple_tree_item("extended", "extended");
	  }
	| CHANGED  
	  {
	    $$= new_simple_tree_item("changed", "changed");
	  }
    | FOR_SYM UPGRADE_SYM/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "FOR_SYM"));
	    tree_item_list_add(p, set_item_name($2, "UPGRADE_SYM"));
	    $$= new_tree_item("mi_check_type", "", p);
	  }
	;

optimize:
	  OPTIMIZE opt_no_write_to_binlog table_or_tables table_list opt_mi_check_type
	  {
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, $5);
	  }
	;

opt_no_write_to_binlog:
	  /* empty */        
	  {
	    $$= NULL;
	  }
	| NO_WRITE_TO_BINLOG  
	  {
	    $$= new_simple_tree_item("no_write_to_binlog", "no_write_to_binlog");
	  }
	| LOCAL_SYM  
	  {
	    $$= new_simple_tree_item("local", "local");
	  }
	;

rename:
	  RENAME table_or_tables table_to_table_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("rename", "", p);
	  }
    | RENAME DATABASE db_to_db/*1*/
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "RENAME"));
	    tree_item_list_add(p, set_item_name($2, "DATABASE"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("rename", "", p);
    }
	| RENAME USER clear_privileges rename_list
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("user", "user"));
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("rename", "", p);
    }
	;

rename_list:
    user TO_SYM user
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("to", "to"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("rename_list", "", p);
    }
  | rename_list ',' user TO_SYM user
    {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("to", "to"));
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("rename_list", "", p);
    }
  ;

table_to_table_list:
	  table_to_table
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("table_to_table_list", "", p);
	  }
	| table_to_table_list ',' table_to_table
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("table_to_table_list", "", p);
	  }
	;

table_to_table:
	  table_ident TO_SYM table_ident
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, new_simple_tree_item("to", "to"));
        tree_item_list_add(p, $3);
        $$= new_tree_item("table_to_table_list", "", p);
      }
    ;

db_to_db:/*3*/
      ident TO_SYM ident
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, $1);
        tree_item_list_add(p, set_item_name($2, "TO_SYM"));
        tree_item_list_add(p, $3);
        $$= new_tree_item("db_to_db", "", p);
     }
  ;

keycache:
    CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("index", "index"));
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("in", "in"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("keycache", "", p);
    }
  ;

keycache_list:
    assign_to_keycache
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("keycache_list", "", p);
    }
  | keycache_list ',' assign_to_keycache
    {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("keycache_list", "", p);
    }
  ;

assign_to_keycache:
    table_ident cache_keys_spec
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      $$= new_tree_item("assign_to_keycache", "", p);
    }
  ;

key_cache_name:
	  ident	   
	  {
	    $$= $1;
	  }
	| DEFAULT  
	  {
	    $$= new_simple_tree_item("default", "default");
	  }
	;

preload:
  	LOAD INDEX_SYM INTO CACHE_SYM preload_list
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("index", "index"));
      tree_item_list_add(p, new_simple_tree_item("into", "into"));
      tree_item_list_add(p, new_simple_tree_item("cache", "cache"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("preload", "", p);
	  }
	;

preload_list:
	  preload_keys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("preload_list", "", p);
	  }
	| preload_list ',' preload_keys
    {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("preload_list", "", p);
    }
	;

preload_keys:
	  table_ident cache_keys_spec opt_ignore_leaves
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("preload_keys", "", p);
    }
	;

cache_keys_spec:
    cache_key_list_or_empty
    {
      $$= $1;
    }
  ;

cache_key_list_or_empty:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| key_or_index '(' opt_key_usage_list ')'
	  {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("cache_key_list_or_empty", "", p);
    }
	;

opt_ignore_leaves:
	/* empty */
	  {
	    $$= NULL;
	  }
	| IGNORE_SYM LEAVES 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("ignore", "ignore"));
      tree_item_list_add(p, new_simple_tree_item("leaves", "leaves"));
      $$= new_tree_item("opt_ignore_leaves", "", p);
	  }
	;

/*
  Select : retrieve data from table
*/

select:
	select_init { $$= $1; }
	;

/* Need select_init2 for subselects. */
select_init:
	  SELECT_SYM select_init2 
	  { 
	    // ignore  statement name
	    void *p= new_tree_item_list_reuse($2); 
	    delete_tree_item($2);
	    $$= new_tree_item("select", "", p); 
	  }
	| '(' select_paren ')' union_opt
	;

select_paren:
	  SELECT_SYM select_part2 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("select", "select"));
      tree_item_list_add_all(p, $2);
      delete_tree_item($2);
      $$= new_tree_item("select_paren", "", p);
	  }
	| '(' select_paren ')'
	  {
	    void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("select_paren", "", p);
	  }
	;

select_init2:
	  select_part2 union_clause 
	  { 
	    void *p= new_tree_item_list_reuse($1); 
	    delete_tree_item($1);
      tree_item_list_add(p, $2);
	    $$= new_tree_item("select_init2", "", p); 
	  }
	;

select_part2:
	  select_options select_item_list select_into select_lock_type 
	  { 
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, $2);
	    tree_item_list_add_all(p, $3);
	    delete_tree_item($3); 
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("select_part2", "", p); 
	  }
	;

select_into:
	  opt_order_clause opt_limit_clause 
	  {
	    void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $1); 
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("select_into", "", p); 
	  }
  | into
	  {
	    void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $1); 
	    $$= new_tree_item("select_into", "", p); 
	  }
	| select_from 
	  { 
	    void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $1); 
	    $$= new_tree_item("select_into", "", p); 
	  }
	| into select_from
	  {
	    void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $1); 
	    tree_item_list_add(p, $2); 
	    $$= new_tree_item("select_into", "", p); 
	  }
	| select_from into
	  {
	    void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $1); 
	    tree_item_list_add(p, $2); 
	    $$= new_tree_item("select_into", "", p); 
	  }
	; 

select_from:
	  FROM join_table_list where_clause group_clause having_clause opt_order_clause opt_limit_clause procedure_clause 
	  { 
	    void* p= new_tree_item_list(); 
	    tree_item_list_add(p, $2); /* join_table_list */
	    tree_item_list_add(p, $3); /* where_clause */
	    tree_item_list_add(p, $4); /* group_clause */
	    tree_item_list_add(p, $5); /* having_clause */
	    tree_item_list_add(p, $6); /* opt_order_clause */
	    tree_item_list_add(p, $7); /* opt_limit_clause */
	    $$= new_tree_item("select_from", "", p);  
	  }
  | FROM DUAL_SYM where_clause opt_limit_clause
          /* oracle compatibility: oracle always requires FROM clause,
             and DUAL is system table without fields.
             Is "SELECT 1 FROM DUAL" any better than "SELECT 1" ?
          Hmmm :) */
	;

select_options:
	  /* empty*/
	  {
	    $$= NULL;
	  }
	| select_option_list 
	  {
	    $$= $1;
	  }
  ;

select_option_list:
	  select_option_list select_option
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("select_option_list", "", p);
	  }
	| select_option
	  {
	    $$= new_simple_tree_item("select_option_list", "");
	  }
	;

select_option:
	  STRAIGHT_JOIN { $$= new_simple_tree_item("straight_join", "straight_join"); }
	| HIGH_PRIORITY { $$= new_simple_tree_item("high_priority", "high_priority"); }
	| DISTINCT      { $$= new_simple_tree_item("distinct", "distinct"); }
	| SQL_SMALL_RESULT { $$= new_simple_tree_item("sql_small_result", "sql_small_result"); }
	| SQL_BIG_RESULT { $$= new_simple_tree_item("sql_big_result", "sql_big_result"); }
	| SQL_BUFFER_RESULT { $$= new_simple_tree_item("sql_buffer_result", "sql_buffer_result"); }
	| SQL_CALC_FOUND_ROWS { $$= new_simple_tree_item("sql_calc_found_rows", "sql_calc_found_rows"); }
	| SQL_NO_CACHE_SYM { $$= new_simple_tree_item("sql_no_cache", "sql_no_cache"); }
	| SQL_CACHE_SYM { $$= new_simple_tree_item("sql_cache", "sql_cache"); }
	| ALL           { $$= new_simple_tree_item("all", "all"); }
	;

select_lock_type:
	  /* empty */
	  {
	    $$= new_simple_tree_item("select_lock_type", "");
	  }
	| FOR_SYM UPDATE_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("for", "for"));
	    tree_item_list_add(p, new_simple_tree_item("update", "update"));
	    $$= new_tree_item("select_lock_type", "", p);
	  }
	| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lock", "lock"));
	    tree_item_list_add(p, new_simple_tree_item("in", "in"));
	    tree_item_list_add(p, new_simple_tree_item("share", "share"));
	    tree_item_list_add(p, new_simple_tree_item("mode", "mode"));
	    $$= new_tree_item("select_lock_type", "", p);
	  }
	;

select_item_list:
	  select_item_list ',' select_item
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("comma", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("select_item_list", "", p);
	  }
	| select_item 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("select_item_list", "", p);
	  }
	| '*'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    $$= new_tree_item("select_item_list", "", p);
	  }
  ;

select_item:
	  remember_name select_item2 remember_end select_alias
	  {
      void *p= $2;
      $$= $2;
    }
  ;

remember_name: { $$= NULL; }
	;

remember_end: { $$= NULL; }
	;

select_item2:
	  table_wild  /* table.* or schema.table.* */
	  {
	    $$= $1;
	  }
	| expr
	  {
	    $$= $1;
	  }
	;

select_alias:
	  /* empty */		
	  {
	    $$= NULL;
	  }
	| AS ident		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("as", "as"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("select_alias", "", p);
	  }
	| AS TEXT_STRING_sys	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("as", "as"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("select_alias", "", p);
	  }
	| ident			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("select_alias", "", p);
	  }
	| TEXT_STRING_sys	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("select_alias", "", p);
	  }
	;

optional_braces:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| '(' ')' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("optional_braces", "", p);
	  }
	;

/* all possible expressions */
expr:	
	  bool_term bool_or_expr 
	  { 
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("expr", "", p);
	  }
	;

bool_or_expr:
	  /* empty */
	  {
	    $$= NULL;
	  }
  | bool_or_expr or bool_term 
    {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("bool_or_expr", "", p);
    }
  ;

bool_term:
	  bool_term XOR bool_term 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "xor"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("bool_or_expr", "", p);
	  }
	| bool_factor bool_and_expr 
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("bool_term", "", p);
	  }
	;

bool_and_expr:
	  /* empty */
	  {
	    $$= NULL;
	  }
  | bool_and_expr and bool_factor 
    {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("bool_and_expr", "", p);
    }
  ;

bool_factor:
	  NOT_SYM bool_factor	
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "not"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("bool_factor", "", p);
	  }
	| bool_test
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("bool_factor", "", p);
	  }
	;

bool_test:
	  bool_pri IS TRUE_SYM	
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, set_item_name($3, "true"));
	    $$= new_tree_item("bool_test", "", p);
	  }
	| bool_pri IS not TRUE_SYM
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, "true"));
	    $$= new_tree_item("bool_test", "", p);
	  }
	| bool_pri IS FALSE_SYM
    {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, set_item_name($2, "false"));
	    $$= new_tree_item("bool_test", "", p);
    }
	| bool_pri IS not FALSE_SYM
    {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, "false"));
	    $$= new_tree_item("bool_test", "", p);
    }
	| bool_pri IS UNKNOWN_SYM
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, set_item_name($3, "unknown"));
	    $$= new_tree_item("bool_test", "", p);
	  }
	| bool_pri IS not UNKNOWN_SYM
    {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, "unknown"));
	    $$= new_tree_item("bool_test", "", p);
    }
	| bool_pri
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("bool_test", "", p);
	  } 
	;

bool_pri:
	  bool_pri IS NULL_SYM
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, set_item_name($3, "null"));
	    $$= new_tree_item("bool_pri", "", p);
	  }
	| bool_pri IS not NULL_SYM { $$= NULL; }
    {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "is"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, "null"));
	    $$= new_tree_item("bool_pri", "", p);
    }
	| bool_pri EQUAL_SYM predicate	
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "equal"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("bool_pri", "", p);
	  }
	| bool_pri comp_op predicate %prec EQ { $$= NULL; }
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      $$= new_tree_item("bool_pri", "", p);
	  }
	| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ /*2*/
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("bool_pri", "", p);
	  }
	| predicate
	  {
  	  void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("bool_pri", "", p);
	  } 
	;

predicate:
      bit_expr IN_SYM '(' subselect ')'/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "IN_SYM"));
	    tree_item_list_add(p, set_item_name($3, "lp"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, set_item_name($5, "rp"));
	    $$= new_tree_item("predicate", "", p);
	  }
    | bit_expr not IN_SYM '(' subselect ')'/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, set_item_name($3, "IN_SYM"));
	    tree_item_list_add(p, set_item_name($4, "lp"));
	    tree_item_list_add(p, $5);
	    tree_item_list_add(p, set_item_name($6, "rp"));
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr IN_SYM '(' expr ')' /*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("in", "in"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr IN_SYM '(' expr ',' expr_list ')' /*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("in", "in"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $6);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr not IN_SYM '(' expr ')' /*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("in", "in"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $5);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr not IN_SYM '(' expr ',' expr_list ')' /*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("in", "in"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $5);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $7);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr BETWEEN_SYM bit_expr AND_SYM predicate 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("between", "between"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("and", "and"));
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("between", "between"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("and", "and"));
	    tree_item_list_add(p, $6);
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr SOUNDS_SYM LIKE bit_expr 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("sounds", "sounds"));
	    tree_item_list_add(p, new_simple_tree_item("like", "like"));	    
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr LIKE simple_expr opt_escape 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("like", "like"));	    
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr not LIKE simple_expr opt_escape 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("like", "like"));	    
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr REGEXP bit_expr 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("regexprlike", "regexprlike"));	    
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr not REGEXP bit_expr 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("regexprlike", "regexprlike"));	    
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("predicate", "", p);
	  }
	| bit_expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("predicate", "", p);
	  }
	;

bit_expr:
	  bit_expr '|' bit_term	{ $$= NULL; }
	| bit_term
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("bit_expr", "", p);
	  } 
	;

bit_term:
	  bit_term '&' bit_factor	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("bitand", "&"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("bit_term", "", p);
	  }
	| bit_factor
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("bit_term", "", p);
	  } 
	;

bit_factor:
	  bit_factor SHIFT_LEFT value_expr
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("shift_left", "<<"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("bit_factor", "", p);
	  }
	| bit_factor SHIFT_RIGHT value_expr 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("shift_right", ">>"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("bit_factor", "", p);
	  }
	| value_expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("bit_factor", "", p);
	  } 
	;

value_expr:
	  value_expr '+' term	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("plus", "+"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("value_expr", "", p);
	  }
	| value_expr '-' term	
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("minus", "-"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("value_expr", "", p);
	  }
	| value_expr '+' interval_expr interval
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("plus", "+"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("value_expr", "", p);
	  }
	| value_expr '-' interval_expr interval
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("minus", "-"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("value_expr", "", p);
	  }
	| term
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("value_expr", "", p);
	  }
	;

term:
	  term '*' factor 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("mull", "*"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("term", "", p);
	    
	  }
	| term '/' factor
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("div", "/"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("term", "", p);
	  }
	| term '%' factor
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("mod", "%"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("term", "", p);
	  }
	| term DIV_SYM factor
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("intdiv", "div"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("term", "", p);
	  }
	| term MOD_SYM factor
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("mod", "mod"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("term", "", p);
	  }
	| factor
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("term", "", p);
	  } 
	;

factor:
    factor '^' simple_expr	
    {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("xor", "^"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("factor", "", p);
    }
	| simple_expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("factor", "", p);
	  }
	;

or:	
    OR_SYM { $$= set_item_name($1, "or"); } 
  | OR2_SYM { $$= set_item_name($1, "or"); } 
  ;
  
and:	
    AND_SYM { $$= set_item_name($1, "and"); } 
  | AND_AND_SYM { $$= set_item_name($1, "and"); }
  ;
  
not:
    NOT_SYM { $$= set_item_name($1, "not"); }
  | NOT2_SYM { $$= set_item_name($1, "not"); }
  ;

not2:	
    '!' { $$= set_item_name($1, "not2"); } 
  | NOT2_SYM { $$= set_item_name($1, "not2"); } 
  ;

comp_op:  
    EQ { $$= new_simple_tree_item("comp_op", "eq"); }
	| GE { $$= new_simple_tree_item("comp_op", "ge"); }
	| GT_SYM { $$= new_simple_tree_item("comp_op", "gt"); }
	| LE { $$= new_simple_tree_item("comp_op", "le"); }
	| LT { $$= new_simple_tree_item("comp_op", "lt"); }
	| NE { $$= new_simple_tree_item("comp_op", "ne"); }
	;

all_or_any: 
    ALL { $$= set_item_name($1, "all"); }
  | ANY_SYM { $$= set_item_name($1, "any"); }
  ;

interval_expr:
    INTERVAL_SYM expr 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, set_item_name($1, "interval"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("interval_expr", "", p);
    }
  ;

simple_expr:
	  simple_ident
	  {
	    $$= $1;
	  }
    | function_call_keyword/*1*/
	  {
	    $$= $1;
	  }
    | function_call_nonkeyword/*1*/
	  {
	    $$= $1;
	  }
    | function_call_generic/*1*/
	  {
	    $$= $1;
	  }
    | function_call_conflict/*1*/
	  {
	    $$= $1;
	  }
 	| simple_expr COLLATE_SYM ident_or_text %prec NEG { $$= NULL; }
	| literal
	  {
	    $$= $1;
	  }
	| param_marker
	  {
	    $$= $1;
	  }
	| variable
	  {
	    $$= $1;
	  }
	| sum_expr
	  {
	    $$= $1;
	  }
	| simple_expr OR_OR_SYM simple_expr { $$= NULL; }
	| '+' simple_expr %prec NEG	{ $$= NULL; }
	| '-' simple_expr %prec NEG	{ $$= NULL; }
	| '~' simple_expr %prec NEG	{ $$= NULL; }
	| not2 simple_expr %prec NEG	{ $$= NULL; }
    | '(' subselect ')'/*1*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("simple_expr", "", p);
	  }
	| '(' expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("simple_expr", "", p);
	  }
	| '(' expr ',' expr_list ')' 
	  {
	  
	  }
	| ROW_SYM '(' expr ',' expr_list ')' { $$= NULL; }
    | EXISTS '(' subselect ')' { $$= NULL; }/*2*/
	| '{' ident expr '}'	{ $$= NULL; }
    | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' { $$= NULL; }
	| BINARY simple_expr %prec NEG { $$= NULL; }
	| CAST_SYM '(' expr AS cast_type ')' { $$= NULL; }
	| CASE_SYM opt_expr when_list opt_else END { $$= NULL; }
	| CONVERT_SYM '(' expr ',' cast_type ')' { $$= NULL; }
	| CONVERT_SYM '(' expr USING charset_name ')' { $$= NULL; }
	| DEFAULT '(' simple_ident ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("default", "default"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("simple_expr", "", p);
	  }
    | VALUES '(' simple_ident_nospvar ')'/*2*/
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("values", "values"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("simple_expr", "", p);
	  }
    | interval_expr interval '+' expr { $$= NULL; }/*1*/
    | interval_expr { $$= NULL; }/*1*/
    ;

function_call_keyword:
	  CHAR_SYM '(' expr_list ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| CHAR_SYM '(' expr_list USING charset_name ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| CURRENT_USER optional_braces { $$= new_simple_tree_item("function_call_keyword", ""); }
	| DATE_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| DAY_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| HOUR_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| INSERT '(' expr ',' expr ',' expr ',' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| LEFT '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| MINUTE_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| MONTH_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| RIGHT '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| SECOND_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TIME_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TIMESTAMP '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TIMESTAMP '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' LEADING expr FROM expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' TRAILING expr FROM expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' BOTH expr FROM expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' LEADING FROM expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' TRAILING FROM expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' BOTH FROM expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| TRIM '(' expr FROM expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	| USER '(' ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
    | YEAR_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_keyword", ""); }
	;
	
function_call_nonkeyword:
      ADDDATE_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | CURDATE optional_braces { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | CURTIME optional_braces { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | CURTIME '(' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | EXTRACT_SYM '(' interval FROM expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | GET_FORMAT '(' date_time_type ',' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | NOW_SYM optional_braces { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | NOW_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | POSITION_SYM '(' bit_expr IN_SYM expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SUBDATE_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SUBSTRING '(' expr ',' expr ',' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SUBSTRING '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SUBSTRING '(' expr FROM expr FOR_SYM expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SUBSTRING '(' expr FROM expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SYSDATE optional_braces { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | SYSDATE '(' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
    | TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')' { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
	| UTC_DATE_SYM optional_braces { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
	| UTC_TIME_SYM optional_braces { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
	| UTC_TIMESTAMP_SYM optional_braces { $$= new_simple_tree_item("function_call_nonkeyword", ""); }
	;
	
function_call_conflict:
      ASCII_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | CHARSET '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | COALESCE '(' expr_list ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | COLLATION_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | DATABASE '(' ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | IF '(' expr ',' expr ',' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | MICROSECOND_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | MOD_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | OLD_PASSWORD '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | PASSWORD '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | QUARTER_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | REPEAT_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | REPLACE '(' expr ',' expr ',' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | TRUNCATE_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
	| WEEK_SYM '(' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
	| WEEK_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("function_call_conflict", ""); }
    | geometry_function
    ;

geometry_function:
	  CONTAINS_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("geometry_function", ""); }
	| GEOMETRYCOLLECTION '(' expr_list ')' { $$= new_simple_tree_item("geometry_function", ""); }
	| LINESTRING '(' expr_list ')' { $$= new_simple_tree_item("geometry_function", ""); }
 	| MULTILINESTRING '(' expr_list ')' { $$= new_simple_tree_item("geometry_function", ""); }
	| MULTIPOINT '(' expr_list ')' { $$= new_simple_tree_item("geometry_function", ""); }
 	| MULTIPOLYGON '(' expr_list ')' { $$= new_simple_tree_item("geometry_function", ""); }
	| POINT_SYM '(' expr ',' expr ')' { $$= new_simple_tree_item("geometry_function", ""); }
	| POLYGON '(' expr_list ')' { $$= new_simple_tree_item("geometry_function", ""); }
	;
	

function_call_generic:
      IDENT_sys '(' udf_expr_list ')' { $$= new_simple_tree_item("function_call_generic", ""); }
    | ident '.' ident '(' opt_expr_list ')' { $$= new_simple_tree_item("function_call_generic", ""); }
    ;
    
fulltext_options:
      opt_natural_language_mode opt_query_expansion { $$= new_simple_tree_item("fulltext_options", ""); }
    | IN_SYM BOOLEAN_SYM MODE_SYM { $$= new_simple_tree_item("fulltext_options", ""); }
    ;

opt_natural_language_mode:/*3*/
	  /* empty */
	  {
	    $$= NULL;
	  }
    | IN_SYM NATURAL LANGUAGE_SYM MODE_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "IN_SYM"));
        tree_item_list_add(p, set_item_name($2, "NATURAL"));
        tree_item_list_add(p, set_item_name($3, "LANGUAGE_SYM"));
        tree_item_list_add(p, set_item_name($4, "MODE_SYM"));
        $$= new_tree_item("opt_natural_language_mode", "", p);
	  }
    ;

opt_query_expansion:/*3*/
	  /* empty */
	  {
	    $$= NULL;
	  }
    | WITH QUERY_SYM EXPANSION_SYM
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "WITH"));
        tree_item_list_add(p, set_item_name($2, "QUERY_SYM"));
        tree_item_list_add(p, set_item_name($3, "EXPANSION_SYM"));
        $$= new_tree_item("opt_query_expansion", "", p);
	  }
    ;

udf_expr_list:
	  /* empty */	 
	  {
	    $$= NULL;
	  }
	| udf_expr_list2 
	  {
	    $$= $1;
	  }
	;

udf_expr_list2:
	  udf_expr_list3
	  {
	    $$= $1;
	  }
	;

udf_expr_list3:
	  udf_expr 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("udf_expr_list3", "", p);
    }
	| udf_expr_list3 ',' udf_expr 
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("udf_expr_list3", "", p);
    }
	;

udf_expr:
	  remember_name expr remember_end select_alias 
	  {
	    void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $2);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("udf_expr", "", p);
	  }
	;

sum_expr:
	  AVG_SYM '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("avg", "avg"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| AVG_SYM '(' DISTINCT in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("avg", "avg"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("distinct", "distinct"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| BIT_AND '(' in_sum_expr ')' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("bitand", "&"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| BIT_OR  '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("bitor", "|"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| BIT_XOR  '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("bitxor", "^"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| COUNT_SYM '(' opt_all '*' ')' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("count", "count"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| COUNT_SYM '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("count", "count"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| COUNT_SYM '(' DISTINCT expr_list ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("count", "count"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("distinct", "distinct"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| MIN_SYM '(' in_sum_expr ')' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("min", "min"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
/*
   According to ANSI SQL, DISTINCT is allowed and has
   no sence inside MIN and MAX grouping functions; so MIN|MAX(DISTINCT ...)
   is processed like an ordinary MIN | MAX()
 */
	| MIN_SYM '(' DISTINCT in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("min", "min"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("distinct", "distinct"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| MAX_SYM '(' in_sum_expr ')' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("max", "max"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| MAX_SYM '(' DISTINCT in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("max", "max"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("distinct", "distinct"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| STD_SYM '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "std")); // (std | stddev | stddev_pop)
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| VARIANCE_SYM '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "variance")); // (variance | var_pop)
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| STDDEV_SAMP_SYM '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("stddev_samp", "stddev_samp"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| VAR_SAMP_SYM '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("var_samp", "var_samp"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| SUM_SYM '(' in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("sum", "sum"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| SUM_SYM '(' DISTINCT in_sum_expr ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("sum", "sum"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, new_simple_tree_item("distinct", "distinct"));	    
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    $$= new_tree_item("sum_expr", "", p);
	  }
	| GROUP_CONCAT_SYM '(' opt_distinct expr_list opt_gorder_clause opt_gconcat_separator ')' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("group_concat", "group_concat"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
        if($3 != NULL)
        {
          tree_item_list_add(p, $3);
        }
        tree_item_list_add(p, $4);
        if($5 != NULL)
        {
          tree_item_list_add(p, $5);
        }
        if($6 != NULL)
        {
          tree_item_list_add(p, $6);
        }
        tree_item_list_add(p, new_simple_tree_item("rp", ")"));
        $$= new_tree_item("sum_expr", "", p);
	  }
  ;


variable:/*3*/
      '@' variable_aux
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "@"));
	    tree_item_list_add(p, $2);
        $$= new_tree_item("variable", "", p);
      }
    ;

variable_aux:/*3*/
      ident_or_text SET_VAR expr
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "@"));
	    tree_item_list_add(p, $3);
        $$= new_tree_item("variable_aux", "", p);
      }
    | ident_or_text
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
        $$= new_tree_item("variable_aux", "", p);
      }
    | '@' opt_var_ident_type ident_or_text opt_component
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "@"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
        $$= new_tree_item("variable_aux", "", p);
      }
    ;

opt_distinct:
      /* empty */ 
      {
        $$= NULL;
      }
    | DISTINCT   
      {
        $$= new_simple_tree_item("distinct", "distinct");
      }
    ;

opt_gconcat_separator:
      /* empty */
      {
        $$= NULL;
      }
    | SEPARATOR_SYM text_string  
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, new_simple_tree_item("separator", "separator"));
      }
    ;


opt_gorder_clause:
	  /* empty */
	  {
      $$= NULL;
    }
	| order_clause
    {
      $$= $1;
    }
  ;

in_sum_expr:
	  opt_all expr 
	  {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, $2);
      $$= new_tree_item("in_sum_expr", "", p);
    }
  ;

cast_type:
        BINARY opt_len		{ $$= NULL; }
        | CHAR_SYM opt_len opt_binary	{ $$= NULL; }
	    | NCHAR_SYM opt_len	{ $$= NULL; }
        | SIGNED_SYM		{ $$= NULL; }
        | SIGNED_SYM INT_SYM	{ $$= NULL; }
        | UNSIGNED		{ $$= NULL; }
        | UNSIGNED INT_SYM	{ $$= NULL; }
        | DATE_SYM		{ $$= NULL; }
        | TIME_SYM		{ $$= NULL; }
        | DATETIME		{ $$= NULL; }
        | DECIMAL_SYM float_options { $$= NULL; }
	;

opt_expr_list:/*3*/
	  /* empty */ 		
	  {
	    $$= NULL;
	  }
    | expr_list
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("opt_expr_list", "", p);
	  }
    ;

expr_list:
	  expr_list2
	  {
	    $$= $1;
	  }
	;

expr_list2:
	expr 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("expr_list", "", p);
	  }
	| expr_list2 ',' expr 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item("comma", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("expr_list", "", p);
	  }
	;

ident_list_arg:
          ident_list          { $$= NULL; }
        | '(' ident_list ')'  { $$= NULL; };

ident_list:
        { $$= NULL; }
        ident_list2
        { $$= NULL; };

ident_list2:
        simple_ident { $$= NULL; }
        | ident_list2 ',' simple_ident { $$= NULL; };

opt_expr:
	/* empty */      { $$= NULL; }
	| expr           { $$= NULL; };

opt_else:
	/* empty */    { $$= NULL; }
	| ELSE expr    { $$= NULL; };

when_list:
	  WHEN_SYM expr THEN_SYM expr { $$= NULL; }
	| when_list WHEN_SYM expr THEN_SYM expr
  ;

/* Warning - may return NULL in case of incomplete SELECT */
table_ref:
    table_factor
    {
      void *p= $$= $1;
      void *t= p;
    }
  | join_table 
    {
      void *p= $$= $1;
      void *t= p;
    }
  ;

join_table_list:
	  derived_table_list		
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    $$= new_tree_item("join_table_list", "", p);
	  }
	;

derived_table_list:
    table_ref 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("derived_table_list", "", p);
    }
  | derived_table_list ',' table_ref 
    {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, $3);
      $$= new_tree_item("derived_table_list", "", p);
    }
  ;

join_table:
    /*
      Evaluate production 'table_ref' before 'normal_join' so that
      [INNER | CROSS] JOIN is properly nested as other left-associative
      joins.
    */
    table_ref %prec TABLE_REF_PRIORITY normal_join table_ref 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      $$= new_tree_item("join_table", "", p);
    }
	| table_ref STRAIGHT_JOIN table_factor { $$= NULL; }
	| table_ref normal_join table_ref ON expr 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("on", ""));
      tree_item_list_add(p, $5);
      $$= new_tree_item("join_table", "", p);
	  }
    | table_ref STRAIGHT_JOIN table_factor ON { $$= NULL; } expr { $$= NULL; }
	| table_ref normal_join table_ref USING { $$= NULL; } '(' using_list ')' { $$= NULL; }
	| table_ref NATURAL JOIN_SYM table_factor { $$= NULL; }
	| table_ref LEFT opt_outer JOIN_SYM table_ref ON { $$= NULL; } expr { $$= NULL; }
	| table_ref LEFT opt_outer JOIN_SYM table_factor { $$= NULL; } USING '(' using_list ')' { $$= NULL; }
	| table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor { $$= NULL; }
	| table_ref RIGHT opt_outer JOIN_SYM table_ref ON { $$= NULL; } expr { $$= NULL; }
	| table_ref RIGHT opt_outer JOIN_SYM table_factor { $$= NULL; } USING '(' using_list ')' { $$= NULL; }
	| table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor { $$= NULL; }
	;

normal_join:
	  JOIN_SYM 
	  {
	    $$= set_item_name($1, "normal_join");
	  }
	| INNER_SYM JOIN_SYM 
	  {
	    $$= set_item_name($1, "normal_join");
	  }
	| CROSS JOIN_SYM 
	  {
	    $$= set_item_name($1, "normal_join");
	  }
	;

table_factor:
    table_ident opt_table_alias opt_key_definition 
    {
      $$= $1;
    }
	| '{' ident table_ref LEFT OUTER JOIN_SYM table_ref ON { $$= NULL; } expr '}' { $$= NULL; }
	| select_derived_init get_select_lex select_derived2 { $$= NULL; }
	| '(' get_select_lex select_derived union_opt ')' opt_table_alias { $$= NULL; }
  ;

/* handle contents of parentheses in join expression */
select_derived:
	  get_select_lex
	  {
}
          derived_table_list
          {
}
 	;

select_derived2:
        {
}
        select_options select_item_list
	{

}
	opt_select_from
        ;

get_select_lex:
	/* Empty */ { $$= NULL; }
        ;

select_derived_init:
    SELECT_SYM { $$= NULL; }
  ;

opt_outer:
	/* empty */	{ $$= NULL; }
	| OUTER		{ $$= NULL; };

index_hint_clause:/*3*/
	  /* empty */	{ $$= NULL; }
    | FOR_SYM JOIN_SYM { $$= NULL; }
    | FOR_SYM ORDER_SYM BY { $$= NULL; }
    | FOR_SYM GROUP_SYM BY { $$= NULL; }
    ;

index_hint_type:/*3*/
      FORCE_SYM { $$= NULL; }
    | IGNORE_SYM { $$= NULL; }
    ;

index_hint_definition:/*3*/
      index_hint_type key_or_index index_hint_clause '(' key_usage_list ')' { $$= NULL; }
    | USE_SYM key_or_index index_hint_clause '(' opt_key_usage_list ')' { $$= NULL; }
    ;

index_hints_list:/*3*/
      index_hint_definition { $$= NULL; }
    | index_hints_list index_hint_definition { $$= NULL; }
    ;

opt_index_hints_list:/*3*/
	  /* empty */	{ $$= NULL; }
    | index_hints_list { $$= NULL; }
    ;

opt_key_definition:
      opt_index_hints_list { $$= NULL; }/*4*/
    ;

opt_key_usage_list:
	  /* empty */ 		
	  {
	    $$= NULL;
	  }
	| key_usage_list/*2*/
	  {
	    $$= $1;
	  }
    ;

key_usage_element:/*3*/
      ident
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("key_usage_element", "", p);
      }
    | PRIMARY_SYM
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "PRIMARY_SYM"));
	    $$= new_tree_item("key_usage_element", "", p);
      }
    ;

key_usage_list:
      key_usage_element
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("key_usage_list", "", p);
      }
    | key_usage_list ',' key_usage_element
      {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, set_item_name($2, ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("key_usage_list", "", p);
      }
    ;

using_list:
	  ident { $$= NULL; }
	| using_list ',' ident { $$= NULL; }
	;

interval:
	interval_time_st	{ $$= NULL; }
	| DAY_HOUR_SYM		{ $$= NULL; }
	| DAY_MICROSECOND_SYM	{ $$= NULL; }
	| DAY_MINUTE_SYM	{ $$= NULL; }
	| DAY_SECOND_SYM	{ $$= NULL; }
	| HOUR_MICROSECOND_SYM	{ $$= NULL; }
	| HOUR_MINUTE_SYM	{ $$= NULL; }
	| HOUR_SECOND_SYM	{ $$= NULL; }
	| MICROSECOND_SYM	{ $$= NULL; }
	| MINUTE_MICROSECOND_SYM	{ $$= NULL; }
	| MINUTE_SECOND_SYM	{ $$= NULL; }
	| SECOND_MICROSECOND_SYM	{ $$= NULL; }
	| YEAR_MONTH_SYM	{ $$= NULL; };

interval_time_st:
	DAY_SYM			{ $$= NULL; }
	| WEEK_SYM		{ $$= NULL; }
	| HOUR_SYM		{ $$= NULL; }
	| FRAC_SECOND_SYM	{ $$= NULL; }
	| MINUTE_SYM		{ $$= NULL; }
	| MONTH_SYM		{ $$= NULL; }
	| QUARTER_SYM		{ $$= NULL; }
	| SECOND_SYM		{ $$= NULL; }
	| YEAR_SYM		{ $$= NULL; }
        ;

date_time_type:
    DATE_SYM { $$= NULL; }
  | TIME_SYM { $$= NULL; }
  | DATETIME { $$= NULL; }
  | TIMESTAMP { $$= NULL; }
  ;

table_alias:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| AS
	  {
	    $$= new_simple_tree_item("table_alias", "as");
	  }
	| EQ
	  {
	    $$= new_simple_tree_item("table_alias", "eq");
	  }
	;

opt_table_alias:
	/* empty */		
	  {
	    $$= NULL;
	  }
	| table_alias ident
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_table_alias", "", p);
	  }
	;

opt_all:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| ALL
	  {
	    $$= new_simple_tree_item("all", "all");
	  }
	;

where_clause:
	  /* empty */
	  {
	    $$= new_simple_tree_item("where_clause", "");
	  }
	| WHERE expr 
	  {
      void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $2); 
	    $$= new_tree_item("where_clause", "", p); 
	  }
 	;

having_clause:
	  /* empty */
	  {
	    $$= new_simple_tree_item("having_clause", "");
	  }
	| HAVING expr
	  {
      void *p= new_tree_item_list(); 
	    tree_item_list_add(p, $2); 
	    $$= new_tree_item("having_clause", "", p); 
	  }
	;

opt_escape:
	  ESCAPE_SYM simple_expr 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("escape", "escape"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("escape_clause", "", p);
	  }
	| /* empty */
    {
      $$= new_simple_tree_item("escape_clause", "");
    }
  ;

/*
   group by statement in select
*/

group_clause:
	  /* empty */
	  {
	    $$= new_simple_tree_item("group_clause", "");
	  }
	| GROUP_SYM BY group_list olap_opt
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("group_clause", "", p);
	  }
	;

group_list:
	  group_list ',' order_ident order_dir
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("group_list_item", "", p);
	  }
	| order_ident order_dir
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("group_list_item", "", p);
	  }
	;

olap_opt:
	  /* empty */ { $$= NULL; }
	| WITH CUBE_SYM { $$= NULL; }
	| WITH ROLLUP_SYM { $$= NULL; }
	;

alter_order_clause:
      ORDER_SYM BY alter_order_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ORDER_SYM"));
	    tree_item_list_add(p, set_item_name($1, "BY"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("alter_order_clause", "", p);
	  }
    ;
    
alter_order_list:
      alter_order_list ',' alter_order_item
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("alter_order_list", "", p);
	  }
    | alter_order_item
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("alter_order_list", "", p);
	  }
    ;

alter_order_item:
      simple_ident_nospvar order_dir
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("alter_order_item", "", p);
	  }
    ;

/*
   Order by statement in select
*/

opt_order_clause:
	  /* empty */
	  {
	    $$= new_simple_tree_item("order_clause", "");
	  }
	| order_clause
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    $$= new_tree_item("order_clause", "", p);
	  }
	;

order_clause:
	  ORDER_SYM BY order_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("order", "order"));
	    tree_item_list_add(p, new_simple_tree_item("by", "by"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("order_clause", "", p);
	  }
	;

order_list:
	order_list ',' order_ident order_dir
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("order_list_item", "", p);
	  }
	| order_ident order_dir
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("order_list", "", p);
	  }
	;

order_dir:
	  /* empty */ 
	  {
	    $$= new_simple_tree_item("order_dir", "");
	  }
	| ASC  
	  {
	    $$= new_simple_tree_item("order_dir", "asc");
	  }
	| DESC 
	  {
	    $$= new_simple_tree_item("order_dir", "desc");
	  }
	;


opt_limit_clause_init:
	  /* empty */
	  {
      $$= NULL;
    }
	| limit_clause 
	  {
	    $$= $1;
	  }
	;

opt_limit_clause:
	  /* empty */ 
	  {
	    $$= new_simple_tree_item("limit_clause", "");
	  }
	| limit_clause 
	  {
	    $$= $1;
	  }
	;

limit_clause:
	  LIMIT limit_options 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("limit", "limit"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("limit_clause", "", p);
	  }
	;

limit_options:
	limit_option
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("limit_options", "", p);
    }
	| limit_option ',' limit_option
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("comma", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("limit_options", "", p);
    }
	| limit_option OFFSET_SYM limit_option
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("offset", "offset"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("limit_options", "", p);
    }
	;

limit_option:
    param_marker
      {
        $$= set_item_name($1, "limit_option");
      }
    | ULONGLONG_NUM
      {
        $$= set_item_name($1, "limit_option");
      }
    | LONG_NUM
      {
        $$= set_item_name($1, "limit_option");
      }
    | NUM 
      {
        $$= set_item_name($1, "limit_option");
      }
  ;

delete_limit_clause:
	  /* empty */
	  {
      $$= new_simple_tree_item("delete_limit_clause", "delete_limit_clause");
    }
	| LIMIT limit_option
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("limit", "limit"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("delete_limit_clause", "", p);
    }
  ;

ulong_num:
      NUM           
      {
	    $$= set_item_name($1, "num");
      }
    | HEX_NUM       
	  {
	    $$= set_item_name($1, "num");
	  }
	| LONG_NUM      
	  {
	    $$= set_item_name($1, "num");
	  }
	| ULONGLONG_NUM 
	  {
	    $$= set_item_name($1, "num");
	  }
    | DECIMAL_NUM   
      {
	    $$= set_item_name($1, "num");
      }
	| FLOAT_NUM	
	  {
	    $$= set_item_name($1, "num");
	  }
	;

real_ulong_num:
      NUM
      {
	    $$= set_item_name($1, "num");
      }
    | HEX_NUM
      {
	    $$= set_item_name($1, "num");
      }
    | LONG_NUM
      {
	    $$= set_item_name($1, "num");
      }
    | ULONGLONG_NUM
      {
	    $$= set_item_name($1, "num");
      }
    | dec_num_error
      {
	    $$= set_item_name($1, "num");
      }
    ;
    
ulonglong_num:
	  NUM
	  {
	    $$= set_item_name($1, "num");
	  }
	| ULONGLONG_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
	| LONG_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
    | DECIMAL_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
	| FLOAT_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
	;

real_ulonglong_num:
      NUM
	  {
	    $$= set_item_name($1, "num");
	  }
    | ULONGLONG_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
    | LONG_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
    | dec_num_error
	  {
	    $$= set_item_name($1, "num");
	  }
    ;

dec_num_error:
      dec_num
	  {
	    $$= set_item_name($1, "num");
	  }
    ;

dec_num:
      DECIMAL_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
	| FLOAT_NUM
	  {
	    $$= set_item_name($1, "num");
	  }
	;

procedure_clause:
	/* empty */
	| PROCEDURE ident			/* Procedure name */
	  {
}
	  '(' procedure_list ')';


procedure_list:
	/* empty */ { $$= NULL; }
	| procedure_list2 { $$= NULL; };

procedure_list2:
	procedure_list2 ',' procedure_item
	| procedure_item;

procedure_item:
	  remember_name expr
	  {
}
          ;


select_var_list_init:
	  select_var_list
	  {
	    $$= $1;
	  }
  ;

select_var_list:
	  select_var_list ',' select_var_ident
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("select_var_list", "", p);
	  }
  | select_var_ident 
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("select_var_list", "", p);
    }
  ;

select_var_ident:  
    '@' ident_or_text
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("at", "@"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("select_var_ident", "", p);
    }
  | ident_or_text
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("select_var_ident", "", p);
    }
  ;

into:
      INTO into_destination
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "INTO"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("into", "", p);
      }
    ;

into_destination:
      OUTFILE TEXT_STRING_filesystem opt_field_term opt_line_term
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "OUTFILE"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("into_destination", "", p);
      }
    | DUMPFILE TEXT_STRING_filesystem
	  {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "DUMPFILE"));
        tree_item_list_add(p, $2);
        $$= new_tree_item("into_destination", "", p);
	  }
    | select_var_list_init
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("into_destination", "", p);
	  }
    ;

/*
  DO statement
*/

do:	
    DO_SYM expr_list
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      $$= new_tree_item("do", "", p);
    }
	;

/*
  Drop : delete tables or index or user
*/

drop:
	  DROP opt_temporary table_or_tables if_exists table_list opt_restrict
	  {
      void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, $3);
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      tree_item_list_add(p, $5);
      if($6 != NULL)
      {
        tree_item_list_add(p, $6);
      }
      $$= new_tree_item("drop", "", p);
    }
	| DROP INDEX_SYM ident ON table_ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("index", "index"));
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("on", "on"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("drop", "", p);
    }
	| DROP DATABASE if_exists ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("database", "database"));
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      $$= new_tree_item("drop", "", p);
    }
	| DROP FUNCTION_SYM if_exists sp_name
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("function", "function"));
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      $$= new_tree_item("drop", "", p);
    }
	| DROP PROCEDURE if_exists sp_name
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("procedure", "procedure"));
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      $$= new_tree_item("drop", "", p);
    }
	| DROP USER clear_privileges user_list
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("user", "user"));
      tree_item_list_add(p, $4);
      $$= new_tree_item("drop", "", p);
    }
	| DROP VIEW_SYM if_exists table_list opt_restrict
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("view", "view"));
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      if($5 != NULL)
      {
        tree_item_list_add(p, $5);
      }
      $$= new_tree_item("drop", "", p);
    }
    | DROP EVENT_SYM if_exists sp_name
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "DROP"));
        tree_item_list_add(p, set_item_name($2, "EVENT_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("drop", "", p);
      }
    | DROP TRIGGER_SYM if_exists sp_name
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "DROP"));
        tree_item_list_add(p, set_item_name($2, "TRIGGER_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("drop", "", p);
      }
    | DROP TABLESPACE tablespace_name opt_ts_engine opt_ts_wait
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "DROP"));
        tree_item_list_add(p, set_item_name($2, "TABLESPACE"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
        $$= new_tree_item("drop", "", p);
      }
    | DROP LOGFILE_SYM GROUP_SYM logfile_group_name opt_ts_engine opt_ts_wait
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "DROP"));
        tree_item_list_add(p, set_item_name($2, "LOGFILE_SYM"));
        tree_item_list_add(p, set_item_name($3, "GROUP_SYM"));
        tree_item_list_add(p, $4);
        tree_item_list_add(p, $5);
        tree_item_list_add(p, $6);
        $$= new_tree_item("drop", "", p);
      }
    | DROP SERVER_SYM if_exists ident_or_text
      {
        void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "DROP"));
        tree_item_list_add(p, set_item_name($2, "SERVER_SYM"));
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("drop", "", p);
      }
	;

table_list:
	  table_name
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("table_list", "", p);
	  }
	| table_list ',' table_name
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("table_list", "", p);
	  }
	;

table_name:
	  table_ident
	  {
      $$= $1;
    }
	;

if_exists:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| IF EXISTS 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("if", "if"));
	    tree_item_list_add(p, new_simple_tree_item("exists", "exists"));
	    $$= new_tree_item("if_exists", "", p);
	  }
	;

opt_temporary:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| TEMPORARY 
	  {
	    $$= new_simple_tree_item("temporary", "temporary");
	  }
	;
/*
** Insert : add new data to table
*/

insert:
	  INSERT insert_lock_option opt_ignore insert2 insert_field_spec opt_insert_update
	  {
	    // statement name token is ignored
	    void *p = new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add_all(p, $4);
	    delete_tree_item($4);
	    tree_item_list_add(p, $5);
	    if($6 != NULL)
	    {
	      tree_item_list_add(p, $6);
	    }
	    $$= new_tree_item("insert", "", p);
	  }
	;

replace:
	  REPLACE replace_lock_option insert2 insert_field_spec
	  {
	    void *p = new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add_all(p, $3);
	    delete_tree_item($3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("replace", "", p);
	  }
	;

insert_lock_option:
	/* empty */	
	  {
	    $$= NULL;
	  }
	| LOW_PRIORITY	
	  {
	    $$= new_simple_tree_item("low_priority", "low_priority");
	  }
	| DELAYED_SYM	
	  {
	    $$= new_simple_tree_item("delayed", "delayed");
	  }
	| HIGH_PRIORITY 
	  {
	    $$= new_simple_tree_item("high_priority", "high_priority");
	  }
	;

replace_lock_option:
	  opt_low_priority 
	  {
	    $$= $1;
	  }
	| DELAYED_SYM	 
	  {
	    $$= new_simple_tree_item("delayed", "delayed");
	  }
	;

insert2:
	  INTO insert_table 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("into", "into"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("insert2", "insert2", p);
	  }
	| insert_table 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("insert2", "insert2", p);
	  }
	;

insert_table:
	  table_name
	  {
      $$= $1;
    }
  ;

insert_field_spec:
	  insert_values 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("insert_field_spec", "", p);
	  }
	| '(' ')' insert_values 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("insert_field_spec", "", p);
	  }
	| '(' fields ')' insert_values 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("insert_field_spec", "", p);
	  }
	| SET ident_eq_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("set", "set"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("insert_field_spec", "", p);
	  }
	;

fields:
	  fields ',' insert_ident 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("fields", "", p);
	  }
	| insert_ident 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("fields", "", p);
	  }
	;

insert_values:
	  VALUES values_list  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("values", "values"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("insert_values", "", p);
	  }
	| VALUE_SYM values_list  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("value", "value"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("insert_values", "", p);
	  }
	| create_select union_clause 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("insert_values", "", p);
	  }
	| '(' create_select ')' union_opt 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("insert_values", "", p);
	  }
  ;

values_list:
	  values_list ',' no_braces
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("values_list", "", p);
	  }
	| no_braces
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("values_list", "", p);
	  }
	;

ident_eq_list:
	  ident_eq_list ',' ident_eq_value
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("ident_eq_list", "", p);
	  }
	| ident_eq_value
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("ident_eq_list", "", p);
	  }
	;

ident_eq_value:
	  simple_ident_nospvar equal expr_or_default
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      $$= new_tree_item("ident_eq_value", "", p);
    }
  ;

equal:	
    EQ		
    {
      $$= new_simple_tree_item("eq", "=");
    }
	| SET_VAR	
	  {
	    $$= new_simple_tree_item("setvar", ":=");
	  }
	;

opt_equal:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| equal		
	  {
	    $$= $1;
	  }
	;

no_braces:
	  '(' opt_values ')'
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      if($2 != NULL) 
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("no_braces", "", p);
    }
  ;

opt_values:
	/* empty */ 
	  {
	    $$= NULL
	  }
	| values
	  {
	    $$= $1;
	  }
	;

values:
	  values ',' expr_or_default
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("values", "", p);
    }
	| expr_or_default
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("values", "", p);
    }
	;

expr_or_default:
	  expr	  
	  {
	    $$= $1;
	  }
	| DEFAULT 
	  {
	    $$= new_simple_tree_item("default", "default");
	  }
	;

opt_insert_update:
    /* empty */
    {
      $$= NULL;
    }
  | ON DUPLICATE_SYM KEY_SYM UPDATE_SYM insert_update_list
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("on", "on"));
      tree_item_list_add(p, new_simple_tree_item("duplicate", "duplicate"));
      tree_item_list_add(p, new_simple_tree_item("key", "key"));
      tree_item_list_add(p, new_simple_tree_item("update", "update"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("opt_insert_update", "", p);
    }
  ;

/* Update rows in a table */

update:
	  UPDATE_SYM opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause 
	  {
	    void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      tree_item_list_add(p, $4);
      tree_item_list_add(p, new_simple_tree_item("set", "set"));
      tree_item_list_add(p, $6);
      tree_item_list_add(p, $7);
      tree_item_list_add(p, $8);
      tree_item_list_add(p, $9);
	    $$= new_tree_item("update", "", p);
	  }
	;

update_list:
	  update_list ',' update_elem
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("update_list", "", p);
	  }
	| update_elem
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
	    $$= new_tree_item("update_list", "", p);
	  }
	;

update_elem:
	  simple_ident_nospvar equal expr_or_default
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      $$= new_tree_item("update_elem", "", p);
    }
  ;

insert_update_list:
	  insert_update_list ',' insert_update_elem
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("insert_update_list", "", p);
	  }
	| insert_update_elem
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("insert_update_list", "", p);
	  }
	;

insert_update_elem:
	  simple_ident_nospvar equal expr_or_default
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      $$= new_tree_item("insert_update_elem", "", p);
    }
  ;

opt_low_priority:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| LOW_PRIORITY	
	  {
	    $$= new_simple_tree_item("low_priority", "low_priority");
	  }
	;

/* Delete rows from a table */

delete:
	  DELETE_SYM opt_delete_options single_multi 
	  {
	    // statement name token is ignored
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add_all(p, $3);
	    delete_tree_item($3);
	    $$= new_tree_item("delete", "", p);
	  }
	;

single_multi:
 	  FROM table_ident where_clause opt_order_clause delete_limit_clause
 	  {
 	    void *p= new_tree_item_list();
 	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
 	    tree_item_list_add(p, $2);
 	    tree_item_list_add(p, $3);
 	    tree_item_list_add(p, $4);
 	    tree_item_list_add(p, $5);
 	    $$= new_tree_item("single_multi", "", p);
 	  }
	| table_wild_list FROM join_table_list where_clause
	  {
 	    void *p= new_tree_item_list();
 	    tree_item_list_add(p, $1);
 	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
 	    tree_item_list_add(p, $3);
 	    tree_item_list_add(p, $4);
      $$= new_tree_item("single_multi", "", p);
	  }
	| FROM table_wild_list USING join_table_list where_clause
	  {
 	    void *p= new_tree_item_list();
 	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
 	    tree_item_list_add(p, $2);
 	    tree_item_list_add(p, new_simple_tree_item("using", "using"));
 	    tree_item_list_add(p, $4);
 	    tree_item_list_add(p, $5);
      $$= new_tree_item("single_multi", "", p);	  
	  }
	;

table_wild_list:
	  table_wild_one 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("table_wild_list", "", p);
	  }
	| table_wild_list ',' table_wild_one 
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    delete_tree_item($3);
	    $$= new_tree_item("table_wild_list", "", p);
	  };

table_wild_one:
	  ident opt_wild opt_table_alias
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      $$= new_tree_item("table_wild_one", "", p);
    }
	| ident '.' ident opt_wild opt_table_alias
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item(".", "."));
      tree_item_list_add(p, $3);
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      if($5 != NULL)
      {
        tree_item_list_add(p, $5);
      }
      $$= new_tree_item("table_wild_one", "", p);
    }
	;

opt_wild:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| '.' '*'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    $$= new_tree_item("opt_wild", "", p);
	  }
	;


opt_delete_options:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| opt_delete_option opt_delete_options 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add_all(p, $2);
	      delete_tree_item($2);
	    }
	    $$= new_tree_item("opt_delete_options", "", p);
	  }
	;

opt_delete_option:
	  QUICK 
	  {
	    $$= new_simple_tree_item("quick", "quick");
	  }
	| LOW_PRIORITY
	  {
	    $$= new_simple_tree_item("low_priority", "low_priority");
	  }
	| IGNORE_SYM
	  {
	    $$= new_simple_tree_item("ignore", "ignore");
	  }
	;

truncate:
	  TRUNCATE_SYM opt_table_sym table_name
	  {
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("truncate", "", p);
    }
	;

opt_table_sym:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| TABLE_SYM
	  {
	    $$= new_simple_tree_item("table", "table");
	  }
	;

/* Show things */

show:	
    SHOW show_param
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add_all(p, $2);
	    delete_tree_item($2);
	    $$= new_tree_item("show", "", p);
	  }
	;

show_param:
    DATABASES wild_and_where
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("databases", "databases"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("show", "", p);
    }
  | opt_full TABLES opt_db wild_and_where
    {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("tables", "tables"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("show", "", p);
    }
  | opt_full TRIGGERS_SYM opt_db wild_and_where
    {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("triggers", "triggers"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("show", "", p);
    }
  | EVENTS_SYM opt_db wild_and_where
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "EVENTS_SYM"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("show", "", p);
    }
  | TABLE_SYM STATUS_SYM opt_db wild_and_where
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("table", "table"));
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));	    
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("show", "", p);
    }
  | OPEN_SYM TABLES opt_db wild_and_where
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("open", "open"));
	    tree_item_list_add(p, new_simple_tree_item("tables", "tables"));	    
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("show", "", p);
    }
    | opt_full PLUGIN_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "PLUGIN_SYM"));
	    $$= new_tree_item("show", "", p);
	  }
    | PLUGINS_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "PLUGINS_SYM"));
	    $$= new_tree_item("show", "", p);
	  }
	| ENGINE_SYM known_storage_engines show_engine_param
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("engine", "engine"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("show", "", p);
	  }
    | ENGINE_SYM ALL show_engine_param
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "ENGINE_SYM"));
	    tree_item_list_add(p, set_item_name($2, "ALL"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("show", "", p);
	  }
	| opt_full COLUMNS from_or_in table_ident opt_db wild_and_where
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("columns", "columns"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    tree_item_list_add(p, $6);
	    $$= new_tree_item("show", "", p);
    }
  | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys AND_SYM MASTER_LOG_POS_SYM EQ ulonglong_num AND_SYM MASTER_SERVER_ID_SYM EQ ulong_num
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("new", "new"));
	    tree_item_list_add(p, new_simple_tree_item("master", "master"));
	    tree_item_list_add(p, new_simple_tree_item("for", "for"));
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    tree_item_list_add(p, new_simple_tree_item("with", "with"));
	    tree_item_list_add(p, new_simple_tree_item("master_log_file", "master_log_file"));
	    tree_item_list_add(p, new_simple_tree_item("eq", "="));
	    tree_item_list_add(p, $8);
	    tree_item_list_add(p, new_simple_tree_item("and", "and"));
	    tree_item_list_add(p, new_simple_tree_item("master_log_pos", "master_log_pos"));
	    tree_item_list_add(p, new_simple_tree_item("eq", "="));
	    tree_item_list_add(p, $12);
      tree_item_list_add(p, new_simple_tree_item("and", "and"));
	    tree_item_list_add(p, new_simple_tree_item("master_server_id", "master_server_id"));
	    tree_item_list_add(p, new_simple_tree_item("eq", "="));
	    tree_item_list_add(p, $16);
	    $$= new_tree_item("show", "", p);
    }
  | master_or_binary LOGS_SYM
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("logs", "logs"));
	    $$= new_tree_item("show", "", p);
    }
  | SLAVE HOSTS_SYM
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    tree_item_list_add(p, new_simple_tree_item("hosts", "hosts"));
	    $$= new_tree_item("show", "", p);
    }
  | BINLOG_SYM EVENTS_SYM binlog_in binlog_from opt_limit_clause_init
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("binlog", "binlog"));
	    tree_item_list_add(p, new_simple_tree_item("events", "events"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    if($5 != NULL)
	    {
	      tree_item_list_add(p, $5);
	    }
	    $$= new_tree_item("show", "", p);
    }
  | keys_or_index from_or_in table_ident opt_db where_clause
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("show", "", p);
    }
	| COLUMN_SYM TYPES_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("column", "column"));
	    tree_item_list_add(p, new_simple_tree_item("types", "types"));
      $$= new_tree_item("show", "", p);
    }
	| TABLE_SYM TYPES_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("table", "table"));
	    tree_item_list_add(p, new_simple_tree_item("types", "types"));
      $$= new_tree_item("show", "", p);
    }
	| opt_storage ENGINES_SYM
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("engines", "engines"));
      $$= new_tree_item("show", "", p);
    }
    | AUTHORS_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "AUTHORS_SYM"));
        $$= new_tree_item("show", "", p);
      } 
    | CONTRIBUTORS_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "CONTRIBUTORS_SYM"));
        $$= new_tree_item("show", "", p);
      } 
	| PRIVILEGES
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("privileges", "privileges"));
      $$= new_tree_item("show", "", p);
    } 
  | COUNT_SYM '(' '*' ')' WARNINGS
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("count", "count"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("show", "", p);
    }
  | COUNT_SYM '(' '*' ')' ERRORS
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("count", "count"));
	    tree_item_list_add(p, new_simple_tree_item("lp", "("));
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      tree_item_list_add(p, new_simple_tree_item("errors", "errors"));
      $$= new_tree_item("show", "", p);
	  }
  | WARNINGS opt_limit_clause_init
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("warnings", "warnings"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
      $$= new_tree_item("show", "", p);
    }
  | ERRORS opt_limit_clause_init
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("errors", "errors"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
      $$= new_tree_item("show", "", p);
    }
  | opt_var_type STATUS_SYM wild_and_where
    {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
      $$= new_tree_item("show", "", p);
    }	
  | INNOBASE_SYM STATUS_SYM
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "INNOBASE_SYM"));
	    tree_item_list_add(p, set_item_name($2, "STATUS_SYM"));
      $$= new_tree_item("show", "", p);
    }
  | MUTEX_SYM STATUS_SYM
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("mutex", "mutex"));
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));
      $$= new_tree_item("show", "", p);
    }
	| opt_full PROCESSLIST_SYM
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("processlist", "processlist"));
      $$= new_tree_item("show", "", p);
	  }
  | opt_var_type  VARIABLES wild_and_where
	  {
	    void *p= new_tree_item_list();
	    if($1 != NULL)
	    {
	      tree_item_list_add(p, $1);
	    }
	    tree_item_list_add(p, new_simple_tree_item("variables", "variables"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    }
  | charset wild_and_where
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
      $$= new_tree_item("show", "", p);
    }
  | COLLATION_SYM wild_and_where
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("collation", "collation"));
	    tree_item_list_add(p, $2);
      $$= new_tree_item("show", "", p);
    }
	| GRANTS
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("grants", "grants"));
      $$= new_tree_item("show", "", p);
    }
	| GRANTS FOR_SYM user
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("grants", "grants"));
	    tree_item_list_add(p, new_simple_tree_item("for", "for"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    }
	| CREATE DATABASE opt_if_not_exists ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("database", "database"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
      $$= new_tree_item("show", "", p);
    }
  | CREATE TABLE_SYM table_ident
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("table", "table"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    }
  | CREATE VIEW_SYM table_ident
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("view", "view"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    }
  | MASTER_SYM STATUS_SYM
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("master", "master"));
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));
      $$= new_tree_item("show", "", p);
    }
  | SLAVE STATUS_SYM
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));
      $$= new_tree_item("show", "", p);
    }
	| CREATE PROCEDURE sp_name
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("procedure", "procedure"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    }
	| CREATE FUNCTION_SYM sp_name
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("function", "function"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    } 
	| PROCEDURE STATUS_SYM wild_and_where
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("procedure", "procedure"));
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    }
	| FUNCTION_SYM STATUS_SYM wild_and_where
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("procedure", "procedure"));
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));
	    tree_item_list_add(p, $3);
      $$= new_tree_item("show", "", p);
    }
    | PROCEDURE CODE_SYM sp_name
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "PROCEDURE"));
	    tree_item_list_add(p, set_item_name($2, "CODE_SYM"));
	    tree_item_list_add(p, $3);
        $$= new_tree_item("show", "", p);
      }
    | FUNCTION_SYM CODE_SYM sp_name
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "FUNCTION_SYM"));
	    tree_item_list_add(p, set_item_name($2, "CODE_SYM"));
	    tree_item_list_add(p, $3);
        $$= new_tree_item("show", "", p);
      }
    | CREATE EVENT_SYM sp_name
      {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "CREATE"));
	    tree_item_list_add(p, set_item_name($2, "EVENT_SYM"));
	    tree_item_list_add(p, $3);
        $$= new_tree_item("show", "", p);
      }
  ;

show_engine_param:
	STATUS_SYM
	  {
      $$= new_simple_tree_item("status", "status");
      }
    | MUTEX_SYM
	  {
	    $$= set_item_name($1, "MUTEX_SYM");
      }
	| LOGS_SYM
      {
	    $$= new_simple_tree_item("logs", "logs");
      }
  ;

master_or_binary:
	  MASTER_SYM
	  {
	    $$= new_simple_tree_item("master", "master");
	  }
	| BINARY
	  {
	    $$= new_simple_tree_item("binary", "binary");
	  }
	;

opt_storage:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| STORAGE_SYM
	  {
	    $$= new_simple_tree_item("storage", "storage");
	  }
	;

opt_db:
	  /* empty */  
	  {
	    $$= NULL;
	  }
	| from_or_in ident 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_db", "", p);
	  }
	;

opt_full:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| FULL	    
	  {
	    $$= new_simple_tree_item("full", "full");
	  }
	;

from_or_in:
	  FROM
	  {
	    $$= new_simple_tree_item("from", "from");
	  }
	| IN_SYM
	  {
	    $$= new_simple_tree_item("in", "in");
	  }
	;

binlog_in:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| IN_SYM TEXT_STRING_sys 
	  {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("in", "in"));
	    tree_item_list_add(p, $2);
      $$= new_tree_item("binlog_in", "", p);
	  }
	;

binlog_from:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
  | FROM ulonglong_num 
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
	    tree_item_list_add(p, $2);
      $$= new_tree_item("binlog_from", "", p);
    }
  ;

wild_and_where:
    /* empty */
  | LIKE TEXT_STRING_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("like", "like"));
	    tree_item_list_add(p, $2);
      $$= new_tree_item("wild_and_where", "", p);
    }
  | WHERE expr
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("where", "where"));
	    tree_item_list_add(p, $2);
      $$= new_tree_item("wild_and_where", "", p);
    }
  ;


/* A Oracle compatible synonym for show */
describe:
	  describe_command table_ident opt_describe_column 
	  {
	   void *p= new_tree_item_list();
	   tree_item_list_add(p, $2);
	   if($3 != NULL)
	   {
	     tree_item_list_add(p, $3);
	   }
	   $$= new_tree_item("describe", "", p);
	  }
	| describe_command opt_extended_describe select
    {
	   void *p= new_tree_item_list();
	   if($2 != NULL)
	   {
	     tree_item_list_add(p, $2);
	   }
	   tree_item_list_add(p, $3);
	   $$= new_tree_item("describe", "", p);
    }
	;

describe_command:
	  DESC
	  {
	    $$= new_simple_tree_item("desc", "desc");
	  }
	| DESCRIBE
	  {
	    $$= new_simple_tree_item("describe", "describe");
	  }
	;

opt_extended_describe:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| EXTENDED_SYM 
	  {
	    $$= new_simple_tree_item("extended", "extended");
	  }
    | PARTITIONS_SYM
	  {
	    $$= set_item_name($1, "PARTITIONS_SYM");
	  }
	;

opt_describe_column:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| text_string	
	  {
	    $$= $1;
	  }
	| ident
	  {
	    $$= $1;
	  }
	;


/* flush things */

flush:
	  FLUSH_SYM opt_no_write_to_binlog flush_options
	  {
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("flush", "", p);
	  }
	;

flush_options:
	  flush_options ',' flush_option
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("flush_options", "", p);
	  }
	| flush_option
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("flush_options", "", p);
	  }
	;

flush_option:
	  table_or_tables	opt_table_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("flush_option", "", p);
	  }
	| TABLES WITH READ_SYM LOCK_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("tables", "tables"));
	    tree_item_list_add(p, new_simple_tree_item("with", "with"));
	    tree_item_list_add(p, new_simple_tree_item("read", "read"));
	    tree_item_list_add(p, new_simple_tree_item("lock", "lock"));
	    $$= new_tree_item("flush_option", "", p);
	  }
	| QUERY_SYM CACHE_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("query", "query"));
	    tree_item_list_add(p, new_simple_tree_item("cache", "cache"));
	    $$= new_tree_item("flush_option", "", p);
	  }
	| HOSTS_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("hosts", "hosts"));
	    $$= new_tree_item("flush_option", "", p);
	  }
	| PRIVILEGES	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("privileges", "privileges"));
	    $$= new_tree_item("flush_option", "", p);
	  }
	| LOGS_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("logs", "logs"));
	    $$= new_tree_item("flush_option", "", p);
	  }
	| STATUS_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("status", "status"));
	    $$= new_tree_item("flush_option", "", p);
	  }
  | SLAVE         
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    $$= new_tree_item("flush_option", "", p);
	  }
  | MASTER_SYM    
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("master", "master"));
	    $$= new_tree_item("flush_option", "", p);
	  }
	| DES_KEY_FILE	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("des_key_file", "des_key_file"));
	    $$= new_tree_item("flush_option", "", p);
	  }
 	| RESOURCES
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("resources", "resources"));
	    $$= new_tree_item("flush_option", "", p);
	  }
 	;

opt_table_list:
	  /* empty */  
	  {
	    $$= NULL;
	  }
	| table_list 
	  {
	    $$= $1;
	  }
	;

reset:
	  RESET_SYM reset_options
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("reset", "", p);
	  }
	;

reset_options:
	  reset_options ',' reset_option
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("reset", "", p);
	  }
	| reset_option
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("reset_options", "", p);
	  }
	;

reset_option:
    SLAVE                 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
      $$= new_tree_item("reset_options", "", p);
    }
  | MASTER_SYM          
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("master", "master"));
      $$= new_tree_item("reset_options", "", p);
    }
  | QUERY_SYM CACHE_SYM
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("query", "query"));
      tree_item_list_add(p, new_simple_tree_item("cache", "cache"));
      $$= new_tree_item("reset_options", "", p);
    }
  ;

purge:
	  PURGE purge_options
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("purge", "", p);
	  }
	;

purge_options:
	  master_or_binary LOGS_SYM purge_option
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("logs", "logs"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("purge_options", "", p);
	  }
	;

purge_option:
    TO_SYM TEXT_STRING_sys
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("to", "to"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("purge_option", "", p);
    }
	| BEFORE_SYM expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("before", "before"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("purge_option", "", p);
    }
	;

/* kill threads */

kill:
	  KILL_SYM kill_option expr
	  {
      void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, $3);
      $$= new_tree_item("kill", "", p);
    }
  ;

kill_option:
	  /* empty */	 
	  {
	    $$= NULL;
	  }
	| CONNECTION_SYM 
	  {
	    $$= new_simple_tree_item("connection", "connection");
	  }
	| QUERY_SYM      
	  {
	    $$= new_simple_tree_item("query", "query");
	  }
	;



/* change database */

use:	
    USE_SYM ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      $$= new_tree_item("use", "", p);
    }
  ;

/* import, export of files */

load:     
    LOAD DATA_SYM load_data 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("data", "data"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("load", "", p);
    }
  | LOAD TABLE_SYM table_ident FROM MASTER_SYM
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("table", "table"));
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("from", "from"));
      tree_item_list_add(p, new_simple_tree_item("master", "master"));
      $$= new_tree_item("load", "", p);
    }
  ;

load_data:
      load_data_lock opt_local INFILE TEXT_STRING_filesystem opt_duplicate INTO TABLE_SYM table_ident opt_load_data_charset opt_field_term
      opt_line_term opt_ignore_lines opt_field_or_var_spec opt_load_data_set_spec
    {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, new_simple_tree_item("infile", "infile"));
      tree_item_list_add(p, $4);
      if($5 != NULL)
      {
        tree_item_list_add(p, $5);
      }
      tree_item_list_add(p, new_simple_tree_item("into", "into"));
      tree_item_list_add(p, new_simple_tree_item("table", "table"));
      tree_item_list_add(p, $8);
      if($9 != NULL)
      {
        tree_item_list_add(p, $9);
      }
      if($10 != NULL)
      {
        tree_item_list_add(p, $10);
      }
      if($11 != NULL)
      {
        tree_item_list_add(p, $11);
      }
      if($12 != NULL)
      {
        tree_item_list_add(p, $12);
      }
      if($13 != NULL)
      {
        tree_item_list_add(p, $13);
      }
      tree_item_list_add(p, $14);
      $$= new_tree_item("load_data", "", p);
    }
  | FROM MASTER_SYM
    {
    }
  ;

opt_local:
	/* empty */	
	  {
	    $$= NULL;
	  }
	| LOCAL_SYM	
	  {
	    $$= new_simple_tree_item("local", "local");
	  }
	;

load_data_lock:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| CONCURRENT	
	  {
	    $$= new_simple_tree_item("concurrent", "concurrent");
	  }
	| LOW_PRIORITY	
	  {
	    $$= new_simple_tree_item("low_priority", "low_priority");
	  }
	;


opt_duplicate:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| REPLACE	
	  {
	    $$= new_simple_tree_item("replace", "replace");
	  }
	| IGNORE_SYM	
	  {
	    $$= new_simple_tree_item("ignore", "ignore");
	  };

opt_field_term:
	  /* empty */
	  {
	    $$= new_simple_tree_item("opt_field_term", "");
	  }
	| COLUMNS field_term_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("columns", "columns"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_field_term", "", p);
	  }
	;

field_term_list:
	  field_term_list field_term
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("field_term_list", "", p);
	  }
	| field_term
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("field_term_list", "", p);
	  }
	;

field_term:
	  TERMINATED BY text_string 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("teminated", "teminated"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("field_term", "", p);
    }
	| OPTIONALLY ENCLOSED BY text_string
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("optionally", "optionally"));
      tree_item_list_add(p, new_simple_tree_item("enclosed", "enclosed"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, $4);
      $$= new_tree_item("field_term", "", p);
    }
  | ENCLOSED BY text_string
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("enclosed", "enclosed"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("field_term", "", p);
    }
  | ESCAPED BY text_string
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("escaped", "escaped"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("field_term", "", p);
    }
  ;

opt_line_term:
	  /* empty */
	  {
	    $$= new_simple_tree_item("opt_line_term", "");
	  }
	| LINES line_term_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lines", "lines"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("opt_line_term", "", p);
	  }
	;

line_term_list:
	  line_term_list line_term
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("line_term_list", "", p);
	  }
	| line_term
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
	    $$= new_tree_item("line_term_list", "", p);
	  }
	;

line_term:
    TERMINATED BY text_string
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("terminated", "terminated"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("line_term", "", p);
    }
  | STARTING BY text_string
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("starting", "starting"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("line_term", "", p);
    }
  ;

opt_ignore_lines:
	  /* empty */
	  {
	    $$= NULL;
	  }
  | IGNORE_SYM NUM LINES
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("ingore", "ingore"));
      tree_item_list_add(p, set_item_name($2, "num"));
      tree_item_list_add(p, new_simple_tree_item("lines", "lines"));
      $$= new_tree_item("opt_ignore_lines", "", p);
    }
  ;

opt_field_or_var_spec:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| '(' fields_or_vars ')'  
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("opt_field_or_var_spec", "", p);
	  }
	| '(' ')'	          
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("opt_field_or_var_spec", "", p);
	  }
	;

fields_or_vars:
    fields_or_vars ',' field_or_var
    {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("fields_or_vars", "", p);
    }
  | field_or_var
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("fields_or_vars", "", p);
    }
  ;

field_or_var:
    simple_ident_nospvar 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("field_or_var", "", p);
    }
  | '@' ident_or_text
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("at", "@"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("field_or_var", "", p);
    }
  ;

opt_load_data_set_spec:
    /* empty */           
    {
      $$= NULL;
    }
  | SET insert_update_list  
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("set", "set"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("opt_load_data_set_spec", "", p);
    }
  ;


/* Common definitions */

text_literal:
	TEXT_STRING_literal
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("text_literal", "", p);
	  }
	| NCHAR_STRING
    {
      $$= NULL /* todo */
    }
	| UNDERSCORE_CHARSET TEXT_STRING
	  {
	    $$= NULL /* todo */
	  }
	| text_literal TEXT_STRING_literal
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("text_literal", "", p);
	  }
	;

text_string:
	  TEXT_STRING_literal 
	  {
	    $$= $1;
	  }
	| HEX_NUM 
	  {
	    $$= set_item_name($1, "hex_num");
	  }
  | BIN_NUM 
    {
      $$= set_item_name($1, "bin_num");
    }
	;

param_marker:
    PARAM_MARKER 
    {
      $$= $1;
    }
	;

signed_literal:
	  literal 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("signed_literal", "", p);
	  }
	| '+' NUM_literal 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("plus", "+"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("signed_literal", "", p);
	  }
	| '-' NUM_literal
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("minus", "-"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("signed_literal", "", p);
	  }
	;

literal:
	  text_literal	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("literal", "", p);
	  }
	| NUM_literal
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("literal", "", p);
	  }
	| NULL_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("null", "null"));
	    $$= new_tree_item("literal", "", p);
	  }
	| FALSE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("false", "false"));
	    $$= new_tree_item("literal", "", p);
	  }
	| TRUE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("true", "true"));
	    $$= new_tree_item("literal", "", p);
	  }
	| HEX_NUM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("literal", "", p);
	  }
	| BIN_NUM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("literal", "", p);
	  }
	| UNDERSCORE_CHARSET HEX_NUM 
	  {
	    $$= NULL; /* todo */
	  }
	| UNDERSCORE_CHARSET BIN_NUM 
	  {
	    $$= NULL; /* todo */
	  }
	| DATE_SYM text_literal 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("date", "date"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("literal", "", p);
	  }
	| TIME_SYM text_literal
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("time", "time"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("literal", "", p);
	  }
	| TIMESTAMP text_literal
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("timestamp", "timestamp"));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("literal", "", p);
	  }
	;

NUM_literal:
	  NUM 
	  { 
	    $$= set_item_name($1, "num"); 
	  }
	| LONG_NUM 
	  { 
	    $$= set_item_name($1, "long_num"); 
	  }
	| ULONGLONG_NUM 
	  { 
	    $$= set_item_name($1, "ulonglong_num"); 
	  }
  | DECIMAL_NUM 
    { 
      $$= set_item_name($1, "decimal_num"); 
    }
	| FLOAT_NUM 
	  { 
	    $$= set_item_name($1, "float_num"); 
	  }
	;

/**********************************************************************
** Creating different items.
**********************************************************************/

insert_ident:
	  simple_ident_nospvar 
	  {
	    $$= $1;
	  }
	| table_wild	 
	  {
	    $$= $1;
	  }
	;

table_wild:
	  ident '.' '*' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    $$= new_tree_item("table_wild", "", p);
	  }
	| ident '.' ident '.' '*' 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item(".", "."));	    
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    $$= new_tree_item("table_wild", "", p);
	  }
	;

order_ident:
	  expr 
	  {
	    $$= $1;
	  }
	;

simple_ident:
	  ident 
	  {
	    $$= $1; 
	  }
  | simple_ident_q 
    { 
      $$= $1; 
    }
	;

simple_ident_nospvar:
	  ident
	  {
      $$= $1;
    }
	| simple_ident_q 
	  {
	    $$= $1;
	  }
	;

simple_ident_q:
	  ident '.' ident 
	  {
	  }
	| '.' ident '.' ident 
	  {
	  }
	| ident '.' ident '.' ident 
	  {
	  }
  ;


field_ident:
	  ident 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("field_ident", "field_ident", p);
	  }
	| ident '.' ident '.' ident 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("field_ident", "field_ident", p);
	  }
	| ident '.' ident 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("field_ident", "field_ident", p);
	  }
	| '.' ident		
	  /* For Delphi */
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("field_ident", "field_ident", p);
	  }
	;	

table_ident:
	  ident 
	  { 
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("table_ident", "table_ident", p);
	  }
	| ident '.' ident	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("table_ident", "table_ident", p);
	  }
	| '.' ident 
	  /* For Delphi */
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("table_ident", "table_ident", p);
	  } 
  ;

table_ident_nodb:
	  ident			
	  {
	    $$= $1;
	  }
  ;

IDENT_sys:
	  IDENT
	  { 
	    $$= set_item_name($1, "ident"); 
	  }
	| IDENT_QUOTED
	  { 
	    $$= set_item_name($1, "ident_quoted"); 
	  }
	;

TEXT_STRING_sys:
	  TEXT_STRING
	  {
        $$= set_item_name($1, "TEXT_STRING_sys");
      }
	;

TEXT_STRING_literal:
	  TEXT_STRING
	  {
        $$= set_item_name($1, "TEXT_STRING_literal");
      }
	;

TEXT_STRING_filesystem:
      TEXT_STRING
	  {
        $$= set_item_name($1, "TEXT_STRING_filesystem");
      }
    ;

ident:
	  IDENT_sys
	  { 
	    $$= set_item_name($1, "ident");
	  }
    | READ_ONLY_SYM
	  { 
	    $$= set_item_name($1, "ident");
	  }
	| keyword
	  { 
	    $$= set_item_name($1, "ident");
	  }
	;

label_ident:
	  IDENT_sys
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("label_ident", "", p);
	  }
	| keyword_sp
	  {
        $$= set_item_name($1, "label_ident");
      }
	;

ident_or_text:
    ident
    {
      $$= $1;
    }
	| TEXT_STRING_sys
    {
      $$= $1;
    }
	| LEX_HOSTNAME
    {
      $$= NULL; /* todo */
    }
	;

user:
	  ident_or_text
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("user", "", p);
    }
	| ident_or_text '@' ident_or_text
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("at", "@"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("user", "", p);
    }
	| CURRENT_USER optional_braces
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("current_user", "current_user"));
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      $$= new_tree_item("user", "", p);
    }
  ;

/* Keyword that we allow for identifiers (except SP labels) */
keyword:
	  keyword_sp		{ $$= set_item_name($1, "keyword"); }
	| ASCII_SYM		{ $$= set_item_name($1, "keyword"); }
	| BACKUP_SYM		{ $$= set_item_name($1, "keyword"); }
	| BEGIN_SYM		{ $$= set_item_name($1, "keyword"); }
	| BYTE_SYM		{ $$= set_item_name($1, "keyword"); }
	| CACHE_SYM		{ $$= set_item_name($1, "keyword"); }
	| CHARSET		{ $$= set_item_name($1, "keyword"); }
	| CHECKSUM_SYM		{ $$= set_item_name($1, "keyword"); }
	| CLOSE_SYM		{ $$= set_item_name($1, "keyword"); }
	| COMMENT_SYM		{ $$= set_item_name($1, "keyword"); }
	| COMMIT_SYM		{ $$= set_item_name($1, "keyword"); }
	| CONTAINS_SYM          { $$= set_item_name($1, "keyword"); }
    | DEALLOCATE_SYM        { $$= set_item_name($1, "keyword"); }
	| DO_SYM		{ $$= set_item_name($1, "keyword"); }
	| END			{ $$= set_item_name($1, "keyword"); }
	| EXECUTE_SYM		{ $$= set_item_name($1, "keyword"); }
	| FLUSH_SYM		{ $$= set_item_name($1, "keyword"); }
	| HANDLER_SYM		{ $$= set_item_name($1, "keyword"); }
	| HELP_SYM		{ $$= set_item_name($1, "keyword"); }
    | HOST_SYM		{ $$= set_item_name($1, "keyword"); }
    | INSTALL_SYM		{ $$= set_item_name($1, "keyword"); }
	| LANGUAGE_SYM          { $$= set_item_name($1, "keyword"); }
	| NO_SYM		{ $$= set_item_name($1, "keyword"); }
	| OPEN_SYM		{ $$= set_item_name($1, "keyword"); }
    | OPTIONS_SYM { $$= set_item_name($1, "keyword"); }
    | OWNER_SYM { $$= set_item_name($1, "keyword"); }
    | PARSER_SYM { $$= set_item_name($1, "keyword"); }
    | PARTITION_SYM { $$= set_item_name($1, "keyword"); }
    | PORT_SYM { $$= set_item_name($1, "keyword"); }
    | PREPARE_SYM           { $$= set_item_name($1, "keyword"); }
    | REMOVE_SYM { $$= set_item_name($1, "keyword"); }
	| REPAIR		{ $$= set_item_name($1, "keyword"); }
	| RESET_SYM		{ $$= set_item_name($1, "keyword"); }
	| RESTORE_SYM		{ $$= set_item_name($1, "keyword"); }
	| ROLLBACK_SYM		{ $$= set_item_name($1, "keyword"); }
	| SAVEPOINT_SYM		{ $$= set_item_name($1, "keyword"); }
	| SECURITY_SYM		{ $$= set_item_name($1, "keyword"); }
    | SERVER_SYM { $$= set_item_name($1, "keyword"); }
	| SIGNED_SYM		{ $$= set_item_name($1, "keyword"); }
    | SOCKET_SYM { $$= set_item_name($1, "keyword"); }
	| SLAVE			{ $$= set_item_name($1, "keyword"); }
    | SONAME_SYM { $$= set_item_name($1, "keyword"); }
	| START_SYM		{ $$= set_item_name($1, "keyword"); }
	| STOP_SYM		{ $$= set_item_name($1, "keyword"); }
	| TRUNCATE_SYM		{ $$= set_item_name($1, "keyword"); }
	| UNICODE_SYM		{ $$= set_item_name($1, "keyword"); }
    | UNINSTALL_SYM { $$= set_item_name($1, "keyword"); }
    | WRAPPER_SYM { $$= set_item_name($1, "keyword"); }
    | XA_SYM { $$= set_item_name($1, "keyword"); }
    | UPGRADE_SYM { $$= set_item_name($1, "keyword"); }
	;

/*
 * Keywords that we allow for labels in SPs.
 * Anything that's the beginning of a statement or characteristics
 * must be in keyword above, otherwise we get (harmful) shift/reduce
 * conflicts.
 */
keyword_sp:
      ACTION { $$ = $1; }
    | ADDDATE_SYM { $$ = $1; }
    | AFTER_SYM { $$ = $1; }
    | AGAINST { $$ = $1; }
    | AGGREGATE_SYM { $$ = $1; }
    | ALGORITHM_SYM { $$ = $1; }
    | ANY_SYM { $$ = $1; }
    | AT_SYM { $$ = $1; }
    | AUTHORS_SYM { $$ = $1; }
    | AUTO_INC { $$ = $1; }
    | AUTOEXTEND_SIZE_SYM { $$ = $1; }
    | AVG_ROW_LENGTH { $$ = $1; }
    | AVG_SYM { $$ = $1; }
    | BINLOG_SYM { $$ = $1; }
    | BIT_SYM { $$ = $1; }
    | BOOL_SYM { $$ = $1; }
    | BOOLEAN_SYM { $$ = $1; }
    | BTREE_SYM { $$ = $1; }
    | CASCADED { $$ = $1; }
    | CHAIN_SYM { $$ = $1; }
    | CHANGED { $$ = $1; }
    | CIPHER_SYM { $$ = $1; }
    | CLIENT_SYM { $$ = $1; }
    | COALESCE { $$ = $1; }
    | CODE_SYM { $$ = $1; }
    | COLLATION_SYM { $$ = $1; }
    | COLUMNS { $$ = $1; }
    | COMMITTED_SYM { $$ = $1; }
    | COMPACT_SYM { $$ = $1; }
    | COMPLETION_SYM { $$ = $1; }
    | COMPRESSED_SYM { $$ = $1; }
    | CONCURRENT { $$ = $1; }
    | CONNECTION_SYM { $$ = $1; }
    | CONSISTENT_SYM { $$ = $1; }
    | CONTRIBUTORS_SYM { $$ = $1; }
    | CUBE_SYM { $$ = $1; }
    | DATA_SYM { $$ = $1; }
    | DATAFILE_SYM { $$ = $1; }
    | DATETIME { $$ = $1; }
    | DATE_SYM { $$ = $1; }
    | DAY_SYM { $$ = $1; }
    | DEFINER_SYM { $$ = $1; }
    | DELAY_KEY_WRITE_SYM { $$ = $1; }
    | DES_KEY_FILE { $$ = $1; }
    | DIRECTORY_SYM { $$ = $1; }
    | DISABLE_SYM { $$ = $1; }
    | DISCARD { $$ = $1; }
    | DISK_SYM { $$ = $1; }
    | DUMPFILE { $$ = $1; }
    | DUPLICATE_SYM { $$ = $1; }
    | DYNAMIC_SYM { $$ = $1; }
    | ENDS_SYM { $$ = $1; }
    | ENUM { $$ = $1; }
    | ENGINE_SYM { $$ = $1; }
    | ENGINES_SYM { $$ = $1; }
    | ERRORS { $$ = $1; }
    | ESCAPE_SYM { $$ = $1; }
    | EVENT_SYM { $$ = $1; }
    | EVENTS_SYM { $$ = $1; }
    | EVERY_SYM { $$ = $1; }
    | EXPANSION_SYM { $$ = $1; }
    | EXTENDED_SYM { $$ = $1; }
    | EXTENT_SIZE_SYM { $$ = $1; }
    | FAST_SYM { $$ = $1; }
    | FOUND_SYM { $$ = $1; }
    | ENABLE_SYM { $$ = $1; }
    | FULL { $$ = $1; }
    | FILE_SYM { $$ = $1; }
    | FIRST_SYM { $$ = $1; }
    | FIXED_SYM { $$ = $1; }
    | FRAC_SECOND_SYM { $$ = $1; }
    | GEOMETRY_SYM { $$ = $1; }
    | GEOMETRYCOLLECTION { $$ = $1; }
    | GET_FORMAT { $$ = $1; }
    | GRANTS { $$ = $1; }
    | GLOBAL_SYM { $$ = $1; }
    | HASH_SYM { $$ = $1; }
    | HOSTS_SYM { $$ = $1; }
    | HOUR_SYM { $$ = $1; }
    | IDENTIFIED_SYM { $$ = $1; }
    | INVOKER_SYM { $$ = $1; }
    | IMPORT { $$ = $1; }
    | INDEXES { $$ = $1; }
    | INITIAL_SIZE_SYM { $$ = $1; }
    | ISOLATION { $$ = $1; }
    | ISSUER_SYM { $$ = $1; }
    | INNOBASE_SYM { $$ = $1; }
    | INSERT_METHOD { $$ = $1; }
    | KEY_BLOCK_SIZE { $$ = $1; }
    | LAST_SYM { $$ = $1; }
    | LEAVES { $$ = $1; }
    | LESS_SYM { $$ = $1; }
    | LEVEL_SYM { $$ = $1; }
    | LINESTRING { $$ = $1; }
    | LIST_SYM { $$ = $1; }
    | LOCAL_SYM { $$ = $1; }
    | LOCKS_SYM { $$ = $1; }
    | LOGFILE_SYM { $$ = $1; }
    | LOGS_SYM { $$ = $1; }
    | MAX_ROWS { $$ = $1; }
    | MASTER_SYM { $$ = $1; }
    | MASTER_HOST_SYM { $$ = $1; }
    | MASTER_PORT_SYM { $$ = $1; }
    | MASTER_LOG_FILE_SYM { $$ = $1; }
    | MASTER_LOG_POS_SYM { $$ = $1; }
    | MASTER_USER_SYM { $$ = $1; }
    | MASTER_PASSWORD_SYM { $$ = $1; }
    | MASTER_SERVER_ID_SYM { $$ = $1; }
    | MASTER_CONNECT_RETRY_SYM { $$ = $1; }
    | MASTER_SSL_SYM { $$ = $1; }
    | MASTER_SSL_CA_SYM { $$ = $1; }
    | MASTER_SSL_CAPATH_SYM { $$ = $1; }
    | MASTER_SSL_CERT_SYM { $$ = $1; }
    | MASTER_SSL_CIPHER_SYM { $$ = $1; }
    | MASTER_SSL_KEY_SYM { $$ = $1; }
    | MAX_CONNECTIONS_PER_HOUR { $$ = $1; }
    | MAX_QUERIES_PER_HOUR { $$ = $1; }
    | MAX_SIZE_SYM { $$ = $1; }
    | MAX_UPDATES_PER_HOUR { $$ = $1; }
    | MAX_USER_CONNECTIONS_SYM { $$ = $1; }
    | MAX_VALUE_SYM { $$ = $1; }
    | MEDIUM_SYM { $$ = $1; }
    | MEMORY_SYM { $$ = $1; }
    | MERGE_SYM { $$ = $1; }
    | MICROSECOND_SYM { $$ = $1; }
    | MIGRATE_SYM { $$ = $1; }
    | MINUTE_SYM { $$ = $1; }
    | MIN_ROWS { $$ = $1; }
    | MODIFY_SYM { $$ = $1; }
    | MODE_SYM { $$ = $1; }
    | MONTH_SYM { $$ = $1; }
    | MULTILINESTRING { $$ = $1; }
    | MULTIPOINT { $$ = $1; }
    | MULTIPOLYGON { $$ = $1; }
    | MUTEX_SYM { $$ = $1; }
    | NAME_SYM { $$ = $1; }
    | NAMES_SYM { $$ = $1; }
    | NATIONAL_SYM { $$ = $1; }
    | NCHAR_SYM { $$ = $1; }
    | NDBCLUSTER_SYM { $$ = $1; }
    | NEXT_SYM { $$ = $1; }
    | NEW_SYM { $$ = $1; }
    | NO_WAIT_SYM { $$ = $1; }
    | NODEGROUP_SYM { $$ = $1; }
    | NONE_SYM { $$ = $1; }
    | NVARCHAR_SYM { $$ = $1; }
    | OFFSET_SYM { $$ = $1; }
    | OLD_PASSWORD { $$ = $1; }
    | ONE_SHOT_SYM { $$ = $1; }
    | ONE_SYM { $$ = $1; }
    | PACK_KEYS_SYM { $$ = $1; }
    | PARTIAL { $$ = $1; }
    | PARTITIONING_SYM { $$ = $1; }
    | PARTITIONS_SYM { $$ = $1; }
    | PASSWORD { $$ = $1; }
    | PHASE_SYM { $$ = $1; }
    | PLUGIN_SYM { $$ = $1; }
    | PLUGINS_SYM { $$ = $1; }
    | POINT_SYM { $$ = $1; }
    | POLYGON { $$ = $1; }
    | PRESERVE_SYM { $$ = $1; }
    | PREV_SYM { $$ = $1; }
    | PRIVILEGES { $$ = $1; }
    | PROCESS { $$ = $1; }
    | PROCESSLIST_SYM { $$ = $1; }
    | QUARTER_SYM { $$ = $1; }
    | QUERY_SYM { $$ = $1; }
    | QUICK { $$ = $1; }
    | REBUILD_SYM { $$ = $1; }
    | RECOVER_SYM { $$ = $1; }
    | REDO_BUFFER_SIZE_SYM { $$ = $1; }
    | REDOFILE_SYM { $$ = $1; }
    | REDUNDANT_SYM { $$ = $1; }
    | RELAY_LOG_FILE_SYM { $$ = $1; }
    | RELAY_LOG_POS_SYM { $$ = $1; }
    | RELAY_THREAD { $$ = $1; }
    | RELOAD { $$ = $1; }
    | REORGANIZE_SYM { $$ = $1; }
    | REPEATABLE_SYM { $$ = $1; }
    | REPLICATION { $$ = $1; }
    | RESOURCES { $$ = $1; }
    | RESUME_SYM { $$ = $1; }
    | RETURNS_SYM { $$ = $1; }
    | ROLLUP_SYM { $$ = $1; }
    | ROUTINE_SYM { $$ = $1; }
    | ROWS_SYM { $$ = $1; }
    | ROW_FORMAT_SYM { $$ = $1; }
    | ROW_SYM { $$ = $1; }
    | RTREE_SYM { $$ = $1; }
    | SCHEDULE_SYM { $$ = $1; }
    | SECOND_SYM { $$ = $1; }
    | SERIAL_SYM { $$ = $1; }
    | SERIALIZABLE_SYM { $$ = $1; }
    | SESSION_SYM { $$ = $1; }
    | SIMPLE_SYM { $$ = $1; }
    | SHARE_SYM { $$ = $1; }
    | SHUTDOWN { $$ = $1; }
    | SNAPSHOT_SYM { $$ = $1; }
    | SOUNDS_SYM { $$ = $1; }
    | SQL_CACHE_SYM { $$ = $1; }
    | SQL_BUFFER_RESULT { $$ = $1; }
    | SQL_NO_CACHE_SYM { $$ = $1; }
    | SQL_THREAD { $$ = $1; }
    | STARTS_SYM { $$ = $1; }
    | STATUS_SYM { $$ = $1; }
    | STORAGE_SYM { $$ = $1; }
    | STRING_SYM { $$ = $1; }
    | SUBDATE_SYM { $$ = $1; }
    | SUBJECT_SYM { $$ = $1; }
    | SUBPARTITION_SYM { $$ = $1; }
    | SUBPARTITIONS_SYM { $$ = $1; }
    | SUPER_SYM { $$ = $1; }
    | SUSPEND_SYM { $$ = $1; }
    | TABLES { $$ = $1; }
    | TABLESPACE { $$ = $1; }
    | TEMPORARY { $$ = $1; }
    | TEMPTABLE_SYM { $$ = $1; }
    | TEXT_SYM { $$ = $1; }
    | THAN_SYM { $$ = $1; }
    | TRANSACTION_SYM { $$ = $1; }
    | TRIGGERS_SYM { $$ = $1; }
    | TIMESTAMP { $$ = $1; }
    | TIMESTAMP_ADD { $$ = $1; }
    | TIMESTAMP_DIFF { $$ = $1; }
    | TIME_SYM { $$ = $1; }
    | TYPES_SYM { $$ = $1; }
    | TYPE_SYM { $$ = $1; }
    | UDF_RETURNS_SYM { $$ = $1; }
    | FUNCTION_SYM { $$ = $1; }
    | UNCOMMITTED_SYM { $$ = $1; }
    | UNDEFINED_SYM { $$ = $1; }
    | UNDO_BUFFER_SIZE_SYM { $$ = $1; }
    | UNDOFILE_SYM { $$ = $1; }
    | UNKNOWN_SYM { $$ = $1; }
    | UNTIL_SYM { $$ = $1; }
    | USER { $$ = $1; }
    | USE_FRM { $$ = $1; }
    | VARIABLES { $$ = $1; }
    | VIEW_SYM { $$ = $1; }
    | VALUE_SYM { $$ = $1; }
    | WARNINGS { $$ = $1; }
    | WAIT_SYM { $$ = $1; }
    | WEEK_SYM { $$ = $1; }
    | WORK_SYM { $$ = $1; }
    | X509_SYM { $$ = $1; }
	| YEAR_SYM { $$ = $1; }
	;

/* Option functions */

set:
	  SET opt_option option_value_list
	  {
	    void *p= new_tree_item_list();
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("set", "", p);
	  }
	;

opt_option:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| OPTION 
	  {
	    $$= new_simple_tree_item("option", "option");
	  }
	;

option_value_list:
	  option_type_value
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("option_value_list", "", p);
	  }
	| option_value_list ',' option_type_value
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("option_value_list", "", p);
	  
	  }
	;

option_type_value:
	  ext_option_value
    {
      $$= $1;
    }
  ;

option_type:
    option_type2    
    {
      $$= $1; // can be NULL
    }
	| GLOBAL_SYM	
	  {
	    $$= new_simple_tree_item("global", "global");
	  }
	| LOCAL_SYM	
	  {
	    $$= new_simple_tree_item("local", "local");
	  }
	| SESSION_SYM	
	  {
	    $$= new_simple_tree_item("session", "session");
	  }
	;

option_type2:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| ONE_SHOT_SYM	
	  {
	    $$= new_simple_tree_item("one_shot", "one_shot");
	  }
	;

opt_var_type:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| GLOBAL_SYM	
	  {
	    $$= new_simple_tree_item("global", "global");
	  }
	| LOCAL_SYM	
	  {
	    $$= new_simple_tree_item("local", "local"); 
	  }
	| SESSION_SYM	
	  {
	    $$= new_simple_tree_item("session", "session");
	  }
	;

opt_var_ident_type:
	  /* empty */		
	  {
	    $$= NULL;
	  }
	| GLOBAL_SYM '.'	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("global", "global"));
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    $$= new_tree_item("opt_var_ident_type", "", p);
	  }
	| LOCAL_SYM '.'	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("local", "local"));
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    $$= new_tree_item("opt_var_ident_type", "", p);
	  }
	| SESSION_SYM '.'	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("session", "session"));
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    $$= new_tree_item("opt_var_ident_type", "", p);
	  }
	;

ext_option_value:
    sys_option_value
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("ext_option_value", "", p);
    }
  | option_type2 option_value
    {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, $2);
      $$= new_tree_item("ext_option_value", "", p);
    }
  ;

sys_option_value:
    option_type internal_variable_name equal set_expr_or_default
    {
      void *p= new_tree_item_list();
      if($1 != NULL)
      {
        tree_item_list_add(p, $1);
      }
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      tree_item_list_add(p, $4);
      $$= new_tree_item("ext_option_value", "", p);
    }
  | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("transaction", "transaction"));
      tree_item_list_add(p, new_simple_tree_item("isolation", "isolation"));
      tree_item_list_add(p, new_simple_tree_item("level", "level"));
      tree_item_list_add(p, $5);
      $$= new_tree_item("ext_option_value", "", p);
    }
  ;

option_value:
	  '@' ident_or_text equal expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("at", "@"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    $$= new_tree_item("option_value", "", p);
    }
	| '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("at", "@"));
	    tree_item_list_add(p, new_simple_tree_item("at", "@"));
      if($3 != NULL)
      {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, $5);
	    tree_item_list_add(p, $6);
	    $$= new_tree_item("option_value", "", p);
    }
	| charset old_or_new_charset_name_or_default
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("option_value", "", p);
    }
  | NAMES_SYM equal expr
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("names", "names"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("option_value", "", p);
    }
	| NAMES_SYM charset_name_or_default opt_collate
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("names", "names"));
	    tree_item_list_add(p, $2);
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    $$= new_tree_item("option_value", "", p);
    }
	| PASSWORD equal text_or_password
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("password", "password"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("option_value", "", p);
    }
	| PASSWORD FOR_SYM user equal text_or_password
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("password", "password"));
	    tree_item_list_add(p, new_simple_tree_item("for", "for"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("option_value", "", p);
    }
	;

internal_variable_name:
	  ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("internal_variable_name", "", p);
    }
	| ident '.' ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("internal_variable_name", "", p);
    }
	| DEFAULT '.' ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("default", "default"));
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("internal_variable_name", "", p);
    }
  ;

isolation_types:
	  READ_SYM UNCOMMITTED_SYM	
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("read", "read"));
      tree_item_list_add(p, new_simple_tree_item("uncommited", "uncommited"));
      $$= new_tree_item("isolation_types", "", p);
	  }
	| READ_SYM COMMITTED_SYM	
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("read", "read"));
      tree_item_list_add(p, new_simple_tree_item("commited", "commited"));
      $$= new_tree_item("isolation_types", "", p);
	  }
	| REPEATABLE_SYM READ_SYM	
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("repeatable", "repeatable"));
      tree_item_list_add(p, new_simple_tree_item("read", "read"));
      $$= new_tree_item("isolation_types", "", p);
	  }
	| SERIALIZABLE_SYM		
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("serializable", "serializable"));
      $$= new_tree_item("isolation_types", "", p);
	  }
	;

text_or_password:
	TEXT_STRING { $$= NULL; }
	| PASSWORD '(' TEXT_STRING ')'
	  {
}
	| OLD_PASSWORD '(' TEXT_STRING ')'
	  {
}
          ;


set_expr_or_default:
	  expr      
	  {
	    $$= $1;
	  }
	| DEFAULT 
	  {
	    $$= new_simple_tree_item("default", "default");
	  }
	| ON	  
	  {
	    $$= new_simple_tree_item("on", "on");
	  }
	| ALL	  
	  {
	    $$= new_simple_tree_item("all", "all");
	  }
	| BINARY  
	  {
	    $$= new_simple_tree_item("binary", "binary");
	  }
	;


/* Lock function */

lock:
	  LOCK_SYM table_or_tables table_lock_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("lock", "", p);
	  }
	;

table_or_tables:
	  TABLE_SYM
	  {
	    $$= new_simple_tree_item("table", "table");
	  }
	| TABLES
	  {
	    $$= new_simple_tree_item("tables", "tables");
	  }
	;

table_lock_list:
	  table_lock
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("table_lock_list", "", p);
	  }
	| table_lock_list ',' table_lock
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("table_lock_list", "", p);
	  }
	;

table_lock:
	  table_ident opt_table_alias lock_option
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("table_lock", "", p);
    }
  ;

lock_option:
	  READ_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("read", "read"));
	    $$= new_tree_item("lock_option", "", p);
	  }
	| WRITE_SYM     
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("write", "write"));
	    $$= new_tree_item("lock_option", "", p);
	  }
	| LOW_PRIORITY WRITE_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("low_priority", "low_priority"));
	    tree_item_list_add(p, new_simple_tree_item("write", "write"));
	    $$= new_tree_item("lock_option", "", p);
	  }
	| READ_SYM LOCAL_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("read", "read"));
	    tree_item_list_add(p, new_simple_tree_item("local", "local"));
	    $$= new_tree_item("lock_option", "", p);
	  }
  ;

unlock:
	  UNLOCK_SYM table_or_tables
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("unlock", "", p);
	  }
  ;


/*
** Handler: direct access to ISAM functions
*/

handler:
	HANDLER_SYM table_ident OPEN_SYM opt_table_alias
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("open", "open"));
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      $$= new_tree_item("handler", "", p);
    }
	| HANDLER_SYM table_ident_nodb CLOSE_SYM
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("close", "close"));
      $$= new_tree_item("handler", "", p);
    }
	| HANDLER_SYM table_ident_nodb READ_SYM handler_read_or_scan where_clause opt_limit_clause 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      tree_item_list_add(p, new_simple_tree_item("read", "read"));
      tree_item_list_add(p, $4);
      tree_item_list_add(p, $5);
      tree_item_list_add(p, $6);
      $$= new_tree_item("handler", "", p);
	  }
  ;

handler_read_or_scan:
	  handler_scan_function         
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("handler_read_or_scan", "", p);
	  }
  | ident handler_rkey_function 
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, $2);
      $$= new_tree_item("handler_read_or_scan", "", p);
    }
  ;

handler_scan_function:
	  FIRST_SYM  
	  {
	    $$= new_simple_tree_item("first", "first");
	  }
	| NEXT_SYM 
	  {
	    $$= new_simple_tree_item("next", "next");
	  }
  ;

handler_rkey_function:
	  FIRST_SYM  
	  {
	    $$= new_simple_tree_item("first", "first");
	  }
	| NEXT_SYM 
	  {
	    $$= new_simple_tree_item("next", "next");
	  }
	| PREV_SYM 
	  {
	    $$= new_simple_tree_item("prev", "prev");
	  }
	| LAST_SYM 
	  {
	    $$= new_simple_tree_item("last", "last");
	  }
	| handler_rkey_mode '(' values ')' 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $3);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("handler_rkey_function", "", p);
	  }
  ;

handler_rkey_mode:
	  EQ
	  {
	    $$= new_simple_tree_item("eq", "=");
	  }     
	| GE     
	  {
	    $$= new_simple_tree_item("ge", ">=");
	  }     
	| LE     
	  {
	    $$= new_simple_tree_item("le", "<=");
	  }     
	| GT_SYM 
	  {
	    $$= new_simple_tree_item("gt", ">");
	  }     
	| LT     
	  {
	    $$= new_simple_tree_item("lt", "<");
	  }     
  ;

/* GRANT / REVOKE */

revoke:
	  REVOKE clear_privileges revoke_command
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add_all(p, $3);
	    delete_tree_item($3);
	    $$= new_tree_item("revoke", "", p);
	  }
  ;

revoke_command:
	  grant_privileges ON opt_table grant_ident FROM grant_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
	    $$= new_tree_item("revoke_command", "", p);
    }
  | grant_privileges ON FUNCTION_SYM grant_ident FROM grant_list
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    tree_item_list_add(p, new_simple_tree_item("function", "function"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
	    $$= new_tree_item("revoke_command", "", p);
    }
	| grant_privileges ON PROCEDURE grant_ident FROM grant_list
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    tree_item_list_add(p, new_simple_tree_item("procedure", "procedure"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
	    $$= new_tree_item("revoke_command", "", p);
    }
	| ALL opt_privileges ',' GRANT OPTION FROM grant_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("all", "all"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, new_simple_tree_item("grant", "grant"));
	    tree_item_list_add(p, new_simple_tree_item("option", "option"));
	    tree_item_list_add(p, new_simple_tree_item("from", "from"));
	    tree_item_list_add(p, $7);
	    $$= new_tree_item("revoke_command", "", p);
    }
	;

grant:
	  GRANT clear_privileges grant_command
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("grant", "", p);
	  }
  ;

grant_command:
	  grant_privileges ON opt_table grant_ident TO_SYM grant_list require_clause grant_options
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    if($3 != NULL)
	    {
	      tree_item_list_add(p, $3);
	    }
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("to", "to"));
	    tree_item_list_add(p, $6);
	    tree_item_list_add(p, $7);
	    if($8 != NULL)
	    {
	      tree_item_list_add(p, $8);
	    }
	    $$= new_tree_item("grant_command", "", p);
    }
  | grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list require_clause grant_options
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    tree_item_list_add(p, new_simple_tree_item("function", "function"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("to", "to"));
	    tree_item_list_add(p, $6);
	    tree_item_list_add(p, $7);
	    if($8 != NULL)
	    {
	      tree_item_list_add(p, $8);
	    }
	    $$= new_tree_item("grant_command", "", p);
    }
  | grant_privileges ON PROCEDURE grant_ident TO_SYM grant_list require_clause grant_options
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item("on", "on"));
	    tree_item_list_add(p, new_simple_tree_item("procedure", "procedure"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, new_simple_tree_item("to", "to"));
	    tree_item_list_add(p, $6);
	    tree_item_list_add(p, $7);
	    if($8 != NULL)
	    {
	      tree_item_list_add(p, $8);
	    }
	    $$= new_tree_item("grant_command", "", p);
    }
  ;

opt_table:
	  /* Empty */
	  {
	    $$= NULL;
	  }
	| TABLE_SYM 
	  {
	    $$= new_simple_tree_item("table", "table");
	  }
	;
        
grant_privileges:
	  object_privilege_list 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("grant_privileges", "", p);
	  }
	| ALL opt_privileges
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("all", "all"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("grant_privileges", "", p);
    }
  ;

opt_privileges:
	  /* empty */
	  {
	    $$= NULL;
	  }
	| PRIVILEGES
	  {
	    $$= new_simple_tree_item("privileges", "privileges");
	  }
	;

object_privilege_list:
	  object_privilege
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("object_privilege_list", "", p);
	  }
	| object_privilege_list ',' object_privilege
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("object_privilege_list", "", p);
	  }
	;

object_privilege:
	  SELECT_SYM opt_column_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("select", "select"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| INSERT opt_column_list 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("insert", "insert"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| UPDATE_SYM opt_column_list 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("update", "update"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| REFERENCES opt_column_list 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("references", "references"));
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| DELETE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("delete", "delete"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| USAGE		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("usage", "usage"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| INDEX_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("index", "index"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| ALTER
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("alter", "alter"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| CREATE	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| DROP
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("drop", "drop"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| EXECUTE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("execute", "execute"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| RELOAD	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("reload", "reload"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| SHUTDOWN	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("shutdown", "shutdown"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| PROCESS	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("process", "process"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| FILE_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("file", "file"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| GRANT OPTION  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("grant", "grant"));
	    tree_item_list_add(p, new_simple_tree_item("option", "option"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| SHOW DATABASES 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("show", "show"));
	    tree_item_list_add(p, new_simple_tree_item("databases", "databases"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| SUPER_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("super", "super"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| CREATE TEMPORARY TABLES 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("temporary", "temporary"));
	    tree_item_list_add(p, new_simple_tree_item("tables", "tables"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| LOCK_SYM TABLES   
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("lock", "lock"));
	    tree_item_list_add(p, new_simple_tree_item("tables", "tables"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| REPLICATION SLAVE  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("replication", "replication"));
	    tree_item_list_add(p, new_simple_tree_item("slave", "slave"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| REPLICATION CLIENT_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("replication", "replication"));
	    tree_item_list_add(p, new_simple_tree_item("client", "client"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| CREATE VIEW_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("view", "view"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| SHOW VIEW_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("show", "show"));
	    tree_item_list_add(p, new_simple_tree_item("view", "view"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| CREATE ROUTINE_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("routine", "routine"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| ALTER ROUTINE_SYM 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("alter", "alter"));
	    tree_item_list_add(p, new_simple_tree_item("routine", "routine"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	| CREATE USER 
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("create", "create"));
	    tree_item_list_add(p, new_simple_tree_item("user", "user"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
    | EVENT_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "EVENT_SYM"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
    | TRIGGER_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "TRIGGER_SYM"));
	    $$= new_tree_item("object_privilege", "", p);
	  }
	;


opt_and:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| AND_SYM	
	  {
	    $$= new_simple_tree_item("and", "and");
	  }
	;

require_list:
	  require_list_element opt_and require_list
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    tree_item_list_add_all(p, $3);
	    delete_tree_item($3);
	    $$= new_tree_item("require_list", "", p);
	  }
  | require_list_element
    {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("require_list", "", p);
    }
  ;

require_list_element:
	  SUBJECT_SYM TEXT_STRING
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("subject", "subject"));
	    tree_item_list_add(p, new_simple_tree_item("string", "string"));
	    $$= new_tree_item("require_list_element", "", p);
    }
	| ISSUER_SYM TEXT_STRING
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("issuer", "issuer"));
	    tree_item_list_add(p, new_simple_tree_item("string", "string"));
	    $$= new_tree_item("require_list_element", "", p);
    }
	| CIPHER_SYM TEXT_STRING
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("cipher", "cipher"));
	    tree_item_list_add(p, new_simple_tree_item("string", "string"));
	    $$= new_tree_item("require_list_element", "", p);
    }
	;

grant_ident:
	  '*'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    $$= new_tree_item("grant_ident", "", p);
    }
	| ident '.' '*'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    $$= new_tree_item("grant_ident", "", p);
    }
	| '*' '.' '*'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    tree_item_list_add(p, new_simple_tree_item(".", "."));
	    tree_item_list_add(p, new_simple_tree_item("*", "*"));
	    $$= new_tree_item("grant_ident", "", p);
    }
	| table_ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("grant_ident", "", p);
    }
  ;

user_list:
	  user  
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("user_list", "", p);
	  }
	| user_list ',' user
	  {
	    void *p= new_tree_item_list_reuse($1);
	    delete_tree_item($1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("user_list", "", p);
    }
	;

grant_list:
	  grant_user  
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("grant_list", "", p);
	  }
	| grant_list ',' grant_user
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);
      $$= new_tree_item("grant_list", "", p);
    }
	;

grant_user:
	  user IDENTIFIED_SYM BY TEXT_STRING
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("identified", "identified"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, set_item_name($4, "string"));
      $$= new_tree_item("grant_user", "", p);
    }
	| user IDENTIFIED_SYM BY PASSWORD TEXT_STRING
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("identified", "identified"));
      tree_item_list_add(p, new_simple_tree_item("by", "by"));
      tree_item_list_add(p, new_simple_tree_item("password", "password"));
      tree_item_list_add(p, set_item_name($4, "string"));
      $$= new_tree_item("grant_user", "", p);
	  }
	| user
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("grant_user", "", p);
	  }
  ;

opt_column_list:
	  /* empty */
	  {
      $$= NULL;
    }
	| '(' column_list ')'
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("lp", "("));
      tree_item_list_add(p, $1);
      tree_item_list_add(p, new_simple_tree_item("rp", ")"));
      $$= new_tree_item("opt_column_list", "", p);
	  }
	;

column_list:
	  column_list ',' column_list_id
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, new_simple_tree_item(",", ","));
      tree_item_list_add(p, $3);      
      $$= new_tree_item("column_list", "", p);
	  }
	| column_list_id
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("column_list", "", p);
	  }
	;

column_list_id:
	  ident
	  {
      $$= $1;
    }
  ;


require_clause: 
    /* empty */
    {
      $$= NULL;
    }
  | REQUIRE_SYM require_list
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("require", "require"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("require_clause", "", p);
    }
  | REQUIRE_SYM SSL_SYM
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("require", "require"));
      tree_item_list_add(p, new_simple_tree_item("ssl", "ssl"));
      $$= new_tree_item("require_clause", "", p);
    }
  | REQUIRE_SYM X509_SYM
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("require", "require"));
      tree_item_list_add(p, new_simple_tree_item("x509", "x509"));
      $$= new_tree_item("require_clause", "", p);
    }
	| REQUIRE_SYM NONE_SYM
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("require", "require"));
      tree_item_list_add(p, new_simple_tree_item("none", "none"));
      $$= new_tree_item("require_clause", "", p);
    }
  ;

grant_options:
	  /* empty */ 
	  {
      $$= NULL;
	  }
	| WITH grant_option_list
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("with", "with"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("grant_options", "", p);
	  }
	;

grant_option_list:
	  grant_option_list grant_option 
	  {
      void *p= new_tree_item_list_reuse($1);
      delete_tree_item($1);
      tree_item_list_add(p, $2);
      $$= new_tree_item("grant_option_list", "", p);
	  }
	| grant_option 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $1);
      $$= new_tree_item("grant_option_list", "", p);
	  }
  ;

grant_option:
	  GRANT OPTION 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("grant", "grant"));
      tree_item_list_add(p, new_simple_tree_item("option", "option"));
      $$= new_tree_item("grant_option_list", "", p);
	  }
  | MAX_QUERIES_PER_HOUR ulong_num
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("max_queries_per_hour", "max_queries_per_hour"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("grant_option_list", "", p);
	  }
  | MAX_UPDATES_PER_HOUR ulong_num
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("max_updates_per_hour", "max_updates_per_hour"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("grant_option_list", "", p);
	  }
  | MAX_CONNECTIONS_PER_HOUR ulong_num
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("max_connections_per_hour", "max_connections_per_hour"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("grant_option_list", "", p);
	  }
  | MAX_USER_CONNECTIONS_SYM ulong_num
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("max_user_connections", "max_user_connections"));
      tree_item_list_add(p, $2);
      $$= new_tree_item("grant_option_list", "", p);
	  }
  ;

begin:
	  BEGIN_SYM opt_work 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("begin", "begin"));
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      $$= new_tree_item("begin", "", p);
	  }
	;

opt_work:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| WORK_SYM  
	  {
	    $$= new_simple_tree_item("work", "work");
	  }
  ;

opt_chain:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| AND_SYM NO_SYM CHAIN_SYM	
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("and", "and"));
	    tree_item_list_add(p, new_simple_tree_item("no", "no"));
	    tree_item_list_add(p, new_simple_tree_item("chain", "chain"));
	    $$= new_tree_item("opt_chain", "", p);
	  }
	| AND_SYM CHAIN_SYM		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("and", "and"));
	    tree_item_list_add(p, new_simple_tree_item("chain", "chain"));
	    $$= new_tree_item("opt_chain", "", p);
	  }
	;

opt_release:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	| RELEASE_SYM 			
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("release", "release"));
	    $$= new_tree_item("opt_release", "", p);
	  }
	| NO_SYM RELEASE_SYM 		
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("no", "no"));
	    tree_item_list_add(p, new_simple_tree_item("release", "release"));
	    $$= new_tree_item("opt_release", "", p);
	  }
	;
	
opt_savepoint:
	  /* empty */	
	  {
	    $$= NULL;
	  }
	| SAVEPOINT_SYM 
	  {
	    $$= new_simple_tree_item("savepoint", "savepoint");
	  }
	;

commit:
	  COMMIT_SYM opt_work opt_chain opt_release
	  {
      void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      $$= new_tree_item("commit", "", p);
    }
	;

rollback:
  	ROLLBACK_SYM opt_work opt_chain opt_release
	  {
      void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      if($3 != NULL)
      {
        tree_item_list_add(p, $3);
      }
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      $$= new_tree_item("rollback", "", p);
    }
	| ROLLBACK_SYM opt_work TO_SYM opt_savepoint ident
	  {
      void *p= new_tree_item_list();
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      tree_item_list_add(p, new_simple_tree_item("to", "to"));
      if($4 != NULL)
      {
        tree_item_list_add(p, $4);
      }
      tree_item_list_add(p, $5);
      $$= new_tree_item("rollback", "", p);
    }
	;

savepoint:
	  SAVEPOINT_SYM ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, $2);
      $$= new_tree_item("savepoint", "", p);
    }
	;

release:
	  RELEASE_SYM SAVEPOINT_SYM ident
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("savepoint", "savepoint"));
      tree_item_list_add(p, $3);
      $$= new_tree_item("release", "", p);
    }
	;
  
/*
   UNIONS : glue selects together
*/


union_clause:
	/* empty */ 
	  {
	    $$= NULL;
	  }
	| union_list
	  {
	    $$= $1;	    
	  }
	;

union_list:
	  UNION_SYM union_option select_init 
	  {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("union", "union"));
      tree_item_list_add(p, $2);
      tree_item_list_add(p, $3);
      $$= new_tree_item("union_list", "", p);
    }
	;

union_opt:
	  /* Empty */ 
	  {
	    $$= NULL;
	  }
	| union_list 
	  {
	    $$= $1;
	  }
	| union_order_or_limit 
	  {
	    $$= $1;
	  }
	;

union_order_or_limit:
	  order_or_limit
    {
      $$= $1;
    }
	;

order_or_limit:
	  order_clause opt_limit_clause_init
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    if($2 != NULL)
	    {
	      tree_item_list_add(p, $2);
	    }
	    $$= new_tree_item("order_or_limit", "", p);
	  }
	| limit_clause
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("order_or_limit", "", p);
	  }
	;

union_option:
	/* empty */ 
	  {
	    $$= NULL;
	  }
	| DISTINCT  
	  {
	    $$= new_simple_tree_item("distinct", "distinct");
	  }
	| ALL
	  {
	    $$= new_simple_tree_item("distinct", "all");
	  }
  ;

subselect:
      SELECT_SYM subselect_start subselect_init subselect_end
      {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "SELECT_SYM"));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, $4);
        $$= new_tree_item("subselect", "", p);
      }
    | '(' subselect_start subselect ')' union_clause subselect_end { $$= NULL; }
      {
	    void *p= new_tree_item_list();
        tree_item_list_add(p, set_item_name($1, "("));
        tree_item_list_add(p, $2);
        tree_item_list_add(p, $3);
        tree_item_list_add(p, set_item_name($4, ")"));
        tree_item_list_add(p, $5);
        tree_item_list_add(p, $6);
        $$= new_tree_item("subselect", "", p);
      }
    ;

subselect_init:
    select_init2
    {
	    void *p= new_tree_item_list_reuse($1); 
	    delete_tree_item($1);
	    $$= new_tree_item("subselect_init", "", p);
    }
  ;

subselect_start:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	;

subselect_end:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
	;

view_or_trigger_or_sp_or_event:
      definer view_or_trigger_or_sp_or_event_tail
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    $$= new_tree_item("view_or_trigger_or_sp_or_event", "", p);
	  }
    | view_replace_or_algorithm definer view_tail
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("view_or_trigger_or_sp_or_event", "", p);
	  }
    ;

view_or_trigger_or_sp_or_event_tail:
      view_tail
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_or_trigger_or_sp_or_event_tail", "", p);
	  }
    | trigger_tail
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_or_trigger_or_sp_or_event_tail", "", p);
	  }
    | sp_tail
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_or_trigger_or_sp_or_event_tail", "", p);
	  }
    | event_tail
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_or_trigger_or_sp_or_event_tail", "", p);
	  }
    ;
    
definer:
	  /* empty */ 
	  {
	    $$= NULL;
	  }
    | DEFINER_SYM EQ user
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "DEFINER_SYM"));
	    tree_item_list_add(p, set_item_name($2, "EQ"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("definer", "", p);
	  }
    ;

view_replace_or_algorithm:
      view_replace
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_replace_or_algorithm", "", p);
	  }
    | view_replace view_algorithm
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_replace_or_algorithm", "", p);
	  }
    | view_algorithm
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_replace_or_algorithm", "", p);
	  }
    ;

view_replace:
      OR_SYM REPLACE
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "OR_SYM"));
	    tree_item_list_add(p, set_item_name($2, "REPLACE"));
	    $$= new_tree_item("view_replace", "", p);
	  }
    ;

view_algorithm:
	ALGORITHM_SYM EQ UNDEFINED_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("algorithm", "algorithm"));
	    tree_item_list_add(p, new_simple_tree_item("eq", "="));
	    tree_item_list_add(p, new_simple_tree_item("undefined", "undefined"));
	    $$= new_tree_item("algorithm", "", p);
	  }
	| ALGORITHM_SYM EQ MERGE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("algorithm", "algorithm"));
	    tree_item_list_add(p, new_simple_tree_item("eq", "="));
	    tree_item_list_add(p, new_simple_tree_item("merge", "merge"));
	    $$= new_tree_item("algorithm", "", p);
	  }
	| ALGORITHM_SYM EQ TEMPTABLE_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("algorithm", "algorithm"));
	    tree_item_list_add(p, new_simple_tree_item("eq", "="));
	    tree_item_list_add(p, new_simple_tree_item("temptable", "temptable"));
	    $$= new_tree_item("algorithm", "", p);
	  }
	;

view_suid:
    /* empty */
	  {
	    $$= NULL;
	  }
  | SQL_SYM SECURITY_SYM DEFINER_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    tree_item_list_add(p, new_simple_tree_item("security", "security"));
	    tree_item_list_add(p, new_simple_tree_item("definer", "definer"));
	    $$= new_tree_item("view_suid", "", p);
	  }
	| SQL_SYM SECURITY_SYM INVOKER_SYM
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("sql", "sql"));
	    tree_item_list_add(p, new_simple_tree_item("security", "security"));
	    tree_item_list_add(p, new_simple_tree_item("invoker", "invoker"));
	    $$= new_tree_item("view_suid", "", p);
	  }
	;

view_tail:
      view_suid VIEW_SYM table_ident view_list_opt AS view_select view_check_option
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, set_item_name($2, "VIEW_SYM"));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, set_item_name($5, "AS"));
	    tree_item_list_add(p, $6);
	    tree_item_list_add(p, $7);
	    $$= new_tree_item("view_tail", "", p);
	  }
    ;
    
view_list_opt:
  /* empty */
    {
      $$= NULL;
    }
    | '(' view_list ')'
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "("));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, set_item_name($3, ")"));
	    $$= new_tree_item("view_list_opt", "", p);
	  }
    ;
    
view_list:
      ident
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_list", "", p);
	  }
    | view_list ',' ident
	  {
        void *p= new_tree_item_list_reuse($1);
        delete_tree_item($1);
	    tree_item_list_add(p, set_item_name($2, ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("view_list_opt", "", p);
	  }
    ;
    
view_select:
      view_select_aux
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("view_select", "", p);
	  }
    ;

view_select_aux:
      SELECT_SYM remember_name select_init2
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "SELECT_SYM"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("view_select_aux", "", p);
	  }
    | '(' remember_name select_paren ')' union_opt
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "("));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, ")"));
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("view_select_aux", "", p);
	  }
    ;
    
view_check_option:
  /* empty */
    {
      $$= NULL;
    }
  | WITH CHECK_SYM OPTION
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("with", "with"));
	    tree_item_list_add(p, new_simple_tree_item("check", "check"));
	    tree_item_list_add(p, new_simple_tree_item("option", "option"));
	    $$= new_tree_item("check_option", "", p);
    }
  | WITH CASCADED CHECK_SYM OPTION
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("with", "with"));
	    tree_item_list_add(p, new_simple_tree_item("cascaded", "cascaded"));
	    tree_item_list_add(p, new_simple_tree_item("check", "check"));
	    tree_item_list_add(p, new_simple_tree_item("option", "option"));
	    $$= new_tree_item("check_option", "", p);
    }
  | WITH LOCAL_SYM CHECK_SYM OPTION
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("with", "with"));
	    tree_item_list_add(p, new_simple_tree_item("local", "local"));
	    tree_item_list_add(p, new_simple_tree_item("check", "check"));
	    tree_item_list_add(p, new_simple_tree_item("option", "option"));
	    $$= new_tree_item("check_option", "", p);
    }
  ;

trigger_tail:
      TRIGGER_SYM remember_name sp_name trg_action_time trg_event ON remember_name table_ident FOR_SYM remember_name EACH_SYM ROW_SYM sp_proc_stmt
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "("));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, ")"));
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("trigger_tail", "", p);
	  }
    ;

sp_tail:
      udf_func_type remember_name FUNCTION_SYM sp_name create_function_tail
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, set_item_name($3, "FUNCTION"));
	    tree_item_list_add(p, $4);
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("sp_tail", "", p);
	  }
    | PROCEDURE remember_name sp_name '(' sp_pdparam_list ')' sp_c_chistics sp_proc_stmt
	  {
	    void *p= new_tree_item_list();
	    tree_item_list_add(p, set_item_name($1, "PROCEDURE"));
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, set_item_name($4, "("));
	    tree_item_list_add(p, $5);
	    tree_item_list_add(p, set_item_name($6, ")"));
	    tree_item_list_add(p, $7);
	    tree_item_list_add(p, $8);
	    $$= new_tree_item("sp_tail", "", p);
	  }
    ;
    
xa: 
    XA_SYM begin_or_start xid opt_join_or_resume
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, $2);
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("xa", "", p);
    }
  | XA_SYM END xid opt_suspend
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("end", "end"));
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("xa", "", p);
    }
  | XA_SYM PREPARE_SYM xid
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("prepare", "prepare"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("xa", "", p);
    }
  | XA_SYM COMMIT_SYM xid opt_one_phase
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("commit", "commit"));
	    tree_item_list_add(p, $3);
	    if($4 != NULL)
	    {
	      tree_item_list_add(p, $4);
	    }
	    $$= new_tree_item("xa", "", p);
    }
  | XA_SYM ROLLBACK_SYM xid
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("rollback", "rollback"));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("xa", "", p);
    }
  | XA_SYM RECOVER_SYM
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, new_simple_tree_item("recover", "recover"));
	    $$= new_tree_item("xa", "", p);
    }
  ;

xid: 
    text_string
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    $$= new_tree_item("xid", "", p);
    }
  | text_string ',' text_string
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    $$= new_tree_item("xid", "", p);
    }
  | text_string ',' text_string ',' ulong_num
    {
      void *p= new_tree_item_list();
	    tree_item_list_add(p, $1);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $3);
	    tree_item_list_add(p, new_simple_tree_item(",", ","));
	    tree_item_list_add(p, $5);
	    $$= new_tree_item("xid", "", p);
    }
  ;

begin_or_start:   
    BEGIN_SYM 
    {
      $$= new_simple_tree_item("begin", "begin");
    }
  | START_SYM 
    {
      $$= new_simple_tree_item("start", "start");
    }
  ;

opt_join_or_resume:
    /* nothing */           
    {
      $$= NULL;
    }
  | JOIN_SYM              
    {
      $$= new_simple_tree_item("join", "join");
    }
  | RESUME_SYM            
    {
      $$= new_simple_tree_item("resume", "resume");
    }
  ;

opt_one_phase:
    /* nothing */           
    {
      $$= NULL;
    }
  | ONE_SYM PHASE_SYM     
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("one", "one"));
      tree_item_list_add(p, new_simple_tree_item("phase", "phase"));
      $$= new_tree_item("opt_one_phase", "", p);
    }
  ;

opt_suspend:
    /* nothing */           
    {
      $$= NULL;
    }
  | SUSPEND_SYM opt_migrate
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("suspend", "suspend"));
      if($2 != NULL)
      {
        tree_item_list_add(p, $2);
      }
      $$= new_tree_item("opt_suspend", "", p);
    }
  ;

opt_migrate:
    /* nothing */           
    {
      $$= NULL;
    }
  | FOR_SYM MIGRATE_SYM   
    {
      void *p= new_tree_item_list();
      tree_item_list_add(p, new_simple_tree_item("for", "for"));
      tree_item_list_add(p, new_simple_tree_item("migrate", "migrate"));
      $$= new_tree_item("opt_suspend", "", p);
    }
  ;

install:
      INSTALL_SYM PLUGIN_SYM ident SONAME_SYM TEXT_STRING_sys { $$= NULL; }
    ;

uninstall:
      UNINSTALL_SYM PLUGIN_SYM ident { $$= NULL; }
    ;
