diff --git a/Makefile.am b/Makefile.am
index 21d070a3416..6d435bff85a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -41,14 +41,6 @@ BUILT_SOURCES = linked_client_sources linked_server_sources \
CLEANFILES = $(BUILT_SOURCES)
DISTCLEANFILES = ac_available_languages_fragment
-# Our current filtering of "sql_yacc.cc" in "sql/Makefile.am" creates
-# a problem, if a VPATH build and "sql_yacc.cc" was part of the source
-# distribution we end up with one "sql_yacc.cc" in the source tree,
-# and one in the build tree. This breaks "distcleancheck", until this
-# is sorted out we redefine the find that scans for files not removed
-
-distcleancheck_listfiles = find . -name sql_yacc.cc -o -type f -print
-
linked_include_sources:
cd include; $(MAKE) link_sources
echo timestamp > linked_include_sources
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 6cb9467c32c..264b469cd8c 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -121,13 +121,14 @@ DEFS = -DMYSQL_SERVER \
-DLIBDIR="\"$(MYSQLLIBdir)\"" \
@DEFS@
-BUILT_DIST_SRC = sql_yacc.cc sql_yacc.h
-BUILT_SOURCES = $(BUILT_DIST_SRC) lex_hash.h
-EXTRA_DIST = udf_example.c udf_example.def $(BUILT_DIST_SRC) \
+BUILT_MAINT_SRC = sql_yacc.cc sql_yacc.h
+BUILT_SOURCES = $(BUILT_MAINT_SRC) lex_hash.h
+EXTRA_DIST = udf_example.c udf_example.def $(BUILT_MAINT_SRC) \
nt_servc.cc nt_servc.h message.mc CMakeLists.txt \
udf_example.c udf_example.def
-CLEANFILES = lex_hash.h sql_yacc.cc sql_yacc.h sql_yacc.output
-AM_YFLAGS = -d --debug --verbose
+CLEANFILES = lex_hash.h sql_yacc.output
+MAINTAINERCLEANFILES = $(BUILT_MAINT_SRC)
+AM_YFLAGS = -d --verbose
mysql_tzinfo_to_sql.cc:
rm -f mysql_tzinfo_to_sql.cc
@@ -148,23 +149,6 @@ link_sources: mysql_tzinfo_to_sql.cc
mysql_tzinfo_to_sql.o: $(mysql_tzinfo_to_sql_SOURCES)
$(CXXCOMPILE) -c $(INCLUDES) -DTZINFO2SQL $<
-# Try to get better dependencies for the grammar. Othervise really bad
-# things like different grammars for different pars of MySQL can
-# happen if you are unlucky.
-sql_yacc.cc: sql_yacc.yy
-
-sql_yacc.h: sql_yacc.yy
-
-# Be careful here, note that we use VPATH and might or might not have
-# a pregenerated "sql_yacc.cc" in $(srcdir) or one we just built in
-# $(builddir). And it has to work if $(srcdir) == $(builddir).
-sql_yacc.o: sql_yacc.cc sql_yacc.h $(HEADERS)
- @SED@ -e 's/__attribute__ ((__unused__))//' $< > sql_yacc.cc-new
- @MV@ sql_yacc.cc-new sql_yacc.cc
- @echo "Note: The following compile may take a long time."
- @echo "If it fails, re-run configure with --with-low-memory"
- $(CXXCOMPILE) $(LM_CFLAGS) -c sql_yacc.cc
-
# FIXME seems like now "lex_hash.h" differs depending on configure
# flags, so can't pregenerate and include in source TAR. Revert to
# dist pregenerated if this changes, so the file doesn't differ.
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 3755f6d3b67..eb8641f011f 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -54,6 +54,28 @@ const LEX_STRING null_lex_str={0,0};
YYABORT; \
}
+/*
+ Work around for broken code generated by bison 1.875.
+
+ The code generated by bison 1.875a and later, bison 2.1 and bison 2.2 is ok.
+ With bison 1.875 however, the generated code contains:
+
+ yyerrlab1:
+ #if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__)
+ __attribute__ ((__unused__))
+ #endif
+
+ This usage of __attribute__ is illegal, so we remove it.
+ See the following references for details:
+ http://lists.gnu.org/archive/html/bug-bison/2004-02/msg00014.html
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14273
+*/
+
+#if defined (__GNUC_MINOR__) && 2093 <= (__GNUC__ * 1000 + __GNUC_MINOR__)
+#undef __attribute__
+#define __attribute__(X)
+#endif
+
/* Helper for parsing "IS [NOT] truth_value" */
inline Item *is_truth_value(THD *thd, Item *A, bool v1, bool v2)
{
diff --git a/sql/sql_yacc.yy.bak b/sql/sql_yacc.yy.bak
deleted file mode 100644
index 574a4ec639b..00000000000
--- a/sql/sql_yacc.yy.bak
+++ /dev/null
@@ -1,11278 +0,0 @@
-/* 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 */
-
-%{
-/* thd is passed as an arg to yyparse(), and subsequently to yylex().
-** The type will be void*, so it must be cast to (THD*) when used.
-** Use the YYTHD macro for this.
-*/
-#define YYPARSE_PARAM yythd
-#define YYLEX_PARAM yythd
-#define YYTHD ((THD *)yythd)
-
-#define MYSQL_YACC
-#define YYINITDEPTH 100
-#define YYMAXDEPTH 3200 /* Because of 64K stack */
-#define Lex (YYTHD->lex)
-#define Select Lex->current_select
-#include "mysql_priv.h"
-#include "slave.h"
-#include "lex_symbol.h"
-#include "item_create.h"
-#include "sp_head.h"
-#include "sp_pcontext.h"
-#include "sp_rcontext.h"
-#include "sp.h"
-#include "event_data_objects.h"
-#include
-#include
-
-int yylex(void *yylval, void *yythd);
-
-const LEX_STRING null_lex_str={0,0};
-
-#define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if (my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }}
-
-#define YYERROR_UNLESS(A) \
- if (!(A)) \
- { \
- yyerror(ER(ER_SYNTAX_ERROR)); \
- YYABORT; \
- }
-
-/* Helper for parsing "IS [NOT] truth_value" */
-inline Item *is_truth_value(THD *thd, Item *A, bool v1, bool v2)
-{
- Item *v1_t= new (thd->mem_root) Item_int((char *) (v1 ? "TRUE" : "FALSE"),
- v1, 1);
- Item *v1_f= new (thd->mem_root) Item_int((char *) (v1 ? "FALSE" : "TRUE"),
- !v1, 1);
- Item *v2_t= new (thd->mem_root) Item_int((char *) (v2 ? "TRUE" : "FALSE"),
- v2, 1);
- Item *ifnull= new (thd->mem_root) Item_func_ifnull(A, v2_t);
-
- return new (thd->mem_root) Item_func_if(ifnull, v1_t, v1_f);
-}
-
-#ifndef DBUG_OFF
-#define YYDEBUG 1
-#else
-#define YYDEBUG 0
-#endif
-
-#ifndef DBUG_OFF
-void turn_parser_debug_on()
-{
- /*
- MYSQLdebug is in sql/sql_yacc.cc, in bison generated code.
- Turning this option on is **VERY** verbose, and should be
- used when investigating a syntax error problem only.
-
- The syntax to run with bison traces is as follows :
- - Starting a server manually :
- mysqld --debug="d,parser_debug" ...
- - Running a test :
- mysql-test-run.pl --mysqld="--debug=d,parser_debug" ...
-
- The result will be in the process stderr (var/log/master.err)
- */
-
- extern int yydebug;
- yydebug= 1;
-}
-#endif
-
-static bool is_native_function(THD *thd, const LEX_STRING *name)
-{
- if (find_native_function_builder(thd, *name))
- return true;
-
- if (is_lex_native_function(name))
- return true;
-
- return false;
-}
-
-%}
-%union {
- int num;
- ulong ulong_num;
- ulonglong ulonglong_number;
- longlong longlong_number;
- LEX_STRING lex_str;
- LEX_STRING *lex_str_ptr;
- LEX_SYMBOL symbol;
- Table_ident *table;
- char *simple_string;
- Item *item;
- Item_num *item_num;
- List- *item_list;
- List *string_list;
- String *string;
- key_part_spec *key_part;
- TABLE_LIST *table_list;
- udf_func *udf;
- LEX_USER *lex_user;
- struct sys_var_with_base variable;
- enum enum_var_type var_type;
- Key::Keytype key_type;
- enum ha_key_alg key_alg;
- handlerton *db_type;
- enum row_type row_type;
- enum ha_rkey_function ha_rkey_mode;
- enum enum_tx_isolation tx_isolation;
- enum Cast_target cast_type;
- enum Item_udftype udf_type;
- CHARSET_INFO *charset;
- thr_lock_type lock_type;
- interval_type interval, interval_time_st;
- timestamp_type date_time_type;
- st_select_lex *select_lex;
- chooser_compare_func_creator boolfunc2creator;
- struct sp_cond_type *spcondtype;
- struct { int vars, conds, hndlrs, curs; } spblock;
- sp_name *spname;
- struct st_lex *lex;
- sp_head *sphead;
- struct p_elem_val *p_elem_value;
-}
-
-%{
-bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
-%}
-
-%pure_parser /* We have threads */
-
-/*
- 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 /* SQL-2003-R */
-%token GROUP_CONCAT_SYM
-%token GROUP_UNIQUE_USERS
-%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_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 UNIQUE_USERS
-%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
-
-%type
- IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM
- LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text
- UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal
- NCHAR_STRING opt_component key_cache_name
- sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
-
-%type
- opt_table_alias
-
-%type
- table_ident table_ident_nodb references xid
-
-%type
- remember_name remember_end opt_ident opt_db text_or_password
- opt_constraint constraint
-
-%type
- text_string opt_gconcat_separator
-
-%type
- type int_type real_type order_dir lock_option
- udf_type if_exists opt_local opt_table_options table_options
- table_option opt_if_not_exists opt_no_write_to_binlog
- delete_option opt_temporary all_or_any opt_distinct
- opt_ignore_leaves fulltext_options spatial_type union_option
- start_transaction_opts opt_chain opt_release
- union_opt select_derived_init option_type2
- opt_natural_language_mode opt_query_expansion
- opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment
- ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt
-
-%type
- ulong_num real_ulong_num merge_insert_types
-
-%type
- ulonglong_num real_ulonglong_num size_number
-
-%type
- part_bit_expr
-
-%type
- replace_lock_option opt_low_priority insert_lock_option load_data_lock
-
-%type -
- literal text_literal insert_ident order_ident
- simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
- variable variable_aux bool_term bool_factor bool_test bool_pri
- predicate bit_expr bit_term bit_factor value_expr term factor
- table_wild simple_expr udf_expr
- expr_or_default set_expr_or_default interval_expr
- param_marker geometry_function
- signed_literal now_or_signed_literal opt_escape
- sp_opt_default
- simple_ident_nospvar simple_ident_q
- field_or_var limit_option
- part_func_expr
- function_call_keyword
- function_call_nonkeyword
- function_call_generic
- function_call_conflict
-
-%type
- NUM_literal
-
-%type
- expr_list udf_expr_list udf_expr_list2 when_list
- ident_list ident_list_arg opt_expr_list
-
-%type
- option_type opt_var_type opt_var_ident_type
-
-%type
- key_type opt_unique_or_fulltext constraint_key_type
-
-%type
- btree_or_rtree
-
-%type
- key_usage_list using_list
-
-%type
- key_part
-
-%type
- join_table_list join_table
- table_factor table_ref
- select_derived derived_table_list
-
-%type date_time_type;
-%type interval
-
-%type interval_time_st
-
-%type storage_engines
-
-%type row_types
-
-%type isolation_types
-
-%type handler_rkey_mode
-
-%type cast_type
-
-%type udf_func_type
-
-%type keyword keyword_sp
-
-%type user grant_user
-
-%type
- opt_collate
- charset_name
- charset_name_or_default
- old_or_new_charset_name
- old_or_new_charset_name_or_default
- collation_name
- collation_name_or_default
-
-%type internal_variable_name
-
-%type subselect subselect_init
- get_select_lex
-
-%type comp_op
-
-%type
- query verb_clause create change select do drop insert replace insert2
- insert_values update delete truncate rename
- show describe load alter optimize keycache preload flush
- reset purge begin commit rollback savepoint release
- slave master_def master_defs master_file_def slave_until_opts
- repair restore backup analyze check start checksum
- field_list field_list_item field_spec kill column_def key_def
- keycache_list assign_to_keycache preload_list preload_keys
- select_item_list select_item values_list no_braces
- opt_limit_clause delete_limit_clause fields opt_values values
- procedure_list procedure_list2 procedure_item
- when_list2 expr_list2 udf_expr_list3 handler
- opt_precision opt_ignore opt_column opt_restrict
- grant revoke set lock unlock string_list field_options field_option
- field_opt_list opt_binary table_lock_list table_lock
- ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use
- opt_delete_options opt_delete_option varchar nchar nvarchar
- opt_outer table_list table_name opt_option opt_place
- opt_attribute opt_attribute_list attribute column_list column_list_id
- opt_column_list grant_privileges grant_ident grant_list grant_option
- object_privilege object_privilege_list user_list rename_list
- clear_privileges flush_options flush_option
- equal optional_braces opt_key_definition key_usage_list2
- opt_mi_check_type opt_to mi_check_types normal_join
- db_to_db table_to_table_list table_to_table opt_table_list opt_as
- handler_rkey_function handler_read_or_scan
- single_multi table_wild_list table_wild_one opt_wild
- union_clause union_list
- precision subselect_start opt_and charset
- subselect_end select_var_list select_var_list_init help opt_len
- opt_extended_describe
- prepare prepare_src execute deallocate
- statement sp_suid
- sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa
- load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec
- definer view_replace_or_algorithm view_replace view_algorithm_opt
- view_algorithm view_or_trigger_or_sp_or_event
- view_or_trigger_or_sp_or_event_tail
- view_suid view_tail view_list_opt view_list view_select
- view_check_option trigger_tail sp_tail
- install uninstall partition_entry binlog_base64_event
- init_key_options key_options key_opts key_opt key_using_alg
- server_def server_options_list server_option
-END_OF_INPUT
-
-%type call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt
-%type sp_proc_stmt_statement sp_proc_stmt_return
-%type sp_proc_stmt_if sp_proc_stmt_case_simple sp_proc_stmt_case
-%type sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave
-%type sp_proc_stmt_iterate
-%type sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close
-
-%type sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list
-%type sp_cond sp_hcond
-%type sp_decls sp_decl
-%type sp_cursor_stmt
-%type sp_name
-
-%type
- '-' '+' '*' '/' '%' '(' ')'
- ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM
- THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM
-%%
-
-
-query:
- END_OF_INPUT
- {
- THD *thd= YYTHD;
- if (!thd->bootstrap &&
- (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT)))
- {
- my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0));
- YYABORT;
- }
- else
- {
- thd->lex->sql_command= SQLCOM_EMPTY_QUERY;
- }
- }
- | verb_clause END_OF_INPUT {};
-
-verb_clause:
- statement
- | begin
- ;
-
-/* Verb clauses, except begin */
-statement:
- alter
- | analyze
- | backup
- | binlog_base64_event
- | call
- | change
- | check
- | checksum
- | commit
- | create
- | deallocate
- | delete
- | describe
- | do
- | drop
- | execute
- | flush
- | grant
- | handler
- | help
- | insert
- | install
- | kill
- | load
- | lock
- | optimize
- | keycache
- | partition_entry
- | preload
- | prepare
- | purge
- | release
- | rename
- | repair
- | replace
- | reset
- | restore
- | revoke
- | rollback
- | savepoint
- | select
- | set
- | show
- | slave
- | start
- | truncate
- | uninstall
- | unlock
- | update
- | use
- | xa
- ;
-
-deallocate:
- deallocate_or_drop PREPARE_SYM ident
- {
- THD *thd=YYTHD;
- LEX *lex= thd->lex;
- if (lex->stmt_prepare_mode)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- lex->sql_command= SQLCOM_DEALLOCATE_PREPARE;
- lex->prepared_stmt_name= $3;
- };
-
-deallocate_or_drop:
- DEALLOCATE_SYM |
- DROP
- ;
-
-
-prepare:
- PREPARE_SYM ident FROM prepare_src
- {
- THD *thd=YYTHD;
- LEX *lex= thd->lex;
- if (lex->stmt_prepare_mode)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- lex->sql_command= SQLCOM_PREPARE;
- lex->prepared_stmt_name= $2;
- };
-
-prepare_src:
- TEXT_STRING_sys
- {
- THD *thd=YYTHD;
- LEX *lex= thd->lex;
- lex->prepared_stmt_code= $1;
- lex->prepared_stmt_code_is_varref= FALSE;
- }
- | '@' ident_or_text
- {
- THD *thd=YYTHD;
- LEX *lex= thd->lex;
- lex->prepared_stmt_code= $2;
- lex->prepared_stmt_code_is_varref= TRUE;
- };
-
-execute:
- EXECUTE_SYM ident
- {
- THD *thd=YYTHD;
- LEX *lex= thd->lex;
- if (lex->stmt_prepare_mode)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- lex->sql_command= SQLCOM_EXECUTE;
- lex->prepared_stmt_name= $2;
- }
- execute_using
- {}
- ;
-
-execute_using:
- /* nothing */
- | USING execute_var_list
- ;
-
-execute_var_list:
- execute_var_list ',' execute_var_ident
- | execute_var_ident
- ;
-
-execute_var_ident: '@' ident_or_text
- {
- LEX *lex=Lex;
- LEX_STRING *lexstr= (LEX_STRING*)sql_memdup(&$2, sizeof(LEX_STRING));
- if (!lexstr || lex->prepared_stmt_params.push_back(lexstr))
- YYABORT;
- }
- ;
-
-/* help */
-
-help:
- HELP_SYM
- {
- if (Lex->sphead)
- {
- my_error(ER_SP_BADSTATEMENT, MYF(0), "HELP");
- YYABORT;
- }
- }
- ident_or_text
- {
- LEX *lex= Lex;
- lex->sql_command= SQLCOM_HELP;
- lex->help_arg= $3.str;
- };
-
-/* change master */
-
-change:
- CHANGE MASTER_SYM TO_SYM
- {
- LEX *lex = Lex;
- lex->sql_command = SQLCOM_CHANGE_MASTER;
- bzero((char*) &lex->mi, sizeof(lex->mi));
- }
- master_defs
- {}
- ;
-
-master_defs:
- master_def
- | master_defs ',' master_def;
-
-master_def:
- MASTER_HOST_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.host = $3.str;
- }
- |
- MASTER_USER_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.user = $3.str;
- }
- |
- MASTER_PASSWORD_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.password = $3.str;
- }
- |
- MASTER_PORT_SYM EQ ulong_num
- {
- Lex->mi.port = $3;
- }
- |
- MASTER_CONNECT_RETRY_SYM EQ ulong_num
- {
- Lex->mi.connect_retry = $3;
- }
- | MASTER_SSL_SYM EQ ulong_num
- {
- Lex->mi.ssl= $3 ?
- LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE;
- }
- | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.ssl_ca= $3.str;
- }
- | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.ssl_capath= $3.str;
- }
- | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.ssl_cert= $3.str;
- }
- | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.ssl_cipher= $3.str;
- }
- | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.ssl_key= $3.str;
- }
- |
- master_file_def
- ;
-
-master_file_def:
- MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.log_file_name = $3.str;
- }
- | MASTER_LOG_POS_SYM EQ ulonglong_num
- {
- Lex->mi.pos = $3;
- /*
- If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it
- instead of causing subsequent errors.
- We need to do it in this file, because only there we know that
- MASTER_LOG_POS has been explicitely specified. On the contrary
- in change_master() (sql_repl.cc) we cannot distinguish between 0
- (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified),
- whereas we want to distinguish (specified 0 means "read the binlog
- from 0" (4 in fact), unspecified means "don't change the position
- (keep the preceding value)").
- */
- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
- }
- | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
- {
- Lex->mi.relay_log_name = $3.str;
- }
- | RELAY_LOG_POS_SYM EQ ulong_num
- {
- Lex->mi.relay_log_pos = $3;
- /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
- }
- ;
-
-/* create a table */
-
-create:
- CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident
- {
- THD *thd= YYTHD;
- LEX *lex=Lex;
- lex->sql_command= SQLCOM_CREATE_TABLE;
- if (!lex->select_lex.add_table_to_list(thd, $5, NULL,
- TL_OPTION_UPDATING,
- (using_update_log ?
- TL_READ_NO_INSERT:
- TL_READ)))
- YYABORT;
- lex->create_list.empty();
- lex->key_list.empty();
- lex->col_list.empty();
- lex->change=NullS;
- bzero((char*) &lex->create_info,sizeof(lex->create_info));
- lex->create_info.options=$2 | $4;
- lex->create_info.db_type= lex->thd->variables.table_type;
- lex->create_info.default_table_charset= NULL;
- lex->name.str= 0;
- lex->name.length= 0;
- lex->like_name= 0;
- }
- create2
- { Lex->current_select= &Lex->select_lex; }
- | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON
- table_ident
- {
- LEX *lex=Lex;
- lex->sql_command= SQLCOM_CREATE_INDEX;
- if (!lex->current_select->add_table_to_list(lex->thd, $7,
- NULL,
- TL_OPTION_UPDATING))
- YYABORT;
- lex->create_list.empty();
- lex->key_list.empty();
- lex->col_list.empty();
- lex->change=NullS;
- }
- '(' key_list ')' key_options
- {
- LEX *lex=Lex;
- if ($2 != Key::FULLTEXT && lex->key_create_info.parser_name.str)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- lex->key_list.push_back(new Key($2, $4.str, &lex->key_create_info, 0,
- lex->col_list));
- lex->col_list.empty();
- }
- | CREATE DATABASE opt_if_not_exists ident
- {
- Lex->create_info.default_table_charset= NULL;
- Lex->create_info.used_fields= 0;
- }
- opt_create_database_options
- {
- LEX *lex=Lex;
- lex->sql_command=SQLCOM_CREATE_DB;
- lex->name= $4;
- lex->create_info.options=$3;
- }
- | CREATE
- {
- Lex->create_view_mode= VIEW_CREATE_NEW;
- Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED;
- Lex->create_view_suid= TRUE;
- }
- view_or_trigger_or_sp_or_event
- {}
- | CREATE USER clear_privileges grant_list
- {
- Lex->sql_command = SQLCOM_CREATE_USER;
- }
- | CREATE LOGFILE_SYM GROUP logfile_group_info
- {
- Lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP;
- }
- | CREATE TABLESPACE tablespace_info
- {
- Lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE;
- }
- | CREATE server_def
- {
- Lex->sql_command= SQLCOM_CREATE_SERVER;
- }
- ;
-server_def:
- SERVER_SYM ident_or_text FOREIGN DATA_SYM WRAPPER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')'
- {
- Lex->server_options.server_name= $2.str;
- Lex->server_options.server_name_length= $2.length;
- Lex->server_options.scheme= $6.str;
- }
- ;
-
-server_options_list:
- server_option
- | server_options_list ',' server_option
- ;
-
-server_option:
- USER TEXT_STRING_sys
- {
- Lex->server_options.username= $2.str;
- }
- |
- HOST_SYM TEXT_STRING_sys
- {
- Lex->server_options.host= $2.str;
- }
- |
- DATABASE TEXT_STRING_sys
- {
- Lex->server_options.db= $2.str;
- }
- |
- OWNER_SYM TEXT_STRING_sys
- {
- Lex->server_options.owner= $2.str;
- }
- |
- PASSWORD TEXT_STRING_sys
- {
- Lex->server_options.password= $2.str;
- }
- |
- SOCKET_SYM TEXT_STRING_sys
- {
- Lex->server_options.socket= $2.str;
- }
- |
- PORT_SYM ulong_num
- {
- Lex->server_options.port= $2;
- }
- ;
-
-event_tail:
- EVENT_SYM opt_if_not_exists sp_name
- /*
- BE CAREFUL when you add a new rule to update the block where
- YYTHD->client_capabilities is set back to original value
- */
- {
- Lex->create_info.options= $2;
-
- if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
- YYABORT;
- Lex->event_parse_data->identifier= $3;
-
- /*
- We have to turn of CLIENT_MULTI_QUERIES while parsing a
- stored procedure, otherwise yylex will chop it into pieces
- at each ';'.
- */
- $$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
- YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES);
-
- Lex->sql_command= SQLCOM_CREATE_EVENT;
- /* We need that for disallowing subqueries */
- }
- ON SCHEDULE_SYM ev_schedule_time
- opt_ev_on_completion
- opt_ev_status
- opt_ev_comment
- DO_SYM ev_sql_stmt
- {
- /*
- Restore flag if it was cleared above
- $1 - EVENT_SYM
- $2 - opt_if_not_exists
- $3 - sp_name
- $4 - the block above
- */
- YYTHD->client_capabilities |= $4;
-
- /*
- sql_command is set here because some rules in ev_sql_stmt
- can overwrite it
- */
- Lex->sql_command= SQLCOM_CREATE_EVENT;
- }
- ;
-
-ev_schedule_time: EVERY_SYM expr interval
- {
- Lex->event_parse_data->item_expression= $2;
- Lex->event_parse_data->interval= $3;
- }
- ev_starts
- ev_ends
- | AT_SYM expr
- {
- Lex->event_parse_data->item_execute_at= $2;
- }
- ;
-
-opt_ev_status: /* empty */ { $$= 0; }
- | ENABLE_SYM
- {
- Lex->event_parse_data->status= Event_parse_data::ENABLED;
- $$= 1;
- }
- | DISABLE_SYM
- {
- Lex->event_parse_data->status= Event_parse_data::DISABLED;
- $$= 1;
- }
- ;
-
-ev_starts: /* empty */
- {
- Lex->event_parse_data->item_starts= new Item_func_now_local();
- }
- | STARTS_SYM expr
- {
- Lex->event_parse_data->item_starts= $2;
- }
- ;
-
-ev_ends: /* empty */
- | ENDS_SYM expr
- {
- Lex->event_parse_data->item_ends= $2;
- }
- ;
-
-opt_ev_on_completion: /* empty */ { $$= 0; }
- | ev_on_completion
- ;
-
-ev_on_completion:
- ON COMPLETION_SYM PRESERVE_SYM
- {
- Lex->event_parse_data->on_completion=
- Event_parse_data::ON_COMPLETION_PRESERVE;
- $$= 1;
- }
- | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM
- {
- Lex->event_parse_data->on_completion=
- Event_parse_data::ON_COMPLETION_DROP;
- $$= 1;
- }
- ;
-
-opt_ev_comment: /* empty */ { $$= 0; }
- | COMMENT_SYM TEXT_STRING_sys
- {
- Lex->comment= Lex->event_parse_data->comment= $2;
- $$= 1;
- }
- ;
-
-ev_sql_stmt:
- {
- LEX *lex= Lex;
-
- /*
- This stops the following :
- - CREATE EVENT ... DO CREATE EVENT ...;
- - ALTER EVENT ... DO CREATE EVENT ...;
- - CREATE EVENT ... DO ALTER EVENT DO ....;
- - CREATE PROCEDURE ... BEGIN CREATE EVENT ... END|
- This allows:
- - CREATE EVENT ... DO DROP EVENT yyy;
- - CREATE EVENT ... DO ALTER EVENT yyy;
- (the nested ALTER EVENT can have anything but DO clause)
- - ALTER EVENT ... DO ALTER EVENT yyy;
- (the nested ALTER EVENT can have anything but DO clause)
- - ALTER EVENT ... DO DROP EVENT yyy;
- - CREATE PROCEDURE ... BEGIN ALTER EVENT ... END|
- (the nested ALTER EVENT can have anything but DO clause)
- - CREATE PROCEDURE ... BEGIN DROP EVENT ... END|
- */
- if (lex->sphead)
- {
- my_error(ER_EVENT_RECURSIVITY_FORBIDDEN, MYF(0));
- YYABORT;
- }
-
- if (!(lex->sphead= new sp_head()))
- YYABORT;
-
- lex->sphead->reset_thd_mem_root(YYTHD);
- lex->sphead->init(lex);
- lex->sphead->init_sp_name(YYTHD, Lex->event_parse_data->identifier);
-
- lex->sphead->m_type= TYPE_ENUM_PROCEDURE;
-
- bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
- lex->sphead->m_chistics= &lex->sp_chistics;
-
- lex->sphead->m_body_begin= lex->ptr;
-
- Lex->event_parse_data->body_begin= lex->ptr;
-
- }
- ev_sql_stmt_inner
- {
- LEX *lex=Lex;
-
- /* return back to the original memory root ASAP */
- lex->sphead->init_strings(YYTHD, lex);
- lex->sphead->restore_thd_mem_root(YYTHD);
-
- lex->sp_chistics.suid= SP_IS_SUID; //always the definer!
-
- Lex->event_parse_data->init_body(YYTHD);
- }
- ;
-
-ev_sql_stmt_inner:
- sp_proc_stmt_statement
- | sp_proc_stmt_return
- | sp_proc_stmt_if
- | sp_proc_stmt_case_simple
- | sp_proc_stmt_case
- | 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 */
- {
- LEX *lex=Lex;
- lex->users_list.empty();
- lex->columns.empty();
- lex->grant= lex->grant_tot_col= 0;
- lex->all_privileges= 0;
- lex->select_lex.db= 0;
- lex->ssl_type= SSL_TYPE_NOT_SPECIFIED;
- lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0;
- bzero((char *)&(lex->mqh),sizeof(lex->mqh));
- }
- ;
-
-sp_name:
- ident '.' ident
- {
- if (!$1.str || check_db_name(&$1))
- {
- my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
- YYABORT;
- }
- if (check_routine_name($3))
- {
- my_error(ER_SP_WRONG_NAME, MYF(0), $3.str);
- YYABORT;
- }
- $$= new sp_name($1, $3);
- $$->init_qname(YYTHD);
- }
- | ident
- {
- THD *thd= YYTHD;
- LEX_STRING db;
- if (check_routine_name($1))
- {
- my_error(ER_SP_WRONG_NAME, MYF(0), $1.str);
- YYABORT;
- }
- if (thd->copy_db_to(&db.str, &db.length))
- YYABORT;
- $$= new sp_name(db, $1);
- if ($$)
- $$->init_qname(YYTHD);
- }
- ;
-
-create_function_tail:
- RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
- {
- THD *thd= YYTHD;
- LEX *lex=Lex;
- if (lex->definer != NULL)
- {
- /*
- DEFINER is a concept meaningful when interpreting SQL code.
- UDF functions are compiled.
- Using DEFINER with UDF has therefore no semantic,
- and is considered a parsing error.
- */
- my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER");
- YYABORT;
- }
- if (is_native_function(thd, & lex->spname->m_name))
- {
- my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0),
- lex->spname->m_name.str);
- YYABORT;
- }
- lex->sql_command = SQLCOM_CREATE_FUNCTION;
- lex->udf.name = lex->spname->m_name;
- lex->udf.returns=(Item_result) $2;
- lex->udf.dl=$4.str;
- }
- | '('
- {
- LEX *lex= Lex;
- sp_head *sp;
-
- /*
- First check if AGGREGATE was used, in that case it's a
- syntax error.
- */
- if (lex->udf.type == UDFTYPE_AGGREGATE)
- {
- my_error(ER_SP_NO_AGGREGATE, MYF(0));
- YYABORT;
- }
-
- if (lex->sphead)
- {
- my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION");
- YYABORT;
- }
- /* Order is important here: new - reset - init */
- sp= new sp_head();
- sp->reset_thd_mem_root(YYTHD);
- sp->init(lex);
- sp->init_sp_name(YYTHD, lex->spname);
-
- sp->m_type= TYPE_ENUM_FUNCTION;
- lex->sphead= sp;
- /*
- We have to turn off CLIENT_MULTI_QUERIES while parsing a
- stored procedure, otherwise yylex will chop it into pieces
- at each ';'.
- */
- $$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
- YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
- lex->sphead->m_param_begin= lex->tok_start+1;
- }
- sp_fdparam_list ')'
- {
- LEX *lex= Lex;
-
- lex->sphead->m_param_end= lex->tok_start;
- }
- RETURNS_SYM
- {
- LEX *lex= Lex;
- lex->charset= NULL;
- lex->length= lex->dec= NULL;
- lex->interval_list.empty();
- lex->type= 0;
- }
- type
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- /*
- This was disabled in 5.1.12. See bug #20701
- When collation support in SP is implemented, then this test
- should be removed.
- */
- if (($8 == FIELD_TYPE_STRING || $8 == MYSQL_TYPE_VARCHAR)
- && (lex->type & BINCMP_FLAG))
- {
- my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation");
- YYABORT;
- }
-
- if (sp->fill_field_definition(YYTHD, lex,
- (enum enum_field_types) $8,
- &sp->m_return_field_def))
- YYABORT;
-
- bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
- }
- sp_c_chistics
- {
- LEX *lex= Lex;
-
- lex->sphead->m_chistics= &lex->sp_chistics;
- lex->sphead->m_body_begin= lex->tok_start;
- }
- sp_proc_stmt
- {
- THD *thd= YYTHD;
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
-
- if (sp->is_not_allowed_in_function("function"))
- YYABORT;
-
- lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
- sp->init_strings(thd, lex);
- if (!(sp->m_flags & sp_head::HAS_RETURN))
- {
- my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
- YYABORT;
- }
- if (is_native_function(thd, & sp->m_name))
- {
- /*
- This warning will be printed when
- [1] A client query is parsed,
- [2] A stored function is loaded by db_load_routine.
- Printing the warning for [2] is intentional, to cover the
- following scenario:
- - A user define a SF 'foo' using MySQL 5.N
- - An application uses select foo(), and works.
- - MySQL 5.{N+1} defines a new native function 'foo', as
- part of a new feature.
- - MySQL 5.{N+1} documentation is updated, and should mention
- that there is a potential incompatible change in case of
- existing stored function named 'foo'.
- - The user deploys 5.{N+1}. At this point, 'select foo()'
- means something different, and the user code is most likely
- broken (it's only safe if the code is 'select db.foo()').
- With a warning printed when the SF is loaded (which has to occur
- before the call), the warning will provide a hint explaining
- the root cause of a later failure of 'select foo()'.
- With no warning printed, the user code will fail with no
- apparent reason.
- Printing a warning each time db_load_routine is executed for
- an ambiguous function is annoying, since that can happen a lot,
- but in practice should not happen unless there *are* name
- collisions.
- If a collision exists, it should not be silenced but fixed.
- */
- push_warning_printf(thd,
- MYSQL_ERROR::WARN_LEVEL_NOTE,
- ER_NATIVE_FCT_NAME_COLLISION,
- ER(ER_NATIVE_FCT_NAME_COLLISION),
- sp->m_name.str);
- }
- /* Restore flag if it was cleared above */
- thd->client_capabilities |= $2;
- sp->restore_thd_mem_root(thd);
- }
- ;
-
-sp_a_chistics:
- /* Empty */ {}
- | sp_a_chistics sp_chistic {}
- ;
-
-sp_c_chistics:
- /* Empty */ {}
- | sp_c_chistics sp_c_chistic {}
- ;
-
-/* Characteristics for both create and alter */
-sp_chistic:
- COMMENT_SYM TEXT_STRING_sys
- { Lex->sp_chistics.comment= $2; }
- | LANGUAGE_SYM SQL_SYM
- { /* Just parse it, we only have one language for now. */ }
- | NO_SYM SQL_SYM
- { Lex->sp_chistics.daccess= SP_NO_SQL; }
- | CONTAINS_SYM SQL_SYM
- { Lex->sp_chistics.daccess= SP_CONTAINS_SQL; }
- | READS_SYM SQL_SYM DATA_SYM
- { Lex->sp_chistics.daccess= SP_READS_SQL_DATA; }
- | MODIFIES_SYM SQL_SYM DATA_SYM
- { Lex->sp_chistics.daccess= SP_MODIFIES_SQL_DATA; }
- | sp_suid
- { }
- ;
-
-/* Create characteristics */
-sp_c_chistic:
- sp_chistic { }
- | DETERMINISTIC_SYM { Lex->sp_chistics.detistic= TRUE; }
- | not DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; }
- ;
-
-sp_suid:
- SQL_SYM SECURITY_SYM DEFINER_SYM
- {
- Lex->sp_chistics.suid= SP_IS_SUID;
- }
- | SQL_SYM SECURITY_SYM INVOKER_SYM
- {
- Lex->sp_chistics.suid= SP_IS_NOT_SUID;
- }
- ;
-
-call:
- CALL_SYM sp_name
- {
- LEX *lex = Lex;
-
- lex->sql_command= SQLCOM_CALL;
- lex->spname= $2;
- lex->value_list.empty();
- sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
- }
- opt_sp_cparam_list {}
- ;
-
-/* CALL parameters */
-opt_sp_cparam_list:
- /* Empty */
- | '(' opt_sp_cparams ')'
- ;
-
-opt_sp_cparams:
- /* Empty */
- | sp_cparams
- ;
-
-sp_cparams:
- sp_cparams ',' expr
- {
- Lex->value_list.push_back($3);
- }
- | expr
- {
- Lex->value_list.push_back($1);
- }
- ;
-
-/* Stored FUNCTION parameter declaration list */
-sp_fdparam_list:
- /* Empty */
- | sp_fdparams
- ;
-
-sp_fdparams:
- sp_fdparams ',' sp_fdparam
- | sp_fdparam
- ;
-
-sp_init_param:
- /* Empty */
- {
- LEX *lex= Lex;
-
- lex->length= 0;
- lex->dec= 0;
- lex->type= 0;
-
- lex->default_value= 0;
- lex->on_update_value= 0;
-
- lex->comment= null_lex_str;
- lex->charset= NULL;
-
- lex->interval_list.empty();
- lex->uint_geom_type= 0;
- }
- ;
-
-sp_fdparam:
- ident sp_init_param type
- {
- LEX *lex= Lex;
- sp_pcontext *spc= lex->spcont;
-
- if (spc->find_variable(&$1, TRUE))
- {
- my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
- YYABORT;
- }
- sp_variable_t *spvar= spc->push_variable(&$1,
- (enum enum_field_types)$3,
- sp_param_in);
-
- if (lex->sphead->fill_field_definition(YYTHD, lex,
- (enum enum_field_types) $3,
- &spvar->field_def))
- {
- YYABORT;
- }
- spvar->field_def.field_name= spvar->name.str;
- spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
- }
- ;
-
-/* Stored PROCEDURE parameter declaration list */
-sp_pdparam_list:
- /* Empty */
- | sp_pdparams
- ;
-
-sp_pdparams:
- sp_pdparams ',' sp_pdparam
- | sp_pdparam
- ;
-
-sp_pdparam:
- sp_opt_inout sp_init_param ident type
- {
- LEX *lex= Lex;
- sp_pcontext *spc= lex->spcont;
-
- if (spc->find_variable(&$3, TRUE))
- {
- my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
- YYABORT;
- }
- sp_variable_t *spvar= spc->push_variable(&$3,
- (enum enum_field_types)$4,
- (sp_param_mode_t)$1);
-
- if (lex->sphead->fill_field_definition(YYTHD, lex,
- (enum enum_field_types) $4,
- &spvar->field_def))
- {
- YYABORT;
- }
- spvar->field_def.field_name= spvar->name.str;
- spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
- }
- ;
-
-sp_opt_inout:
- /* Empty */ { $$= sp_param_in; }
- | IN_SYM { $$= sp_param_in; }
- | OUT_SYM { $$= sp_param_out; }
- | INOUT_SYM { $$= sp_param_inout; }
- ;
-
-sp_proc_stmts:
- /* Empty */ {}
- | sp_proc_stmts sp_proc_stmt ';'
- ;
-
-sp_proc_stmts1:
- sp_proc_stmt ';' {}
- | sp_proc_stmts1 sp_proc_stmt ';'
- ;
-
-sp_decls:
- /* Empty */
- {
- $$.vars= $$.conds= $$.hndlrs= $$.curs= 0;
- }
- | sp_decls sp_decl ';'
- {
- /* We check for declarations out of (standard) order this way
- because letting the grammar rules reflect it caused tricky
- shift/reduce conflicts with the wrong result. (And we get
- better error handling this way.) */
- if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs))
- { /* Variable or condition following cursor or handler */
- my_message(ER_SP_VARCOND_AFTER_CURSHNDLR,
- ER(ER_SP_VARCOND_AFTER_CURSHNDLR), MYF(0));
- YYABORT;
- }
- if ($2.curs && $1.hndlrs)
- { /* Cursor following handler */
- my_message(ER_SP_CURSOR_AFTER_HANDLER,
- ER(ER_SP_CURSOR_AFTER_HANDLER), MYF(0));
- YYABORT;
- }
- $$.vars= $1.vars + $2.vars;
- $$.conds= $1.conds + $2.conds;
- $$.hndlrs= $1.hndlrs + $2.hndlrs;
- $$.curs= $1.curs + $2.curs;
- }
- ;
-
-sp_decl:
- DECLARE_SYM sp_decl_idents
- {
- LEX *lex= Lex;
-
- lex->sphead->reset_lex(YYTHD);
- lex->spcont->declare_var_boundary($2);
- }
- type
- sp_opt_default
- {
- LEX *lex= Lex;
- sp_pcontext *pctx= lex->spcont;
- uint num_vars= pctx->context_var_count();
- enum enum_field_types var_type= (enum enum_field_types) $4;
- Item *dflt_value_item= $5;
- create_field *create_field_op;
-
- if (!dflt_value_item)
- {
- dflt_value_item= new Item_null();
- /* QQ Set to the var_type with null_value? */
- }
-
- for (uint i = num_vars-$2 ; i < num_vars ; i++)
- {
- uint var_idx= pctx->var_context2runtime(i);
- sp_variable_t *spvar= pctx->find_variable(var_idx);
-
- if (!spvar)
- YYABORT;
-
- spvar->type= var_type;
- spvar->dflt= dflt_value_item;
-
- if (lex->sphead->fill_field_definition(YYTHD, lex, var_type,
- &spvar->field_def))
- {
- YYABORT;
- }
-
- spvar->field_def.field_name= spvar->name.str;
- spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
-
- /* The last instruction is responsible for freeing LEX. */
-
- lex->sphead->add_instr(
- new sp_instr_set(lex->sphead->instructions(), pctx, var_idx,
- dflt_value_item, var_type, lex,
- (i == num_vars - 1)));
- }
-
- pctx->declare_var_boundary(0);
- lex->sphead->restore_lex(YYTHD);
-
- $$.vars= $2;
- $$.conds= $$.hndlrs= $$.curs= 0;
- }
- | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond
- {
- LEX *lex= Lex;
- sp_pcontext *spc= lex->spcont;
-
- if (spc->find_cond(&$2, TRUE))
- {
- my_error(ER_SP_DUP_COND, MYF(0), $2.str);
- YYABORT;
- }
- YYTHD->lex->spcont->push_cond(&$2, $5);
- $$.vars= $$.hndlrs= $$.curs= 0;
- $$.conds= 1;
- }
- | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- sp_instr_hpush_jump *i=
- new sp_instr_hpush_jump(sp->instructions(), ctx, $2,
- ctx->current_var_count());
-
- sp->add_instr(i);
- sp->push_backpatch(i, ctx->push_label((char *)"", 0));
- sp->m_flags|= sp_head::IN_HANDLER;
- }
- sp_hcond_list sp_proc_stmt
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- sp_label_t *hlab= lex->spcont->pop_label(); /* After this hdlr */
- sp_instr_hreturn *i;
-
- if ($2 == SP_HANDLER_CONTINUE)
- {
- i= new sp_instr_hreturn(sp->instructions(), ctx,
- ctx->current_var_count());
- sp->add_instr(i);
- }
- else
- { /* EXIT or UNDO handler, just jump to the end of the block */
- i= new sp_instr_hreturn(sp->instructions(), ctx, 0);
-
- sp->add_instr(i);
- sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */
- }
- lex->sphead->backpatch(hlab);
- sp->m_flags&= ~sp_head::IN_HANDLER;
- $$.vars= $$.conds= $$.curs= 0;
- $$.hndlrs= $6;
- ctx->add_handlers($6);
- }
- | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- uint offp;
- sp_instr_cpush *i;
-
- if (ctx->find_cursor(&$2, &offp, TRUE))
- {
- my_error(ER_SP_DUP_CURS, MYF(0), $2.str);
- delete $5;
- YYABORT;
- }
- i= new sp_instr_cpush(sp->instructions(), ctx, $5,
- ctx->current_cursor_count());
- sp->add_instr(i);
- ctx->push_cursor(&$2);
- $$.vars= $$.conds= $$.hndlrs= 0;
- $$.curs= 1;
- }
- ;
-
-sp_cursor_stmt:
- {
- Lex->sphead->reset_lex(YYTHD);
-
- /*
- We use statement here just be able to get a better
- error message. Using 'select' works too, but will then
- result in a generic "syntax error" if a non-select
- statement is given.
- */
- }
- statement
- {
- LEX *lex= Lex;
-
- if (lex->sql_command != SQLCOM_SELECT &&
- !(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND))
- {
- my_message(ER_SP_BAD_CURSOR_QUERY, ER(ER_SP_BAD_CURSOR_QUERY),
- MYF(0));
- YYABORT;
- }
- if (lex->result)
- {
- my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT),
- MYF(0));
- YYABORT;
- }
- lex->sp_lex_in_use= TRUE;
- $$= lex;
- lex->sphead->restore_lex(YYTHD);
- }
- ;
-
-sp_handler_type:
- EXIT_SYM { $$= SP_HANDLER_EXIT; }
- | CONTINUE_SYM { $$= SP_HANDLER_CONTINUE; }
-/* | UNDO_SYM { QQ No yet } */
- ;
-
-sp_hcond_list:
- sp_hcond
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
-
- if (ctx->find_handler($1))
- {
- my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0));
- YYABORT;
- }
- else
- {
- sp_instr_hpush_jump *i=
- (sp_instr_hpush_jump *)sp->last_instruction();
-
- i->add_condition($1);
- ctx->push_handler($1);
- $$= 1;
- }
- }
- | sp_hcond_list ',' sp_hcond
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
-
- if (ctx->find_handler($3))
- {
- my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0));
- YYABORT;
- }
- else
- {
- sp_instr_hpush_jump *i=
- (sp_instr_hpush_jump *)sp->last_instruction();
-
- i->add_condition($3);
- ctx->push_handler($3);
- $$= $1 + 1;
- }
- }
- ;
-
-sp_cond:
- ulong_num
- { /* mysql errno */
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
- $$->type= sp_cond_type_t::number;
- $$->mysqlerr= $1;
- }
- | SQLSTATE_SYM opt_value TEXT_STRING_literal
- { /* SQLSTATE */
- if (!sp_cond_check(&$3))
- {
- my_error(ER_SP_BAD_SQLSTATE, MYF(0), $3.str);
- YYABORT;
- }
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
- $$->type= sp_cond_type_t::state;
- memcpy($$->sqlstate, $3.str, 5);
- $$->sqlstate[5]= '\0';
- }
- ;
-
-opt_value:
- /* Empty */ {}
- | VALUE_SYM {}
- ;
-
-sp_hcond:
- sp_cond
- {
- $$= $1;
- }
- | ident /* CONDITION name */
- {
- $$= Lex->spcont->find_cond(&$1);
- if ($$ == NULL)
- {
- my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str);
- YYABORT;
- }
- }
- | SQLWARNING_SYM /* SQLSTATEs 01??? */
- {
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
- $$->type= sp_cond_type_t::warning;
- }
- | not FOUND_SYM /* SQLSTATEs 02??? */
- {
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
- $$->type= sp_cond_type_t::notfound;
- }
- | SQLEXCEPTION_SYM /* All other SQLSTATEs */
- {
- $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t));
- $$->type= sp_cond_type_t::exception;
- }
- ;
-
-sp_decl_idents:
- ident
- {
- /* NOTE: field definition is filled in sp_decl section. */
-
- LEX *lex= Lex;
- sp_pcontext *spc= lex->spcont;
-
- if (spc->find_variable(&$1, TRUE))
- {
- my_error(ER_SP_DUP_VAR, MYF(0), $1.str);
- YYABORT;
- }
- spc->push_variable(&$1, (enum_field_types)0, sp_param_in);
- $$= 1;
- }
- | sp_decl_idents ',' ident
- {
- /* NOTE: field definition is filled in sp_decl section. */
-
- LEX *lex= Lex;
- sp_pcontext *spc= lex->spcont;
-
- if (spc->find_variable(&$3, TRUE))
- {
- my_error(ER_SP_DUP_VAR, MYF(0), $3.str);
- YYABORT;
- }
- spc->push_variable(&$3, (enum_field_types)0, sp_param_in);
- $$= $1 + 1;
- }
- ;
-
-sp_opt_default:
- /* Empty */ { $$ = NULL; }
- | DEFAULT expr { $$ = $2; }
- ;
-
-sp_proc_stmt:
- sp_proc_stmt_statement
- | sp_proc_stmt_return
- | sp_proc_stmt_if
- | sp_proc_stmt_case_simple
- | sp_proc_stmt_case
- | 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
- ;
-
-sp_proc_stmt_if:
- IF { Lex->sphead->new_cont_backpatch(NULL); }
- sp_if END IF
- { Lex->sphead->do_cont_backpatch(); }
- ;
-
-sp_proc_stmt_statement:
- {
- LEX *lex= Lex;
-
- lex->sphead->reset_lex(YYTHD);
- lex->sphead->m_tmp_query= lex->tok_start;
- }
- statement
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
-
- sp->m_flags|= sp_get_flags_for_command(lex);
- if (lex->sql_command == SQLCOM_CHANGE_DB)
- { /* "USE db" doesn't work in a procedure */
- my_error(ER_SP_BADSTATEMENT, MYF(0), "USE");
- YYABORT;
- }
- /*
- Don't add an instruction for SET statements, since all
- instructions for them were already added during processing
- of "set" rule.
- */
- DBUG_ASSERT(lex->sql_command != SQLCOM_SET_OPTION ||
- lex->var_list.is_empty());
- if (lex->sql_command != SQLCOM_SET_OPTION)
- {
- sp_instr_stmt *i=new sp_instr_stmt(sp->instructions(),
- lex->spcont, lex);
-
- /*
- Extract the query statement from the tokenizer. The
- end is either lex->ptr, if there was no lookahead,
- lex->tok_end otherwise.
- */
- if (yychar == YYEMPTY)
- i->m_query.length= lex->ptr - sp->m_tmp_query;
- else
- i->m_query.length= lex->tok_end - sp->m_tmp_query;
- i->m_query.str= strmake_root(YYTHD->mem_root,
- (char *)sp->m_tmp_query,
- i->m_query.length);
- sp->add_instr(i);
- }
- sp->restore_lex(YYTHD);
- }
- ;
-
-sp_proc_stmt_return:
- RETURN_SYM
- { Lex->sphead->reset_lex(YYTHD); }
- expr
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
-
- if (sp->m_type != TYPE_ENUM_FUNCTION)
- {
- my_message(ER_SP_BADRETURN, ER(ER_SP_BADRETURN), MYF(0));
- YYABORT;
- }
- else
- {
- sp_instr_freturn *i;
-
- i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3,
- sp->m_return_field_def.sql_type, lex);
- sp->add_instr(i);
- sp->m_flags|= sp_head::HAS_RETURN;
- }
- sp->restore_lex(YYTHD);
- }
- ;
-
-sp_proc_stmt_case_simple:
- CASE_SYM WHEN_SYM
- {
- Lex->sphead->m_flags&= ~sp_head::IN_SIMPLE_CASE;
- Lex->sphead->new_cont_backpatch(NULL);
- }
- sp_case END CASE_SYM { Lex->sphead->do_cont_backpatch(); }
- ;
-
-sp_proc_stmt_case:
- CASE_SYM
- {
- Lex->sphead->reset_lex(YYTHD);
- Lex->sphead->new_cont_backpatch(NULL);
- }
- expr WHEN_SYM
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *parsing_ctx= lex->spcont;
- int case_expr_id= parsing_ctx->register_case_expr();
- sp_instr_set_case_expr *i;
-
- if (parsing_ctx->push_case_expr_id(case_expr_id))
- YYABORT;
-
- i= new sp_instr_set_case_expr(sp->instructions(),
- parsing_ctx,
- case_expr_id,
- $3,
- lex);
- sp->add_cont_backpatch(i);
- sp->add_instr(i);
- sp->m_flags|= sp_head::IN_SIMPLE_CASE;
- sp->restore_lex(YYTHD);
- }
- sp_case END CASE_SYM
- {
- Lex->spcont->pop_case_expr_id();
- Lex->sphead->do_cont_backpatch();
- }
- ;
-
-sp_proc_stmt_unlabeled:
- { /* Unlabeled controls get a secret label. */
- LEX *lex= Lex;
-
- lex->spcont->push_label((char *)"", lex->sphead->instructions());
- }
- sp_unlabeled_control
- {
- LEX *lex= Lex;
-
- lex->sphead->backpatch(lex->spcont->pop_label());
- }
- ;
-
-sp_proc_stmt_leave:
- LEAVE_SYM label_ident
- {
- LEX *lex= Lex;
- sp_head *sp = lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- sp_label_t *lab= ctx->find_label($2.str);
-
- if (! lab)
- {
- my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str);
- YYABORT;
- }
- else
- {
- sp_instr_jump *i;
- uint ip= sp->instructions();
- uint n;
-
- n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */
- if (n)
- sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
- n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */
- if (n)
- sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
- i= new sp_instr_jump(ip, ctx);
- sp->push_backpatch(i, lab); /* Jumping forward */
- sp->add_instr(i);
- }
- }
- ;
-
-sp_proc_stmt_iterate:
- ITERATE_SYM label_ident
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- sp_label_t *lab= ctx->find_label($2.str);
-
- if (! lab || lab->type != SP_LAB_ITER)
- {
- my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str);
- YYABORT;
- }
- else
- {
- sp_instr_jump *i;
- uint ip= sp->instructions();
- uint n;
-
- n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */
- if (n)
- sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
- n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
- if (n)
- sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
- i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
- sp->add_instr(i);
- }
- }
- ;
-
-sp_proc_stmt_open:
- OPEN_SYM ident
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- uint offset;
- sp_instr_copen *i;
-
- if (! lex->spcont->find_cursor(&$2, &offset))
- {
- my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str);
- YYABORT;
- }
- i= new sp_instr_copen(sp->instructions(), lex->spcont, offset);
- sp->add_instr(i);
- }
- ;
-
-sp_proc_stmt_fetch:
- FETCH_SYM sp_opt_fetch_noise ident INTO
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- uint offset;
- sp_instr_cfetch *i;
-
- if (! lex->spcont->find_cursor(&$3, &offset))
- {
- my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $3.str);
- YYABORT;
- }
- i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset);
- sp->add_instr(i);
- }
- sp_fetch_list
- { }
- ;
-
-sp_proc_stmt_close:
- CLOSE_SYM ident
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- uint offset;
- sp_instr_cclose *i;
-
- if (! lex->spcont->find_cursor(&$2, &offset))
- {
- my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str);
- YYABORT;
- }
- i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset);
- sp->add_instr(i);
- }
- ;
-
-sp_opt_fetch_noise:
- /* Empty */
- | NEXT_SYM FROM
- | FROM
- ;
-
-sp_fetch_list:
- ident
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *spc= lex->spcont;
- sp_variable_t *spv;
-
- if (!spc || !(spv = spc->find_variable(&$1)))
- {
- my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
- YYABORT;
- }
- else
- {
- /* An SP local variable */
- sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
-
- i->add_to_varlist(spv);
- }
- }
- |
- sp_fetch_list ',' ident
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *spc= lex->spcont;
- sp_variable_t *spv;
-
- if (!spc || !(spv = spc->find_variable(&$3)))
- {
- my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str);
- YYABORT;
- }
- else
- {
- /* An SP local variable */
- sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction();
-
- i->add_to_varlist(spv);
- }
- }
- ;
-
-sp_if:
- { Lex->sphead->reset_lex(YYTHD); }
- expr THEN_SYM
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
- uint ip= sp->instructions();
- sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx,
- $2, lex);
-
- sp->push_backpatch(i, ctx->push_label((char *)"", 0));
- sp->add_cont_backpatch(i);
- sp->add_instr(i);
- sp->restore_lex(YYTHD);
- }
- sp_proc_stmts1
- {
- sp_head *sp= Lex->sphead;
- sp_pcontext *ctx= Lex->spcont;
- uint ip= sp->instructions();
- sp_instr_jump *i = new sp_instr_jump(ip, ctx);
-
- sp->add_instr(i);
- sp->backpatch(ctx->pop_label());
- sp->push_backpatch(i, ctx->push_label((char *)"", 0));
- }
- sp_elseifs
- {
- LEX *lex= Lex;
-
- lex->sphead->backpatch(lex->spcont->pop_label());
- }
- ;
-
-sp_elseifs:
- /* Empty */
- | ELSEIF_SYM sp_if
- | ELSE sp_proc_stmts1
- ;
-
-sp_case:
- { Lex->sphead->reset_lex(YYTHD); }
- expr THEN_SYM
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= Lex->spcont;
- uint ip= sp->instructions();
- sp_instr_jump_if_not *i;
-
- if (! (sp->m_flags & sp_head::IN_SIMPLE_CASE))
- i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
- else
- { /* Simple case: = */
-
- Item_case_expr *var;
- Item *expr;
-
- var= new Item_case_expr(ctx->get_current_case_expr_id());
-
-#ifndef DBUG_OFF
- if (var)
- var->m_sp= sp;
-#endif
-
- expr= new Item_func_eq(var, $2);
-
- i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
- }
- sp->push_backpatch(i, ctx->push_label((char *)"", 0));
- sp->add_cont_backpatch(i);
- sp->add_instr(i);
- sp->restore_lex(YYTHD);
- }
- sp_proc_stmts1
- {
- sp_head *sp= Lex->sphead;
- sp_pcontext *ctx= Lex->spcont;
- uint ip= sp->instructions();
- sp_instr_jump *i = new sp_instr_jump(ip, ctx);
-
- sp->add_instr(i);
- sp->backpatch(ctx->pop_label());
- sp->push_backpatch(i, ctx->push_label((char *)"", 0));
- }
- sp_whens
- {
- LEX *lex= Lex;
-
- lex->sphead->backpatch(lex->spcont->pop_label());
- }
- ;
-
-sp_whens:
- /* Empty */
- {
- sp_head *sp= Lex->sphead;
- uint ip= sp->instructions();
- sp_instr_error *i= new sp_instr_error(ip, Lex->spcont,
- ER_SP_CASE_NOT_FOUND);
-
- sp->add_instr(i);
- }
- | ELSE sp_proc_stmts1 {}
- | WHEN_SYM sp_case {}
- ;
-
-sp_labeled_control:
- label_ident ':'
- {
- LEX *lex= Lex;
- sp_pcontext *ctx= lex->spcont;
- sp_label_t *lab= ctx->find_label($1.str);
-
- if (lab)
- {
- my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str);
- YYABORT;
- }
- else
- {
- lab= lex->spcont->push_label($1.str,
- lex->sphead->instructions());
- lab->type= SP_LAB_ITER;
- }
- }
- sp_unlabeled_control sp_opt_label
- {
- LEX *lex= Lex;
-
- if ($5.str)
- {
- sp_label_t *lab= lex->spcont->find_label($5.str);
-
- if (!lab ||
- my_strcasecmp(system_charset_info, $5.str, lab->name) != 0)
- {
- my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str);
- YYABORT;
- }
- }
- lex->sphead->backpatch(lex->spcont->pop_label());
- }
- ;
-
-sp_opt_label:
- /* Empty */ { $$= null_lex_str; }
- | label_ident { $$= $1; }
- ;
-
-sp_unlabeled_control:
- BEGIN_SYM
- { /* QQ This is just a dummy for grouping declarations and statements
- together. No [[NOT] ATOMIC] yet, and we need to figure out how
- make it coexist with the existing BEGIN COMMIT/ROLLBACK. */
- LEX *lex= Lex;
- sp_label_t *lab= lex->spcont->last_label();
-
- lab->type= SP_LAB_BEGIN;
- lex->spcont= lex->spcont->push_context();
- }
- sp_decls
- sp_proc_stmts
- END
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- sp_pcontext *ctx= lex->spcont;
-
- sp->backpatch(ctx->last_label()); /* We always have a label */
- if ($3.hndlrs)
- sp->add_instr(new sp_instr_hpop(sp->instructions(), ctx,
- $3.hndlrs));
- if ($3.curs)
- sp->add_instr(new sp_instr_cpop(sp->instructions(), ctx,
- $3.curs));
- lex->spcont= ctx->pop_context();
- }
- | LOOP_SYM
- sp_proc_stmts1 END LOOP_SYM
- {
- LEX *lex= Lex;
- uint ip= lex->sphead->instructions();
- sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
- sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip);
-
- lex->sphead->add_instr(i);
- }
- | WHILE_SYM
- { Lex->sphead->reset_lex(YYTHD); }
- expr DO_SYM
- {
- LEX *lex= Lex;
- sp_head *sp= lex->sphead;
- uint ip= sp->instructions();
- sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont,
- $3, lex);
-
- /* Jumping forward */
- sp->push_backpatch(i, lex->spcont->last_label());
- sp->new_cont_backpatch(i);
- sp->add_instr(i);
- sp->restore_lex(YYTHD);
- }
- sp_proc_stmts1 END WHILE_SYM
- {
- LEX *lex= Lex;
- uint ip= lex->sphead->instructions();
- sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
- sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip);
-
- lex->sphead->add_instr(i);
- lex->sphead->do_cont_backpatch();
- }
- | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM
- { Lex->sphead->reset_lex(YYTHD); }
- expr END REPEAT_SYM
- {
- LEX *lex= Lex;
- uint ip= lex->sphead->instructions();
- sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
- sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont,
- $5, lab->ip,
- lex);
- lex->sphead->add_instr(i);
- lex->sphead->restore_lex(YYTHD);
- /* We can shortcut the cont_backpatch here */
- i->m_cont_dest= ip+1;
- }
- ;
-
-trg_action_time:
- BEFORE_SYM
- { Lex->trg_chistics.action_time= TRG_ACTION_BEFORE; }
- | AFTER_SYM
- { Lex->trg_chistics.action_time= TRG_ACTION_AFTER; }
- ;
-
-trg_event:
- INSERT
- { Lex->trg_chistics.event= TRG_EVENT_INSERT; }
- | UPDATE_SYM
- { Lex->trg_chistics.event= TRG_EVENT_UPDATE; }
- | DELETE_SYM
- { Lex->trg_chistics.event= TRG_EVENT_DELETE; }
- ;
-/*
- This part of the parser contains common code for all TABLESPACE
- commands.
- CREATE TABLESPACE name ...
- ALTER TABLESPACE name CHANGE DATAFILE ...
- ALTER TABLESPACE name ADD DATAFILE ...
- ALTER TABLESPACE name access_mode
- CREATE LOGFILE GROUP name ...
- ALTER LOGFILE GROUP name ADD UNDOFILE ..
- ALTER LOGFILE GROUP name ADD REDOFILE ..
- DROP TABLESPACE name
- DROP LOGFILE GROUP name
-*/
-change_tablespace_access:
- tablespace_name
- ts_access_mode
- ;
-
-change_tablespace_info:
- tablespace_name
- CHANGE ts_datafile
- change_ts_option_list
- ;
-
-tablespace_info:
- tablespace_name
- ADD ts_datafile
- opt_logfile_group_name
- tablespace_option_list
- ;
-
-opt_logfile_group_name:
- /* empty */ {}
- | USE_SYM LOGFILE_SYM GROUP ident
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->logfile_group_name= $4.str;
- };
-
-alter_tablespace_info:
- tablespace_name
- ADD ts_datafile
- alter_tablespace_option_list
- {
- Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_ADD_FILE;
- }
- |
- tablespace_name
- DROP ts_datafile
- alter_tablespace_option_list
- {
- Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_DROP_FILE;
- };
-
-logfile_group_info:
- logfile_group_name
- add_log_file
- logfile_group_option_list
- ;
-
-alter_logfile_group_info:
- logfile_group_name
- add_log_file
- alter_logfile_group_option_list
- ;
-
-add_log_file:
- ADD lg_undofile
- | ADD lg_redofile
- ;
-
-change_ts_option_list:
- /* empty */ {}
- change_ts_options
- ;
-
-change_ts_options:
- change_ts_option
- | change_ts_options change_ts_option
- | change_ts_options ',' change_ts_option
- ;
-
-change_ts_option:
- opt_ts_initial_size
- | opt_ts_autoextend_size
- | opt_ts_max_size
- ;
-
-tablespace_option_list:
- /* empty */ {}
- tablespace_options
- ;
-
-tablespace_options:
- tablespace_option
- | tablespace_options tablespace_option
- | tablespace_options ',' tablespace_option
- ;
-
-tablespace_option:
- opt_ts_initial_size
- | opt_ts_autoextend_size
- | opt_ts_max_size
- | opt_ts_extent_size
- | opt_ts_nodegroup
- | opt_ts_engine
- | ts_wait
- | opt_ts_comment
- ;
-
-alter_tablespace_option_list:
- /* empty */ {}
- alter_tablespace_options
- ;
-
-alter_tablespace_options:
- alter_tablespace_option
- | alter_tablespace_options alter_tablespace_option
- | alter_tablespace_options ',' alter_tablespace_option
- ;
-
-alter_tablespace_option:
- opt_ts_initial_size
- | opt_ts_autoextend_size
- | opt_ts_max_size
- | opt_ts_engine
- | ts_wait
- ;
-
-logfile_group_option_list:
- /* empty */ {}
- logfile_group_options
- ;
-
-logfile_group_options:
- logfile_group_option
- | logfile_group_options logfile_group_option
- | logfile_group_options ',' logfile_group_option
- ;
-
-logfile_group_option:
- opt_ts_initial_size
- | opt_ts_undo_buffer_size
- | opt_ts_redo_buffer_size
- | opt_ts_nodegroup
- | opt_ts_engine
- | ts_wait
- | opt_ts_comment
- ;
-
-alter_logfile_group_option_list:
- /* empty */ {}
- alter_logfile_group_options
- ;
-
-alter_logfile_group_options:
- alter_logfile_group_option
- | alter_logfile_group_options alter_logfile_group_option
- | alter_logfile_group_options ',' alter_logfile_group_option
- ;
-
-alter_logfile_group_option:
- opt_ts_initial_size
- | opt_ts_engine
- | ts_wait
- ;
-
-
-ts_datafile:
- DATAFILE_SYM TEXT_STRING_sys
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->data_file_name= $2.str;
- };
-
-lg_undofile:
- UNDOFILE_SYM TEXT_STRING_sys
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->undo_file_name= $2.str;
- };
-
-lg_redofile:
- REDOFILE_SYM TEXT_STRING_sys
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->redo_file_name= $2.str;
- };
-
-tablespace_name:
- ident
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info= new st_alter_tablespace();
- lex->alter_tablespace_info->tablespace_name= $1.str;
- lex->sql_command= SQLCOM_ALTER_TABLESPACE;
- };
-
-logfile_group_name:
- ident
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info= new st_alter_tablespace();
- lex->alter_tablespace_info->logfile_group_name= $1.str;
- lex->sql_command= SQLCOM_ALTER_TABLESPACE;
- };
-
-ts_access_mode:
- READ_ONLY_SYM
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->ts_access_mode= TS_READ_ONLY;
- }
- | READ_WRITE_SYM
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->ts_access_mode= TS_READ_WRITE;
- }
- | NOT_SYM ACCESSIBLE_SYM
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->ts_access_mode= TS_NOT_ACCESSIBLE;
- };
-
-opt_ts_initial_size:
- INITIAL_SIZE_SYM opt_equal size_number
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->initial_size= $3;
- };
-
-opt_ts_autoextend_size:
- AUTOEXTEND_SIZE_SYM opt_equal size_number
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->autoextend_size= $3;
- };
-
-opt_ts_max_size:
- MAX_SIZE_SYM opt_equal size_number
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->max_size= $3;
- };
-
-opt_ts_extent_size:
- EXTENT_SIZE_SYM opt_equal size_number
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->extent_size= $3;
- };
-
-opt_ts_undo_buffer_size:
- UNDO_BUFFER_SIZE_SYM opt_equal size_number
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->undo_buffer_size= $3;
- };
-
-opt_ts_redo_buffer_size:
- REDO_BUFFER_SIZE_SYM opt_equal size_number
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->redo_buffer_size= $3;
- };
-
-opt_ts_nodegroup:
- NODEGROUP_SYM opt_equal real_ulong_num
- {
- LEX *lex= Lex;
- if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP)
- {
- my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP");
- YYABORT;
- }
- lex->alter_tablespace_info->nodegroup_id= $3;
- };
-
-opt_ts_comment:
- COMMENT_SYM opt_equal TEXT_STRING_sys
- {
- LEX *lex= Lex;
- if (lex->alter_tablespace_info->ts_comment != NULL)
- {
- my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"COMMENT");
- YYABORT;
- }
- lex->alter_tablespace_info->ts_comment= $3.str;
- };
-
-opt_ts_engine:
- opt_storage ENGINE_SYM opt_equal storage_engines
- {
- LEX *lex= Lex;
- if (lex->alter_tablespace_info->storage_engine != NULL)
- {
- my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),
- "STORAGE ENGINE");
- YYABORT;
- }
- lex->alter_tablespace_info->storage_engine= $4;
- };
-
-opt_ts_wait:
- /* empty */
- | ts_wait
- ;
-
-ts_wait:
- WAIT_SYM
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->wait_until_completed= TRUE;
- }
- | NO_WAIT_SYM
- {
- LEX *lex= Lex;
- if (!(lex->alter_tablespace_info->wait_until_completed))
- {
- my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT");
- YYABORT;
- }
- lex->alter_tablespace_info->wait_until_completed= FALSE;
- };
-
-size_number:
- real_ulong_num { $$= $1;}
- | IDENT
- {
- ulonglong number, test_number;
- uint text_shift_number= 0;
- longlong prefix_number;
- char *start_ptr= $1.str;
- uint str_len= $1.length;
- char *end_ptr= start_ptr + str_len;
- int error;
- prefix_number= my_strtoll10(start_ptr, &end_ptr, &error);
- if ((start_ptr + str_len - 1) == end_ptr)
- {
- switch (end_ptr[0])
- {
- case 'g':
- case 'G':
- text_shift_number+=10;
- case 'm':
- case 'M':
- text_shift_number+=10;
- case 'k':
- case 'K':
- text_shift_number+=10;
- break;
- default:
- {
- my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
- YYABORT;
- }
- }
- if (prefix_number >> 31)
- {
- my_error(ER_SIZE_OVERFLOW_ERROR, MYF(0));
- YYABORT;
- }
- number= prefix_number << text_shift_number;
- }
- else
- {
- my_error(ER_WRONG_SIZE_NUMBER, MYF(0));
- YYABORT;
- }
- $$= number;
- }
- ;
-
-/*
- End tablespace part
-*/
-
-create2:
- '(' create2a {}
- | opt_create_table_options
- opt_partitioning {}
- create3 {}
- | LIKE table_ident
- {
- LEX *lex=Lex;
- THD *thd= lex->thd;
- if (!(lex->like_name= $2))
- YYABORT;
- if ($2->db.str == NULL &&
- thd->copy_db_to(&($2->db.str), &($2->db.length)))
- {
- YYABORT;
- }
- }
- | '(' LIKE table_ident ')'
- {
- LEX *lex=Lex;
- THD *thd= lex->thd;
- if (!(lex->like_name= $3))
- YYABORT;
- if ($3->db.str == NULL &&
- thd->copy_db_to(&($3->db.str), &($3->db.length)))
- {
- YYABORT;
- }
- }
- ;
-
-create2a:
- field_list ')' opt_create_table_options
- opt_partitioning {}
- create3 {}
- | opt_partitioning {}
- create_select ')'
- { Select->set_braces(1);} union_opt {}
- ;
-
-create3:
- /* empty */ {}
- | opt_duplicate opt_as create_select
- { Select->set_braces(0);} union_clause {}
- | opt_duplicate opt_as '(' create_select ')'
- { Select->set_braces(1);} union_opt {}
- ;
-
-/*
- This part of the parser is about handling of the partition information.
-
- It's first version was written by Mikael Ronström with lots of answers to
- questions provided by Antony Curtis.
-
- The partition grammar can be called from three places.
- 1) CREATE TABLE ... PARTITION ..
- 2) ALTER TABLE table_name PARTITION ...
- 3) PARTITION ...
-
- The first place is called when a new table is created from a MySQL client.
- The second place is called when a table is altered with the ALTER TABLE
- command from a MySQL client.
- The third place is called when opening an frm file and finding partition
- info in the .frm file. It is necessary to avoid allowing PARTITION to be
- an allowed entry point for SQL client queries. This is arranged by setting
- some state variables before arriving here.
-
- To be able to handle errors we will only set error code in this code
- and handle the error condition in the function calling the parser. This
- is necessary to ensure we can also handle errors when calling the parser
- from the openfrm function.
-*/
-opt_partitioning:
- /* empty */ {}
- | partitioning
- ;
-
-partitioning:
- PARTITION_SYM
- {
-#ifdef WITH_PARTITION_STORAGE_ENGINE
- LEX *lex= Lex;
- lex->part_info= new partition_info();
- if (!lex->part_info)
- {
- mem_alloc_error(sizeof(partition_info));
- YYABORT;
- }
- if (lex->sql_command == SQLCOM_ALTER_TABLE)
- {
- lex->alter_info.flags|= ALTER_PARTITION;
- }
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- "partitioning", "--with-partition");
- YYABORT;
-#endif
-
- }
- partition
- ;
-
-partition_entry:
- PARTITION_SYM
- {
- LEX *lex= Lex;
- if (!lex->part_info)
- {
- yyerror(ER(ER_PARTITION_ENTRY_ERROR));
- YYABORT;
- }
- /*
- We enter here when opening the frm file to translate
- partition info string into part_info data structure.
- */
- }
- partition {}
- ;
-
-partition:
- BY part_type_def opt_no_parts {} opt_sub_part {} part_defs
- ;
-
-part_type_def:
- opt_linear KEY_SYM '(' part_field_list ')'
- {
- LEX *lex= Lex;
- lex->part_info->list_of_part_fields= TRUE;
- lex->part_info->part_type= HASH_PARTITION;
- }
- | opt_linear HASH_SYM
- { Lex->part_info->part_type= HASH_PARTITION; }
- part_func {}
- | RANGE_SYM
- { Lex->part_info->part_type= RANGE_PARTITION; }
- part_func {}
- | LIST_SYM
- { Lex->part_info->part_type= LIST_PARTITION; }
- part_func {}
- ;
-
-opt_linear:
- /* empty */ {}
- | LINEAR_SYM
- { Lex->part_info->linear_hash_ind= TRUE;}
- ;
-
-part_field_list:
- /* empty */ {}
- | part_field_item_list {}
- ;
-
-part_field_item_list:
- part_field_item {}
- | part_field_item_list ',' part_field_item {}
- ;
-
-part_field_item:
- ident
- {
- if (Lex->part_info->part_field_list.push_back($1.str))
- {
- mem_alloc_error(1);
- YYABORT;
- }
- }
- ;
-
-part_func:
- '(' remember_name part_func_expr remember_end ')'
- {
- LEX *lex= Lex;
- uint expr_len= (uint)($4 - $2) - 1;
- lex->part_info->list_of_part_fields= FALSE;
- lex->part_info->part_expr= $3;
- lex->part_info->part_func_string= (char* ) sql_memdup($2+1, expr_len);
- lex->part_info->part_func_len= expr_len;
- }
- ;
-
-sub_part_func:
- '(' remember_name part_func_expr remember_end ')'
- {
- LEX *lex= Lex;
- uint expr_len= (uint)($4 - $2) - 1;
- lex->part_info->list_of_subpart_fields= FALSE;
- lex->part_info->subpart_expr= $3;
- lex->part_info->subpart_func_string= (char* ) sql_memdup($2+1, expr_len);
- lex->part_info->subpart_func_len= expr_len;
- }
- ;
-
-
-opt_no_parts:
- /* empty */ {}
- | PARTITIONS_SYM real_ulong_num
- {
- uint no_parts= $2;
- LEX *lex= Lex;
- if (no_parts == 0)
- {
- my_error(ER_NO_PARTS_ERROR, MYF(0), "partitions");
- YYABORT;
- }
-
- lex->part_info->no_parts= no_parts;
- lex->part_info->use_default_no_partitions= FALSE;
- }
- ;
-
-opt_sub_part:
- /* empty */ {}
- | SUBPARTITION_SYM BY opt_linear HASH_SYM sub_part_func
- { Lex->part_info->subpart_type= HASH_PARTITION; }
- opt_no_subparts {}
- | SUBPARTITION_SYM BY opt_linear KEY_SYM
- '(' sub_part_field_list ')'
- {
- LEX *lex= Lex;
- lex->part_info->subpart_type= HASH_PARTITION;
- lex->part_info->list_of_subpart_fields= TRUE;
- }
- opt_no_subparts {}
- ;
-
-sub_part_field_list:
- sub_part_field_item {}
- | sub_part_field_list ',' sub_part_field_item {}
- ;
-
-sub_part_field_item:
- ident
- {
- if (Lex->part_info->subpart_field_list.push_back($1.str))
- {
- mem_alloc_error(1);
- YYABORT;
- }
- }
- ;
-
-part_func_expr:
- bit_expr
- {
- LEX *lex= Lex;
- bool not_corr_func;
- not_corr_func= !lex->safe_to_cache_query;
- lex->safe_to_cache_query= 1;
- if (not_corr_func)
- {
- yyerror(ER(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR));
- YYABORT;
- }
- $$=$1;
- }
- ;
-
-opt_no_subparts:
- /* empty */ {}
- | SUBPARTITIONS_SYM real_ulong_num
- {
- uint no_parts= $2;
- LEX *lex= Lex;
- if (no_parts == 0)
- {
- my_error(ER_NO_PARTS_ERROR, MYF(0), "subpartitions");
- YYABORT;
- }
- lex->part_info->no_subparts= no_parts;
- lex->part_info->use_default_no_subpartitions= FALSE;
- }
- ;
-
-part_defs:
- /* empty */
- {}
- | '(' part_def_list ')'
- {
- LEX *lex= Lex;
- partition_info *part_info= lex->part_info;
- uint count_curr_parts= part_info->partitions.elements;
- if (part_info->no_parts != 0)
- {
- if (part_info->no_parts !=
- count_curr_parts)
- {
- yyerror(ER(ER_PARTITION_WRONG_NO_PART_ERROR));
- YYABORT;
- }
- }
- else if (count_curr_parts > 0)
- {
- part_info->no_parts= count_curr_parts;
- }
- part_info->count_curr_subparts= 0;
- }
- ;
-
-part_def_list:
- part_definition {}
- | part_def_list ',' part_definition {}
- ;
-
-part_definition:
- PARTITION_SYM
- {
- LEX *lex= Lex;
- partition_info *part_info= lex->part_info;
- partition_element *p_elem= new partition_element();
- uint part_id= part_info->partitions.elements;
-
- if (!p_elem || part_info->partitions.push_back(p_elem))
- {
- mem_alloc_error(sizeof(partition_element));
- YYABORT;
- }
- p_elem->part_state= PART_NORMAL;
- part_info->curr_part_elem= p_elem;
- part_info->current_partition= p_elem;
- part_info->use_default_partitions= FALSE;
- part_info->use_default_no_partitions= FALSE;
- }
- part_name {}
- opt_part_values {}
- opt_part_options {}
- opt_sub_partition {}
- ;
-
-part_name:
- ident
- {
- LEX *lex= Lex;
- partition_info *part_info= lex->part_info;
- partition_element *p_elem= part_info->curr_part_elem;
- p_elem->partition_name= $1.str;
- }
- ;
-
-opt_part_values:
- /* empty */
- {
- LEX *lex= Lex;
- if (!is_partition_management(lex))
- {
- if (lex->part_info->part_type == RANGE_PARTITION)
- {
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
- YYABORT;
- }
- if (lex->part_info->part_type == LIST_PARTITION)
- {
- my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0),
- "LIST", "IN");
- YYABORT;
- }
- }
- else
- lex->part_info->part_type= HASH_PARTITION;
- }
- | VALUES LESS_SYM THAN_SYM part_func_max
- {
- LEX *lex= Lex;
- if (!is_partition_management(lex))
- {
- if (Lex->part_info->part_type != RANGE_PARTITION)
- {
- my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
- "RANGE", "LESS THAN");
- YYABORT;
- }
- }
- else
- lex->part_info->part_type= RANGE_PARTITION;
- }
- | VALUES IN_SYM '(' part_list_func ')'
- {
- LEX *lex= Lex;
- if (!is_partition_management(lex))
- {
- if (Lex->part_info->part_type != LIST_PARTITION)
- {
- my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
- "LIST", "IN");
- YYABORT;
- }
- }
- else
- lex->part_info->part_type= LIST_PARTITION;
- }
- ;
-
-part_func_max:
- max_value_sym
- {
- LEX *lex= Lex;
- if (lex->part_info->defined_max_value)
- {
- yyerror(ER(ER_PARTITION_MAXVALUE_ERROR));
- YYABORT;
- }
- lex->part_info->defined_max_value= TRUE;
- lex->part_info->curr_part_elem->max_value= TRUE;
- lex->part_info->curr_part_elem->range_value= LONGLONG_MAX;
- }
- | part_range_func
- {
- if (Lex->part_info->defined_max_value)
- {
- yyerror(ER(ER_PARTITION_MAXVALUE_ERROR));
- YYABORT;
- }
- if (Lex->part_info->curr_part_elem->has_null_value)
- {
- yyerror(ER(ER_NULL_IN_VALUES_LESS_THAN));
- YYABORT;
- }
- }
- ;
-
-max_value_sym:
- MAX_VALUE_SYM
- | '(' MAX_VALUE_SYM ')'
- ;
-
-part_range_func:
- '(' part_bit_expr ')'
- {
- partition_info *part_info= Lex->part_info;
- if (!($2->unsigned_flag))
- part_info->curr_part_elem->signed_flag= TRUE;
- part_info->curr_part_elem->range_value= $2->value;
- }
- ;
-
-part_list_func:
- part_list_item {}
- | part_list_func ',' part_list_item {}
- ;
-
-part_list_item:
- part_bit_expr
- {
- part_elem_value *value_ptr= $1;
- partition_info *part_info= Lex->part_info;
- if (!value_ptr->unsigned_flag)
- part_info->curr_part_elem->signed_flag= TRUE;
- if (!value_ptr->null_value &&
- part_info->curr_part_elem->
- list_val_list.push_back(value_ptr))
- {
- mem_alloc_error(sizeof(part_elem_value));
- YYABORT;
- }
- }
- ;
-
-part_bit_expr:
- bit_expr
- {
- Item *part_expr= $1;
- bool not_corr_func;
- int part_expression_ok= 1;
- LEX *lex= Lex;
- THD *thd= YYTHD;
- longlong item_value;
- Name_resolution_context *context= &lex->current_select->context;
- TABLE_LIST *save_list= context->table_list;
- const char *save_where= thd->where;
-
- context->table_list= 0;
- thd->where= "partition function";
-
- part_elem_value *value_ptr=
- (part_elem_value*)sql_alloc(sizeof(part_elem_value));
- if (!value_ptr)
- {
- mem_alloc_error(sizeof(part_elem_value));
- YYABORT;
- }
- if (part_expr->walk(&Item::check_partition_func_processor, 0,
- NULL))
- {
- my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
- YYABORT;
- }
- if (part_expr->fix_fields(YYTHD, (Item**)0) ||
- ((context->table_list= save_list), FALSE) ||
- (!part_expr->const_item()) ||
- (!lex->safe_to_cache_query))
- {
- my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
- YYABORT;
- }
- thd->where= save_where;
- value_ptr->value= part_expr->val_int();
- value_ptr->unsigned_flag= TRUE;
- if (!part_expr->unsigned_flag &&
- value_ptr->value < 0)
- value_ptr->unsigned_flag= FALSE;
- if ((value_ptr->null_value= part_expr->null_value))
- {
- if (Lex->part_info->curr_part_elem->has_null_value)
- {
- my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0));
- YYABORT;
- }
- Lex->part_info->curr_part_elem->has_null_value= TRUE;
- }
- else if (part_expr->result_type() != INT_RESULT &&
- !part_expr->null_value)
- {
- yyerror(ER(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR));
- YYABORT;
- }
- $$= value_ptr;
- }
- ;
-
-opt_sub_partition:
- /* empty */
- {
- if (Lex->part_info->no_subparts != 0 &&
- !Lex->part_info->use_default_subpartitions)
- {
- yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
- YYABORT;
- }
- }
- | '(' sub_part_list ')'
- {
- LEX *lex= Lex;
- partition_info *part_info= lex->part_info;
- if (part_info->no_subparts != 0)
- {
- if (part_info->no_subparts !=
- part_info->count_curr_subparts)
- {
- yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
- YYABORT;
- }
- }
- else if (part_info->count_curr_subparts > 0)
- {
- if (part_info->partitions.elements > 1)
- {
- yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR));
- YYABORT;
- }
- part_info->no_subparts= part_info->count_curr_subparts;
- }
- part_info->count_curr_subparts= 0;
- }
- ;
-
-sub_part_list:
- sub_part_definition {}
- | sub_part_list ',' sub_part_definition {}
- ;
-
-sub_part_definition:
- SUBPARTITION_SYM
- {
- LEX *lex= Lex;
- partition_info *part_info= lex->part_info;
- partition_element *curr_part= part_info->current_partition;
- partition_element *sub_p_elem= new partition_element(curr_part);
- if (!sub_p_elem ||
- curr_part->subpartitions.push_back(sub_p_elem))
- {
- mem_alloc_error(sizeof(partition_element));
- YYABORT;
- }
- part_info->curr_part_elem= sub_p_elem;
- part_info->use_default_subpartitions= FALSE;
- part_info->use_default_no_subpartitions= FALSE;
- part_info->count_curr_subparts++;
- }
- sub_name opt_part_options {}
- ;
-
-sub_name:
- ident_or_text
- { Lex->part_info->curr_part_elem->partition_name= $1.str; }
- ;
-
-opt_part_options:
- /* empty */ {}
- | opt_part_option_list {}
- ;
-
-opt_part_option_list:
- opt_part_option_list opt_part_option {}
- | opt_part_option {}
- ;
-
-opt_part_option:
- TABLESPACE opt_equal ident_or_text
- { Lex->part_info->curr_part_elem->tablespace_name= $3.str; }
- | opt_storage ENGINE_SYM opt_equal storage_engines
- {
- LEX *lex= Lex;
- lex->part_info->curr_part_elem->engine_type= $4;
- lex->part_info->default_engine_type= $4;
- }
- | NODEGROUP_SYM opt_equal real_ulong_num
- { Lex->part_info->curr_part_elem->nodegroup_id= $3; }
- | MAX_ROWS opt_equal real_ulonglong_num
- { Lex->part_info->curr_part_elem->part_max_rows= $3; }
- | MIN_ROWS opt_equal real_ulonglong_num
- { Lex->part_info->curr_part_elem->part_min_rows= $3; }
- | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
- { Lex->part_info->curr_part_elem->data_file_name= $4.str; }
- | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
- { Lex->part_info->curr_part_elem->index_file_name= $4.str; }
- | COMMENT_SYM opt_equal TEXT_STRING_sys
- { Lex->part_info->curr_part_elem->part_comment= $3.str; }
- ;
-
-/*
- End of partition parser part
-*/
-
-create_select:
- SELECT_SYM
- {
- LEX *lex=Lex;
- lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ;
- if (lex->sql_command == SQLCOM_INSERT)
- lex->sql_command= SQLCOM_INSERT_SELECT;
- else if (lex->sql_command == SQLCOM_REPLACE)
- lex->sql_command= SQLCOM_REPLACE_SELECT;
- /*
- The following work only with the local list, the global list
- is created correctly in this case
- */
- lex->current_select->table_list.save_and_clear(&lex->save_list);
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
- }
- opt_select_from
- {
- /*
- The following work only with the local list, the global list
- is created correctly in this case
- */
- Lex->current_select->table_list.push_front(&Lex->save_list);
- }
- ;
-
-opt_as:
- /* empty */ {}
- | AS {};
-
-opt_create_database_options:
- /* empty */ {}
- | create_database_options {};
-
-create_database_options:
- create_database_option {}
- | create_database_options create_database_option {};
-
-create_database_option:
- default_collation {}
- | default_charset {};
-
-opt_table_options:
- /* empty */ { $$= 0; }
- | table_options { $$= $1;};
-
-table_options:
- table_option { $$=$1; }
- | table_option table_options { $$= $1 | $2; };
-
-table_option:
- TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; };
-
-opt_if_not_exists:
- /* empty */ { $$= 0; }
- | IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; };
-
-opt_create_table_options:
- /* empty */
- | create_table_options;
-
-create_table_options_space_separated:
- create_table_option
- | create_table_option create_table_options_space_separated;
-
-create_table_options:
- create_table_option
- | create_table_option create_table_options
- | create_table_option ',' create_table_options;
-
-create_table_option:
- ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; }
- | TYPE_SYM opt_equal storage_engines
- {
- Lex->create_info.db_type= $3;
- WARN_DEPRECATED(yythd, "5.2", "TYPE=storage_engine",
- "'ENGINE=storage_engine'");
- Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE;
- }
- | MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
- | MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
- | AVG_ROW_LENGTH opt_equal ulong_num { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
- | PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; }
- | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; }
- | AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
- | PACK_KEYS_SYM opt_equal ulong_num
- {
- switch($3) {
- case 0:
- Lex->create_info.table_options|= HA_OPTION_NO_PACK_KEYS;
- break;
- case 1:
- Lex->create_info.table_options|= HA_OPTION_PACK_KEYS;
- break;
- default:
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
- }
- | PACK_KEYS_SYM opt_equal DEFAULT
- {
- Lex->create_info.table_options&=
- ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
- Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;
- }
- | CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
- | DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
- | ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
- | UNION_SYM opt_equal '(' table_list ')'
- {
- /* Move the union list to the merge_list */
- LEX *lex=Lex;
- TABLE_LIST *table_list= lex->select_lex.get_table_list();
- lex->create_info.merge_list= lex->select_lex.table_list;
- lex->create_info.merge_list.elements--;
- lex->create_info.merge_list.first=
- (byte*) (table_list->next_local);
- lex->select_lex.table_list.elements=1;
- lex->select_lex.table_list.next=
- (byte**) &(table_list->next_local);
- table_list->next_local= 0;
- lex->create_info.used_fields|= HA_CREATE_USED_UNION;
- }
- | default_charset
- | default_collation
- | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
- | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR; }
- | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR; }
- | TABLESPACE ident {Lex->create_info.tablespace= $2.str;}
- | STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;}
- | STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;}
- | CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; }
- | KEY_BLOCK_SIZE opt_equal ulong_num
- {
- Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE;
- Lex->create_info.key_block_size= $3;
- }
- ;
-
-default_charset:
- opt_default charset opt_equal charset_name_or_default
- {
- HA_CREATE_INFO *cinfo= &Lex->create_info;
- if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
- cinfo->default_table_charset && $4 &&
- !my_charset_same(cinfo->default_table_charset,$4))
- {
- my_error(ER_CONFLICTING_DECLARATIONS, MYF(0),
- "CHARACTER SET ", cinfo->default_table_charset->csname,
- "CHARACTER SET ", $4->csname);
- YYABORT;
- }
- Lex->create_info.default_table_charset= $4;
- Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
- };
-
-default_collation:
- opt_default COLLATE_SYM opt_equal collation_name_or_default
- {
- HA_CREATE_INFO *cinfo= &Lex->create_info;
- if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) &&
- cinfo->default_table_charset && $4 &&
- !my_charset_same(cinfo->default_table_charset,$4))
- {
- my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
- $4->name, cinfo->default_table_charset->csname);
- YYABORT;
- }
- Lex->create_info.default_table_charset= $4;
- Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
- };
-
-storage_engines:
- ident_or_text
- {
- $$ = ha_resolve_by_name(YYTHD, &$1);
- if ($$ == NULL)
- if (YYTHD->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION)
- {
- my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str);
- YYABORT;
- }
- else
- {
- push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_ERROR,
- ER_UNKNOWN_STORAGE_ENGINE,
- ER(ER_UNKNOWN_STORAGE_ENGINE), $1.str);
- }
- };
-
-row_types:
- DEFAULT { $$= ROW_TYPE_DEFAULT; }
- | FIXED_SYM { $$= ROW_TYPE_FIXED; }
- | DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; }
- | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; }
- | REDUNDANT_SYM { $$= ROW_TYPE_REDUNDANT; }
- | COMPACT_SYM { $$= ROW_TYPE_COMPACT; };
-
-merge_insert_types:
- NO_SYM { $$= MERGE_INSERT_DISABLED; }
- | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; }
- | LAST_SYM { $$= MERGE_INSERT_TO_LAST; };
-
-opt_select_from:
- opt_limit_clause {}
- | select_from select_lock_type;
-
-udf_func_type:
- /* empty */ { $$ = UDFTYPE_FUNCTION; }
- | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; };
-
-udf_type:
- STRING_SYM {$$ = (int) STRING_RESULT; }
- | REAL {$$ = (int) REAL_RESULT; }
- | DECIMAL_SYM {$$ = (int) DECIMAL_RESULT; }
- | INT_SYM {$$ = (int) INT_RESULT; };
-
-field_list:
- field_list_item
- | field_list ',' field_list_item;
-
-
-field_list_item:
- column_def
- | key_def
- ;
-
-column_def:
- field_spec opt_check_constraint
- | field_spec references
- {
- Lex->col_list.empty(); /* Alloced by sql_alloc */
- }
- ;
-
-key_def:
- key_type opt_ident key_alg '(' key_list ')' key_options
- {
- LEX *lex=Lex;
- if ($1 != Key::FULLTEXT && lex->key_create_info.parser_name.str)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- lex->key_list.push_back(new Key($1,$2, &lex->key_create_info, 0,
- lex->col_list));
- lex->col_list.empty(); /* Alloced by sql_alloc */
- }
- | opt_constraint constraint_key_type opt_ident key_alg
- '(' key_list ')' key_options
- {
- LEX *lex=Lex;
- const char *key_name= $3 ? $3 : $1;
- lex->key_list.push_back(new Key($2, key_name, &lex->key_create_info, 0,
- lex->col_list));
- lex->col_list.empty(); /* Alloced by sql_alloc */
- }
- | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references
- {
- LEX *lex=Lex;
- lex->key_list.push_back(new foreign_key($4 ? $4:$1, lex->col_list,
- $8,
- lex->ref_list,
- lex->fk_delete_opt,
- lex->fk_update_opt,
- lex->fk_match_option));
- lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1,
- &default_key_create_info, 1,
- lex->col_list));
- lex->col_list.empty(); /* Alloced by sql_alloc */
-
- /* Only used for ALTER TABLE. Ignored otherwise. */
- lex->alter_info.flags|= ALTER_FOREIGN_KEY;
- }
- | constraint opt_check_constraint
- {
- Lex->col_list.empty(); /* Alloced by sql_alloc */
- }
- | opt_constraint check_constraint
- {
- Lex->col_list.empty(); /* Alloced by sql_alloc */
- }
- ;
-
-opt_check_constraint:
- /* empty */
- | check_constraint
- ;
-
-check_constraint:
- CHECK_SYM expr
- ;
-
-opt_constraint:
- /* empty */ { $$=(char*) 0; }
- | constraint { $$= $1; }
- ;
-
-constraint:
- CONSTRAINT opt_ident { $$=$2; }
- ;
-
-field_spec:
- field_ident
- {
- LEX *lex=Lex;
- lex->length=lex->dec=0; lex->type=0;
- lex->default_value= lex->on_update_value= 0;
- lex->comment=null_lex_str;
- lex->charset=NULL;
- }
- type opt_attribute
- {
- LEX *lex=Lex;
- if (add_field_to_list(lex->thd, $1.str,
- (enum enum_field_types) $3,
- lex->length,lex->dec,lex->type,
- lex->default_value, lex->on_update_value,
- &lex->comment,
- lex->change,&lex->interval_list,lex->charset,
- lex->uint_geom_type))
- YYABORT;
- };
-
-type:
- int_type opt_len field_options { $$=$1; }
- | real_type opt_precision field_options { $$=$1; }
- | FLOAT_SYM float_options field_options { $$=FIELD_TYPE_FLOAT; }
- | BIT_SYM { Lex->length= (char*) "1";
- $$=FIELD_TYPE_BIT; }
- | BIT_SYM '(' NUM ')' { Lex->length= $3.str;
- $$=FIELD_TYPE_BIT; }
- | BOOL_SYM { Lex->length=(char*) "1";
- $$=FIELD_TYPE_TINY; }
- | BOOLEAN_SYM { Lex->length=(char*) "1";
- $$=FIELD_TYPE_TINY; }
- | char '(' NUM ')' opt_binary { Lex->length=$3.str;
- $$=FIELD_TYPE_STRING; }
- | char opt_binary { Lex->length=(char*) "1";
- $$=FIELD_TYPE_STRING; }
- | nchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str;
- $$=FIELD_TYPE_STRING;
- Lex->charset=national_charset_info; }
- | nchar opt_bin_mod { Lex->length=(char*) "1";
- $$=FIELD_TYPE_STRING;
- Lex->charset=national_charset_info; }
- | BINARY '(' NUM ')' { Lex->length=$3.str;
- Lex->charset=&my_charset_bin;
- $$=FIELD_TYPE_STRING; }
- | BINARY { Lex->length= (char*) "1";
- Lex->charset=&my_charset_bin;
- $$=FIELD_TYPE_STRING; }
- | varchar '(' NUM ')' opt_binary { Lex->length=$3.str;
- $$= MYSQL_TYPE_VARCHAR; }
- | nvarchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str;
- $$= MYSQL_TYPE_VARCHAR;
- Lex->charset=national_charset_info; }
- | VARBINARY '(' NUM ')' { Lex->length=$3.str;
- Lex->charset=&my_charset_bin;
- $$= MYSQL_TYPE_VARCHAR; }
- | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; }
- | DATE_SYM { $$=FIELD_TYPE_DATE; }
- | TIME_SYM { $$=FIELD_TYPE_TIME; }
- | TIMESTAMP opt_len
- {
- if (YYTHD->variables.sql_mode & MODE_MAXDB)
- $$=FIELD_TYPE_DATETIME;
- else
- {
- /*
- Unlike other types TIMESTAMP fields are NOT NULL by default.
- */
- Lex->type|= NOT_NULL_FLAG;
- $$=FIELD_TYPE_TIMESTAMP;
- }
- }
- | DATETIME { $$=FIELD_TYPE_DATETIME; }
- | TINYBLOB { Lex->charset=&my_charset_bin;
- $$=FIELD_TYPE_TINY_BLOB; }
- | BLOB_SYM opt_len { Lex->charset=&my_charset_bin;
- $$=FIELD_TYPE_BLOB; }
- | spatial_type
- {
-#ifdef HAVE_SPATIAL
- Lex->charset=&my_charset_bin;
- Lex->uint_geom_type= (uint)$1;
- $$=FIELD_TYPE_GEOMETRY;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
- YYABORT;
-#endif
- }
- | MEDIUMBLOB { Lex->charset=&my_charset_bin;
- $$=FIELD_TYPE_MEDIUM_BLOB; }
- | LONGBLOB { Lex->charset=&my_charset_bin;
- $$=FIELD_TYPE_LONG_BLOB; }
- | LONG_SYM VARBINARY { Lex->charset=&my_charset_bin;
- $$=FIELD_TYPE_MEDIUM_BLOB; }
- | LONG_SYM varchar opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; }
- | TINYTEXT opt_binary { $$=FIELD_TYPE_TINY_BLOB; }
- | TEXT_SYM opt_len opt_binary { $$=FIELD_TYPE_BLOB; }
- | MEDIUMTEXT opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; }
- | LONGTEXT opt_binary { $$=FIELD_TYPE_LONG_BLOB; }
- | DECIMAL_SYM float_options field_options
- { $$=FIELD_TYPE_NEWDECIMAL;}
- | NUMERIC_SYM float_options field_options
- { $$=FIELD_TYPE_NEWDECIMAL;}
- | FIXED_SYM float_options field_options
- { $$=FIELD_TYPE_NEWDECIMAL;}
- | ENUM {Lex->interval_list.empty();} '(' string_list ')' opt_binary
- { $$=FIELD_TYPE_ENUM; }
- | SET { Lex->interval_list.empty();} '(' string_list ')' opt_binary
- { $$=FIELD_TYPE_SET; }
- | LONG_SYM opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; }
- | SERIAL_SYM
- {
- $$=FIELD_TYPE_LONGLONG;
- Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG |
- UNIQUE_FLAG);
- }
- ;
-
-spatial_type:
- GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; }
- | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; }
- | POINT_SYM { Lex->length= (char*)"21";
- $$= Field::GEOM_POINT;
- }
- | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; }
- | LINESTRING { $$= Field::GEOM_LINESTRING; }
- | MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; }
- | POLYGON { $$= Field::GEOM_POLYGON; }
- | MULTIPOLYGON { $$= Field::GEOM_MULTIPOLYGON; }
- ;
-
-char:
- CHAR_SYM {}
- ;
-
-nchar:
- NCHAR_SYM {}
- | NATIONAL_SYM CHAR_SYM {}
- ;
-
-varchar:
- char VARYING {}
- | VARCHAR {}
- ;
-
-nvarchar:
- NATIONAL_SYM VARCHAR {}
- | NVARCHAR_SYM {}
- | NCHAR_SYM VARCHAR {}
- | NATIONAL_SYM CHAR_SYM VARYING {}
- | NCHAR_SYM VARYING {}
- ;
-
-int_type:
- INT_SYM { $$=FIELD_TYPE_LONG; }
- | TINYINT { $$=FIELD_TYPE_TINY; }
- | SMALLINT { $$=FIELD_TYPE_SHORT; }
- | MEDIUMINT { $$=FIELD_TYPE_INT24; }
- | BIGINT { $$=FIELD_TYPE_LONGLONG; };
-
-real_type:
- REAL { $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ?
- FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; }
- | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; }
- | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; };
-
-
-float_options:
- /* empty */ { Lex->dec=Lex->length= (char*)0; }
- | '(' NUM ')' { Lex->length=$2.str; Lex->dec= (char*)0; }
- | precision {};
-
-precision:
- '(' NUM ',' NUM ')'
- {
- LEX *lex=Lex;
- lex->length=$2.str; lex->dec=$4.str;
- };
-
-field_options:
- /* empty */ {}
- | field_opt_list {};
-
-field_opt_list:
- field_opt_list field_option {}
- | field_option {};
-
-field_option:
- SIGNED_SYM {}
- | UNSIGNED { Lex->type|= UNSIGNED_FLAG;}
- | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; };
-
-opt_len:
- /* empty */ { Lex->length=(char*) 0; } /* use default length */
- | '(' NUM ')' { Lex->length= $2.str; };
-
-opt_precision:
- /* empty */ {}
- | precision {};
-
-opt_attribute:
- /* empty */ {}
- | opt_attribute_list {};
-
-opt_attribute_list:
- opt_attribute_list attribute {}
- | attribute;
-
-attribute:
- NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; }
- | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; }
- | DEFAULT now_or_signed_literal { Lex->default_value=$2; }
- | ON UPDATE_SYM NOW_SYM optional_braces
- { Lex->on_update_value= new Item_func_now_local(); }
- | AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
- | SERIAL_SYM DEFAULT VALUE_SYM
- {
- LEX *lex=Lex;
- lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
- lex->alter_info.flags|= ALTER_ADD_INDEX;
- }
- | opt_primary KEY_SYM
- {
- LEX *lex=Lex;
- lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
- lex->alter_info.flags|= ALTER_ADD_INDEX;
- }
- | UNIQUE_SYM
- {
- LEX *lex=Lex;
- lex->type|= UNIQUE_FLAG;
- lex->alter_info.flags|= ALTER_ADD_INDEX;
- }
- | UNIQUE_SYM KEY_SYM
- {
- LEX *lex=Lex;
- lex->type|= UNIQUE_KEY_FLAG;
- lex->alter_info.flags|= ALTER_ADD_INDEX;
- }
- | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; }
- | COLLATE_SYM collation_name
- {
- if (Lex->charset && !my_charset_same(Lex->charset,$2))
- {
- my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
- $2->name,Lex->charset->csname);
- YYABORT;
- }
- else
- {
- Lex->charset=$2;
- }
- }
- ;
-
-now_or_signed_literal:
- NOW_SYM optional_braces { $$= new Item_func_now_local(); }
- | signed_literal { $$=$1; }
- ;
-
-charset:
- CHAR_SYM SET {}
- | CHARSET {}
- ;
-
-charset_name:
- ident_or_text
- {
- if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))))
- {
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str);
- YYABORT;
- }
- }
- | BINARY { $$= &my_charset_bin; }
- ;
-
-charset_name_or_default:
- charset_name { $$=$1; }
- | DEFAULT { $$=NULL; } ;
-
-
-old_or_new_charset_name:
- ident_or_text
- {
- if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) &&
- !($$=get_old_charset_by_name($1.str)))
- {
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str);
- YYABORT;
- }
- }
- | BINARY { $$= &my_charset_bin; }
- ;
-
-old_or_new_charset_name_or_default:
- old_or_new_charset_name { $$=$1; }
- | DEFAULT { $$=NULL; } ;
-
-collation_name:
- ident_or_text
- {
- if (!($$=get_charset_by_name($1.str,MYF(0))))
- {
- my_error(ER_UNKNOWN_COLLATION, MYF(0), $1.str);
- YYABORT;
- }
- };
-
-opt_collate:
- /* empty */ { $$=NULL; }
- | COLLATE_SYM collation_name_or_default { $$=$2; }
- ;
-
-collation_name_or_default:
- collation_name { $$=$1; }
- | DEFAULT { $$=NULL; } ;
-
-opt_default:
- /* empty */ {}
- | DEFAULT {};
-
-opt_binary:
- /* empty */ { Lex->charset=NULL; }
- | ASCII_SYM opt_bin_mod { Lex->charset=&my_charset_latin1; }
- | BYTE_SYM { Lex->charset=&my_charset_bin; }
- | UNICODE_SYM opt_bin_mod
- {
- if (!(Lex->charset=get_charset_by_csname("ucs2",
- MY_CS_PRIMARY,MYF(0))))
- {
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2");
- YYABORT;
- }
- }
- | charset charset_name opt_bin_mod { Lex->charset=$2; }
- | BINARY opt_bin_charset { Lex->type|= BINCMP_FLAG; };
-
-opt_bin_mod:
- /* empty */ { }
- | BINARY { Lex->type|= BINCMP_FLAG; };
-
-opt_bin_charset:
- /* empty */ { Lex->charset= NULL; }
- | ASCII_SYM { Lex->charset=&my_charset_latin1; }
- | UNICODE_SYM
- {
- if (!(Lex->charset=get_charset_by_csname("ucs2",
- MY_CS_PRIMARY,MYF(0))))
- {
- my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2");
- YYABORT;
- }
- }
- | charset charset_name { Lex->charset=$2; } ;
-
-opt_primary:
- /* empty */
- | PRIMARY_SYM
- ;
-
-references:
- REFERENCES table_ident
- {
- LEX *lex=Lex;
- lex->fk_delete_opt= lex->fk_update_opt= lex->fk_match_option= 0;
- lex->ref_list.empty();
- }
- opt_ref_list
- {
- $$=$2;
- };
-
-opt_ref_list:
- /* empty */ opt_on_delete {}
- | '(' ref_list ')' opt_on_delete {};
-
-ref_list:
- ref_list ',' ident { Lex->ref_list.push_back(new key_part_spec($3.str)); }
- | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); };
-
-
-opt_on_delete:
- /* empty */ {}
- | opt_on_delete_list {};
-
-opt_on_delete_list:
- opt_on_delete_list opt_on_delete_item {}
- | opt_on_delete_item {};
-
-opt_on_delete_item:
- ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; }
- | ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; }
- | MATCH FULL { Lex->fk_match_option= foreign_key::FK_MATCH_FULL; }
- | MATCH PARTIAL { Lex->fk_match_option= foreign_key::FK_MATCH_PARTIAL; }
- | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; };
-
-delete_option:
- RESTRICT { $$= (int) foreign_key::FK_OPTION_RESTRICT; }
- | CASCADE { $$= (int) foreign_key::FK_OPTION_CASCADE; }
- | SET NULL_SYM { $$= (int) foreign_key::FK_OPTION_SET_NULL; }
- | NO_SYM ACTION { $$= (int) foreign_key::FK_OPTION_NO_ACTION; }
- | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; };
-
-key_type:
- key_or_index { $$= Key::MULTIPLE; }
- | FULLTEXT_SYM opt_key_or_index { $$= Key::FULLTEXT; }
- | SPATIAL_SYM opt_key_or_index
- {
-#ifdef HAVE_SPATIAL
- $$= Key::SPATIAL;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
- YYABORT;
-#endif
- };
-
-constraint_key_type:
- PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; }
- | UNIQUE_SYM opt_key_or_index { $$= Key::UNIQUE; };
-
-key_or_index:
- KEY_SYM {}
- | INDEX_SYM {};
-
-opt_key_or_index:
- /* empty */ {}
- | key_or_index
- ;
-
-keys_or_index:
- KEYS {}
- | INDEX_SYM {}
- | INDEXES {};
-
-opt_unique_or_fulltext:
- /* empty */ { $$= Key::MULTIPLE; }
- | UNIQUE_SYM { $$= Key::UNIQUE; }
- | FULLTEXT_SYM { $$= Key::FULLTEXT;}
- | SPATIAL_SYM
- {
-#ifdef HAVE_SPATIAL
- $$= Key::SPATIAL;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
- YYABORT;
-#endif
- }
- ;
-
-init_key_options:
- {
- Lex->key_create_info= default_key_create_info;
- }
- ;
-
-/*
- For now, key_alg initializies lex->key_create_info.
- In the future, when all key options are after key definition,
- we can remove key_alg and move init_key_options to key_options
-*/
-
-key_alg:
- /* empty */ init_key_options
- | init_key_options key_using_alg
- ;
-
-key_options:
- /* empty */ {}
- | key_opts
- ;
-
-key_opts:
- key_opt
- | key_opts key_opt
- ;
-
-key_using_alg:
- USING btree_or_rtree { Lex->key_create_info.algorithm= $2; }
- | TYPE_SYM btree_or_rtree { Lex->key_create_info.algorithm= $2; }
- ;
-
-key_opt:
- key_using_alg
- | KEY_BLOCK_SIZE opt_equal ulong_num
- { Lex->key_create_info.block_size= $3; }
- | WITH PARSER_SYM IDENT_sys
- {
- if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN))
- Lex->key_create_info.parser_name= $3;
- else
- {
- my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str);
- YYABORT;
- }
- }
- ;
-
-
-btree_or_rtree:
- BTREE_SYM { $$= HA_KEY_ALG_BTREE; }
- | RTREE_SYM
- {
- $$= HA_KEY_ALG_RTREE;
- }
- | HASH_SYM { $$= HA_KEY_ALG_HASH; };
-
-key_list:
- key_list ',' key_part order_dir { Lex->col_list.push_back($3); }
- | key_part order_dir { Lex->col_list.push_back($1); };
-
-key_part:
- ident { $$=new key_part_spec($1.str); }
- | ident '(' NUM ')'
- {
- int key_part_len= atoi($3.str);
- if (!key_part_len)
- {
- my_error(ER_KEY_PART_0, MYF(0), $1.str);
- }
- $$=new key_part_spec($1.str,(uint) key_part_len);
- };
-
-opt_ident:
- /* empty */ { $$=(char*) 0; } /* Defaultlength */
- | field_ident { $$=$1.str; };
-
-opt_component:
- /* empty */ { $$= null_lex_str; }
- | '.' ident { $$= $2; };
-
-string_list:
- text_string { Lex->interval_list.push_back($1); }
- | string_list ',' text_string { Lex->interval_list.push_back($3); };
-
-/*
-** Alter table
-*/
-
-alter:
- ALTER opt_ignore TABLE_SYM table_ident
- {
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- lex->name.str= 0;
- lex->name.length= 0;
- lex->sql_command= SQLCOM_ALTER_TABLE;
- lex->duplicates= DUP_ERROR;
- if (!lex->select_lex.add_table_to_list(thd, $4, NULL,
- TL_OPTION_UPDATING))
- YYABORT;
- lex->create_list.empty();
- lex->key_list.empty();
- lex->col_list.empty();
- lex->select_lex.init_order();
- lex->like_name= 0;
- lex->select_lex.db=
- ((TABLE_LIST*) lex->select_lex.table_list.first)->db;
- bzero((char*) &lex->create_info,sizeof(lex->create_info));
- lex->create_info.db_type= 0;
- lex->create_info.default_table_charset= NULL;
- lex->create_info.row_type= ROW_TYPE_NOT_USED;
- lex->alter_info.reset();
- lex->alter_info.flags= 0;
- lex->no_write_to_binlog= 0;
- }
- alter_commands
- {}
- | ALTER DATABASE ident_or_empty
- {
- Lex->create_info.default_table_charset= NULL;
- Lex->create_info.used_fields= 0;
- }
- opt_create_database_options
- {
- LEX *lex=Lex;
- THD *thd= Lex->thd;
- lex->sql_command=SQLCOM_ALTER_DB;
- lex->name= $3;
- if (lex->name.str == NULL &&
- thd->copy_db_to(&lex->name.str, &lex->name.length))
- YYABORT;
- }
- | ALTER PROCEDURE sp_name
- {
- LEX *lex= Lex;
-
- if (lex->sphead)
- {
- my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE");
- YYABORT;
- }
- bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
- }
- sp_a_chistics
- {
- LEX *lex=Lex;
-
- lex->sql_command= SQLCOM_ALTER_PROCEDURE;
- lex->spname= $3;
- }
- | ALTER FUNCTION_SYM sp_name
- {
- LEX *lex= Lex;
-
- if (lex->sphead)
- {
- my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION");
- YYABORT;
- }
- bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
- }
- sp_a_chistics
- {
- LEX *lex=Lex;
-
- lex->sql_command= SQLCOM_ALTER_FUNCTION;
- lex->spname= $3;
- }
- | ALTER view_algorithm_opt definer view_suid
- VIEW_SYM table_ident
- {
- THD *thd= YYTHD;
- LEX *lex= thd->lex;
- lex->sql_command= SQLCOM_CREATE_VIEW;
- lex->create_view_mode= VIEW_ALTER;
- /* first table in list is target VIEW name */
- lex->select_lex.add_table_to_list(thd, $6, NULL, TL_OPTION_UPDATING);
- }
- view_list_opt AS view_select view_check_option
- {}
- | ALTER EVENT_SYM sp_name
- /*
- BE CAREFUL when you add a new rule to update the block where
- YYTHD->client_capabilities is set back to original value
- */
- {
- /*
- It is safe to use Lex->spname because
- ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO
- is not allowed. Lex->spname is used in the case of RENAME TO
- If it had to be supported spname had to be added to
- Event_parse_data.
- */
-
- if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD)))
- YYABORT;
- Lex->event_parse_data->identifier= $3;
-
- /*
- We have to turn off CLIENT_MULTI_QUERIES while parsing a
- stored procedure, otherwise yylex will chop it into pieces
- at each ';'.
- */
- $$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES;
- YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
-
- Lex->sql_command= SQLCOM_ALTER_EVENT;
- }
- ev_alter_on_schedule_completion
- opt_ev_rename_to
- opt_ev_status
- opt_ev_comment
- opt_ev_sql_stmt
- {
- /*
- $1 - ALTER
- $2 - EVENT_SYM
- $3 - sp_name
- $4 - the block above
- */
- YYTHD->client_capabilities |= $4;
-
- if (!($5 || $6 || $7 || $8 || $9))
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- /*
- sql_command is set here because some rules in ev_sql_stmt
- can overwrite it
- */
- Lex->sql_command= SQLCOM_ALTER_EVENT;
- }
- | ALTER TABLESPACE alter_tablespace_info
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE;
- }
- | ALTER LOGFILE_SYM GROUP alter_logfile_group_info
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP;
- }
- | ALTER TABLESPACE change_tablespace_info
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->ts_cmd_type= CHANGE_FILE_TABLESPACE;
- }
- | ALTER TABLESPACE change_tablespace_access
- {
- LEX *lex= Lex;
- lex->alter_tablespace_info->ts_cmd_type= ALTER_ACCESS_MODE_TABLESPACE;
- }
- | ALTER SERVER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')'
- {
- LEX *lex= Lex;
- Lex->sql_command= SQLCOM_ALTER_SERVER;
- Lex->server_options.server_name= $3.str;
- Lex->server_options.server_name_length= $3.length;
- }
- ;
-
-ev_alter_on_schedule_completion: /* empty */ { $$= 0;}
- | ON SCHEDULE_SYM ev_schedule_time { $$= 1; }
- | ev_on_completion { $$= 1; }
- | ON SCHEDULE_SYM ev_schedule_time ev_on_completion { $$= 1; }
- ;
-
-opt_ev_rename_to: /* empty */ { $$= 0;}
- | RENAME TO_SYM sp_name
- {
- /*
- Use lex's spname to hold the new name.
- The original name is in the Event_parse_data object
- */
- Lex->spname= $3;
- $$= 1;
- }
- ;
-
-opt_ev_sql_stmt: /* empty*/ { $$= 0;}
- | DO_SYM ev_sql_stmt { $$= 1; }
- ;
-
-
-ident_or_empty:
- /* empty */ { $$.str= 0; $$.length= 0; }
- | ident { $$= $1; };
-
-alter_commands:
- | DISCARD TABLESPACE { Lex->alter_info.tablespace_op= DISCARD_TABLESPACE; }
- | IMPORT TABLESPACE { Lex->alter_info.tablespace_op= IMPORT_TABLESPACE; }
- | alter_list
- opt_partitioning
- | alter_list
- remove_partitioning
- | remove_partitioning
- | partitioning
-/*
- This part was added for release 5.1 by Mikael Ronström.
- From here we insert a number of commands to manage the partitions of a
- partitioned table such as adding partitions, dropping partitions,
- reorganising partitions in various manners. In future releases the list
- will be longer and also include moving partitions to a
- new table and so forth.
-*/
- | add_partition_rule
- | DROP PARTITION_SYM alt_part_name_list
- {
- Lex->alter_info.flags|= ALTER_DROP_PARTITION;
- }
- | REBUILD_SYM PARTITION_SYM opt_no_write_to_binlog
- all_or_alt_part_name_list
- {
- LEX *lex= Lex;
- lex->alter_info.flags|= ALTER_REBUILD_PARTITION;
- lex->no_write_to_binlog= $3;
- }
- | OPTIMIZE PARTITION_SYM opt_no_write_to_binlog
- all_or_alt_part_name_list
- {
- LEX *lex= Lex;
- lex->alter_info.flags|= ALTER_OPTIMIZE_PARTITION;
- lex->no_write_to_binlog= $3;
- lex->check_opt.init();
- }
- opt_no_write_to_binlog opt_mi_check_type
- | ANALYZE_SYM PARTITION_SYM opt_no_write_to_binlog
- all_or_alt_part_name_list
- {
- LEX *lex= Lex;
- lex->alter_info.flags|= ALTER_ANALYZE_PARTITION;
- lex->no_write_to_binlog= $3;
- lex->check_opt.init();
- }
- opt_mi_check_type
- | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list
- {
- LEX *lex= Lex;
- lex->alter_info.flags|= ALTER_CHECK_PARTITION;
- lex->check_opt.init();
- }
- opt_mi_check_type
- | REPAIR PARTITION_SYM opt_no_write_to_binlog
- all_or_alt_part_name_list
- {
- LEX *lex= Lex;
- lex->alter_info.flags|= ALTER_REPAIR_PARTITION;
- lex->no_write_to_binlog= $3;
- lex->check_opt.init();
- }
- opt_mi_repair_type
- | COALESCE PARTITION_SYM opt_no_write_to_binlog real_ulong_num
- {
- LEX *lex= Lex;
- lex->alter_info.flags|= ALTER_COALESCE_PARTITION;
- lex->no_write_to_binlog= $3;
- lex->alter_info.no_parts= $4;
- }
- | reorg_partition_rule
- ;
-
-remove_partitioning:
- REMOVE_SYM PARTITIONING_SYM
- {
- Lex->alter_info.flags|= ALTER_REMOVE_PARTITIONING;
- }
- ;
-
-all_or_alt_part_name_list:
- ALL
- {
- Lex->alter_info.flags|= ALTER_ALL_PARTITION;
- }
- | alt_part_name_list
- ;
-
-add_partition_rule:
- ADD PARTITION_SYM opt_no_write_to_binlog
- {
- LEX *lex= Lex;
- lex->part_info= new partition_info();
- if (!lex->part_info)
- {
- mem_alloc_error(sizeof(partition_info));
- YYABORT;
- }
- lex->alter_info.flags|= ALTER_ADD_PARTITION;
- lex->no_write_to_binlog= $3;
- }
- add_part_extra
- {}
- ;
-
-add_part_extra:
- | '(' part_def_list ')'
- {
- LEX *lex= Lex;
- lex->part_info->no_parts= lex->part_info->partitions.elements;
- }
- | PARTITIONS_SYM real_ulong_num
- {
- LEX *lex= Lex;
- lex->part_info->no_parts= $2;
- }
- ;
-
-reorg_partition_rule:
- REORGANIZE_SYM PARTITION_SYM opt_no_write_to_binlog
- {
- LEX *lex= Lex;
- lex->part_info= new partition_info();
- if (!lex->part_info)
- {
- mem_alloc_error(sizeof(partition_info));
- YYABORT;
- }
- lex->no_write_to_binlog= $3;
- }
- reorg_parts_rule
- ;
-
-reorg_parts_rule:
- /* empty */
- {
- Lex->alter_info.flags|= ALTER_TABLE_REORG;
- }
- |
- alt_part_name_list
- {
- Lex->alter_info.flags|= ALTER_REORGANIZE_PARTITION;
- }
- INTO '(' part_def_list ')'
- {
- LEX *lex= Lex;
- lex->part_info->no_parts= lex->part_info->partitions.elements;
- }
- ;
-
-alt_part_name_list:
- alt_part_name_item {}
- | alt_part_name_list ',' alt_part_name_item {}
- ;
-
-alt_part_name_item:
- ident
- {
- if (Lex->alter_info.partition_names.push_back($1.str))
- {
- mem_alloc_error(1);
- YYABORT;
- }
- }
- ;
-
-/*
- End of management of partition commands
-*/
-
-alter_list:
- alter_list_item
- | alter_list ',' alter_list_item
- ;
-
-add_column:
- ADD opt_column
- {
- LEX *lex=Lex;
- lex->change=0;
- lex->alter_info.flags|= ALTER_ADD_COLUMN;
- };
-
-alter_list_item:
- add_column column_def opt_place { }
- | ADD key_def
- {
- Lex->alter_info.flags|= ALTER_ADD_INDEX;
- }
- | add_column '(' field_list ')'
- {
- Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX;
- }
- | CHANGE opt_column field_ident
- {
- LEX *lex=Lex;
- lex->change= $3.str;
- lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
- }
- field_spec opt_place
- | MODIFY_SYM opt_column field_ident
- {
- LEX *lex=Lex;
- lex->length=lex->dec=0; lex->type=0;
- lex->default_value= lex->on_update_value= 0;
- lex->comment=null_lex_str;
- lex->charset= NULL;
- lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
- }
- type opt_attribute
- {
- LEX *lex=Lex;
- if (add_field_to_list(lex->thd,$3.str,
- (enum enum_field_types) $5,
- lex->length,lex->dec,lex->type,
- lex->default_value, lex->on_update_value,
- &lex->comment,
- $3.str, &lex->interval_list, lex->charset,
- lex->uint_geom_type))
- YYABORT;
- }
- opt_place
- | DROP opt_column field_ident opt_restrict
- {
- LEX *lex=Lex;
- lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
- $3.str));
- lex->alter_info.flags|= ALTER_DROP_COLUMN;
- }
- | DROP FOREIGN KEY_SYM opt_ident
- {
- Lex->alter_info.flags|= ALTER_DROP_INDEX | ALTER_FOREIGN_KEY;
- }
- | DROP PRIMARY_SYM KEY_SYM
- {
- LEX *lex=Lex;
- lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
- primary_key_name));
- lex->alter_info.flags|= ALTER_DROP_INDEX;
- }
- | DROP key_or_index field_ident
- {
- LEX *lex=Lex;
- lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
- $3.str));
- lex->alter_info.flags|= ALTER_DROP_INDEX;
- }
- | DISABLE_SYM KEYS
- {
- LEX *lex=Lex;
- lex->alter_info.keys_onoff= DISABLE;
- lex->alter_info.flags|= ALTER_KEYS_ONOFF;
- }
- | ENABLE_SYM KEYS
- {
- LEX *lex=Lex;
- lex->alter_info.keys_onoff= ENABLE;
- lex->alter_info.flags|= ALTER_KEYS_ONOFF;
- }
- | ALTER opt_column field_ident SET DEFAULT signed_literal
- {
- LEX *lex=Lex;
- lex->alter_info.alter_list.push_back(new Alter_column($3.str,$6));
- lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
- }
- | ALTER opt_column field_ident DROP DEFAULT
- {
- LEX *lex=Lex;
- lex->alter_info.alter_list.push_back(new Alter_column($3.str,
- (Item*) 0));
- lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
- }
- | RENAME opt_to table_ident
- {
- LEX *lex=Lex;
- THD *thd= lex->thd;
- uint dummy;
- lex->select_lex.db=$3->db.str;
- if (lex->select_lex.db == NULL &&
- thd->copy_db_to(&lex->select_lex.db, &dummy))
- {
- YYABORT;
- }
- if (check_table_name($3->table.str,$3->table.length) ||
- $3->db.str && check_db_name(&$3->db))
- {
- my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
- YYABORT;
- }
- lex->name= $3->table;
- lex->alter_info.flags|= ALTER_RENAME;
- }
- | CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
- {
- if (!$4)
- {
- THD *thd= YYTHD;
- $4= thd->variables.collation_database;
- }
- $5= $5 ? $5 : $4;
- if (!my_charset_same($4,$5))
- {
- my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
- $5->name, $4->csname);
- YYABORT;
- }
- LEX *lex= Lex;
- lex->create_info.table_charset=
- lex->create_info.default_table_charset= $5;
- lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET |
- HA_CREATE_USED_DEFAULT_CHARSET);
- lex->alter_info.flags|= ALTER_CONVERT;
- }
- | create_table_options_space_separated
- {
- LEX *lex=Lex;
- lex->alter_info.flags|= ALTER_OPTIONS;
- }
- | FORCE_SYM
- {
- Lex->alter_info.flags|= ALTER_FORCE;
- }
- | order_clause
- {
- LEX *lex=Lex;
- lex->alter_info.flags|= ALTER_ORDER;
- };
-
-opt_column:
- /* empty */ {}
- | COLUMN_SYM {};
-
-opt_ignore:
- /* empty */ { Lex->ignore= 0;}
- | IGNORE_SYM { Lex->ignore= 1;}
- ;
-
-opt_restrict:
- /* empty */ { Lex->drop_mode= DROP_DEFAULT; }
- | RESTRICT { Lex->drop_mode= DROP_RESTRICT; }
- | CASCADE { Lex->drop_mode= DROP_CASCADE; }
- ;
-
-opt_place:
- /* empty */ {}
- | AFTER_SYM ident { store_position_for_column($2.str); }
- | FIRST_SYM { store_position_for_column(first_keyword); };
-
-opt_to:
- /* empty */ {}
- | TO_SYM {}
- | EQ {}
- | AS {};
-
-/*
- SLAVE START and SLAVE STOP are deprecated. We keep them for compatibility.
-*/
-
-slave:
- START_SYM SLAVE slave_thread_opts
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_SLAVE_START;
- lex->type = 0;
- /* We'll use mi structure for UNTIL options */
- bzero((char*) &lex->mi, sizeof(lex->mi));
- /* If you change this code don't forget to update SLAVE START too */
- }
- slave_until
- {}
- | STOP_SYM SLAVE slave_thread_opts
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_SLAVE_STOP;
- lex->type = 0;
- /* If you change this code don't forget to update SLAVE STOP too */
- }
- | SLAVE START_SYM slave_thread_opts
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_SLAVE_START;
- lex->type = 0;
- /* We'll use mi structure for UNTIL options */
- bzero((char*) &lex->mi, sizeof(lex->mi));
- }
- slave_until
- {}
- | SLAVE STOP_SYM slave_thread_opts
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_SLAVE_STOP;
- lex->type = 0;
- }
- ;
-
-
-start:
- START_SYM TRANSACTION_SYM start_transaction_opts
- {
- LEX *lex= Lex;
- lex->sql_command= SQLCOM_BEGIN;
- lex->start_transaction_opt= $3;
- }
- ;
-
-start_transaction_opts:
- /*empty*/ { $$ = 0; }
- | WITH CONSISTENT_SYM SNAPSHOT_SYM
- {
- $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT;
- }
- ;
-
-slave_thread_opts:
- { Lex->slave_thd_opt= 0; }
- slave_thread_opt_list
- {}
- ;
-
-slave_thread_opt_list:
- slave_thread_opt
- | slave_thread_opt_list ',' slave_thread_opt
- ;
-
-slave_thread_opt:
- /*empty*/ {}
- | SQL_THREAD { Lex->slave_thd_opt|=SLAVE_SQL; }
- | RELAY_THREAD { Lex->slave_thd_opt|=SLAVE_IO; }
- ;
-
-slave_until:
- /*empty*/ {}
- | UNTIL_SYM slave_until_opts
- {
- LEX *lex=Lex;
- if ((lex->mi.log_file_name || lex->mi.pos) &&
- (lex->mi.relay_log_name || lex->mi.relay_log_pos) ||
- !((lex->mi.log_file_name && lex->mi.pos) ||
- (lex->mi.relay_log_name && lex->mi.relay_log_pos)))
- {
- my_message(ER_BAD_SLAVE_UNTIL_COND,
- ER(ER_BAD_SLAVE_UNTIL_COND), MYF(0));
- YYABORT;
- }
-
- }
- ;
-
-slave_until_opts:
- master_file_def
- | slave_until_opts ',' master_file_def ;
-
-
-restore:
- RESTORE_SYM table_or_tables
- {
- Lex->sql_command = SQLCOM_RESTORE_TABLE;
- WARN_DEPRECATED(yythd, "5.2", "RESTORE TABLE",
- "MySQL Administrator (mysqldump, mysql)");
- }
- table_list FROM TEXT_STRING_sys
- {
- Lex->backup_dir = $6.str;
- };
-
-backup:
- BACKUP_SYM table_or_tables
- {
- Lex->sql_command = SQLCOM_BACKUP_TABLE;
- WARN_DEPRECATED(yythd, "5.2", "BACKUP TABLE",
- "MySQL Administrator (mysqldump, mysql)");
- }
- table_list TO_SYM TEXT_STRING_sys
- {
- Lex->backup_dir = $6.str;
- };
-
-checksum:
- CHECKSUM_SYM table_or_tables
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_CHECKSUM;
- }
- table_list opt_checksum_type
- {}
- ;
-
-opt_checksum_type:
- /* nothing */ { Lex->check_opt.flags= 0; }
- | QUICK { Lex->check_opt.flags= T_QUICK; }
- | EXTENDED_SYM { Lex->check_opt.flags= T_EXTEND; }
- ;
-
-repair:
- REPAIR opt_no_write_to_binlog table_or_tables
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_REPAIR;
- lex->no_write_to_binlog= $2;
- lex->check_opt.init();
- }
- table_list opt_mi_repair_type
- {}
- ;
-
-opt_mi_repair_type:
- /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
- | mi_repair_types {};
-
-mi_repair_types:
- mi_repair_type {}
- | mi_repair_type mi_repair_types {};
-
-mi_repair_type:
- QUICK { Lex->check_opt.flags|= T_QUICK; }
- | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
- | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; };
-
-analyze:
- ANALYZE_SYM opt_no_write_to_binlog table_or_tables
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_ANALYZE;
- lex->no_write_to_binlog= $2;
- lex->check_opt.init();
- }
- table_list opt_mi_check_type
- {}
- ;
-
-binlog_base64_event:
- BINLOG_SYM TEXT_STRING_sys
- {
- Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT;
- Lex->comment= $2;
- }
- ;
-
-check:
- CHECK_SYM table_or_tables
- {
- LEX *lex=Lex;
-
- if (lex->sphead)
- {
- my_error(ER_SP_BADSTATEMENT, MYF(0), "CHECK");
- YYABORT;
- }
- lex->sql_command = SQLCOM_CHECK;
- lex->check_opt.init();
- }
- table_list opt_mi_check_type
- {}
- ;
-
-opt_mi_check_type:
- /* empty */ { Lex->check_opt.flags = T_MEDIUM; }
- | mi_check_types {};
-
-mi_check_types:
- mi_check_type {}
- | mi_check_type mi_check_types {};
-
-mi_check_type:
- QUICK { Lex->check_opt.flags|= T_QUICK; }
- | FAST_SYM { Lex->check_opt.flags|= T_FAST; }
- | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; }
- | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; }
- | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; }
- | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; };
-
-optimize:
- OPTIMIZE opt_no_write_to_binlog table_or_tables
- {
- LEX *lex=Lex;
- lex->sql_command = SQLCOM_OPTIMIZE;
- lex->no_write_to_binlog= $2;
- lex->check_opt.init();
- }
- table_list opt_mi_check_type
- {}
- ;
-
-opt_no_write_to_binlog:
- /* empty */ { $$= 0; }
- | NO_WRITE_TO_BINLOG { $$= 1; }
- | LOCAL_SYM { $$= 1; }
- ;
-
-rename:
- RENAME table_or_tables
- {
- Lex->sql_command= SQLCOM_RENAME_TABLE;
- }
- table_to_table_list
- {}
- | RENAME DATABASE
- {
- Lex->db_list.empty();
- Lex->sql_command= SQLCOM_RENAME_DB;
- }
- db_to_db
- {}
- | RENAME USER clear_privileges rename_list
- {
- Lex->sql_command = SQLCOM_RENAME_USER;
- }
- ;
-
-rename_list:
- user TO_SYM user
- {
- if (Lex->users_list.push_back($1) || Lex->users_list.push_back($3))
- YYABORT;
- }
- | rename_list ',' user TO_SYM user
- {
- if (Lex->users_list.push_back($3) || Lex->users_list.push_back($5))
- YYABORT;
- }
- ;
-
-table_to_table_list:
- table_to_table
- | table_to_table_list ',' table_to_table;
-
-table_to_table:
- table_ident TO_SYM table_ident
- {
- LEX *lex=Lex;
- SELECT_LEX *sl= lex->current_select;
- if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING,
- TL_IGNORE) ||
- !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING,
- TL_IGNORE))
- YYABORT;
- };
-
-db_to_db:
- ident TO_SYM ident
- {
- LEX *lex=Lex;
- if (Lex->db_list.push_back((LEX_STRING*)
- sql_memdup(&$1, sizeof(LEX_STRING))) ||
- Lex->db_list.push_back((LEX_STRING*)
- sql_memdup(&$3, sizeof(LEX_STRING))))
- YYABORT;
- };
-
-keycache:
- CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name
- {
- LEX *lex=Lex;
- lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE;
- lex->ident= $5;
- }
- ;
-
-keycache_list:
- assign_to_keycache
- | keycache_list ',' assign_to_keycache;
-
-assign_to_keycache:
- table_ident cache_keys_spec
- {
- LEX *lex=Lex;
- SELECT_LEX *sel= &lex->select_lex;
- if (!sel->add_table_to_list(lex->thd, $1, NULL, 0,
- TL_READ,
- sel->get_use_index(),
- (List *)0))
- YYABORT;
- }
- ;
-
-key_cache_name:
- ident { $$= $1; }
- | DEFAULT { $$ = default_key_cache_base; }
- ;
-
-preload:
- LOAD INDEX_SYM INTO CACHE_SYM
- {
- LEX *lex=Lex;
- lex->sql_command=SQLCOM_PRELOAD_KEYS;
- }
- preload_list
- {}
- ;
-
-preload_list:
- preload_keys
- | preload_list ',' preload_keys;
-
-preload_keys:
- table_ident cache_keys_spec opt_ignore_leaves
- {
- LEX *lex=Lex;
- SELECT_LEX *sel= &lex->select_lex;
- if (!sel->add_table_to_list(lex->thd, $1, NULL, $3,
- TL_READ,
- sel->get_use_index(),
- (List *)0))
- YYABORT;
- }
- ;
-
-cache_keys_spec:
- { Select->interval_list.empty(); }
- cache_key_list_or_empty
- {
- LEX *lex=Lex;
- SELECT_LEX *sel= &lex->select_lex;
- sel->use_index= sel->interval_list;
- }
- ;
-
-cache_key_list_or_empty:
- /* empty */ { Lex->select_lex.use_index_ptr= 0; }
- | opt_key_or_index '(' key_usage_list2 ')'
- {
- SELECT_LEX *sel= &Lex->select_lex;
- sel->use_index_ptr= &sel->use_index;
- }
- ;
-
-opt_ignore_leaves:
- /* empty */
- { $$= 0; }
- | IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; }
- ;
-
-/*
- Select : retrieve data from table
-*/
-
-
-select:
- select_init
- {
- LEX *lex= Lex;
- lex->sql_command= SQLCOM_SELECT;
- }
- ;
-
-/* Need select_init2 for subselects. */
-select_init:
- SELECT_SYM select_init2
- |
- '(' select_paren ')' union_opt;
-
-select_paren:
- SELECT_SYM select_part2
- {
- LEX *lex= Lex;
- SELECT_LEX * sel= lex->current_select;
- if (sel->set_braces(1))
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- if (sel->linkage == UNION_TYPE &&
- !sel->master_unit()->first_select()->braces &&
- sel->master_unit()->first_select()->linkage ==
- UNION_TYPE)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- /* select in braces, can't contain global parameters */
- if (sel->master_unit()->fake_select_lex)
- sel->master_unit()->global_parameters=
- sel->master_unit()->fake_select_lex;
- }
- | '(' select_paren ')';
-
-select_init2:
- select_part2
- {
- LEX *lex= Lex;
- SELECT_LEX * sel= lex->current_select;
- if (lex->current_select->set_braces(0))
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- if (sel->linkage == UNION_TYPE &&
- sel->master_unit()->first_select()->braces)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- }
- union_clause
- ;
-
-select_part2:
- {
- LEX *lex= Lex;
- SELECT_LEX *sel= lex->current_select;
- if (sel->linkage != UNION_TYPE)
- mysql_init_select(lex);
- lex->current_select->parsing_place= SELECT_LIST;
- }
- select_options select_item_list
- {
- Select->parsing_place= NO_MATTER;
- }
- select_into select_lock_type;
-
-select_into:
- opt_order_clause opt_limit_clause {}
- | into
- | select_from
- | into select_from
- | select_from into;
-
-select_from:
- FROM join_table_list where_clause group_clause having_clause
- opt_order_clause opt_limit_clause procedure_clause
- | 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*/
- | select_option_list
- {
- if (Select->options & SELECT_DISTINCT && Select->options & SELECT_ALL)
- {
- my_error(ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT");
- YYABORT;
- }
- }
- ;
-
-select_option_list:
- select_option_list select_option
- | select_option;
-
-select_option:
- STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; }
- | HIGH_PRIORITY
- {
- if (check_simple_select())
- YYABORT;
- Lex->lock_option= TL_READ_HIGH_PRIORITY;
- }
- | DISTINCT { Select->options|= SELECT_DISTINCT; }
- | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; }
- | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; }
- | SQL_BUFFER_RESULT
- {
- if (check_simple_select())
- YYABORT;
- Select->options|= OPTION_BUFFER_RESULT;
- }
- | SQL_CALC_FOUND_ROWS
- {
- if (check_simple_select())
- YYABORT;
- Select->options|= OPTION_FOUND_ROWS;
- }
- | SQL_NO_CACHE_SYM
- {
- Lex->safe_to_cache_query=0;
- Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE;
- Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE;
- }
- | SQL_CACHE_SYM
- {
- /* Honor this flag only if SQL_NO_CACHE wasn't specified. */
- if (Lex->select_lex.sql_cache != SELECT_LEX::SQL_NO_CACHE)
- {
- Lex->safe_to_cache_query=1;
- Lex->select_lex.options|= OPTION_TO_QUERY_CACHE;
- Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE;
- }
- }
- | ALL { Select->options|= SELECT_ALL; }
- ;
-
-select_lock_type:
- /* empty */
- | FOR_SYM UPDATE_SYM
- {
- LEX *lex=Lex;
- lex->current_select->set_lock_for_tables(TL_WRITE);
- lex->safe_to_cache_query=0;
- }
- | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
- {
- LEX *lex=Lex;
- lex->current_select->
- set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS);
- lex->safe_to_cache_query=0;
- }
- ;
-
-select_item_list:
- select_item_list ',' select_item
- | select_item
- | '*'
- {
- THD *thd= YYTHD;
- if (add_item_to_list(thd,
- new Item_field(&thd->lex->current_select->
- context,
- NULL, NULL, "*")))
- YYABORT;
- (thd->lex->current_select->with_wild)++;
- };
-
-
-select_item:
- remember_name select_item2 remember_end select_alias
- {
- if (add_item_to_list(YYTHD, $2))
- YYABORT;
- if ($4.str)
- {
- $2->is_autogenerated_name= FALSE;
- $2->set_name($4.str, $4.length, system_charset_info);
- }
- else if (!$2->name) {
- char *str = $1;
- if (str[-1] == '`')
- str--;
- $2->set_name(str,(uint) ($3 - str), YYTHD->charset());
- }
- };
-
-remember_name:
- { $$=(char*) Lex->tok_start; };
-
-remember_end:
- { $$=(char*) Lex->tok_end; };
-
-select_item2:
- table_wild { $$=$1; } /* table.* */
- | expr { $$=$1; };
-
-select_alias:
- /* empty */ { $$=null_lex_str;}
- | AS ident { $$=$2; }
- | AS TEXT_STRING_sys { $$=$2; }
- | ident { $$=$1; }
- | TEXT_STRING_sys { $$=$1; }
- ;
-
-optional_braces:
- /* empty */ {}
- | '(' ')' {};
-
-/* all possible expressions */
-expr:
- bool_term { Select->expr_list.push_front(new List
- ); }
- bool_or_expr
- {
- List
- *list= Select->expr_list.pop();
- if (list->elements)
- {
- list->push_front($1);
- $$= new Item_cond_or(*list);
- /* optimize construction of logical OR to reduce
- amount of objects for complex expressions */
- }
- else
- $$= $1;
- delete list;
- }
- ;
-
-bool_or_expr:
- /* empty */
- | bool_or_expr or bool_term
- { Select->expr_list.head()->push_back($3); }
- ;
-
-bool_term:
- bool_term XOR bool_term { $$= new Item_cond_xor($1,$3); }
- | bool_factor { Select->expr_list.push_front(new List
- ); }
- bool_and_expr
- {
- List
- *list= Select->expr_list.pop();
- if (list->elements)
- {
- list->push_front($1);
- $$= new Item_cond_and(*list);
- /* optimize construction of logical AND to reduce
- amount of objects for complex expressions */
- }
- else
- $$= $1;
- delete list;
- }
- ;
-
-bool_and_expr:
- /* empty */
- | bool_and_expr and bool_factor
- { Select->expr_list.head()->push_back($3); }
- ;
-
-bool_factor:
- NOT_SYM bool_factor { $$= negate_expression(YYTHD, $2); }
- | bool_test ;
-
-bool_test:
- bool_pri IS TRUE_SYM { $$= is_truth_value(YYTHD, $1,1,0); }
- | bool_pri IS not TRUE_SYM { $$= is_truth_value(YYTHD, $1,0,0); }
- | bool_pri IS FALSE_SYM { $$= is_truth_value(YYTHD, $1,0,1); }
- | bool_pri IS not FALSE_SYM { $$= is_truth_value(YYTHD, $1,1,1); }
- | bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); }
- | bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); }
- | bool_pri ;
-
-bool_pri:
- bool_pri IS NULL_SYM { $$= new Item_func_isnull($1); }
- | bool_pri IS not NULL_SYM { $$= new Item_func_isnotnull($1); }
- | bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); }
- | bool_pri comp_op predicate %prec EQ
- { $$= (*$2)(0)->create($1,$3); }
- | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
- { $$= all_any_subquery_creator($1, $2, $3, $5); }
- | predicate ;
-
-predicate:
- bit_expr IN_SYM '(' subselect ')'
- { $$= new Item_in_subselect($1, $4); }
- | bit_expr not IN_SYM '(' subselect ')'
- { $$= negate_expression(YYTHD, new Item_in_subselect($1, $5)); }
- | bit_expr IN_SYM '(' expr ')'
- {
- $$= new Item_func_eq($1, $4);
- }
- | bit_expr IN_SYM '(' expr ',' expr_list ')'
- {
- $6->push_front($4);
- $6->push_front($1);
- $$= new Item_func_in(*$6);
- }
- | bit_expr not IN_SYM '(' expr ')'
- {
- $$= new Item_func_ne($1, $5);
- }
- | bit_expr not IN_SYM '(' expr ',' expr_list ')'
- {
- $7->push_front($5);
- $7->push_front($1);
- Item_func_in *item = new Item_func_in(*$7);
- item->negate();
- $$= item;
- }
- | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate
- { $$= new Item_func_between($1,$3,$5); }
- | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate
- {
- Item_func_between *item= new Item_func_between($1,$4,$6);
- item->negate();
- $$= item;
- }
- | bit_expr SOUNDS_SYM LIKE bit_expr
- { $$= new Item_func_eq(new Item_func_soundex($1),
- new Item_func_soundex($4)); }
- | bit_expr LIKE simple_expr opt_escape
- { $$= new Item_func_like($1,$3,$4,Lex->escape_used); }
- | bit_expr not LIKE simple_expr opt_escape
- { $$= new Item_func_not(new Item_func_like($1,$4,$5, Lex->escape_used)); }
- | bit_expr REGEXP bit_expr { $$= new Item_func_regex($1,$3); }
- | bit_expr not REGEXP bit_expr
- { $$= negate_expression(YYTHD, new Item_func_regex($1,$4)); }
- | bit_expr ;
-
-bit_expr:
- bit_expr '|' bit_term { $$= new Item_func_bit_or($1,$3); }
- | bit_term ;
-
-bit_term:
- bit_term '&' bit_factor { $$= new Item_func_bit_and($1,$3); }
- | bit_factor ;
-
-bit_factor:
- bit_factor SHIFT_LEFT value_expr
- { $$= new Item_func_shift_left($1,$3); }
- | bit_factor SHIFT_RIGHT value_expr
- { $$= new Item_func_shift_right($1,$3); }
- | value_expr ;
-
-value_expr:
- value_expr '+' term { $$= new Item_func_plus($1,$3); }
- | value_expr '-' term { $$= new Item_func_minus($1,$3); }
- | value_expr '+' interval_expr interval
- { $$= new Item_date_add_interval($1,$3,$4,0); }
- | value_expr '-' interval_expr interval
- { $$= new Item_date_add_interval($1,$3,$4,1); }
- | term ;
-
-term:
- term '*' factor { $$= new Item_func_mul($1,$3); }
- | term '/' factor { $$= new Item_func_div($1,$3); }
- | term '%' factor { $$= new Item_func_mod($1,$3); }
- | term DIV_SYM factor { $$= new Item_func_int_div($1,$3); }
- | term MOD_SYM factor { $$= new Item_func_mod($1,$3); }
- | factor ;
-
-factor:
- factor '^' simple_expr { $$= new Item_func_bit_xor($1,$3); }
- | simple_expr ;
-
-or: OR_SYM | OR2_SYM;
-and: AND_SYM | AND_AND_SYM;
-not: NOT_SYM | NOT2_SYM;
-not2: '!' | NOT2_SYM;
-
-comp_op: EQ { $$ = &comp_eq_creator; }
- | GE { $$ = &comp_ge_creator; }
- | GT_SYM { $$ = &comp_gt_creator; }
- | LE { $$ = &comp_le_creator; }
- | LT { $$ = &comp_lt_creator; }
- | NE { $$ = &comp_ne_creator; }
- ;
-
-all_or_any: ALL { $$ = 1; }
- | ANY_SYM { $$ = 0; }
- ;
-
-interval_expr:
- INTERVAL_SYM expr { $$=$2; }
- ;
-
-simple_expr:
- simple_ident
- | function_call_keyword
- | function_call_nonkeyword
- | function_call_generic
- | function_call_conflict
- | simple_expr COLLATE_SYM ident_or_text %prec NEG
- {
- THD *thd= YYTHD;
- Item *i1= new (thd->mem_root) Item_string($3.str,
- $3.length,
- thd->charset());
- $$= new (thd->mem_root) Item_func_set_collation($1, i1);
- }
- | literal
- | param_marker
- | variable
- | sum_expr
- | simple_expr OR_OR_SYM simple_expr
- { $$= new (YYTHD->mem_root) Item_func_concat($1, $3); }
- | '+' simple_expr %prec NEG { $$= $2; }
- | '-' simple_expr %prec NEG
- { $$= new (YYTHD->mem_root) Item_func_neg($2); }
- | '~' simple_expr %prec NEG
- { $$= new (YYTHD->mem_root) Item_func_bit_neg($2); }
- | not2 simple_expr %prec NEG
- { $$= negate_expression(YYTHD, $2); }
- | '(' subselect ')'
- {
- $$= new (YYTHD->mem_root) Item_singlerow_subselect($2);
- }
- | '(' expr ')' { $$= $2; }
- | '(' expr ',' expr_list ')'
- {
- $4->push_front($2);
- $$= new (YYTHD->mem_root) Item_row(*$4);
- }
- | ROW_SYM '(' expr ',' expr_list ')'
- {
- $5->push_front($3);
- $$= new (YYTHD->mem_root) Item_row(*$5);
- }
- | EXISTS '(' subselect ')'
- {
- $$= new (YYTHD->mem_root) Item_exists_subselect($3);
- }
- | '{' ident expr '}' { $$= $3; }
- | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')'
- {
- $2->push_front($5);
- Item_func_match *i1= new (YYTHD->mem_root) Item_func_match(*$2, $6);
- Select->add_ftfunc_to_list(i1);
- $$= i1;
- }
- | BINARY simple_expr %prec NEG
- {
- $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, -1, 0,
- &my_charset_bin);
- }
- | CAST_SYM '(' expr AS cast_type ')'
- {
- LEX *lex= Lex;
- $$= create_func_cast(YYTHD, $3, $5,
- lex->length ? atoi(lex->length) : -1,
- lex->dec ? atoi(lex->dec) : 0,
- lex->charset);
- if (!$$)
- YYABORT;
- }
- | CASE_SYM opt_expr WHEN_SYM when_list opt_else END
- { $$= new (YYTHD->mem_root) Item_func_case(* $4, $2, $5 ); }
- | CONVERT_SYM '(' expr ',' cast_type ')'
- {
- $$= create_func_cast(YYTHD, $3, $5,
- Lex->length ? atoi(Lex->length) : -1,
- Lex->dec ? atoi(Lex->dec) : 0,
- Lex->charset);
- if (!$$)
- YYABORT;
- }
- | CONVERT_SYM '(' expr USING charset_name ')'
- { $$= new (YYTHD->mem_root) Item_func_conv_charset($3,$5); }
- | DEFAULT '(' simple_ident ')'
- {
- if ($3->is_splocal())
- {
- Item_splocal *il= static_cast($3);
-
- my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
- YYABORT;
- }
- $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context(),
- $3);
- }
- | VALUES '(' simple_ident_nospvar ')'
- { $$= new (YYTHD->mem_root) Item_insert_value(Lex->current_context(),
- $3); }
- | interval_expr interval '+' expr
- /* we cannot put interval before - */
- { $$= new (YYTHD->mem_root) Item_date_add_interval($4,$1,$2,0); }
- | interval_expr
- {
- if ($1->type() != Item::ROW_ITEM)
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- $$= new (YYTHD->mem_root) Item_func_interval((Item_row *)$1);
- }
- | UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
- {
- $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9);
- }
- ;
-
-/*
- Function call syntax using official SQL 2003 keywords.
- Because the function name is an official token,
- a dedicated grammar rule is needed in the parser.
- There is no potential for conflicts
-*/
-function_call_keyword:
- CHAR_SYM '(' expr_list ')'
- { $$= new (YYTHD->mem_root) Item_func_char(*$3); }
- | CHAR_SYM '(' expr_list USING charset_name ')'
- { $$= new (YYTHD->mem_root) Item_func_char(*$3, $5); }
- | CURRENT_USER optional_braces
- {
- $$= new (YYTHD->mem_root) Item_func_current_user(Lex->current_context());
- Lex->safe_to_cache_query= 0;
- }
- | DATE_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_date_typecast($3); }
- | DAY_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_dayofmonth($3); }
- | HOUR_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_hour($3); }
- | INSERT '(' expr ',' expr ',' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_insert($3,$5,$7,$9); }
- | LEFT '(' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_left($3,$5); }
- | MINUTE_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_minute($3); }
- | MONTH_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_month($3); }
- | RIGHT '(' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_right($3,$5); }
- | SECOND_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_second($3); }
- | TIME_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_time_typecast($3); }
- | TIMESTAMP '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_datetime_typecast($3); }
- | TIMESTAMP '(' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_add_time($3, $5, 1, 0); }
- | TRIM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_trim($3); }
- | TRIM '(' LEADING expr FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_ltrim($6,$4); }
- | TRIM '(' TRAILING expr FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_rtrim($6,$4); }
- | TRIM '(' BOTH expr FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_trim($6,$4); }
- | TRIM '(' LEADING FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_ltrim($5); }
- | TRIM '(' TRAILING FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_rtrim($5); }
- | TRIM '(' BOTH FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_trim($5); }
- | TRIM '(' expr FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_trim($5,$3); }
- | USER '(' ')'
- {
- $$= new (YYTHD->mem_root) Item_func_user();
- Lex->safe_to_cache_query=0;
- }
- | YEAR_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_year($3); }
- ;
-
-/*
- Function calls using non reserved keywords, with special syntaxic forms.
- Dedicated grammar rules are needed because of the syntax,
- but also have the potential to cause incompatibilities with other
- parts of the language.
- MAINTAINER:
- The only reasons a function should be added here are:
- - for compatibility reasons with another SQL syntax (CURDATE),
- - for typing reasons (GET_FORMAT)
- Any other 'Syntaxic sugar' enhancements should be *STRONGLY*
- discouraged.
-*/
-function_call_nonkeyword:
- ADDDATE_SYM '(' expr ',' expr ')'
- {
- $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
- INTERVAL_DAY, 0);
- }
- | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
- { $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 0); }
- | CURDATE optional_braces
- {
- $$= new (YYTHD->mem_root) Item_func_curdate_local();
- Lex->safe_to_cache_query=0;
- }
- | CURTIME optional_braces
- {
- $$= new (YYTHD->mem_root) Item_func_curtime_local();
- Lex->safe_to_cache_query=0;
- }
- | CURTIME '(' expr ')'
- {
- $$= new (YYTHD->mem_root) Item_func_curtime_local($3);
- Lex->safe_to_cache_query=0;
- }
- | DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
- { $$= new (YYTHD->mem_root) Item_date_add_interval($3,$5,$6,0); }
- | DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
- { $$= new (YYTHD->mem_root) Item_date_add_interval($3,$5,$6,1); }
- | EXTRACT_SYM '(' interval FROM expr ')'
- { $$=new (YYTHD->mem_root) Item_extract( $3, $5); }
- | GET_FORMAT '(' date_time_type ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_get_format($3, $5); }
- | NOW_SYM optional_braces
- {
- $$= new (YYTHD->mem_root) Item_func_now_local();
- Lex->safe_to_cache_query=0;
- }
- | NOW_SYM '(' expr ')'
- {
- $$= new (YYTHD->mem_root) Item_func_now_local($3);
- Lex->safe_to_cache_query=0;
- }
- | POSITION_SYM '(' bit_expr IN_SYM expr ')'
- { $$ = new (YYTHD->mem_root) Item_func_locate($5,$3); }
- | SUBDATE_SYM '(' expr ',' expr ')'
- {
- $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
- INTERVAL_DAY, 1);
- }
- | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
- { $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 1); }
- | SUBSTRING '(' expr ',' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); }
- | SUBSTRING '(' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); }
- | SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); }
- | SUBSTRING '(' expr FROM expr ')'
- { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); }
- | SYSDATE optional_braces
- {
- if (global_system_variables.sysdate_is_now == 0)
- $$= new (YYTHD->mem_root) Item_func_sysdate_local();
- else
- $$= new (YYTHD->mem_root) Item_func_now_local();
- Lex->safe_to_cache_query=0;
- }
- | SYSDATE '(' expr ')'
- {
- if (global_system_variables.sysdate_is_now == 0)
- $$= new (YYTHD->mem_root) Item_func_sysdate_local($3);
- else
- $$= new (YYTHD->mem_root) Item_func_now_local($3);
- Lex->safe_to_cache_query=0;
- }
- | TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_date_add_interval($7,$5,$3,0); }
- | TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_timestamp_diff($5,$7,$3); }
- | UTC_DATE_SYM optional_braces
- {
- $$= new (YYTHD->mem_root) Item_func_curdate_utc();
- Lex->safe_to_cache_query=0;
- }
- | UTC_TIME_SYM optional_braces
- {
- $$= new (YYTHD->mem_root) Item_func_curtime_utc();
- Lex->safe_to_cache_query=0;
- }
- | UTC_TIMESTAMP_SYM optional_braces
- {
- $$= new (YYTHD->mem_root) Item_func_now_utc();
- Lex->safe_to_cache_query=0;
- }
- ;
-
-/*
- Functions calls using a non reserved keywork, and using a regular syntax.
- Because the non reserved keyword is used in another part of the grammar,
- a dedicated rule is needed here.
-*/
-function_call_conflict:
- ASCII_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_ascii($3); }
- | CHARSET '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_charset($3); }
- | COALESCE '(' expr_list ')'
- { $$= new (YYTHD->mem_root) Item_func_coalesce(* $3); }
- | COLLATION_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_collation($3); }
- | DATABASE '(' ')'
- {
- $$= new (YYTHD->mem_root) Item_func_database();
- Lex->safe_to_cache_query=0;
- }
- | IF '(' expr ',' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_if($3,$5,$7); }
- | MICROSECOND_SYM '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_microsecond($3); }
- | MOD_SYM '(' expr ',' expr ')'
- { $$ = new (YYTHD->mem_root) Item_func_mod( $3, $5); }
- | OLD_PASSWORD '(' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_old_password($3); }
- | PASSWORD '(' expr ')'
- {
- THD *thd= YYTHD;
- Item* i1;
- if (thd->variables.old_passwords)
- i1= new (thd->mem_root) Item_func_old_password($3);
- else
- i1= new (thd->mem_root) Item_func_password($3);
- $$= i1;
- }
- | QUARTER_SYM '(' expr ')'
- { $$ = new (YYTHD->mem_root) Item_func_quarter($3); }
- | REPEAT_SYM '(' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_repeat($3,$5); }
- | REPLACE '(' expr ',' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_replace($3,$5,$7); }
- | TRUNCATE_SYM '(' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_round($3,$5,1); }
- | WEEK_SYM '(' expr ')'
- {
- THD *thd= YYTHD;
- Item *i1= new (thd->mem_root) Item_int((char*) "0",
- thd->variables.default_week_format,
- 1);
-
- $$= new (thd->mem_root) Item_func_week($3, i1);
- }
- | WEEK_SYM '(' expr ',' expr ')'
- { $$= new (YYTHD->mem_root) Item_func_week($3,$5); }
- | geometry_function
- {
-#ifdef HAVE_SPATIAL
- $$= $1;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
- YYABORT;
-#endif
- }
- ;
-
-geometry_function:
- CONTAINS_SYM '(' expr ',' expr ')'
- {
- $$= GEOM_NEW(YYTHD,
- Item_func_spatial_rel($3, $5,
- Item_func::SP_CONTAINS_FUNC));
- }
- | GEOMETRYCOLLECTION '(' expr_list ')'
- {
- $$= GEOM_NEW(YYTHD,
- Item_func_spatial_collection(* $3,
- Geometry::wkb_geometrycollection,
- Geometry::wkb_point));
- }
- | LINESTRING '(' expr_list ')'
- {
- $$= GEOM_NEW(YYTHD,
- Item_func_spatial_collection(* $3,
- Geometry::wkb_linestring,
- Geometry::wkb_point));
- }
- | MULTILINESTRING '(' expr_list ')'
- {
- $$= GEOM_NEW(YYTHD,
- Item_func_spatial_collection(* $3,
- Geometry::wkb_multilinestring,
- Geometry::wkb_linestring));
- }
- | MULTIPOINT '(' expr_list ')'
- {
- $$= GEOM_NEW(YYTHD,
- Item_func_spatial_collection(* $3,
- Geometry::wkb_multipoint,
- Geometry::wkb_point));
- }
- | MULTIPOLYGON '(' expr_list ')'
- {
- $$= GEOM_NEW(YYTHD,
- Item_func_spatial_collection(* $3,
- Geometry::wkb_multipolygon,
- Geometry::wkb_polygon));
- }
- | POINT_SYM '(' expr ',' expr ')'
- { $$= GEOM_NEW(YYTHD, Item_func_point($3,$5)); }
- | POLYGON '(' expr_list ')'
- {
- $$= GEOM_NEW(YYTHD,
- Item_func_spatial_collection(* $3,
- Geometry::wkb_polygon,
- Geometry::wkb_linestring));
- }
- ;
-
-/*
- Regular function calls.
- The function name is *not* a token, and therefore is guaranteed to not
- introduce side effects to the language in general.
- MAINTAINER:
- All the new functions implemented for new features should fit into
- this category. The place to implement the function itself is
- in sql/item_create.cc
-*/
-function_call_generic:
- IDENT_sys '('
- {
-#ifdef HAVE_DLOPEN
- udf_func *udf= 0;
- LEX *lex= Lex;
- if (using_udf_functions &&
- (udf= find_udf($1.str, $1.length)) &&
- udf->type == UDFTYPE_AGGREGATE)
- {
- if (lex->current_select->inc_in_sum_expr())
- {
- yyerror(ER(ER_SYNTAX_ERROR));
- YYABORT;
- }
- }
- /* Temporary placing the result of find_udf in $3 */
- lex->current_select->udf_list.push_front(udf);
-#endif
- }
- udf_expr_list ')'
- {
- THD *thd= YYTHD;
- LEX *lex= Lex;
- Create_func *builder;
- Item *item= NULL;
-
- /*
- Implementation note:
- names are resolved with the following order:
- - MySQL native functions,
- - User Defined Functions,
- - Stored Functions (assuming the current