List:Commits« Previous MessageNext Message »
From:Patrick Galbraith Date:December 7 2006 11:27pm
Subject:bk commit into 5.2 tree (patg:1.2352)
View as plain text  
Below is the list of changes that have just been committed into a local
5.2 repository of patg. When patg does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-12-07 18:27:46-05:00, patg@stripped +17 -0
  Merge govinda.patg.net:/home/patg/mysql-build/mysql-5.2-5.1-merge
  into  govinda.patg.net:/home/patg/mysql-build/mysql-5.2-wl3031.clone2
  MERGE: 1.2273.60.10

  libmysqld/Makefile.am@stripped, 2006-12-07 18:19:27-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.78.1.25

  mysql-test/lib/init_db.sql@stripped, 2006-12-07 18:19:27-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.26.1.3

  mysql-test/r/connect.result@stripped, 2006-12-07 18:19:27-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.23.1.1

  scripts/mysql_create_system_tables.sh@stripped, 2006-12-07 18:19:27-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.39.1.3

  sql/Makefile.am@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.129.1.38

  sql/field.cc@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.340.2.1

  sql/lex.h@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.153.1.13

  sql/mysql_priv.h@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.390.1.72

  sql/mysqld.cc@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.576.1.2

  sql/share/errmsg.txt@stripped, 2006-12-07 18:19:29-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.96.1.1

  sql/sql_acl.cc@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.188.1.36

  sql/sql_lex.cc@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.175.1.36

  sql/sql_lex.h@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.214.1.37

  sql/sql_parse.cc@stripped, 2006-12-07 18:19:28-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.515.1.88

  sql/sql_yacc.yy@stripped, 2006-12-07 18:27:43-05:00, patg@stripped +15 -13
    WL #3031
    
    Hand merge of conflicts for private 5.2 tree with freshly 5.1-5.2 merge
    MERGE: 1.447.1.28

  storage/federated/ha_federated.cc@stripped, 2006-12-07 18:27:43-05:00, patg@stripped +1 -3
    WL #3031
    
    Hand merge of conflicts for private 5.2 tree with freshly 5.1-5.2 merge
    MERGE: 1.56.1.34

  storage/federated/ha_federated.h@stripped, 2006-12-07 18:19:29-05:00, patg@stripped +0 -0
    Auto merged
    MERGE: 1.25.1.16

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	patg
# Host:	govinda.patg.net
# Root:	/home/patg/mysql-build/mysql-5.2-wl3031.clone2/RESYNC

--- 1.134/sql/Makefile.am	2006-12-07 18:27:53 -05:00
+++ 1.135/sql/Makefile.am	2006-12-07 18:27:53 -05:00
@@ -30,12 +30,13 @@
 noinst_PROGRAMS =	gen_lex_hash
 bin_PROGRAMS =		mysql_tzinfo_to_sql
 gen_lex_hash_LDFLAGS =  @NOINST_LDFLAGS@
-LDADD =			$(top_builddir)/vio/libvio.a \
+SUPPORTING_LIBS =			$(top_builddir)/vio/libvio.a \
 			$(top_builddir)/mysys/libmysys.a \
 			$(top_builddir)/dbug/libdbug.a \
 			$(top_builddir)/regex/libregex.a \
-			$(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
-mysqld_DEPENDENCIES=	@mysql_plugin_libs@ $(LDADD)
+			$(top_builddir)/strings/libmystrings.a
+mysqld_DEPENDENCIES=	@mysql_plugin_libs@ $(SUPPORTING_LIBS)
+LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@
 mysqld_LDADD =		@MYSQLD_EXTRA_LDFLAGS@ \
 			@pstack_libs@ \
 			@mysql_plugin_libs@ \
@@ -52,8 +53,8 @@
 			ha_partition.h \
 			ha_ndbcluster.h ha_ndbcluster_binlog.h \
 			ha_ndbcluster_tables.h \
-			opt_range.h protocol.h rpl_tblmap.h \
-			log.h sql_show.h rpl_rli.h \
+			opt_range.h protocol.h rpl_tblmap.h rpl_utility.h \
+			log.h sql_show.h rpl_rli.h rpl_mi.h \
 			sql_select.h structs.h table.h sql_udf.h hash_filo.h \
 			lex.h lex_symbol.h sql_acl.h sql_crypt.h  \
 			log_event.h sql_repl.h slave.h rpl_filter.h \
@@ -93,7 +94,7 @@
 			sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
 			sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \
 			slave.cc sql_repl.cc rpl_filter.cc rpl_tblmap.cc \
-			rpl_injector.cc \
+			rpl_utility.cc rpl_injector.cc rpl_rli.cc rpl_mi.cc \
                         sql_union.cc sql_derived.cc \
 			client.c sql_client.cc mini_client_errors.c pack.c\
 			stacktrace.c repl_failsafe.h repl_failsafe.cc \
@@ -119,9 +120,11 @@
 			-DLIBDIR="\"$(MYSQLLIBdir)\"" \
 			@DEFS@
 
-BUILT_SOURCES =		sql_yacc.cc sql_yacc.h lex_hash.h
-EXTRA_DIST =		udf_example.c $(BUILT_SOURCES) \
-			nt_servc.cc nt_servc.h message.mc CMakeLists.txt
+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) \
+			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
 
@@ -148,13 +151,22 @@
 # 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 $<
+		$(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.
 lex_hash.h:	gen_lex_hash$(EXEEXT)
 		./gen_lex_hash$(EXEEXT) > $@
 

--- 1.359/sql/field.cc	2006-12-07 18:27:53 -05:00
+++ 1.360/sql/field.cc	2006-12-07 18:27:53 -05:00
@@ -52,6 +52,13 @@
 #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
 ((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
 
+/*
+  This code necessitates the call
+
+  table->use_all_columns() prior to calling get_field(&mem, table->field[n])
+  or table->field[n]->store,
+
+*/
 #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
 #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
 

--- 1.156/sql/lex.h	2006-12-07 18:27:53 -05:00
+++ 1.157/sql/lex.h	2006-12-07 18:27:53 -05:00
@@ -30,21 +30,16 @@
 #define SYM_OR_NULL(A) A
 #endif
 
-#define SYM(A) SYM_OR_NULL(A),0,0,&sym_group_common
-#define F_SYM(A) SYM_OR_NULL(A)
-
-#define CREATE_FUNC(A) (void *)(SYM_OR_NULL(A)), &sym_group_common
-
-#ifdef HAVE_SPATIAL
-#define CREATE_FUNC_GEOM(A) (void *)(SYM_OR_NULL(A)), &sym_group_geom
-#else
-#define CREATE_FUNC_GEOM(A) 0, &sym_group_geom
-#endif
+#define SYM(A) SYM_OR_NULL(A),0,&sym_group_common
 
 /*
   Symbols are broken into separated arrays to allow field names with
   same name as functions.
   These are kept sorted for human lookup (the symbols are hashed).
+
+  NOTE! The symbol tables should be the same regardless of what features
+  are compiled into the server. Don't add ifdef'ed symbols to the
+  lists
 */
 
 static SYMBOL symbols[] = {
@@ -386,11 +381,9 @@
   { "PACK_KEYS",	SYM(PACK_KEYS_SYM)},
   { "PARSER",           SYM(PARSER_SYM)},
   { "PARTIAL",		SYM(PARTIAL)},
-#ifdef WITH_PARTITION_STORAGE_ENGINE
   { "PARTITION",        SYM(PARTITION_SYM)},
   { "PARTITIONING",     SYM(PARTITIONING_SYM)},
   { "PARTITIONS",       SYM(PARTITIONS_SYM)},
-#endif
   { "PASSWORD",		SYM(PASSWORD)},
   { "PHASE",            SYM(PHASE_SYM)},
   { "PLUGIN",           SYM(PLUGIN_SYM)},
@@ -595,235 +588,38 @@
 
 
 static SYMBOL sql_functions[] = {
-  { "ABS",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_abs)},
-  { "ACOS",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_acos)},
   { "ADDDATE",		SYM(ADDDATE_SYM)},
-  { "ADDTIME",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_addtime)},
-  { "AES_ENCRYPT",      F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_encrypt)},
-  { "AES_DECRYPT",      F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_aes_decrypt)},
-  { "AREA",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_area)},
-  { "ASIN",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_asin)},
-  { "ASBINARY",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkb)},
-  { "ASTEXT",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkt)},
-  { "ASWKB",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkb)},
-  { "ASWKT",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_as_wkt)},
-  { "ATAN",		SYM(ATAN)},
-  { "ATAN2",		SYM(ATAN)},
-  { "BENCHMARK",	SYM(BENCHMARK_SYM)},
-  { "BIN",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bin)},
-  { "BIT_COUNT",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_count)},
-  { "BIT_OR",		SYM(BIT_OR)},
   { "BIT_AND",		SYM(BIT_AND)},
+  { "BIT_OR",		SYM(BIT_OR)},
   { "BIT_XOR",		SYM(BIT_XOR)},
   { "CAST",		SYM(CAST_SYM)},
-  { "CEIL",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
-  { "CEILING",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ceiling)},
-  { "BIT_LENGTH",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_bit_length)},
-  { "CENTROID",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_centroid)},
-  { "CHAR_LENGTH",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
-  { "CHARACTER_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_char_length)},
-  { "COERCIBILITY",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_coercibility)},
-  { "COMPRESS",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_compress)},
-  { "CONCAT",		SYM(CONCAT)},
-  { "CONCAT_WS",	SYM(CONCAT_WS)},
-  { "CONNECTION_ID",	F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)},
-  { "CONV",		F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)},
-  { "CONVERT_TZ",	SYM(CONVERT_TZ_SYM)},
   { "COUNT",		SYM(COUNT_SYM)},
-  { "COS",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)},
-  { "COT",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)},
-  { "CRC32",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_crc32)},
-  { "CROSSES",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_crosses)},
   { "CURDATE",		SYM(CURDATE)},
   { "CURTIME",		SYM(CURTIME)},
   { "DATE_ADD",		SYM(DATE_ADD_INTERVAL)},
-  { "DATEDIFF",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_datediff)},
-  { "DATE_FORMAT",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_date_format)},
   { "DATE_SUB",		SYM(DATE_SUB_INTERVAL)},
-  { "DAYNAME",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayname)},
-  { "DAYOFMONTH",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofmonth)},
-  { "DAYOFWEEK",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofweek)},
-  { "DAYOFYEAR",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_dayofyear)},
-  { "DECODE",		SYM(DECODE_SYM)},
-  { "DEGREES",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_degrees)},
-  { "DES_ENCRYPT",	SYM(DES_ENCRYPT_SYM)},
-  { "DES_DECRYPT",	SYM(DES_DECRYPT_SYM)},
-  { "DIMENSION",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_dimension)},
-  { "DISJOINT",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_disjoint)},
-  { "ELT",		SYM(ELT_FUNC)},
-  { "ENCODE",		SYM(ENCODE_SYM)},
-  { "ENCRYPT",		SYM(ENCRYPT)},
-  { "ENDPOINT",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_endpoint)},
-  { "ENVELOPE",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_envelope)},
-  { "EQUALS",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_equals)},
-  { "EXTERIORRING",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_exteriorring)},
   { "EXTRACT",		SYM(EXTRACT_SYM)},
-  { "EXTRACTVALUE",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_xml_extractvalue)},
-  { "EXP",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_exp)},
-  { "EXPORT_SET",	SYM(EXPORT_SET)},
-  { "FIELD",		SYM(FIELD_FUNC)},	/* For compability */
-  { "FIND_IN_SET",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_find_in_set)},
-  { "FLOOR",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_floor)},
-  { "FORMAT",		SYM(FORMAT_SYM)},
-  { "FOUND_ROWS",	F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_found_rows)},
-  { "FROM_DAYS",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_from_days)},
-  { "FROM_UNIXTIME",	SYM(FROM_UNIXTIME)},
-  { "GET_LOCK",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_get_lock)},
-  { "GEOMETRYN",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_geometryn)},
-  { "GEOMETRYTYPE",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_geometry_type)},
-  { "GEOMCOLLFROMTEXT",	SYM(GEOMCOLLFROMTEXT)},
-  { "GEOMCOLLFROMWKB",	SYM(GEOMFROMWKB)},
-  { "GEOMETRYCOLLECTIONFROMTEXT",SYM(GEOMCOLLFROMTEXT)},
-  { "GEOMETRYCOLLECTIONFROMWKB",SYM(GEOMFROMWKB)},
-  { "GEOMETRYFROMTEXT", SYM(GEOMFROMTEXT)},
-  { "GEOMETRYFROMWKB",	SYM(GEOMFROMWKB)},
-  { "GEOMFROMTEXT",	SYM(GEOMFROMTEXT)},
-  { "GEOMFROMWKB",	SYM(GEOMFROMWKB)},
-  { "GLENGTH",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_glength)},
-  { "GREATEST",		SYM(GREATEST_SYM)},
   { "GROUP_CONCAT",	SYM(GROUP_CONCAT_SYM)},
   { "GROUP_UNIQUE_USERS",	SYM(GROUP_UNIQUE_USERS)},
-  { "HEX",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_hex)},
-  { "IFNULL",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_ifnull)},
-  { "INET_ATON",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_aton)},
-  { "INET_NTOA",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_inet_ntoa)},
-  { "INSTR",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_instr)},
-  { "INTERIORRINGN",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_interiorringn)},
-  { "INTERSECTS",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_intersects)},
-  { "ISCLOSED",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_isclosed)},
-  { "ISEMPTY",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_isempty)},
-  { "ISNULL",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_isnull)},
-  { "IS_FREE_LOCK",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_free_lock)},
-  { "IS_USED_LOCK",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_is_used_lock)},
-  { "LAST_INSERT_ID",	SYM(LAST_INSERT_ID)},
-  { "ISSIMPLE",         F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_issimple)},
-  { "LAST_DAY",         F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_last_day)},
-  { "LCASE",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
-  { "LEAST",		SYM(LEAST_SYM)},
-  { "LENGTH",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
-  { "LN",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ln)},
-  { "LINEFROMTEXT",	SYM(LINEFROMTEXT)},
-  { "LINEFROMWKB",	SYM(GEOMFROMWKB)},
-  { "LINESTRINGFROMTEXT",SYM(LINEFROMTEXT)},
-  { "LINESTRINGFROMWKB",SYM(GEOMFROMWKB)},
-  { "LOAD_FILE",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_load_file)},
-  { "LOCATE",		SYM(LOCATE)},
-  { "LOG",		SYM(LOG_SYM)},
-  { "LOG2",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log2)},
-  { "LOG10",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_log10)},
-  { "LOWER",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_lcase)},
-  { "LPAD",		F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_lpad)},
-  { "LTRIM",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ltrim)},
-  { "MAKE_SET",		SYM(MAKE_SET_SYM)},
-  { "MAKEDATE",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_makedate)},
-  { "MAKETIME",		F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_maketime)},
-  { "MASTER_POS_WAIT",	SYM(MASTER_POS_WAIT)},
   { "MAX",		SYM(MAX_SYM)},
-  { "MBRCONTAINS",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)},
-  { "MBRDISJOINT",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_disjoint)},
-  { "MBREQUAL",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_equals)},
-  { "MBRINTERSECTS",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_intersects)},
-  { "MBROVERLAPS",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_overlaps)},
-  { "MBRTOUCHES",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_touches)},
-  { "MBRWITHIN",	F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_within)},
-  { "MD5",              F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_md5)},
   { "MID",		SYM(SUBSTRING)},	/* unireg function */
   { "MIN",		SYM(MIN_SYM)},
-  { "MLINEFROMTEXT",	SYM(MLINEFROMTEXT)},
-  { "MLINEFROMWKB",	SYM(GEOMFROMWKB)},
-  { "MPOINTFROMTEXT",	SYM(MPOINTFROMTEXT)},
-  { "MPOINTFROMWKB",	SYM(GEOMFROMWKB)},
-  { "MPOLYFROMTEXT",	SYM(MPOLYFROMTEXT)},
-  { "MPOLYFROMWKB",	SYM(GEOMFROMWKB)},
-  { "MONTHNAME",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_monthname)},
-  { "MULTILINESTRINGFROMTEXT",SYM(MLINEFROMTEXT)},
-  { "MULTILINESTRINGFROMWKB",SYM(GEOMFROMWKB)},
-  { "MULTIPOINTFROMTEXT",SYM(MPOINTFROMTEXT)},
-  { "MULTIPOINTFROMWKB",SYM(GEOMFROMWKB)},
-  { "MULTIPOLYGONFROMTEXT",SYM(MPOLYFROMTEXT)},
-  { "MULTIPOLYGONFROMWKB",SYM(GEOMFROMWKB)},
-  { "NAME_CONST",       F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_name_const)},
   { "NOW",		SYM(NOW_SYM)},
-  { "NULLIF",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_nullif)},
-  { "NUMGEOMETRIES",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numgeometries)},
-  { "NUMINTERIORRINGS",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numinteriorring)},
-  { "NUMPOINTS",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_numpoints)},
-  { "OCTET_LENGTH",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_length)},
-  { "OCT",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_oct)},
-  { "ORD",              F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ord)},
-  { "OVERLAPS",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_overlaps)},
-  { "PERIOD_ADD",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_add)},
-  { "PERIOD_DIFF",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_period_diff)},
-  { "PI",		F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_pi)},
-  { "POINTFROMTEXT",	SYM(POINTFROMTEXT)},
-  { "POINTFROMWKB",	SYM(GEOMFROMWKB)},
-  { "POINTN",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_pointn)},
-  { "POLYFROMTEXT",	SYM(POLYFROMTEXT)},
-  { "POLYFROMWKB",	SYM(GEOMFROMWKB)},
-  { "POLYGONFROMTEXT",	SYM(POLYFROMTEXT)},
-  { "POLYGONFROMWKB",	SYM(GEOMFROMWKB)},
   { "POSITION",		SYM(POSITION_SYM)},
-  { "POW",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
-  { "POWER",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)},
-  { "QUOTE",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)},
-  { "RADIANS",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)},
-  { "RAND",		SYM(RAND)},
-  { "RELEASE_LOCK",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_release_lock)},
-  { "REVERSE",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_reverse)},
-  { "ROUND",		SYM(ROUND)},
-  { "ROW_COUNT",	SYM(ROW_COUNT_SYM)},
-  { "RPAD",		F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_rpad)},
-  { "RTRIM",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_rtrim)},
-  { "SEC_TO_TIME",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sec_to_time)},
-  { "SESSION_USER",	SYM(USER)},
-  { "SUBDATE",		SYM(SUBDATE_SYM)},
-  { "SIGN",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sign)},
-  { "SIN",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sin)},
-  { "SHA",              F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
-  { "SHA1",             F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sha)},
-  { "SLEEP",            F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sleep)},
-  { "SOUNDEX",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_soundex)},
-  { "SPACE",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_space)},
-  { "SQRT",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_sqrt)},
-  { "SRID",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_srid)},
-  { "STARTPOINT",	F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_startpoint)},
+  { "SESSION_USER",     SYM(USER)},
   { "STD",		SYM(STD_SYM)},
   { "STDDEV",		SYM(STD_SYM)},
   { "STDDEV_POP",	SYM(STD_SYM)},
   { "STDDEV_SAMP",	SYM(STDDEV_SAMP_SYM)},
-  { "STR_TO_DATE",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_str_to_date)},
-  { "STRCMP",		F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_strcmp)},
+  { "SUBDATE",		SYM(SUBDATE_SYM)},
   { "SUBSTR",		SYM(SUBSTRING)},
   { "SUBSTRING",	SYM(SUBSTRING)},
-  { "SUBSTRING_INDEX",	SYM(SUBSTRING_INDEX)},
-  { "SUBTIME",          F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_subtime)},
   { "SUM",		SYM(SUM_SYM)},
   { "SYSDATE",		SYM(SYSDATE)},
-  { "SYSTEM_USER",	SYM(USER)},
-  { "TAN",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_tan)},
-  { "TIME_FORMAT",	F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_time_format)},
-  { "TIME_TO_SEC",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_time_to_sec)},
-  { "TIMEDIFF",         F_SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_timediff)},
-  { "TO_DAYS",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_to_days)},
-  { "TOUCHES",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_touches)},
+  { "SYSTEM_USER",      SYM(USER)},
   { "TRIM",		SYM(TRIM)},
-  { "UCASE",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
-  { "UNCOMPRESS",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompress)},
-  { "UNCOMPRESSED_LENGTH", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_uncompressed_length)},
-  { "UNHEX",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_unhex)},
   { "UNIQUE_USERS",	SYM(UNIQUE_USERS)},
-  { "UNIX_TIMESTAMP",	SYM(UNIX_TIMESTAMP)},
-  { "UPDATEXML",	F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_xml_update)},
-  { "UPPER",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)},
-  { "UUID",		F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_uuid)},
   { "VARIANCE",		SYM(VARIANCE_SYM)},
   { "VAR_POP",		SYM(VARIANCE_SYM)},
   { "VAR_SAMP",		SYM(VAR_SAMP_SYM)},
-  { "VERSION",		F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)},
-  { "WEEKDAY",		F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)},
-  { "WEEKOFYEAR",	F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekofyear)},
-  { "WITHIN",		F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_within)},
-  { "X",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_x)},
-  { "Y",		F_SYM(FUNC_ARG1),0,CREATE_FUNC_GEOM(create_func_y)},
-  { "YEARWEEK",		SYM(YEARWEEK)}
 };

--- 1.393/sql/mysql_priv.h	2006-12-07 18:27:53 -05:00
+++ 1.394/sql/mysql_priv.h	2006-12-07 18:27:53 -05:00
@@ -21,6 +21,9 @@
   except the part which must be in the server and in the client.
 */
 
+#ifndef MYSQL_PRIV_H
+#define MYSQL_PRIV_H
+
 #ifndef MYSQL_CLIENT
 
 #include <my_global.h>
@@ -102,6 +105,17 @@
 extern CHARSET_INFO *national_charset_info, *table_alias_charset;
 
 
+enum Derivation
+{
+  DERIVATION_IGNORABLE= 5,
+  DERIVATION_COERCIBLE= 4,
+  DERIVATION_SYSCONST= 3,
+  DERIVATION_IMPLICIT= 2,
+  DERIVATION_NONE= 1,
+  DERIVATION_EXPLICIT= 0
+};
+
+
 typedef struct my_locale_st
 {
   const char *name;
@@ -137,7 +151,20 @@
 #define MAX_ACCEPT_RETRY	10	// Test accept this many times
 #define MAX_FIELDS_BEFORE_HASH	32
 #define USER_VARS_HASH_SIZE     16
-#define STACK_MIN_SIZE		8192	// Abort if less stack during eval.
+#define TABLE_OPEN_CACHE_MIN    64
+#define TABLE_OPEN_CACHE_DEFAULT 64
+
+/* 
+ Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
+ Drake, libc6 2.3.6-0ubuntu2, Linux kernel 2.6.15-27-686, on x86.  (Added 
+ 100 bytes as reasonable buffer against growth and other environments'
+ requirements.)
+
+ Feel free to raise this by the smallest amount you can to get the
+ "execution_constants" test to pass.
+ */
+#define STACK_MIN_SIZE          10788   // Abort if less stack during eval.
+
 #define STACK_MIN_SIZE_FOR_OPEN 1024*80
 #define STACK_BUFF_ALLOC	256	// For stack overrun checks
 #ifndef MYSQLD_NET_RETRY_COUNT
@@ -207,12 +234,6 @@
 /* Characters shown for the command in 'information_schema.processlist' */
 #define PROCESS_LIST_INFO_WIDTH 65535
 
-/* Time handling defaults */
-#define TIMESTAMP_MAX_YEAR 2038
-#define YY_PART_YEAR	   70
-#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
-#define TIMESTAMP_MAX_VALUE 2145916799
-#define TIMESTAMP_MIN_VALUE 1
 #define PRECISION_FOR_DOUBLE 53
 #define PRECISION_FOR_FLOAT  24
 
@@ -427,6 +448,7 @@
 #define TL_OPTION_UPDATING	1
 #define TL_OPTION_FORCE_INDEX	2
 #define TL_OPTION_IGNORE_LEAVES 4
+#define TL_OPTION_ALIAS         8
 
 /* Some portable defines */
 
@@ -454,7 +476,8 @@
   NO_MATTER,
   IN_HAVING,
   SELECT_LIST,
-  IN_WHERE
+  IN_WHERE,
+  IN_ON
 };
 
 struct st_table;
@@ -584,7 +607,7 @@
 LEX_USER *create_default_definer(THD *thd);
 LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name);
 LEX_USER *get_current_user(THD *thd, LEX_USER *user);
-bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str,
+bool check_string_length(LEX_STRING *str,
                          const char *err_msg, uint max_length);
 
 
@@ -770,6 +793,9 @@
                     const char *table_name, uint flags);
 void close_cached_table(THD *thd, TABLE *table);
 bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent);
+bool do_rename(THD *thd, TABLE_LIST *ren_table, char *new_db,
+                      char *new_table_name, char *new_table_alias,
+                      bool skip_error);
 bool mysql_change_db(THD *thd,const char *name,bool no_access_check);
 void mysql_parse(THD *thd,char *inBuf,uint length);
 bool mysql_test_parse_for_slave(THD *thd,char *inBuf,uint length);
@@ -856,7 +882,8 @@
 bool check_simple_select();
 int mysql_alter_tablespace(THD* thd, st_alter_tablespace *ts_info);
 
-SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length);
+SORT_FIELD * make_unireg_sortorder(ORDER *order, uint *length,
+                                  SORT_FIELD *sortorder);
 int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
 		List<Item> &fields, List <Item> &all_fields, ORDER *order);
 int setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
@@ -868,7 +895,7 @@
 bool mysql_select(THD *thd, Item ***rref_pointer_array,
                   TABLE_LIST *tables, uint wild_num,  List<Item> &list,
                   COND *conds, uint og_num, ORDER *order, ORDER *group,
-                  Item *having, ORDER *proc_param, ulong select_type, 
+                  Item *having, ORDER *proc_param, ulonglong select_type, 
                   select_result *result, SELECT_LEX_UNIT *unit, 
                   SELECT_LEX *select_lex);
 void free_underlaid_joins(THD *thd, SELECT_LEX *select);
@@ -894,7 +921,7 @@
 int prepare_create_field(create_field *sql_field, 
 			 uint *blob_columns, 
 			 int *timestamps, int *timestamps_with_niladic,
-			 uint table_flags);
+			 longlong table_flags);
 bool mysql_create_table(THD *thd,const char *db, const char *table_name,
                         HA_CREATE_INFO *create_info,
                         List<create_field> &fields, List<Key> &keys,
@@ -1409,13 +1436,14 @@
 #endif
 void mysql_print_status();
 /* key.cc */
-int find_ref_key(KEY *key, uint key_count, Field *field, uint *key_length);
+int find_ref_key(KEY *key, uint key_count, byte *record, Field *field,
+                 uint *key_length);
 void key_copy(byte *to_key, byte *from_record, KEY *key_info, uint key_length);
 void key_restore(byte *to_record, byte *from_key, KEY *key_info,
                  uint key_length);
 bool key_cmp_if_same(TABLE *form,const byte *key,uint index,uint key_length);
 void key_unpack(String *to,TABLE *form,uint index);
-bool check_if_key_used(TABLE *table, uint idx, List<Item> &fields);
+bool is_key_used(TABLE *table, uint idx, const MY_BITMAP *fields);
 int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length);
 int key_rec_cmp(void *key_info, byte *a, byte *b);
 
@@ -1425,16 +1453,14 @@
 
 
 int vprint_msg_to_log(enum loglevel level, const char *format, va_list args);
-void sql_print_error(const char *format, ...);
-void sql_print_warning(const char *format, ...);
-void sql_print_information(const char *format, ...);
-typedef void (*sql_print_message_func)(const char *format, ...);
+void sql_print_error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2);
+void sql_print_information(const char *format, ...)
+  ATTRIBUTE_FORMAT(printf, 1, 2);
+typedef void (*sql_print_message_func)(const char *format, ...)
+  ATTRIBUTE_FORMAT(printf, 1, 2);
 extern sql_print_message_func sql_print_message_handlers[];
 
-/* type of the log table */
-#define QUERY_LOG_SLOW 1
-#define QUERY_LOG_GENERAL 2
-
 int error_log_print(enum loglevel level, const char *format,
                     va_list args);
 
@@ -1465,6 +1491,8 @@
 void unhex_type2(TYPELIB *lib);
 uint check_word(TYPELIB *lib, const char *val, const char *end,
 		const char **end_of_word);
+int find_string_in_array(LEX_STRING * const haystack, LEX_STRING * const needle,
+                         CHARSET_INFO * const cs);
 
 
 bool is_keyword(const char *name, uint len);
@@ -1556,7 +1584,6 @@
 extern bool opt_disable_networking, opt_skip_show_db;
 extern my_bool opt_character_set_client_handshake;
 extern bool volatile abort_loop, shutdown_in_progress, grant_option;
-extern bool mysql_proc_table_exists;
 extern uint volatile thread_count, thread_running, global_read_lock;
 extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types;
 extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap;
@@ -1626,67 +1653,17 @@
 
 /* optional things, have_* variables */
 
-#ifdef WITH_INNOBASE_STORAGE_ENGINE
-extern handlerton *innobase_hton;
-extern SHOW_COMP_OPTION have_innodb;
-#else
 extern SHOW_COMP_OPTION have_innodb;
-#endif
-#ifdef WITH_EXAMPLE_STORAGE_ENGINE
-extern handlerton *example_hton;
-extern SHOW_COMP_OPTION have_example_db;
-#else
-extern SHOW_COMP_OPTION have_example_db;
-#endif
-#ifdef WITH_ARCHIVE_STORAGE_ENGINE
-extern handlerton *archive_hton;
-extern SHOW_COMP_OPTION have_archive_db;
-#else
-extern SHOW_COMP_OPTION have_archive_db;
-#endif
-#ifdef WITH_CSV_STORAGE_ENGINE
-extern handlerton *tina_hton;
-extern SHOW_COMP_OPTION have_csv_db;
-#else
 extern SHOW_COMP_OPTION have_csv_db;
-#endif
-#ifdef WITH_FEDERATED_STORAGE_ENGINE
-extern handlerton *federated_hton;
-extern SHOW_COMP_OPTION have_federated_db;
-#else
-extern SHOW_COMP_OPTION have_federated_db;
-#endif
-#ifdef WITH_BLACKHOLE_STORAGE_ENGINE
-extern handlerton *blackhole_hton;
-extern SHOW_COMP_OPTION have_blackhole_db;
-#else
-extern SHOW_COMP_OPTION have_blackhole_db;
-#endif
-#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-extern handlerton *ndbcluster_hton;
 extern SHOW_COMP_OPTION have_ndbcluster;
-#else
-extern SHOW_COMP_OPTION have_ndbcluster;
-#endif
-#ifdef WITH_PARTITION_STORAGE_ENGINE
-extern handlerton *partition_hton;
 extern SHOW_COMP_OPTION have_partition_db;
-#else
-extern SHOW_COMP_OPTION have_partition_db;
-#endif
-
-#ifdef WITH_MYISAMMRG_STORAGE_ENGINE
-extern handlerton *myisammrg_hton;
-extern SHOW_COMP_OPTION have_merge_db;
-#else
-extern SHOW_COMP_OPTION have_merge_db;
-#endif
 
+extern handlerton *partition_hton;
 extern handlerton *myisam_hton;
 extern handlerton *heap_hton;
 
 extern SHOW_COMP_OPTION have_row_based_replication;
-extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_dlopen;
+extern SHOW_COMP_OPTION have_openssl, have_symlink, have_dlopen;
 extern SHOW_COMP_OPTION have_query_cache;
 extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
 extern SHOW_COMP_OPTION have_crypt;
@@ -1742,7 +1719,7 @@
 /* old unireg functions */
 
 void unireg_init(ulong options);
-void unireg_end(void);
+void unireg_end(void) __attribute__((noreturn));
 bool mysql_create_frm(THD *thd, const char *file_name,
                       const char *db, const char *table,
 		      HA_CREATE_INFO *create_info,
@@ -1824,7 +1801,7 @@
 		 uint s_length, SQL_SELECT *select,
 		 ha_rows max_rows, bool sort_positions,
                  ha_rows *examined_rows);
-void filesort_free_buffers(TABLE *table);
+void filesort_free_buffers(TABLE *table, bool full);
 void change_double_for_sort(double nr,byte *to);
 double my_double_round(double value, int dec, bool truncate);
 int get_quick_record(SQL_SELECT *select);
@@ -1844,7 +1821,7 @@
 	       HA_CREATE_INFO *create_info, uint keys);
 void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
 int rename_file_ext(const char * from,const char * to,const char * ext);
-bool check_db_name(char *db);
+bool check_db_name(LEX_STRING *db);
 bool check_column_name(const char *name);
 bool check_table_name(const char *name, uint length);
 char *get_field(MEM_ROOT *mem, Field *field);
@@ -2027,7 +2004,7 @@
 */
 
 #ifndef EMBEDDED_LIBRARY
-extern "C" void unireg_abort(int exit_code);
+extern "C" void unireg_abort(int exit_code) __attribute__((noreturn));
 void kill_delayed_threads(void);
 bool check_stack_overrun(THD *thd, long margin, char *dummy);
 #else
@@ -2037,7 +2014,52 @@
 #endif
 
 /* Used by handlers to store things in schema tables */
+#define IS_FILES_FILE_ID              0
+#define IS_FILES_FILE_NAME            1
+#define IS_FILES_FILE_TYPE            2
+#define IS_FILES_TABLESPACE_NAME      3
+#define IS_FILES_TABLE_CATALOG        4
+#define IS_FILES_TABLE_SCHEMA         5
+#define IS_FILES_TABLE_NAME           6
+#define IS_FILES_LOGFILE_GROUP_NAME   7
+#define IS_FILES_LOGFILE_GROUP_NUMBER 8
+#define IS_FILES_ENGINE               9
+#define IS_FILES_FULLTEXT_KEYS       10
+#define IS_FILES_DELETED_ROWS        11
+#define IS_FILES_UPDATE_COUNT        12
+#define IS_FILES_FREE_EXTENTS        13
+#define IS_FILES_TOTAL_EXTENTS       14
+#define IS_FILES_EXTENT_SIZE         15
+#define IS_FILES_INITIAL_SIZE        16
+#define IS_FILES_MAXIMUM_SIZE        17
+#define IS_FILES_AUTOEXTEND_SIZE     18
+#define IS_FILES_CREATION_TIME       19
+#define IS_FILES_LAST_UPDATE_TIME    20
+#define IS_FILES_LAST_ACCESS_TIME    21
+#define IS_FILES_RECOVER_TIME        22
+#define IS_FILES_TRANSACTION_COUNTER 23
+#define IS_FILES_VERSION             24
+#define IS_FILES_ROW_FORMAT          25
+#define IS_FILES_TABLE_ROWS          26
+#define IS_FILES_AVG_ROW_LENGTH      27
+#define IS_FILES_DATA_LENGTH         28
+#define IS_FILES_MAX_DATA_LENGTH     29
+#define IS_FILES_INDEX_LENGTH        30
+#define IS_FILES_DATA_FREE           31
+#define IS_FILES_CREATE_TIME         32
+#define IS_FILES_UPDATE_TIME         33
+#define IS_FILES_CHECK_TIME          34
+#define IS_FILES_CHECKSUM            35
+#define IS_FILES_STATUS              36
+#define IS_FILES_EXTRA               37
+void init_fill_schema_files_row(TABLE* table);
 bool schema_table_store_record(THD *thd, TABLE *table);
 
+/* sql/item_create.cc */
+int item_create_init();
+void item_create_cleanup();
+
 #endif /* MYSQL_SERVER */
 #endif /* MYSQL_CLIENT */
+
+#endif /* MYSQL_PRIV_H */

--- 1.596/sql/mysqld.cc	2006-12-07 18:27:54 -05:00
+++ 1.597/sql/mysqld.cc	2006-12-07 18:27:54 -05:00
@@ -1180,6 +1180,7 @@
   my_tz_free();
   my_database_names_free();
 #ifndef NO_EMBEDDED_ACCESS_CHECKS
+  servers_free(1);
   acl_free(1);
   grant_free();
 #endif
@@ -3643,6 +3644,9 @@
   }
   if (!opt_noacl)
     (void) grant_init();
+
+  if (!opt_bootstrap)
+    servers_init(0);
 
   if (!opt_noacl)
   {

--- 1.190/sql/sql_acl.cc	2006-12-07 18:27:54 -05:00
+++ 1.191/sql/sql_acl.cc	2006-12-07 18:27:54 -05:00
@@ -169,7 +169,7 @@
 }
 
 #define IP_ADDR_STRLEN (3+1+3+1+3+1+3)
-#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_BYTE_LEN+1+USERNAME_BYTE_LENGTH+1)
+#define ACL_KEY_LENGTH (IP_ADDR_STRLEN+1+NAME_LEN+1+USERNAME_LENGTH+1)
 
 static DYNAMIC_ARRAY acl_hosts,acl_users,acl_dbs;
 static MEM_ROOT mem, memex;
@@ -313,12 +313,11 @@
   READ_RECORD read_record_info;
   my_bool return_val= 1;
   bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE;
-  char tmp_name[NAME_BYTE_LEN+1];
+  char tmp_name[NAME_LEN+1];
   int password_length;
   DBUG_ENTER("acl_load");
 
   grant_version++; /* Privileges updated */
-  mysql_proc_table_exists= 1;			// Assume mysql.proc exists
 
   acl_cache->clear(1);				// Clear locked hostname cache
 
@@ -2402,7 +2401,7 @@
                                     const char *user, const char *tname,
                                     bool exact)
 {
-  char helping [NAME_BYTE_LEN*2+USERNAME_BYTE_LENGTH+3];
+  char helping [NAME_LEN*2+USERNAME_LENGTH+3];
   uint len;
   GRANT_NAME *grant_name,*found=0;
   HASH_SEARCH_STATE state;
@@ -3142,9 +3141,22 @@
   grant_option=TRUE;
   thd->mem_root= old_root;
   pthread_mutex_unlock(&acl_cache->lock);
+
+  if (!result) /* success */
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                        thd->query, thd->query_length, FALSE, FALSE);
+    }
+  }
+
   rw_unlock(&LOCK_grant);
-  if (!result)
+
+  if (!result) /* success */
     send_ok(thd);
+
   /* Tables are automatically closed */
   DBUG_RETURN(result);
 }
@@ -3296,9 +3308,21 @@
   grant_option=TRUE;
   thd->mem_root= old_root;
   pthread_mutex_unlock(&acl_cache->lock);
+  if (!result && !no_error)
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                        thd->query, thd->query_length, FALSE, FALSE);
+    }
+  }
+
   rw_unlock(&LOCK_grant);
+
   if (!result && !no_error)
     send_ok(thd);
+
   /* Tables are automatically closed */
   DBUG_RETURN(result);
 }
@@ -3309,7 +3333,7 @@
 {
   List_iterator <LEX_USER> str_list (list);
   LEX_USER *Str, *tmp_Str;
-  char tmp_db[NAME_BYTE_LEN+1];
+  char tmp_db[NAME_LEN+1];
   bool create_new_users=0;
   TABLE_LIST tables[2];
   DBUG_ENTER("mysql_grant");
@@ -3373,7 +3397,7 @@
     {
       result= TRUE;
       continue;
-    }  
+    }
     if (replace_user_table(thd, tables[0].table, *Str,
                            (!db ? rights : 0), revoke_grant, create_new_users,
                            test(thd->variables.sql_mode &
@@ -3396,11 +3420,23 @@
     }
   }
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (!result)
+  {
+    if (mysql_bin_log.is_open())
+    {
+      thd->clear_error();
+      thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                        thd->query, thd->query_length, FALSE, FALSE);
+    }
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
 
   if (!result)
     send_ok(thd);
+
   DBUG_RETURN(result);
 }
 
@@ -3836,7 +3872,7 @@
   GRANT_COLUMN *grant_column;
   ulong want_access= grant->want_privilege & ~grant->privilege;
   DBUG_ENTER("check_grant_column");
-  DBUG_PRINT("enter", ("table: %s  want_access: %u", table_name, want_access));
+  DBUG_PRINT("enter", ("table: %s  want_access: %lu", table_name, want_access));
 
   if (!want_access)
     DBUG_RETURN(0);				// Already checked
@@ -4013,7 +4049,7 @@
 bool check_grant_db(THD *thd,const char *db)
 {
   Security_context *sctx= thd->security_ctx;
-  char helping [NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+2];
+  char helping [NAME_LEN+USERNAME_LENGTH+2];
   uint len;
   bool error= 1;
 
@@ -5400,6 +5436,13 @@
   }
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                      thd->query, thd->query_length, FALSE, FALSE);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
   if (result)
@@ -5456,6 +5499,13 @@
   rebuild_check_host();
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                      thd->query, thd->query_length, FALSE, FALSE);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
   if (result)
@@ -5525,6 +5575,13 @@
   rebuild_check_host();
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                      thd->query, thd->query_length, FALSE, FALSE);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
   if (result)
@@ -5699,6 +5756,13 @@
   }
 
   VOID(pthread_mutex_unlock(&acl_cache->lock));
+
+  if (mysql_bin_log.is_open())
+  {
+    thd->binlog_query(THD::MYSQL_QUERY_TYPE,
+                      thd->query, thd->query_length, FALSE, FALSE);
+  }
+
   rw_unlock(&LOCK_grant);
   close_thread_tables(thd);
 

--- 1.177/sql/sql_lex.cc	2006-12-07 18:27:54 -05:00
+++ 1.178/sql/sql_lex.cc	2006-12-07 18:27:54 -05:00
@@ -151,7 +151,6 @@
   lex->safe_to_cache_query= 1;
   lex->time_zone_tables_used= 0;
   lex->leaf_tables_insert= 0;
-  lex->variables_used= 0;
   lex->empty_field_list_on_rset= 0;
   lex->select_lex.select_number= 1;
   lex->next_state=MY_LEX_START;
@@ -177,7 +176,8 @@
   lex->reset_query_tables_list(FALSE);
   lex->expr_allows_subselect= TRUE;
 
-  lex->name= 0;
+  lex->name.str= 0;
+  lex->name.length= 0;
   lex->event_parse_data= NULL;
 
   lex->nest_level=0 ;
@@ -258,6 +258,12 @@
   return get_hash_symbol(name,len,0)!=0;
 }
 
+bool is_lex_native_function(const LEX_STRING *name)
+{
+  DBUG_ASSERT(name != NULL);
+  return (get_hash_symbol(name->str, name->length, 1) != 0);
+}
+
 /* make a copy of token before ptr and set yytoklen */
 
 static LEX_STRING get_token(LEX *lex,uint length)
@@ -1162,7 +1168,7 @@
     initialization is checked for failure.
   */
   parent_lex->push_context(&context);
-  cond_count= with_wild= 0;
+  cond_count= between_count= with_wild= 0;
   conds_processed_with_permanent_arena= 0;
   ref_pointer_array= 0;
   select_n_having_items= 0;
@@ -1203,7 +1209,7 @@
   select_limit= 0;      /* denotes the default limit = HA_POS_ERROR */
   offset_limit= 0;      /* denotes the default offset = 0 */
   with_sum_func= 0;
-
+  is_correlated= 0;
 }
 
 /*
@@ -1397,6 +1403,8 @@
       SELECT_LEX_UNIT *munit= s->master_unit();
       munit->uncacheable|= UNCACHEABLE_DEPENDENT;
     }
+  is_correlated= TRUE;
+  this->master_unit()->item->is_correlated= TRUE;
 }
 
 bool st_select_lex_node::set_braces(bool value)      { return 1; }
@@ -1459,7 +1467,7 @@
 bool st_select_lex::add_item_to_list(THD *thd, Item *item)
 {
   DBUG_ENTER("st_select_lex::add_item_to_list");
-  DBUG_PRINT("info", ("Item: %p", item));
+  DBUG_PRINT("info", ("Item: 0x%lx", (long) item));
   DBUG_RETURN(item_list.push_back(item));
 }
 
@@ -1659,9 +1667,18 @@
   query_tables_last= &query_tables;
   query_tables_own_last= 0;
   if (init)
-    hash_init(&sroutines, system_charset_info, 0, 0, 0, sp_sroutine_key, 0, 0);
+  {
+    /*
+      We delay real initialization of hash (and therefore related
+      memory allocation) until first insertion into this hash.
+    */
+    hash_clear(&sroutines);
+  }
   else if (sroutines.records)
+  {
+    /* Non-zero sroutines.records means that hash was initialized. */
     my_hash_reset(&sroutines);
+  }
   sroutines_list.empty();
   sroutines_list_own_last= sroutines_list.next;
   sroutines_list_own_elements= 0;
@@ -1737,7 +1754,8 @@
          unit= unit->next_unit())
     {
       if (unit->first_select()->parent_lex == this &&
-          (unit->item == 0 || unit->item->place() != IN_WHERE))
+          (unit->item == 0 ||
+           (unit->item->place() != IN_WHERE && unit->item->place() != IN_ON)))
       {
         selects_allow_merge= 0;
         break;
@@ -2156,6 +2174,28 @@
 
 
 /*
+  Checks for usage of routines and/or tables in a parsed statement
+
+  SYNOPSIS
+    st_lex:table_or_sp_used()
+
+  RETURN
+    FALSE  No routines and tables used
+    TRUE   Either or both routines and tables are used.
+*/
+
+bool st_lex::table_or_sp_used()
+{
+  DBUG_ENTER("table_or_sp_used");
+
+  if (sroutines.records || query_tables)
+    DBUG_RETURN(TRUE);
+
+  DBUG_RETURN(FALSE);
+}
+
+
+/*
   Do end-of-prepare fixup for list of tables and their merge-VIEWed tables
 
   SYNOPSIS
@@ -2185,15 +2225,25 @@
 
 
 /*
-  fix some structures at the end of preparation
+  Save WHERE/HAVING/ON clauses and replace them with disposable copies
 
   SYNOPSIS
     st_select_lex::fix_prepare_information
-    thd   thread handler
-    conds pointer on conditions which will be used for execution statement
+      thd          thread handler
+      conds        in/out pointer to WHERE condition to be met at execution
+      having_conds in/out pointer to HAVING condition to be met at execution
+  
+  DESCRIPTION
+    The passed WHERE and HAVING are to be saved for the future executions.
+    This function saves it, and returns a copy which can be thrashed during
+    this execution of the statement. By saving/thrashing here we mean only
+    AND/OR trees.
+    The function also calls fix_prepare_info_in_table_list that saves all
+    ON expressions.    
 */
 
-void st_select_lex::fix_prepare_information(THD *thd, Item **conds)
+void st_select_lex::fix_prepare_information(THD *thd, Item **conds, 
+                                            Item **having_conds)
 {
   if (!thd->stmt_arena->is_conventional() && first_execution)
   {
@@ -2203,9 +2253,15 @@
       prep_where= *conds;
       *conds= where= prep_where->copy_andor_structure(thd);
     }
+    if (*having_conds)
+    {
+      prep_having= *having_conds;
+      *having_conds= having= prep_having->copy_andor_structure(thd);
+    }
     fix_prepare_info_in_table_list(thd, (TABLE_LIST *)table_list.first);
   }
 }
+
 
 /*
   There are st_select_lex::add_table_to_list &

--- 1.219/sql/sql_lex.h	2006-12-07 18:27:54 -05:00
+++ 1.220/sql/sql_lex.h	2006-12-07 18:27:54 -05:00
@@ -432,7 +432,7 @@
   TABLE *table; /* temporary table using for appending UNION results */
 
   select_result *result;
-  ulong found_rows_for_union;
+  ulonglong found_rows_for_union;
   bool res;
 public:
   bool  prepared, // prepare phase already performed for UNION (unit)
@@ -505,7 +505,7 @@
   void set_thd(THD *thd_arg) { thd= thd_arg; }
 
   friend void lex_start(THD *thd, const uchar *buf, uint length);
-  friend int subselect_union_engine::exec();
+  friend int subselect_union_engine::exec(bool);
 
   List<Item> *get_unit_column_types();
 };
@@ -565,7 +565,8 @@
     list during split_sum_func
   */
   uint select_n_having_items;
-  uint cond_count;      /* number of arguments of and/or/xor in where/having */
+  uint cond_count;    /* number of arguments of and/or/xor in where/having/on */
+  uint between_count; /* number of between predicates in where/having/on      */   
   enum_parsing_place parsing_place; /* where we are parsing expression */
   bool with_sum_func;   /* sum function indicator */
   /* 
@@ -596,6 +597,8 @@
     query processing end even if we use temporary table
   */
   bool subquery_in_having;
+  /* TRUE <=> this SELECT is correlated w.r.t. some ancestor select */
+  bool is_correlated;
   /*
     This variable is required to ensure proper work of subqueries and
     stored procedures. Generally, one should use the states of
@@ -691,7 +694,7 @@
   void print(THD *thd, String *str);
   static void print_order(String *str, ORDER *order);
   void print_limit(THD *thd, String *str);
-  void fix_prepare_information(THD *thd, Item **conds);
+  void fix_prepare_information(THD *thd, Item **conds, Item **having_conds);
   /*
     Destroy the used execution plan (JOIN) of this subtree (this
     SELECT_LEX and all nested SELECT_LEXes and SELECT_LEX_UNITs).
@@ -800,7 +803,11 @@
     0 - indicates that this query does not need prelocking.
   */
   TABLE_LIST **query_tables_own_last;
-  /* Set of stored routines called by statement. */
+  /*
+    Set of stored routines called by statement.
+    (Note that we use lazy-initialization for this hash).
+  */
+  enum { START_SROUTINES_HASH_SIZE= 16 };
   HASH sroutines;
   /*
     List linking elements of 'sroutines' set. Allows you to add new elements
@@ -875,6 +882,25 @@
 };
 
 
+/*
+  st_parsing_options contains the flags for constructions that are
+  allowed in the current statement.
+*/
+
+struct st_parsing_options
+{
+  bool allows_variable;
+  bool allows_select_into;
+  bool allows_select_procedure;
+  bool allows_derived;
+
+  st_parsing_options()
+    : allows_variable(TRUE), allows_select_into(TRUE),
+      allows_select_procedure(TRUE), allows_derived(TRUE)
+  {}
+};
+
+
 /* The state of the lex parsing. This is saved in the THD struct */
 
 typedef struct st_lex : public Query_tables_list
@@ -893,7 +919,8 @@
   /* The values of tok_start/tok_end as they were one call of MYSQLlex before */
   const uchar *tok_start_prev, *tok_end_prev;
 
-  char *length,*dec,*change,*name;
+  char *length,*dec,*change;
+  LEX_STRING name;
   Table_ident *like_name;
   char *help_arg;
   char *backup_dir;				/* For RESTORE/BACKUP */
@@ -1032,7 +1059,7 @@
   bool stmt_prepare_mode;
   bool safe_to_cache_query;
   bool subqueries, ignore;
-  bool variables_used;
+  st_parsing_options parsing_options;
   ALTER_INFO alter_info;
   /* Prepared statements SQL syntax:*/
   LEX_STRING prepared_stmt_name; /* Statement name (in all queries) */
@@ -1189,6 +1216,8 @@
 
   void reset_n_backup_query_tables_list(Query_tables_list *backup);
   void restore_backup_query_tables_list(Query_tables_list *backup);
+
+  bool table_or_sp_used();
 } LEX;
 
 struct st_lex_local: public st_lex
@@ -1213,5 +1242,7 @@
 extern void lex_end(LEX *lex);
 extern int MYSQLlex(void *arg, void *yythd);
 extern const uchar *skip_rear_comments(const uchar *ubegin, const uchar *uend);
+
+extern bool is_lex_native_function(const LEX_STRING *name);
 
 #endif /* MYSQL_SERVER */

--- 1.521/sql/sql_parse.cc	2006-12-07 18:27:54 -05:00
+++ 1.522/sql/sql_parse.cc	2006-12-07 18:27:54 -05:00
@@ -394,9 +394,9 @@
           NO_ACCESS)) // authentication is OK
     {
       DBUG_PRINT("info",
-                 ("Capabilities: %lx  packet_length: %ld  Host: '%s'  "
+                 ("Capabilities: %lu  packet_length: %ld  Host: '%s'  "
                   "Login user: '%s' Priv_user: '%s'  Using password: %s "
-                  "Access: %u  db: '%s'",
+                  "Access: %lu  db: '%s'",
                   thd->client_capabilities,
                   thd->max_client_packet_length,
                   thd->main_security_ctx.host_or_ip,
@@ -1002,7 +1002,7 @@
   if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
     thd->variables.sql_mode|= MODE_IGNORE_SPACE;
 #ifdef HAVE_OPENSSL
-  DBUG_PRINT("info", ("client capabilities: %d", thd->client_capabilities));
+  DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
   if (thd->client_capabilities & CLIENT_SSL)
   {
     /* Do the SSL layering. */
@@ -1047,19 +1047,22 @@
   char *passwd= strend(user)+1;
   uint user_len= passwd - user - 1;
   char *db= passwd;
-  char db_buff[NAME_BYTE_LEN + 1];              // buffer to store db in utf8
-  char user_buff[USERNAME_BYTE_LENGTH + 1];	// buffer to store user in utf8
+  char db_buff[NAME_LEN + 1];           // buffer to store db in utf8
+  char user_buff[USERNAME_LENGTH + 1];	// buffer to store user in utf8
   uint dummy_errors;
 
   /*
     Old clients send null-terminated string as password; new clients send
     the size (1 byte) + string (not null-terminated). Hence in case of empty
     password both send '\0'.
+
+    This strlen() can't be easily deleted without changing protocol.
   */
   uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
     *passwd++ : strlen(passwd);
   db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
     db + passwd_len + 1 : 0;
+  /* strlen() can't be easily deleted without changing protocol */
   uint db_len= db ? strlen(db) : 0;
 
   if (passwd + passwd_len + db_len > (char *)net->read_pos + pkt_len)
@@ -1158,7 +1161,7 @@
     of handle_one_connection, which is thd. We need to know the
     start of the stack so that we could check for stack overruns.
   */
-  DBUG_PRINT("info", ("handle_one_connection called by thread %d\n",
+  DBUG_PRINT("info", ("handle_one_connection called by thread %lu\n",
 		      thd->thread_id));
   /* now that we've called my_thread_init(), it is safe to call DBUG_* */
 
@@ -1214,7 +1217,14 @@
     {
       execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
       if (thd->query_error)
+      {
 	thd->killed= THD::KILL_CONNECTION;
+        sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
+                          thd->thread_id,(thd->db ? thd->db : "unconnected"),
+                          sctx->user ? sctx->user : "unauthenticated",
+                          sctx->host_or_ip, "init_connect command failed");
+        sql_print_warning("%s", net->last_error);
+      }
       THD_SET_PROC_INFO(thd, 0);
       thd->set_time();
       thd->init_for_queries();
@@ -1314,28 +1324,31 @@
   thd->init_for_queries();
   while (fgets(buff, thd->net.max_packet, file))
   {
-   ulong length= (ulong) strlen(buff);
-   while (buff[length-1] != '\n' && !feof(file))
-   {
-     /*
-       We got only a part of the current string. Will try to increase
-       net buffer then read the rest of the current string.
-     */
-     if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
-     {
-       net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
-       thd->fatal_error();
-       break;
-     }
-     buff= (char*) thd->net.buff;
-     fgets(buff + length, thd->net.max_packet - length, file);
-     length+= (ulong) strlen(buff + length);
-   }
-   if (thd->is_fatal_error)
-     break;
+    /* strlen() can't be deleted because fgets() doesn't return length */
+    ulong length= (ulong) strlen(buff);
+    while (buff[length-1] != '\n' && !feof(file))
+    {
+      /*
+        We got only a part of the current string. Will try to increase
+        net buffer then read the rest of the current string.
+      */
+      /* purecov: begin tested */
+      if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
+      {
+        net_send_error(thd, ER_NET_PACKET_TOO_LARGE, NullS);
+        thd->fatal_error();
+        break;
+      }
+      buff= (char*) thd->net.buff;
+      fgets(buff + length, thd->net.max_packet - length, file);
+      length+= (ulong) strlen(buff + length);
+      /* purecov: end */
+    }
+    if (thd->is_fatal_error)
+      break;                                    /* purecov: inspected */
 
     while (length && (my_isspace(thd->charset(), buff[length-1]) ||
-           buff[length-1] == ';'))
+                      buff[length-1] == ';'))
       length--;
     buff[length]=0;
     thd->query_length=length;
@@ -1420,24 +1433,30 @@
 */
 
 static
-int mysql_table_dump(THD* thd, char* db, char* tbl_name)
+int mysql_table_dump(THD *thd, LEX_STRING *db, char *tbl_name)
 {
   TABLE* table;
   TABLE_LIST* table_list;
   int error = 0;
   DBUG_ENTER("mysql_table_dump");
-  db = (db && db[0]) ? db : thd->db;
+  if (db->length == 0)
+  {
+    db->str= thd->db;            /* purecov: inspected */
+    db->length= thd->db_length;  /* purecov: inspected */
+  }
   if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
     DBUG_RETURN(1); // out of memory
-  table_list->db= db;
+  table_list->db= db->str;
   table_list->table_name= table_list->alias= tbl_name;
   table_list->lock_type= TL_READ_NO_INSERT;
   table_list->prev_global= &table_list;	// can be removed after merge with 4.1
 
-  if (!db || check_db_name(db))
+  if (check_db_name(db))
   {
-    my_error(ER_WRONG_DB_NAME ,MYF(0), db ? db : "NULL");
+    /* purecov: begin inspected */
+    my_error(ER_WRONG_DB_NAME ,MYF(0), db->str ? db->str : "NULL");
     goto err;
+    /* purecov: end */
   }
   if (lower_case_table_names)
     my_casedn_str(files_charset_info, tbl_name);
@@ -1597,7 +1616,7 @@
       command= COM_END;				// Wrong command
     DBUG_PRINT("info",("Command on %s = %d (%s)",
 		       vio_description(net->vio), command,
-		       command_name[command]));
+		       command_name[command].str));
   }
   net->read_timeout=old_timeout;		// restore it
   /*
@@ -1666,7 +1685,7 @@
     statistic_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB],
 			&LOCK_status);
     thd->convert_string(&tmp, system_charset_info,
-			packet, strlen(packet), thd->charset());
+			packet, packet_length-1, thd->charset());
     if (!mysql_change_db(thd, tmp.str, FALSE))
     {
       general_log_print(thd, command, "%s",thd->db);
@@ -1684,7 +1703,8 @@
 #endif
   case COM_TABLE_DUMP:
   {
-    char *db, *tbl_name;
+    char *tbl_name;
+    LEX_STRING db;
     uint db_len= *(uchar*) packet;
     if (db_len >= packet_length || db_len > NAME_LEN)
     {
@@ -1700,34 +1720,41 @@
 
     statistic_increment(thd->status_var.com_other, &LOCK_status);
     thd->enable_slow_log= opt_log_slow_admin_statements;
-    db= thd->alloc(db_len + tbl_len + 2);
-    if (!db)
+    db.str= thd->alloc(db_len + tbl_len + 2);
+    db.length= db_len;
+    if (!db.str)
     {
       my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
       break;
     }
-    tbl_name= strmake(db, packet + 1, db_len)+1;
+    tbl_name= strmake(db.str, packet + 1, db_len)+1;
     strmake(tbl_name, packet + db_len + 2, tbl_len);
-    mysql_table_dump(thd, db, tbl_name);
+    mysql_table_dump(thd, &db, tbl_name);
     break;
   }
   case COM_CHANGE_USER:
   {
+    statistic_increment(thd->status_var.com_other, &LOCK_status);
+    char *user= (char*) packet, *packet_end= packet+ packet_length;
+    char *passwd= strend(user)+1;
+
     thd->change_user();
     thd->clear_error();                         // if errors from rollback
 
-    statistic_increment(thd->status_var.com_other, &LOCK_status);
-    char *user= (char*) packet;
-    char *passwd= strend(user)+1;
     /*
       Old clients send null-terminated string ('\0' for empty string) for
       password.  New clients send the size (1 byte) + string (not null
       terminated, so also '\0' for empty string).
     */
-    char db_buff[NAME_BYTE_LEN+1];               // buffer to store db in utf8
+    char db_buff[NAME_LEN+1];                 // buffer to store db in utf8
     char *db= passwd;
-    uint passwd_len= thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
-      *passwd++ : strlen(passwd);
+    char *save_db;
+    uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
+                      *passwd++ : strlen(passwd));
+    uint dummy_errors, save_db_length, db_length, res;
+    Security_context save_security_ctx= *thd->security_ctx;
+    USER_CONN *save_user_connect;
+
     db+= passwd_len + 1;
 #ifndef EMBEDDED_LIBRARY
     /* Small check for incoming packet */
@@ -1738,17 +1765,22 @@
     }
 #endif
     /* Convert database name to utf8 */
-    uint dummy_errors;
+    /*
+      Handle problem with old bug in client protocol where db had an extra
+      \0
+    */
+    db_length= (packet_end - db);
+    if (db_length > 0 && db[db_length-1] == 0)
+      db_length--;
     db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
-                             system_charset_info, db, strlen(db),
+                             system_charset_info, db, db_length,
                              thd->charset(), &dummy_errors)]= 0;
     db= db_buff;
 
     /* Save user and privileges */
-    uint save_db_length= thd->db_length;
-    char *save_db= thd->db;
-    Security_context save_security_ctx= *thd->security_ctx;
-    USER_CONN *save_user_connect= thd->user_connect;
+    save_db_length= thd->db_length;
+    save_db= thd->db;
+    save_user_connect= thd->user_connect;
 
     if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
     {
@@ -1759,7 +1791,7 @@
 
     /* Clear variables that are allocated */
     thd->user_connect= 0;
-    int res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
+    res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
 
     if (res)
     {
@@ -1819,7 +1851,9 @@
     if (alloc_query(thd, packet, packet_length))
       break;					// fatal error is set
     char *packet_end= thd->query + thd->query_length;
-    general_log_print(thd, command, "%.*b", thd->query_length, thd->query);
+    /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
+    const char *format= "%.*b";
+    general_log_print(thd, command, format, thd->query_length, thd->query);
     DBUG_PRINT("query",("%-.4096s",thd->query));
 
     if (!(specialflag & SPECIAL_NO_PRIOR))
@@ -1869,29 +1903,31 @@
     break;
 #else
   {
-    char *fields, *pend;
+    char *fields, *packet_end= packet + packet_length - 1, *arg_end;
     /* Locked closure of all tables */
     TABLE_LIST *locked_tables= NULL;
     TABLE_LIST table_list;
     LEX_STRING conv_name;
     /* Saved variable value */
     my_bool old_innodb_table_locks=  thd->variables.innodb_table_locks;
-
+    uint dummy;
 
     /* used as fields initializator */
     lex_start(thd, 0, 0);
 
-
     statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS],
 			&LOCK_status);
     bzero((char*) &table_list,sizeof(table_list));
-    if (thd->copy_db_to(&table_list.db, 0))
+    if (thd->copy_db_to(&table_list.db, &dummy))
       break;
-    pend= strend(packet);
+    /*
+      We have name + wildcard in packet, separated by endzero
+    */
+    arg_end= strend(packet);
     thd->convert_string(&conv_name, system_charset_info,
-			packet, (uint) (pend-packet), thd->charset());
+			packet, (uint) (arg_end - packet), thd->charset());
     table_list.alias= table_list.table_name= conv_name.str;
-    packet= pend+1;
+    packet= arg_end + 1;
 
     if (!my_strcasecmp(system_charset_info, table_list.db,
                        information_schema_name.str))
@@ -1901,7 +1937,7 @@
         table_list.schema_table= schema_table;
     }
 
-    thd->query_length= strlen(packet);       // for simplicity: don't optimize
+    thd->query_length= (uint) (packet_end - packet); // Don't count end \0
     if (!(thd->query=fields=thd->memdup(packet,thd->query_length+1)))
       break;
     general_log_print(thd, command, "%s %s", table_list.table_name, fields);
@@ -1937,24 +1973,27 @@
     error=TRUE;					// End server
     break;
 
+#ifdef REMOVED
   case COM_CREATE_DB:				// QQ: To be removed
     {
-      char *db=thd->strdup(packet), *alias;
+      LEX_STRING db, alias;
       HA_CREATE_INFO create_info;
 
       statistic_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB],
 			  &LOCK_status);
-      // null test to handle EOM
-      if (!db || !(alias= thd->strdup(db)) || check_db_name(db))
+      if (thd->LEX_STRING_make(&db, packet, packet_length -1) ||
+          thd->LEX_STRING_make(&alias, db.str, db.length) ||
+          check_db_name(&db))
       {
-	my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
+	my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
 	break;
       }
-      if (check_access(thd,CREATE_ACL,db,0,1,0,is_schema_db(db)))
+      if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
+                       is_schema_db(db.str)))
 	break;
       general_log_print(thd, command, packet);
       bzero(&create_info, sizeof(create_info));
-      mysql_create_db(thd, (lower_case_table_names == 2 ? alias : db),
+      mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
                       &create_info, 0);
       break;
     }
@@ -1962,14 +2001,15 @@
     {
       statistic_increment(thd->status_var.com_stat[SQLCOM_DROP_DB],
 			  &LOCK_status);
-      char *db=thd->strdup(packet);
-      /*  null test to handle EOM */
-      if (!db || check_db_name(db))
+      LEX_STRING db;
+
+      if (thd->LEX_STRING_make(&db, packet, packet_length - 1) ||
+          check_db_name(&db))
       {
-	my_error(ER_WRONG_DB_NAME, MYF(0), db ? db : "NULL");
+	my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
 	break;
       }
-      if (check_access(thd,DROP_ACL,db,0,1,0,is_schema_db(db)))
+      if (check_access(thd, DROP_ACL, db.str, 0, 1, 0, is_schema_db(db.str)))
 	break;
       if (thd->locked_tables || thd->active_transaction())
       {
@@ -1977,10 +2017,11 @@
                    ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
 	break;
       }
-      general_log_print(thd, command, db);
-      mysql_rm_db(thd, db, 0, 0);
+      general_log_print(thd, command, db.str);
+      mysql_rm_db(thd, db.str, 0, 0);
       break;
     }
+#endif
 #ifndef EMBEDDED_LIBRARY
   case COM_BINLOG_DUMP:
     {
@@ -2052,7 +2093,12 @@
 #ifdef __WIN__
     sleep(1);					// must wait after eof()
 #endif
-    send_eof(thd);				// This is for 'quit request'
+    /*
+      The client is next going to send a COM_QUIT request (as part of
+      mysql_close()). Make the life simpler for the client by sending
+      the response for the coming COM_QUIT in advance
+    */
+    send_eof(thd);
     close_connection(thd, 0, 1);
     close_thread_tables(thd);			// Free before kill
     kill_mysql();
@@ -2062,37 +2108,47 @@
 #endif
   case COM_STATISTICS:
   {
-    general_log_print(thd, command, NullS);
-    statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
-			&LOCK_status);
+    STATUS_VAR current_global_status_var;
+    ulong uptime;
+    uint length;
 #ifndef EMBEDDED_LIBRARY
-    char buff[200];
+    char buff[250];
+    uint buff_len= sizeof(buff);
 #else
     char *buff= thd->net.last_error;
+    uint buff_len= sizeof(thd->net.last_error);
 #endif
 
-    STATUS_VAR current_global_status_var;
+    general_log_print(thd, command, NullS);
+    statistic_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS],
+			&LOCK_status);
     calc_sum_of_all_status(&current_global_status_var);
-
-    ulong uptime = (ulong) (thd->start_time - start_time);
-    sprintf((char*) buff,
-	    "Uptime: %lu  Threads: %d  Questions: %lu  Slow queries: %lu  Opens: %lu  Flush tables: %lu  Open tables: %u  Queries per second avg: %.3f",
-	    uptime,
-	    (int) thread_count, (ulong) thd->query_id,
-	    current_global_status_var.long_query_count,
-	    current_global_status_var.opened_tables, refresh_version,
-            cached_open_tables(),
-	    (uptime ? (ulonglong2double(thd->query_id) / (double) uptime) :
-	     (double) 0));
+    uptime= (ulong) (thd->start_time - start_time);
+    length= my_snprintf((char*) buff, buff_len - 1,
+                        "Uptime: %lu  Threads: %d  Questions: %lu  "
+                        "Slow queries: %lu  Opens: %lu  Flush tables: %lu  "
+                        "Open tables: %u  Queries per second avg: %.3f",
+                        uptime,
+                        (int) thread_count, (ulong) thd->query_id,
+                        current_global_status_var.long_query_count,
+                        current_global_status_var.opened_tables,
+                        refresh_version,
+                        cached_open_tables(),
+                        (uptime ? (ulonglong2double(thd->query_id) /
+                                   (double) uptime) : (double) 0));
 #ifdef SAFEMALLOC
     if (sf_malloc_cur_memory)				// Using SAFEMALLOC
-      sprintf(strend(buff), "  Memory in use: %ldK  Max memory used: %ldK",
-	      (sf_malloc_cur_memory+1023L)/1024L,
-	      (sf_malloc_max_memory+1023L)/1024L);
+    {
+      char *end= buff + length;
+      length+= my_snprintf(end, buff_len - length - 1,
+                           end,"  Memory in use: %ldK  Max memory used: %ldK",
+                           (sf_malloc_cur_memory+1023L)/1024L,
+                           (sf_malloc_max_memory+1023L)/1024L);
+    }
 #endif
 #ifndef EMBEDDED_LIBRARY
-    VOID(my_net_write(net, buff,(uint) strlen(buff)));
-    VOID(net_flush(net));
+    VOID(my_net_write(net, buff, length));
+      VOID(net_flush(net));
 #endif
     break;
   }
@@ -2289,26 +2345,28 @@
     DBUG_RETURN(1);
 #else
     {
-      char *db;
+      LEX_STRING db;
+      uint dummy;
       if (lex->select_lex.db == NULL &&
-          thd->copy_db_to(&lex->select_lex.db, 0))
+          thd->copy_db_to(&lex->select_lex.db, &dummy))
       {
         DBUG_RETURN(1);
       }
-      db= lex->select_lex.db;
-      if (check_db_name(db))
+      db.str= lex->select_lex.db;
+      db.length= strlen(db.str);
+      if (check_db_name(&db))
       {
-        my_error(ER_WRONG_DB_NAME, MYF(0), db);
+        my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
         DBUG_RETURN(1);
       }
-      if (check_access(thd, SELECT_ACL, db, &thd->col_access, 0, 0,
-                       is_schema_db(db)))
+      if (check_access(thd, SELECT_ACL, db.str, &thd->col_access, 0, 0,
+                       is_schema_db(db.str)))
         DBUG_RETURN(1);			        /* purecov: inspected */
-      if (!thd->col_access && check_grant_db(thd,db))
+      if (!thd->col_access && check_grant_db(thd, db.str))
       {
 	my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
                  thd->security_ctx->priv_user, thd->security_ctx->priv_host,
-                 db);
+                 db.str);
 	DBUG_RETURN(1);
       }
       break;
@@ -2544,7 +2602,23 @@
     {
       /* we warn the slave SQL thread */
       my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-      reset_one_shot_variables(thd);
+      if (thd->one_shot_set)
+      {
+        /*
+          It's ok to check thd->one_shot_set here:
+
+          The charsets in a MySQL 5.0 slave can change by both a binlogged
+          SET ONE_SHOT statement and the event-internal charset setting, 
+          and these two ways to change charsets do not seems to work
+          together.
+
+          At least there seems to be problems in the rli cache for
+          charsets if we are using ONE_SHOT.  Note that this is normally no
+          problem because either the >= 5.0 slave reads a 4.1 binlog (with
+          ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
+        */
+        reset_one_shot_variables(thd);
+      }
       DBUG_RETURN(0);
     }
   }
@@ -2849,11 +2923,6 @@
       if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
 	goto error;
     }
-    if (strlen(first_table->table_name) > NAME_LEN)
-    {
-      my_error(ER_WRONG_TABLE_NAME, MYF(0), first_table->table_name);
-      break;
-    }
     pthread_mutex_lock(&LOCK_active_mi);
     /*
       fetch_master_table will send the error to the client on failure.
@@ -3076,11 +3145,6 @@
 
   case SQLCOM_ALTER_TABLE:
     DBUG_ASSERT(first_table == all_tables && first_table != 0);
-#if defined(DONT_ALLOW_SHOW_COMMANDS)
-    my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-               MYF(0)); /* purecov: inspected */
-    goto error;
-#else
     {
       ulong priv=0;
       ulong priv_needed= ALTER_ACL;
@@ -3088,11 +3152,6 @@
       if (lex->alter_info.flags & ALTER_DROP_PARTITION)
         priv_needed|= DROP_ACL;
 
-      if (lex->name && (!lex->name[0] || strlen(lex->name) > NAME_LEN))
-      {
-	my_error(ER_WRONG_TABLE_NAME, MYF(0), lex->name);
-        goto error;
-      }
       /* Must be set in the parser */
       DBUG_ASSERT(select_lex->db);
       if (check_access(thd, priv_needed, first_table->db,
@@ -3108,11 +3167,11 @@
       {
 	if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
 	  goto error;
-	if (lex->name && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
+	if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
 	{					// Rename of table
 	  TABLE_LIST tmp_table;
 	  bzero((char*) &tmp_table,sizeof(tmp_table));
-	  tmp_table.table_name=lex->name;
+	  tmp_table.table_name= lex->name.str;
 	  tmp_table.db=select_lex->db;
 	  tmp_table.grant.privilege=priv;
 	  if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
@@ -3140,7 +3199,7 @@
       }
 
       thd->enable_slow_log= opt_log_slow_admin_statements;
-      res= mysql_alter_table(thd, select_lex->db, lex->name,
+      res= mysql_alter_table(thd, select_lex->db, lex->name.str,
                              &lex->create_info,
                              first_table, lex->create_list,
                              lex->key_list,
@@ -3149,7 +3208,6 @@
                              lex->ignore, &lex->alter_info, 1);
       break;
     }
-#endif /*DONT_ALLOW_SHOW_COMMANDS*/
   case SQLCOM_RENAME_TABLE:
   {
     DBUG_ASSERT(first_table == all_tables && first_table != 0);
@@ -3238,6 +3296,7 @@
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
     {
+      /* Presumably, REPAIR and binlog writing doesn't require synchronization */
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
@@ -3270,6 +3329,7 @@
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
     {
+      /* Presumably, ANALYZE and binlog writing doesn't require synchronization */
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
@@ -3294,6 +3354,7 @@
     /* ! we write after unlocking the table */
     if (!res && !lex->no_write_to_binlog)
     {
+      /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */
       if (mysql_bin_log.is_open())
       {
 	thd->clear_error(); // No binlog error generated
@@ -3395,9 +3456,17 @@
     res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
 		      lex->update_list, lex->value_list,
                       lex->duplicates, lex->ignore);
-    /* do not show last insert ID if VIEW does not have auto_inc */
+
+    /*
+      If we have inserted into a VIEW, and the base table has
+      AUTO_INCREMENT column, but this column is not accessible through
+      a view, then we should restore LAST_INSERT_ID to the value it
+      had before the statement.
+    */
     if (first_table->view && !first_table->contain_auto_increment)
-      thd->first_successful_insert_id_in_cur_stmt= 0;
+      thd->first_successful_insert_id_in_cur_stmt=
+        thd->first_successful_insert_id_in_prev_stmt;
+
     break;
   }
   case SQLCOM_REPLACE_SELECT:
@@ -3448,8 +3517,12 @@
         if (first_table->lock_type ==  TL_WRITE_CONCURRENT_INSERT &&
             thd->lock)
         {
+          /* INSERT ... SELECT should invalidate only the very first table */
+          TABLE_LIST *save_table= first_table->next_local;
+          first_table->next_local= 0;
           mysql_unlock_tables(thd, thd->lock);
           query_cache_invalidate3(thd, first_table, 1);
+          first_table->next_local= save_table;
           thd->lock=0;
         }
         delete result;
@@ -3457,9 +3530,17 @@
       /* revert changes for SP */
       select_lex->table_list.first= (byte*) first_table;
     }
-    /* do not show last insert ID if VIEW does not have auto_inc */
+
+    /*
+      If we have inserted into a VIEW, and the base table has
+      AUTO_INCREMENT column, but this column is not accessible through
+      a view, then we should restore LAST_INSERT_ID to the value it
+      had before the statement.
+    */
     if (first_table->view && !first_table->contain_auto_increment)
-      thd->first_successful_insert_id_in_cur_stmt= 0;
+      thd->first_successful_insert_id_in_cur_stmt=
+        thd->first_successful_insert_id_in_prev_stmt;
+
     break;
   }
   case SQLCOM_TRUNCATE:
@@ -3581,6 +3662,7 @@
       /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
       thd->options|= OPTION_KEEP_LOG;
     }
+    /* DDL and binlog write order protected by LOCK_open */
     res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
 			lex->drop_temporary);
   }
@@ -3733,9 +3815,10 @@
       break;
     }
     char *alias;
-    if (!(alias=thd->strdup(lex->name)) || check_db_name(lex->name))
+    if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
+        check_db_name(&lex->name))
     {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
       break;
     }
     /*
@@ -3747,17 +3830,18 @@
     */
 #ifdef HAVE_REPLICATION
     if (thd->slave_thread && 
-	(!rpl_filter->db_ok(lex->name) ||
-	 !rpl_filter->db_ok_with_wild_table(lex->name)))
+	(!rpl_filter->db_ok(lex->name.str) ||
+	 !rpl_filter->db_ok_with_wild_table(lex->name.str)))
     {
       my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
       break;
     }
 #endif
-    if (check_access(thd,CREATE_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
+    if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
+                     is_schema_db(lex->name.str)))
       break;
-    res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias : lex->name),
-			 &lex->create_info, 0);
+    res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
+                              lex->name.str), &lex->create_info, 0);
     break;
   }
   case SQLCOM_DROP_DB:
@@ -3767,9 +3851,9 @@
       res= -1;
       break;
     }
-    if (check_db_name(lex->name))
+    if (check_db_name(&lex->name))
     {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
       break;
     }
     /*
@@ -3781,14 +3865,15 @@
     */
 #ifdef HAVE_REPLICATION
     if (thd->slave_thread && 
-	(!rpl_filter->db_ok(lex->name) ||
-	 !rpl_filter->db_ok_with_wild_table(lex->name)))
+	(!rpl_filter->db_ok(lex->name.str) ||
+	 !rpl_filter->db_ok_with_wild_table(lex->name.str)))
     {
       my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
       break;
     }
 #endif
-    if (check_access(thd,DROP_ACL,lex->name,0,1,0,is_schema_db(lex->name)))
+    if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
+                     is_schema_db(lex->name.str)))
       break;
     if (thd->locked_tables || thd->active_transaction())
     {
@@ -3796,7 +3881,7 @@
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
       goto error;
     }
-    res= mysql_rm_db(thd, lex->name, lex->drop_if_exists, 0);
+    res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
     break;
   }
   case SQLCOM_RENAME_DB:
@@ -3822,6 +3907,11 @@
       break;
     }
 #endif
+    if (check_db_name(newdb))
+    {
+      my_error(ER_WRONG_DB_NAME, MYF(0), newdb->str);
+      break;
+    }
     if (check_access(thd,ALTER_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
         check_access(thd,DROP_ACL,olddb->str,0,1,0,is_schema_db(olddb->str)) ||
         check_access(thd,CREATE_ACL,newdb->str,0,1,0,is_schema_db(newdb->str)))
@@ -3843,11 +3933,10 @@
   }
   case SQLCOM_ALTER_DB:
   {
-    char *db= lex->name;
-    DBUG_ASSERT(db); /* Must be set in the parser */
-    if (!strip_sp(db) || check_db_name(db))
+    LEX_STRING *db= &lex->name;
+    if (check_db_name(db))
     {
-      my_error(ER_WRONG_DB_NAME, MYF(0), db);
+      my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
       break;
     }
     /*
@@ -3859,14 +3948,14 @@
     */
 #ifdef HAVE_REPLICATION
     if (thd->slave_thread &&
-	(!rpl_filter->db_ok(db) ||
-	 !rpl_filter->db_ok_with_wild_table(db)))
+	(!rpl_filter->db_ok(db->str) ||
+	 !rpl_filter->db_ok_with_wild_table(db->str)))
     {
       my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
       break;
     }
 #endif
-    if (check_access(thd, ALTER_ACL, db, 0, 1, 0, is_schema_db(db)))
+    if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0, is_schema_db(db->str)))
       break;
     if (thd->locked_tables || thd->active_transaction())
     {
@@ -3874,23 +3963,30 @@
                  ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
       goto error;
     }
-    res= mysql_alter_db(thd, db, &lex->create_info);
+    res= mysql_alter_db(thd, db->str, &lex->create_info);
     break;
   }
   case SQLCOM_SHOW_CREATE_DB:
   {
-    if (!strip_sp(lex->name) || check_db_name(lex->name))
+    if (check_db_name(&lex->name))
     {
-      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name);
+      my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
       break;
     }
-    res=mysqld_show_create_db(thd,lex->name,&lex->create_info);
+    res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
     break;
   }
   case SQLCOM_CREATE_EVENT:
   case SQLCOM_ALTER_EVENT:
+  do
   {
     DBUG_ASSERT(lex->event_parse_data);
+    if (lex->table_or_sp_used())
+    {
+      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
+               "function calls as part of this statement");
+      break;
+    }
     switch (lex->sql_command) {
     case SQLCOM_CREATE_EVENT:
       res= Events::get_instance()->
@@ -3908,16 +4004,15 @@
     if (!res)
       send_ok(thd);
 
-    /* Don't do it, if we are inside a SP */
-    if (!thd->spcont)
-    {
-      delete lex->sphead;
-      lex->sphead= NULL;
-    }
-
-    /* lex->unit.cleanup() is called outside, no need to call it here */
-    break;
+  } while (0);
+  /* Don't do it, if we are inside a SP */
+  if (!thd->spcont)
+  {
+    delete lex->sphead;
+    lex->sphead= NULL;
   }
+  /* lex->unit.cleanup() is called outside, no need to call it here */
+  break;
   case SQLCOM_DROP_EVENT:
   case SQLCOM_SHOW_CREATE_EVENT:
   {
@@ -3980,13 +4075,9 @@
       break;
     if (end_active_trans(thd))
       goto error;
+    /* Conditionally writes to binlog */
     if (!(res= mysql_create_user(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-        thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                          thd->query, thd->query_length, FALSE, FALSE);
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_DROP_USER:
@@ -3996,15 +4087,9 @@
       break;
     if (end_active_trans(thd))
       goto error;
+    /* Conditionally writes to binlog */
     if (!(res= mysql_drop_user(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-      {
-        thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                          thd->query, thd->query_length, FALSE, FALSE);
-      }
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_RENAME_USER:
@@ -4014,15 +4099,9 @@
       break;
     if (end_active_trans(thd))
       goto error;
+    /* Conditionally writes to binlog */
     if (!(res= mysql_rename_user(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-      {
-        thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                          thd->query, thd->query_length, FALSE, FALSE);
-      }
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_REVOKE_ALL:
@@ -4030,15 +4109,9 @@
     if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
         check_global_access(thd,CREATE_USER_ACL))
       break;
+    /* Conditionally writes to binlog */
     if (!(res = mysql_revoke_all(thd, lex->users_list)))
-    {
-      if (mysql_bin_log.is_open())
-      {
-        thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                          thd->query, thd->query_length, FALSE, FALSE);
-      }
       send_ok(thd);
-    }
     break;
   }
   case SQLCOM_REVOKE:
@@ -4097,6 +4170,7 @@
 	    check_grant_routine(thd, grants | GRANT_ACL, all_tables,
                                 lex->type == TYPE_ENUM_PROCEDURE, 0))
 	  goto error;
+        /* Conditionally writes to binlog */
         res= mysql_routine_grant(thd, all_tables,
                                  lex->type == TYPE_ENUM_PROCEDURE, 
                                  lex->users_list, grants,
@@ -4109,16 +4183,11 @@
 					 GRANT_ACL),
 					all_tables, 0, UINT_MAX, 0))
 	  goto error;
+        /* Conditionally writes to binlog */
         res= mysql_table_grant(thd, all_tables, lex->users_list,
 			       lex->columns, lex->grant,
 			       lex->sql_command == SQLCOM_REVOKE);
       }
-      if (!res && mysql_bin_log.is_open())
-      {
-        thd->clear_error();
-        thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                          thd->query, thd->query_length, FALSE, FALSE);
-      }
     }
     else
     {
@@ -4129,16 +4198,11 @@
         goto error;
       }
       else
+	/* Conditionally writes to binlog */
 	res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
 			  lex->sql_command == SQLCOM_REVOKE);
       if (!res)
       {
-	if (mysql_bin_log.is_open())
-	{
-          thd->clear_error();
-          thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                            thd->query, thd->query_length, FALSE, FALSE);
-	}
 	if (lex->sql_command == SQLCOM_GRANT)
 	{
 	  List_iterator <LEX_USER> str_list(lex->users_list);
@@ -4176,6 +4240,7 @@
         We WANT to write and we CAN write.
         ! we write after unlocking the table.
       */
+      /* Presumably, RESET and binlog writing doesn't require synchronization */
       if (!lex->no_write_to_binlog && write_to_binlog)
       {
         if (mysql_bin_log.is_open())
@@ -4192,6 +4257,13 @@
   {
     Item *it= (Item *)lex->value_list.head();
 
+    if (lex->table_or_sp_used())
+    {
+      my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
+               "function calls as part of this statement");
+      break;
+    }
+
     if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
     {
       my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
@@ -4634,7 +4706,10 @@
 	  send_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
                                 thd->row_count_func));
 	else
+        {
+          DBUG_ASSERT(thd->net.report_error == 1 || thd->killed);
 	  goto error;		// Substatement should already have sent error
+        }
       }
       break;
     }
@@ -4692,20 +4767,16 @@
             already puts on CREATE FUNCTION.
           */
           if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
+            /* Conditionally writes to binlog */
             result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics);
           else
+            /* Conditionally writes to binlog */
             result= sp_update_function(thd, lex->spname, &lex->sp_chistics);
         }
       }
       switch (result)
       {
       case SP_OK:
-        if (mysql_bin_log.is_open())
-        {
-          thd->clear_error();
-          thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                            thd->query, thd->query_length, FALSE, FALSE);
-        }
 	send_ok(thd);
 	break;
       case SP_KEY_NOT_FOUND:
@@ -4750,9 +4821,11 @@
 	}
 #endif
 	if (lex->sql_command == SQLCOM_DROP_PROCEDURE)
-	  result= sp_drop_procedure(thd, lex->spname);
+          /* Conditionally writes to binlog */
+	  result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */
 	else
-	  result= sp_drop_function(thd, lex->spname);
+          /* Conditionally writes to binlog */
+	  result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */
       }
       else
       {
@@ -4765,6 +4838,8 @@
           {
 	    if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
 	      goto error;
+
+	    /* Does NOT write to binlog */
 	    if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
 	    {
 	      send_ok(thd);
@@ -4785,12 +4860,6 @@
       switch (result)
       {
       case SP_OK:
-        if (mysql_bin_log.is_open())
-        {
-          thd->clear_error();
-          thd->binlog_query(THD::MYSQL_QUERY_TYPE,
-                            thd->query, thd->query_length, FALSE, FALSE);
-        }
 	send_ok(thd);
 	break;
       case SP_KEY_NOT_FOUND:
@@ -4889,36 +4958,7 @@
       if (end_active_trans(thd))
         goto error;
 
-      if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) &&
-          mysql_bin_log.is_open())
-      {
-        String buff;
-        const LEX_STRING command[3]=
-          {{ C_STRING_WITH_LEN("CREATE ") },
-           { C_STRING_WITH_LEN("ALTER ") },
-           { C_STRING_WITH_LEN("CREATE OR REPLACE ") }};
-        thd->clear_error();
-
-        buff.append(command[thd->lex->create_view_mode].str,
-                    command[thd->lex->create_view_mode].length);
-        view_store_options(thd, first_table, &buff);
-        buff.append(STRING_WITH_LEN("VIEW "));
-        /* Test if user supplied a db (ie: we did not use thd->db) */
-        if (first_table->db && first_table->db[0] &&
-            (thd->db == NULL || strcmp(first_table->db, thd->db)))
-        {
-          append_identifier(thd, &buff, first_table->db,
-                            first_table->db_length);
-          buff.append('.');
-        }
-        append_identifier(thd, &buff, first_table->table_name,
-                          first_table->table_name_length);
-        buff.append(STRING_WITH_LEN(" AS "));
-        buff.append(first_table->source.str, first_table->source.length);
-
-        thd->binlog_query(THD::STMT_QUERY_TYPE,
-                          buff.ptr(), buff.length(), FALSE, FALSE);
-      }
+      res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
       break;
     }
   case SQLCOM_DROP_VIEW:
@@ -4926,13 +4966,8 @@
       if (check_table_access(thd, DROP_ACL, all_tables, 0) ||
           end_active_trans(thd))
         goto error;
-      if (!(res= mysql_drop_view(thd, first_table, thd->lex->drop_mode)) &&
-          mysql_bin_log.is_open())
-      {
-        thd->clear_error();
-        thd->binlog_query(THD::STMT_QUERY_TYPE,
-                          thd->query, thd->query_length, FALSE, FALSE);
-      }
+      /* Conditionally writes to binlog. */
+      res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
       break;
     }
   case SQLCOM_CREATE_TRIGGER:
@@ -4940,6 +4975,7 @@
     if (end_active_trans(thd))
       goto error;
 
+    /* Conditionally writes to binlog. */
     res= mysql_create_or_drop_trigger(thd, all_tables, 1);
 
     /* We don't care about trigger body after this point */
@@ -4952,6 +4988,7 @@
     if (end_active_trans(thd))
       goto error;
 
+    /* Conditionally writes to binlog. */
     res= mysql_create_or_drop_trigger(thd, all_tables, 0);
     break;
   }
@@ -5212,7 +5249,6 @@
     break;
   }
 
-end:
   THD_SET_PROC_INFO(thd, "query end");
 
   /*
@@ -5883,9 +5919,14 @@
   DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
   thd->free_list= 0;
   thd->select_number= 1;
+  /*
+    Those two lines below are theoretically unneeded as
+    THD::cleanup_after_query() should take care of this already.
+  */
   thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
-  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 
-    thd->query_start_used= 0;
+  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
+
+  thd->query_start_used= 0;
   thd->is_fatal_error= thd->time_zone_used= 0;
   thd->server_status&= ~ (SERVER_MORE_RESULTS_EXISTS | 
                           SERVER_QUERY_NO_INDEX_USED |
@@ -6123,14 +6164,19 @@
       DBUG_ASSERT(thd->net.report_error);
       DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
 			 thd->is_fatal_error));
-      query_cache_abort(&thd->net);
-      lex->unit.cleanup();
+
+      /*
+        The first thing we do after parse error is freeing sp_head to
+        ensure that we have restored original memroot.
+      */
       if (lex->sphead)
       {
 	/* Clean up after failed stored procedure/function */
 	delete lex->sphead;
 	lex->sphead= NULL;
       }
+      query_cache_abort(&thd->net);
+      lex->unit.cleanup();
     }
     THD_SET_PROC_INFO(thd, "freeing items");
     thd->end_statement();
@@ -6327,6 +6373,7 @@
     table_options	A set of the following bits:
 			TL_OPTION_UPDATING	Table will be updated
 			TL_OPTION_FORCE_INDEX	Force usage of index
+			TL_OPTION_ALIAS	        an alias in multi table DELETE
     lock_type		How table should be locked
     use_index		List of indexed used in USE INDEX
     ignore_index	List of indexed used in IGNORE INDEX
@@ -6355,14 +6402,15 @@
   if (!table)
     DBUG_RETURN(0);				// End of memory
   alias_str= alias ? alias->str : table->table.str;
-  if (check_table_name(table->table.str, table->table.length))
+  if (!test(table_options & TL_OPTION_ALIAS) && 
+      check_table_name(table->table.str, table->table.length))
   {
     my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
     DBUG_RETURN(0);
   }
 
   if (table->is_derived_table() == FALSE && table->db.str &&
-      check_db_name(table->db.str))
+      check_db_name(&table->db))
   {
     my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
     DBUG_RETURN(0);
@@ -6391,7 +6439,7 @@
 
   ptr->alias= alias_str;
   if (lower_case_table_names && table->table.length)
-    my_casedn_str(files_charset_info, table->table.str);
+    table->table.length= my_casedn_str(files_charset_info, table->table.str);
   ptr->table_name=table->table.str;
   ptr->table_name_length=table->table.length;
   ptr->lock_type=   lock_type;
@@ -7646,7 +7694,7 @@
 #ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
     /* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
     /*
-      Only do the check for PS, becasue we on execute we have to check that
+      Only do the check for PS, because we on execute we have to check that
       against the opened tables to ensure we don't use a table that is part
       of the view (which can only be done after the table has been opened).
     */
@@ -7816,7 +7864,6 @@
 
   SYNOPSIS
     check_string_length()
-      cs          string charset
       str         string to be checked
       err_msg     error message to be displayed if the string is too long
       max_length  max length
@@ -7826,13 +7873,13 @@
     TRUE    the passed string is longer than max_length
 */
 
-bool check_string_length(CHARSET_INFO *cs, LEX_STRING *str,
-                         const char *err_msg, uint max_length)
+bool check_string_length(LEX_STRING *str, const char *err_msg,
+                         uint max_length)
 {
-  if (cs->cset->charpos(cs, str->str, str->str + str->length,
-                        max_length) >= str->length)
-    return FALSE; 
+  if (str->length <= max_length)
+    return FALSE;
 
   my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_length);
+
   return TRUE;
 }

--- 1.454/sql/sql_yacc.yy	2006-12-07 18:27:54 -05:00
+++ 1.455/sql/sql_yacc.yy	2006-12-07 18:27:54 -05:00
@@ -56,12 +56,17 @@
   }
 
 /* Helper for parsing "IS [NOT] truth_value" */
-inline Item *is_truth_value(Item *A, bool v1, bool v2)
+inline Item *is_truth_value(THD *thd, Item *A, bool v1, bool v2)
 {
-  return new Item_func_if(create_func_ifnull(A,
-	new Item_int((char *) (v2 ? "TRUE" : "FALSE"), v2, 1)),
-	new Item_int((char *) (v1 ? "TRUE" : "FALSE"), v1, 1),
-	new Item_int((char *) (v1 ? "FALSE" : "TRUE"),!v1, 1));
+  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
@@ -92,6 +97,17 @@
 }
 #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;
@@ -142,213 +158,209 @@
 
 %pure_parser					/* We have threads */
 
-%token  END_OF_INPUT
+/*
+   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
+%token  ABORT_SYM                     /* INTERNAL (used in lex) */
 %token  ACCESSIBLE_SYM
-%token  ACTION
-%token  ADD
-%token  ADDDATE_SYM
-%token  AFTER_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
-%token  ALTER
+%token  ALL                           /* SQL-2003-R */
+%token  ALTER                         /* SQL-2003-R */
 %token  ANALYZE_SYM
-%token  AND_AND_SYM
-%token  AND_SYM
-%token  ANY_SYM
-%token  AS
-%token  ASC
-%token  ASCII_SYM
-%token  ASENSITIVE_SYM
-%token  AT_SYM
-%token  ATAN
+%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  AUTO_INC
 %token  AUTOEXTEND_SIZE_SYM
+%token  AUTO_INC
 %token  AVG_ROW_LENGTH
-%token  AVG_SYM
+%token  AVG_SYM                       /* SQL-2003-N */
 %token  BACKUP_SYM
-%token  BEFORE_SYM
-%token  BEGIN_SYM
-%token  BENCHMARK_SYM
-%token  BIGINT
-%token  BINARY
+%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
-%token  BIT_OR
-%token  BIT_SYM
-%token  BIT_XOR
-%token  BLOB_SYM
-%token  BOOLEAN_SYM
+%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
+%token  BOTH                          /* SQL-2003-R */
 %token  BTREE_SYM
-%token  BY
+%token  BY                            /* SQL-2003-R */
 %token  BYTE_SYM
 %token  CACHE_SYM
-%token  CALL_SYM
-%token  CASCADE
-%token  CASCADED
-%token  CAST_SYM
-%token  CHAIN_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
+%token  CHAR_SYM                      /* SQL-2003-R */
 %token  CHECKSUM_SYM
-%token  CHECK_SYM
+%token  CHECK_SYM                     /* SQL-2003-R */
 %token  CIPHER_SYM
 %token  CLIENT_SYM
-%token  CLOSE_SYM
-%token  COALESCE
+%token  CLOSE_SYM                     /* SQL-2003-R */
+%token  COALESCE                      /* SQL-2003-N */
 %token  CODE_SYM
-%token  COLLATE_SYM
-%token  COLLATION_SYM
+%token  COLLATE_SYM                   /* SQL-2003-R */
+%token  COLLATION_SYM                 /* SQL-2003-N */
 %token  COLUMNS
-%token  COLUMN_SYM
+%token  COLUMN_SYM                    /* SQL-2003-R */
 %token  COMMENT_SYM
-%token  COMMITTED_SYM
-%token  COMMIT_SYM
+%token  COMMITTED_SYM                 /* SQL-2003-N */
+%token  COMMIT_SYM                    /* SQL-2003-R */
 %token  COMPACT_SYM
 %token  COMPLETION_SYM
 %token  COMPRESSED_SYM
-%token  CONCAT
-%token  CONCAT_WS
 %token  CONCURRENT
-%token  CONDITION_SYM
+%token  CONDITION_SYM                 /* SQL-2003-N */
 %token  CONNECTION_SYM
 %token  CONSISTENT_SYM
-%token  CONSTRAINT
-%token  CONTAINS_SYM
-%token  CONTINUE_SYM
+%token  CONSTRAINT                    /* SQL-2003-R */
+%token  CONTAINS_SYM                  /* SQL-2003-N */
+%token  CONTINUE_SYM                  /* SQL-2003-R */
 %token  CONTRIBUTORS_SYM
-%token  CONVERT_SYM
-%token  CONVERT_TZ_SYM
-%token  COUNT_SYM
-%token  CREATE
-%token  CROSS
-%token  CUBE_SYM
-%token  CURDATE
-%token  CURRENT_USER
-%token  CURSOR_SYM
-%token  CURTIME
+%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
+%token  DATA_SYM                      /* SQL-2003-N */
 %token  DATETIME
-%token  DATE_ADD_INTERVAL
-%token  DATE_SUB_INTERVAL
-%token  DATE_SYM
+%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
-%token  DEALLOCATE_SYM
+%token  DAY_SYM                       /* SQL-2003-R */
+%token  DEALLOCATE_SYM                /* SQL-2003-R */
 %token  DECIMAL_NUM
-%token  DECIMAL_SYM
-%token  DECLARE_SYM
-%token  DECODE_SYM
-%token  DEFAULT
+%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
-%token  DESC
-%token  DESCRIBE
-%token  DES_DECRYPT_SYM
-%token  DES_ENCRYPT_SYM
+%token  DELETE_SYM                    /* SQL-2003-R */
+%token  DESC                          /* SQL-2003-N */
+%token  DESCRIBE                      /* SQL-2003-R */
 %token  DES_KEY_FILE
-%token  DETERMINISTIC_SYM
+%token  DETERMINISTIC_SYM             /* SQL-2003-R */
 %token  DIRECTORY_SYM
 %token  DISABLE_SYM
 %token  DISCARD
 %token  DISK_SYM
-%token  DISTINCT
+%token  DISTINCT                      /* SQL-2003-R */
 %token  DIV_SYM
-%token  DOUBLE_SYM
+%token  DOUBLE_SYM                    /* SQL-2003-R */
 %token  DO_SYM
-%token  DROP
+%token  DROP                          /* SQL-2003-R */
 %token  DUAL_SYM
 %token  DUMPFILE
 %token  DUPLICATE_SYM
-%token  DYNAMIC_SYM
-%token  EACH_SYM
+%token  DYNAMIC_SYM                   /* SQL-2003-R */
+%token  EACH_SYM                      /* SQL-2003-R */
+%token  ELSE                          /* SQL-2003-R */
 %token  ELSEIF_SYM
-%token  ELT_FUNC
 %token  ENABLE_SYM
 %token  ENCLOSED
-%token  ENCODE_SYM
-%token  ENCRYPT
-%token  END
+%token  END                           /* SQL-2003-R */
 %token  ENDS_SYM
+%token  END_OF_INPUT                  /* INTERNAL */
 %token  ENGINES_SYM
 %token  ENGINE_SYM
 %token  ENUM
-%token  EQ
-%token  EQUAL_SYM
+%token  EQ                            /* OPERATOR */
+%token  EQUAL_SYM                     /* OPERATOR */
 %token  ERRORS
 %token  ESCAPED
-%token  ESCAPE_SYM
-%token  EVENT_SYM
+%token  ESCAPE_SYM                    /* SQL-2003-R */
 %token  EVENTS_SYM
-%token  EVERY_SYM
-%token  EXECUTE_SYM
-%token  EXISTS
+%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  EXPORT_SET
 %token  EXTENDED_SYM
 %token  EXTENT_SIZE_SYM
-%token  EXTRACT_SYM
-%token  FALSE_SYM
+%token  EXTRACT_SYM                   /* SQL-2003-N */
+%token  FALSE_SYM                     /* SQL-2003-R */
 %token  FAST_SYM
-%token  FETCH_SYM
-%token  FIELD_FUNC
+%token  FETCH_SYM                     /* SQL-2003-R */
 %token  FILE_SYM
-%token  FIRST_SYM
+%token  FIRST_SYM                     /* SQL-2003-N */
 %token  FIXED_SYM
 %token  FLOAT_NUM
-%token  FLOAT_SYM
+%token  FLOAT_SYM                     /* SQL-2003-R */
 %token  FLUSH_SYM
 %token  FORCE_SYM
-%token  FOREIGN
-%token  FORMAT_SYM
-%token  FOR_SYM
-%token  FOUND_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  FROM_UNIXTIME
-%token  FULL
+%token  FULL                          /* SQL-2003-R */
 %token  FULLTEXT_SYM
-%token  FUNCTION_SYM
-%token  FUNC_ARG0
-%token  FUNC_ARG1
-%token  FUNC_ARG2
-%token  FUNC_ARG3
+%token  FUNCTION_SYM                  /* SQL-2003-R */
 %token  GE
-%token  GEOMCOLLFROMTEXT
 %token  GEOMETRYCOLLECTION
 %token  GEOMETRY_SYM
-%token  GEOMFROMTEXT
-%token  GEOMFROMWKB
-%token  GET_FORMAT
-%token  GLOBAL_SYM
-%token  GRANT
+%token  GET_FORMAT                    /* MYSQL-FUNC */
+%token  GLOBAL_SYM                    /* SQL-2003-R */
+%token  GRANT                         /* SQL-2003-R */
 %token  GRANTS
-%token  GREATEST_SYM
-%token  GROUP
+%token  GROUP                         /* SQL-2003-R */
 %token  GROUP_CONCAT_SYM
 %token  GROUP_UNIQUE_USERS
-%token  GT_SYM
+%token  GT_SYM                        /* OPERATOR */
 %token  HANDLER_SYM
 %token  HASH_SYM
-%token  HAVING
+%token  HAVING                        /* SQL-2003-R */
 %token  HELP_SYM
 %token  HEX_NUM
 %token  HIGH_PRIORITY
@@ -357,7 +369,7 @@
 %token  HOUR_MICROSECOND_SYM
 %token  HOUR_MINUTE_SYM
 %token  HOUR_SECOND_SYM
-%token  HOUR_SYM
+%token  HOUR_SYM                      /* SQL-2003-R */
 %token  IDENT
 %token  IDENTIFIED_SYM
 %token  IDENT_QUOTED
@@ -368,70 +380,63 @@
 %token  INDEX_SYM
 %token  INFILE
 %token  INITIAL_SIZE_SYM
-%token  INNER_SYM
+%token  INNER_SYM                     /* SQL-2003-R */
 %token  INNOBASE_SYM
-%token  INOUT_SYM
-%token  INSENSITIVE_SYM
-%token  INSERT
+%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
-%token  INTO
-%token  INT_SYM
+%token  INTERVAL_SYM                  /* SQL-2003-R */
+%token  INTO                          /* SQL-2003-R */
+%token  INT_SYM                       /* SQL-2003-R */
 %token  INVOKER_SYM
-%token  IN_SYM
-%token  IS
-%token  ISOLATION
+%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
+%token  JOIN_SYM                      /* SQL-2003-R */
 %token  KEYS
-%token  KEY_SYM
 %token  KEY_BLOCK_SIZE
+%token  KEY_SYM                       /* SQL-2003-N */
 %token  KILL_SYM
-%token  LANGUAGE_SYM
-%token  LAST_INSERT_ID
-%token  LAST_SYM
-%token  LE
-%token  LEADING
-%token  LEAST_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
+%token  LEFT                          /* SQL-2003-R */
 %token  LESS_SYM
 %token  LEVEL_SYM
 %token  LEX_HOSTNAME
-%token  LIKE
+%token  LIKE                          /* SQL-2003-R */
 %token  LIMIT
 %token  LINEAR_SYM
-%token  LINEFROMTEXT
 %token  LINES
 %token  LINESTRING
 %token  LIST_SYM
 %token  LOAD
-%token  LOCAL_SYM
-%token  LOCATE
-%token  LOCATOR_SYM
+%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  LOG_SYM
 %token  LONGBLOB
 %token  LONGTEXT
 %token  LONG_NUM
 %token  LONG_SYM
 %token  LOOP_SYM
 %token  LOW_PRIORITY
-%token  LT
-%token  MAKE_SET_SYM
+%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_POS_WAIT
 %token  MASTER_SERVER_ID_SYM
 %token  MASTER_SSL_CAPATH_SYM
 %token  MASTER_SSL_CA_SYM
@@ -441,95 +446,90 @@
 %token  MASTER_SSL_SYM
 %token  MASTER_SYM
 %token  MASTER_USER_SYM
-%token  MATCH
+%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
+%token  MAX_SYM                       /* SQL-2003-N */
 %token  MAX_UPDATES_PER_HOUR
 %token  MAX_USER_CONNECTIONS_SYM
-%token  MAX_VALUE_SYM
+%token  MAX_VALUE_SYM                 /* SQL-2003-N */
 %token  MEDIUMBLOB
 %token  MEDIUMINT
 %token  MEDIUMTEXT
 %token  MEDIUM_SYM
 %token  MEMORY_SYM
-%token  MERGE_SYM
-%token  MICROSECOND_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
+%token  MINUTE_SYM                    /* SQL-2003-R */
 %token  MIN_ROWS
-%token  MIN_SYM
-%token  MLINEFROMTEXT
+%token  MIN_SYM                       /* SQL-2003-N */
 %token  MODE_SYM
-%token  MODIFIES_SYM
+%token  MODIFIES_SYM                  /* SQL-2003-R */
 %token  MODIFY_SYM
-%token  MOD_SYM
-%token  MONTH_SYM
-%token  MPOINTFROMTEXT
-%token  MPOLYFROMTEXT
+%token  MOD_SYM                       /* SQL-2003-N */
+%token  MONTH_SYM                     /* SQL-2003-R */
 %token  MULTILINESTRING
 %token  MULTIPOINT
 %token  MULTIPOLYGON
 %token  MUTEX_SYM
-%token  NAMES_SYM
-%token  NAME_SYM
-%token  NATIONAL_SYM
-%token  NATURAL
+%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
+%token  NCHAR_SYM                     /* SQL-2003-R */
 %token  NDBCLUSTER_SYM
-%token  NE
-%token  NEW_SYM
-%token  NEXT_SYM
+%token  NE                            /* OPERATOR */
+%token  NEG
+%token  NEW_SYM                       /* SQL-2003-R */
+%token  NEXT_SYM                      /* SQL-2003-N */
 %token  NODEGROUP_SYM
-%token  NONE_SYM
+%token  NONE_SYM                      /* SQL-2003-R */
 %token  NOT2_SYM
-%token  NOT_SYM
+%token  NOT_SYM                       /* SQL-2003-R */
 %token  NOW_SYM
-%token  NO_SYM
+%token  NO_SYM                        /* SQL-2003-R */
 %token  NO_WAIT_SYM
 %token  NO_WRITE_TO_BINLOG
-%token  NULL_SYM
+%token  NULL_SYM                      /* SQL-2003-R */
 %token  NUM
-%token  NUMERIC_SYM
+%token  NUMERIC_SYM                   /* SQL-2003-R */
 %token  NVARCHAR_SYM
 %token  OFFSET_SYM
-%token  OJ_SYM
 %token  OLD_PASSWORD
-%token  ON
+%token  ON                            /* SQL-2003-R */
 %token  ONE_SHOT_SYM
 %token  ONE_SYM
-%token  OPEN_SYM
+%token  OPEN_SYM                      /* SQL-2003-R */
 %token  OPTIMIZE
 %token  OPTIONS_SYM
 %token  OPTION
 %token  OPTIONALLY
 %token  OR2_SYM
-%token  ORDER_SYM
-%token  OR_OR_SYM
-%token  OR_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
 %token  OWNER_SYM
 %token  PACK_KEYS_SYM
+%token  PARAM_MARKER
 %token  PARSER_SYM
-%token  PARTIAL
-%token  PARTITION_SYM
+%token  PARTIAL                       /* SQL-2003-N */
 %token  PARTITIONING_SYM
 %token  PARTITIONS_SYM
+%token  PARTITION_SYM                 /* SQL-2003-R */
 %token  PASSWORD
-%token  PARAM_MARKER
 %token  PHASE_SYM
-%token  PLUGIN_SYM
 %token  PLUGINS_SYM
-%token  POINTFROMTEXT
+%token  PLUGIN_SYM
 %token  POINT_SYM
-%token  POLYFROMTEXT
 %token  POLYGON
 %token  PORT_SYM
 %token  POSITION_SYM
@@ -537,41 +537,40 @@
 %token  PREPARE_SYM
 %token  PRESERVE_SYM
 %token  PREV_SYM
-%token  PRIMARY_SYM
-%token  PRIVILEGES
-%token  PROCEDURE
+%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  RAND
-%token  RANGE_SYM
-%token  READS_SYM
+%token  RANGE_SYM                     /* SQL-2003-R */
+%token  READS_SYM                     /* SQL-2003-R */
 %token  READ_ONLY_SYM
-%token  READ_SYM
+%token  READ_SYM                      /* SQL-2003-N */
 %token  READ_WRITE_SYM
-%token  REAL
+%token  REAL                          /* SQL-2003-R */
 %token  REBUILD_SYM
 %token  RECOVER_SYM
-%token  REDO_BUFFER_SIZE_SYM
 %token  REDOFILE_SYM
+%token  REDO_BUFFER_SIZE_SYM
 %token  REDUNDANT_SYM
-%token  REFERENCES
+%token  REFERENCES                    /* SQL-2003-R */
 %token  REGEXP
 %token  RELAY_LOG_FILE_SYM
 %token  RELAY_LOG_POS_SYM
 %token  RELAY_THREAD
-%token  RELEASE_SYM
+%token  RELEASE_SYM                   /* SQL-2003-R */
 %token  RELOAD
 %token  REMOVE_SYM
 %token  RENAME
 %token  REORGANIZE_SYM
 %token  REPAIR
-%token  REPEATABLE_SYM
-%token  REPEAT_SYM
-%token  REPLACE
+%token  REPEATABLE_SYM                /* SQL-2003-N */
+%token  REPEAT_SYM                    /* MYSQL-FUNC */
+%token  REPLACE                       /* MYSQL-FUNC */
 %token  REPLICATION
 %token  REQUIRE_SYM
 %token  RESET_SYM
@@ -579,28 +578,26 @@
 %token  RESTORE_SYM
 %token  RESTRICT
 %token  RESUME_SYM
-%token  RETURNS_SYM
-%token  RETURN_SYM
-%token  REVOKE
-%token  RIGHT
-%token  ROLLBACK_SYM
-%token  ROLLUP_SYM
-%token  ROUND
-%token  ROUTINE_SYM
-%token  ROWS_SYM
-%token  ROW_COUNT_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
+%token  ROW_SYM                       /* SQL-2003-R */
 %token  RTREE_SYM
-%token  SAVEPOINT_SYM
+%token  SAVEPOINT_SYM                 /* SQL-2003-R */
 %token  SCHEDULE_SYM
 %token  SECOND_MICROSECOND_SYM
-%token  SECOND_SYM
-%token  SECURITY_SYM
-%token  SELECT_SYM
-%token  SENSITIVE_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
+%token  SERIALIZABLE_SYM              /* SQL-2003-N */
 %token  SERIAL_SYM
 %token  SESSION_SYM
 %token  SERVER_SYM
@@ -608,120 +605,120 @@
 %token  SET
 %token  SET_VAR
 %token  SHARE_SYM
-%token  SHIFT_LEFT
-%token  SHIFT_RIGHT
+%token  SHIFT_LEFT                    /* OPERATOR */
+%token  SHIFT_RIGHT                   /* OPERATOR */
 %token  SHOW
 %token  SHUTDOWN
 %token  SIGNED_SYM
-%token  SIMPLE_SYM
+%token  SIMPLE_SYM                    /* SQL-2003-N */
 %token  SLAVE
-%token  SMALLINT
+%token  SMALLINT                      /* SQL-2003-R */
 %token  SNAPSHOT_SYM
 %token  SOCKET_SYM
 %token  SONAME_SYM
 %token  SOUNDS_SYM
 %token  SPATIAL_SYM
-%token  SPECIFIC_SYM
-%token  SQLEXCEPTION_SYM
-%token  SQLSTATE_SYM
-%token  SQLWARNING_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
+%token  SQL_SYM                       /* SQL-2003-R */
 %token  SQL_THREAD
 %token  SSL_SYM
 %token  STARTING
-%token  START_SYM
 %token  STARTS_SYM
+%token  START_SYM                     /* SQL-2003-R */
 %token  STATUS_SYM
+%token  STDDEV_SAMP_SYM               /* SQL-2003-N */
 %token  STD_SYM
-%token  STDDEV_SAMP_SYM
 %token  STOP_SYM
 %token  STORAGE_SYM
 %token  STRAIGHT_JOIN
 %token  STRING_SYM
 %token  SUBDATE_SYM
 %token  SUBJECT_SYM
-%token  SUBPARTITION_SYM
 %token  SUBPARTITIONS_SYM
-%token  SUBSTRING
-%token  SUBSTRING_INDEX
-%token  SUM_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_SYM
-%token  TEMPORARY
+%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  TIMESTAMP
+%token  THAN_SYM
+%token  THEN_SYM                      /* SQL-2003-R */
+%token  TIMESTAMP                     /* SQL-2003-R */
 %token  TIMESTAMP_ADD
 %token  TIMESTAMP_DIFF
-%token  TIME_SYM
+%token  TIME_SYM                      /* SQL-2003-R */
 %token  TINYBLOB
 %token  TINYINT
 %token  TINYTEXT
-%token  THAN_SYM
-%token  TO_SYM
-%token  TRAILING
+%token  TO_SYM                        /* SQL-2003-R */
+%token  TRAILING                      /* SQL-2003-R */
 %token  TRANSACTION_SYM
-%token  TRIGGER_SYM
 %token  TRIGGERS_SYM
-%token  TRIM
-%token  TRUE_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
+%token  TYPE_SYM                      /* SQL-2003-N */
 %token  UDF_RETURNS_SYM
 %token  ULONGLONG_NUM
-%token  UNCOMMITTED_SYM
+%token  UNCOMMITTED_SYM               /* SQL-2003-N */
 %token  UNDEFINED_SYM
-%token  UNDO_BUFFER_SIZE_SYM
-%token  UNDOFILE_SYM
 %token  UNDERSCORE_CHARSET
-%token  UNDO_SYM
+%token  UNDOFILE_SYM
+%token  UNDO_BUFFER_SIZE_SYM
+%token  UNDO_SYM                      /* FUTURE-USE */
 %token  UNICODE_SYM
 %token  UNINSTALL_SYM
-%token  UNION_SYM
+%token  UNION_SYM                     /* SQL-2003-R */
 %token  UNIQUE_SYM
 %token  UNIQUE_USERS
-%token  UNIX_TIMESTAMP
-%token  UNKNOWN_SYM
+%token  UNKNOWN_SYM                   /* SQL-2003-R */
 %token  UNLOCK_SYM
 %token  UNSIGNED
 %token  UNTIL_SYM
-%token  UPDATE_SYM
+%token  UPDATE_SYM                    /* SQL-2003-R */
 %token  UPGRADE_SYM
-%token  USAGE
-%token  USER
+%token  USAGE                         /* SQL-2003-N */
+%token  USER                          /* SQL-2003-R */
 %token  USE_FRM
 %token  USE_SYM
-%token  USING
+%token  USING                         /* SQL-2003-R */
 %token  UTC_DATE_SYM
 %token  UTC_TIMESTAMP_SYM
 %token  UTC_TIME_SYM
-%token  VAR_SAMP_SYM
-%token  VALUES
-%token  VALUE_SYM
+%token  VALUES                        /* SQL-2003-R */
+%token  VALUE_SYM                     /* SQL-2003-R */
 %token  VARBINARY
-%token  VARCHAR
+%token  VARCHAR                       /* SQL-2003-R */
 %token  VARIABLES
 %token  VARIANCE_SYM
-%token  VARYING
-%token  VIEW_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
-%token  WHERE
+%token  WHEN_SYM                      /* SQL-2003-R */
+%token  WHERE                         /* SQL-2003-R */
 %token  WHILE_SYM
 %token  WITH
 %token  WORK_SYM
@@ -730,12 +727,10 @@
 %token  X509_SYM
 %token  XA_SYM
 %token  XOR
-%token  YEARWEEK
 %token  YEAR_MONTH_SYM
-%token  YEAR_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
@@ -759,7 +754,7 @@
 	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
+        sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty
 
 %type <lex_str_ptr>
 	opt_table_alias
@@ -769,7 +764,7 @@
 
 %type <simple_string>
 	remember_name remember_end opt_ident opt_db text_or_password
-	opt_constraint constraint ident_or_empty
+	opt_constraint constraint
 
 %type <string>
 	text_string opt_gconcat_separator
@@ -801,24 +796,27 @@
 %type <item>
 	literal text_literal insert_ident order_ident
 	simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr
-	bool_term bool_factor bool_test bool_pri 
+	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 singlerow_subselect singlerow_subselect_init
-	exists_subselect exists_subselect_init geometry_function
+	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 <item_num>
 	NUM_literal
 
 %type <item_list>
 	expr_list udf_expr_list udf_expr_list2 when_list
-	ident_list ident_list_arg
+	ident_list ident_list_arg opt_expr_list
 
 %type <var_type>
         option_type opt_var_type opt_var_ident_type
@@ -857,7 +855,7 @@
 
 %type <udf_type> udf_func_type
 
-%type <symbol> FUNC_ARG0 FUNC_ARG1 FUNC_ARG2 FUNC_ARG3 keyword keyword_sp
+%type <symbol> keyword keyword_sp
 
 %type <lex_user> user grant_user
 
@@ -872,7 +870,7 @@
 
 %type <variable> internal_variable_name
 
-%type <select_lex> in_subselect in_subselect_init
+%type <select_lex> subselect subselect_init
 	get_select_lex
 
 %type <boolfunc2creator> comp_op
@@ -1250,7 +1248,8 @@
 	  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= 0;
+	  lex->name.str= 0;
+          lex->name.length= 0;
          lex->like_name= 0;
 	}
 	create2
@@ -1290,7 +1289,7 @@
 	  {
 	    LEX *lex=Lex;
 	    lex->sql_command=SQLCOM_CREATE_DB;
-	    lex->name=$4.str;
+	    lex->name= $4;
             lex->create_info.options=$3;
 	  }
 	| CREATE
@@ -1414,7 +1413,6 @@
               can overwrite it
             */
             Lex->sql_command= SQLCOM_CREATE_EVENT;
-            Lex->expr_allows_subselect= TRUE;
           }
       ;
 
@@ -1429,7 +1427,7 @@
           {
             Lex->event_parse_data->item_execute_at= $2;
           }
-      ;
+        ;
 
 opt_ev_status: /* empty */ { $$= 0; }
         | ENABLE_SYM
@@ -1484,6 +1482,7 @@
         | COMMENT_SYM TEXT_STRING_sys
           {
             Lex->comment= Lex->event_parse_data->comment= $2;
+            $$= 1;
           }
       ;
 
@@ -1578,7 +1577,7 @@
 sp_name:
 	  ident '.' ident
 	  {
-            if (!$1.str || check_db_name($1.str))
+            if (!$1.str || check_db_name(&$1))
             {
 	      my_error(ER_WRONG_DB_NAME, MYF(0), $1.str);
 	      YYABORT;
@@ -1611,6 +1610,7 @@
 create_function_tail:
 	  RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys
 	  {
+            THD *thd= YYTHD;
 	    LEX *lex=Lex;
             if (lex->definer != NULL)
             {
@@ -1623,6 +1623,12 @@
 	      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;
@@ -1711,6 +1717,7 @@
 	  }
 	  sp_proc_stmt
 	  {
+            THD *thd= YYTHD;
 	    LEX *lex= Lex;
 	    sp_head *sp= lex->sphead;
 
@@ -1718,15 +1725,50 @@
               YYABORT;
 
 	    lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
-	    sp->init_strings(YYTHD, lex);
+	    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 */
-	    YYTHD->client_capabilities |= $<ulong_num>2;
-	    sp->restore_thd_mem_root(YYTHD);
+	    thd->client_capabilities |= $<ulong_num>2;
+	    sp->restore_thd_mem_root(thd);
 	  }
 	;
 
@@ -1786,15 +1828,20 @@
 	    lex->value_list.empty();
 	    sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE);
 	  }
-          '(' sp_cparam_list ')' {}
+          opt_sp_cparam_list {}
 	;
 
 /* CALL parameters */
-sp_cparam_list:
+opt_sp_cparam_list:
 	  /* Empty */
-	| sp_cparams
+	| '(' opt_sp_cparams ')'
 	;
 
+opt_sp_cparams:
+          /* Empty */
+        | sp_cparams
+        ;
+
 sp_cparams:
 	  sp_cparams ',' expr
 	  {
@@ -1963,7 +2010,6 @@
             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)
             {
@@ -3159,11 +3205,11 @@
           real_ulong_num { $$= $1;}
           | IDENT
           {
-            ulonglong number, test_number;
+            ulonglong number;
             uint text_shift_number= 0;
             longlong prefix_number;
             char *start_ptr= $1.str;
-            uint str_len= strlen(start_ptr);
+            uint str_len= $1.length;
             char *end_ptr= start_ptr + str_len;
             int error;
             prefix_number= my_strtoll10(start_ptr, &end_ptr, &error);
@@ -3287,6 +3333,7 @@
 partitioning:
         PARTITION_SYM
         {
+#ifdef WITH_PARTITION_STORAGE_ENGINE
           LEX *lex= Lex;
           lex->part_info= new partition_info();
           if (!lex->part_info)
@@ -3298,6 +3345,12 @@
           {
             lex->alter_info.flags|= ALTER_PARTITION;
           }
+#else
+          my_error(ER_FEATURE_DISABLED, MYF(0),
+       	           "partitioning", "--with-partition");
+          YYABORT;
+#endif
+
         }
         partition
         ;
@@ -3661,10 +3714,9 @@
         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;
@@ -3679,13 +3731,18 @@
             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))
           {
-            yyerror(ER(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR));
+            my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
             YYABORT;
           }
           thd->where= save_where;
@@ -3800,11 +3857,11 @@
           lex->part_info->default_engine_type= $4;
         }
         | NODEGROUP_SYM opt_equal real_ulong_num
-        { Lex->part_info->curr_part_elem->nodegroup_id= $3; }
+        { Lex->part_info->curr_part_elem->nodegroup_id= (uint16) $3; }
         | MAX_ROWS opt_equal real_ulonglong_num
-        { Lex->part_info->curr_part_elem->part_max_rows= $3; }
+        { Lex->part_info->curr_part_elem->part_max_rows= (ha_rows) $3; }
         | MIN_ROWS opt_equal real_ulonglong_num
-        { Lex->part_info->curr_part_elem->part_min_rows= $3; }
+        { Lex->part_info->curr_part_elem->part_min_rows= (ha_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
@@ -4674,7 +4731,8 @@
 	{
 	  THD *thd= YYTHD;
 	  LEX *lex= thd->lex;
-         lex->name= 0;
+          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,
@@ -4684,7 +4742,6 @@
 	  lex->key_list.empty();
 	  lex->col_list.empty();
           lex->select_lex.init_order();
-	  lex->name= 0;
 	  lex->like_name= 0;
 	  lex->select_lex.db=
             ((TABLE_LIST*) lex->select_lex.table_list.first)->db;
@@ -4709,7 +4766,8 @@
             THD *thd= Lex->thd;
 	    lex->sql_command=SQLCOM_ALTER_DB;
 	    lex->name= $3;
-            if (lex->name == NULL && thd->copy_db_to(&lex->name, NULL))
+            if (lex->name.str == NULL &&
+                thd->copy_db_to(&lex->name.str, &lex->name.length))
               YYABORT;
 	  }
 	| ALTER PROCEDURE sp_name
@@ -4787,8 +4845,6 @@
             YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES;
 
             Lex->sql_command= SQLCOM_ALTER_EVENT;
-            /* we need that for disallowing subqueries */
-            Lex->expr_allows_subselect= FALSE;
           }
           ev_alter_on_schedule_completion
           opt_ev_rename_to
@@ -4814,7 +4870,6 @@
               can overwrite it
             */
             Lex->sql_command= SQLCOM_ALTER_EVENT;
-            Lex->expr_allows_subselect= TRUE;
           }
         | ALTER TABLESPACE alter_tablespace_info
           {
@@ -4869,8 +4924,8 @@
 
 
 ident_or_empty:
-	/* empty */  { $$= 0; }
-	| ident      { $$= $1.str; };
+	/* empty */  { $$.str= 0; $$.length= 0; }
+	| ident      { $$= $1; };
 
 alter_commands:
 	| DISCARD TABLESPACE { Lex->alter_info.tablespace_op= DISCARD_TABLESPACE; }
@@ -5148,19 +5203,20 @@
 	  {
 	    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, 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.str))
+                $3->db.str && check_db_name(&$3->db))
             {
               my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
               YYABORT;
             }
-	    lex->name= $3->table.str;
+	    lex->name= $3->table;
 	    lex->alter_info.flags|= ALTER_RENAME;
 	  }
 	| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
@@ -5632,12 +5688,14 @@
 	      yyerror(ER(ER_SYNTAX_ERROR));
 	      YYABORT;
 	    }
-	  if (sel->linkage == UNION_TYPE &&
-	      !sel->master_unit()->first_select()->braces)
-	  {
-	    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=
@@ -5881,10 +5939,10 @@
 	| bool_test ;
 
 bool_test:
-	bool_pri IS TRUE_SYM	{ $$= is_truth_value($1,1,0); }
-	| bool_pri IS not TRUE_SYM { $$= is_truth_value($1,0,0); }
-	| bool_pri IS FALSE_SYM	{ $$= is_truth_value($1,0,1); }
-	| bool_pri IS not FALSE_SYM { $$= is_truth_value($1,1,1); }
+	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 ;
@@ -5895,37 +5953,37 @@
 	| 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 in_subselect %prec EQ
-	  { $$= all_any_subquery_creator($1, $2, $3, $4); }
+	| bool_pri comp_op all_or_any '(' subselect ')' %prec EQ
+	  { $$= all_any_subquery_creator($1, $2, $3, $5); }
 	| predicate ;
 
 predicate:
-	 bit_expr IN_SYM '(' expr_list ')'
+        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 ')'
 	  { 
-            if ($4->elements == 1)
-              $$= new Item_func_eq($1, $4->head());
-            else
-            {
-              $4->push_front($1);
-              $$= new Item_func_in(*$4);
-            }
+              $6->push_front($4);
+              $6->push_front($1);
+              $$= new Item_func_in(*$6);
           }
-	| bit_expr not IN_SYM '(' expr_list ')'
+        | bit_expr not IN_SYM '(' expr ')'
           {
-            if ($5->elements == 1)
-              $$= new Item_func_ne($1, $5->head());
-            else
-            {
-              $5->push_front($1);
-              Item_func_in *item = new Item_func_in(*$5);
+              $$= 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 IN_SYM in_subselect
-	  { $$= new Item_in_subselect($1, $3); }
-	| bit_expr not IN_SYM in_subselect
-          { $$= negate_expression(YYTHD, new Item_in_subselect($1, $4)); }
 	| 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
@@ -6005,75 +6063,67 @@
 
 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
 	  {
-	    $$= new Item_func_set_collation($1,
-					    new Item_string($3.str,
-							    $3.length,
-                                                            YYTHD->charset()));
+            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
-	| '@' ident_or_text SET_VAR expr
-	  {
-	    $$= new Item_func_set_user_var($2,$4);
-	    LEX *lex= Lex;
-	    lex->uncacheable(UNCACHEABLE_RAND);
-	    lex->variables_used= 1;
-	  }
-	| '@' ident_or_text
-	  {
-	    $$= new Item_func_get_user_var($2);
-	    LEX *lex= Lex;
-	    lex->uncacheable(UNCACHEABLE_RAND);
-	    lex->variables_used= 1;
-	  }
-	| '@' '@' opt_var_ident_type ident_or_text opt_component
-	  {
-
-            if ($4.str && $5.str && check_reserved_words(&$4))
-            {
-              yyerror(ER(ER_SYNTAX_ERROR));
-              YYABORT;
-            }
-	    if (!($$= get_system_var(YYTHD, $3, $4, $5)))
-	      YYABORT;
-	    Lex->variables_used= 1;
-	  }
+	| variable
 	| sum_expr
 	| simple_expr OR_OR_SYM simple_expr
-	  { $$= new Item_func_concat($1, $3); }
+	  { $$= new (YYTHD->mem_root) Item_func_concat($1, $3); }
 	| '+' simple_expr %prec NEG	{ $$= $2; }
-	| '-' simple_expr %prec NEG	{ $$= new Item_func_neg($2); }
-	| '~' simple_expr %prec NEG	{ $$= new Item_func_bit_neg($2); }
-	| not2 simple_expr %prec NEG	{ $$= negate_expression(YYTHD, $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 Item_row(*$4);
+	    $$= new (YYTHD->mem_root) Item_row(*$4);
 	  }
 	| ROW_SYM '(' expr ',' expr_list ')'
 	  {
 	    $5->push_front($3);
-	    $$= new Item_row(*$5);
+	    $$= new (YYTHD->mem_root) Item_row(*$5);
 	  }
-	| EXISTS exists_subselect { $$= $2; }
-	| singlerow_subselect   { $$= $1; }
+	| 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);
-            Select->add_ftfunc_to_list((Item_func_match*)
-                                        ($$=new Item_func_match(*$2,$6))); }
-	| ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); }
+          {
+            $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($2, ITEM_CAST_CHAR, -1, 0, &my_charset_bin);
+            $$= 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($3, $5,
+	    $$= create_func_cast(YYTHD, $3, $5,
                                  lex->length ? atoi(lex->length) : -1,
                                  lex->dec ? atoi(lex->dec) : 0,
                                  lex->charset);
@@ -6081,10 +6131,10 @@
               YYABORT;
 	  }
 	| CASE_SYM opt_expr WHEN_SYM when_list opt_else END
-	  { $$= new Item_func_case(* $4, $2, $5 ); }
+	  { $$= new (YYTHD->mem_root) Item_func_case(* $4, $2, $5 ); }
 	| CONVERT_SYM '(' expr ',' cast_type ')'
 	  {
-	    $$= create_func_cast($3, $5,
+	    $$= create_func_cast(YYTHD, $3, $5,
 				 Lex->length ? atoi(Lex->length) : -1,
                                  Lex->dec ? atoi(Lex->dec) : 0,
 				 Lex->charset);
@@ -6092,7 +6142,7 @@
               YYABORT;
 	  }
 	| CONVERT_SYM '(' expr USING charset_name ')'
-	  { $$= new Item_func_conv_charset($3,$5); }
+	  { $$= new (YYTHD->mem_root) Item_func_conv_charset($3,$5); }
 	| DEFAULT '(' simple_ident ')'
 	  {
 	    if ($3->is_splocal())
@@ -6102,545 +6152,433 @@
 	      my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
 	      YYABORT;
 	    }
-	    $$= new Item_default_value(Lex->current_context(), $3);
+	    $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context(),
+                                                         $3);
 	  }
 	| VALUES '(' simple_ident_nospvar ')'
-	  { $$= new Item_insert_value(Lex->current_context(), $3); }
-	| FUNC_ARG0 '(' ')'
-	  {
-	    if (!$1.symbol->create_func)
-	    {
-              my_error(ER_FEATURE_DISABLED, MYF(0),
-                       $1.symbol->group->name,
-                       $1.symbol->group->needed_define);
-	      YYABORT;
-	    }
-	    $$= ((Item*(*)(void))($1.symbol->create_func))();
-	  }
-	| FUNC_ARG1 '(' expr ')'
-	  {
-	    if (!$1.symbol->create_func)
-	    {
-              my_error(ER_FEATURE_DISABLED, MYF(0),
-                       $1.symbol->group->name,
-                       $1.symbol->group->needed_define);
-	      YYABORT;
-	    }
-	    $$= ((Item*(*)(Item*))($1.symbol->create_func))($3);
-	  }
-	| FUNC_ARG2 '(' expr ',' expr ')'
-	  {
-	    if (!$1.symbol->create_func)
-	    {
-	      my_error(ER_FEATURE_DISABLED, MYF(0),
-                       $1.symbol->group->name,
-                       $1.symbol->group->needed_define);
-	      YYABORT;
-	    }
-	    $$= ((Item*(*)(Item*,Item*))($1.symbol->create_func))($3,$5);
-	  }
-	| FUNC_ARG3 '(' expr ',' expr ',' expr ')'
-	  {
-	    if (!$1.symbol->create_func)
-	    {
-              my_error(ER_FEATURE_DISABLED, MYF(0),
-                       $1.symbol->group->name,
-                       $1.symbol->group->needed_define);
-	      YYABORT;
-	    }
-	    $$= ((Item*(*)(Item*,Item*,Item*))($1.symbol->create_func))($3,$5,$7);
-	  }
-	| ADDDATE_SYM '(' expr ',' expr ')'
-	  { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 0);}
-	| ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
-	  { $$= new Item_date_add_interval($3, $6, $7, 0); }
-	| REPEAT_SYM '(' expr ',' expr ')'
-	  { $$= new Item_func_repeat($3,$5); }
-	| ATAN	'(' expr ')'
-	  { $$= new Item_func_atan($3); }
-	| ATAN	'(' expr ',' expr ')'
-	  { $$= new Item_func_atan($3,$5); }
-	| CHAR_SYM '(' expr_list ')'
-	  { $$= new Item_func_char(*$3); }
-	| CHAR_SYM '(' expr_list USING charset_name ')'
-	  { $$= new Item_func_char(*$3, $5); }
-	| CHARSET '(' expr ')'
-	  { $$= new Item_func_charset($3); }
-	| COALESCE '(' expr_list ')'
-	  { $$= new Item_func_coalesce(* $3); }
-	| COLLATION_SYM '(' expr ')'
-	  { $$= new Item_func_collation($3); }
-	| CONCAT '(' expr_list ')'
-	  { $$= new Item_func_concat(* $3); }
-	| CONCAT_WS '(' expr ',' expr_list ')'
-	  { $5->push_front($3); $$= new Item_func_concat_ws(*$5); }
-	| CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')'
+	  { $$= 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 (Lex->add_time_zone_tables_to_query_tables(YYTHD))
+            if ($1->type() != Item::ROW_ITEM)
+            {
+              yyerror(ER(ER_SYNTAX_ERROR));
               YYABORT;
-	    $$= new Item_func_convert_tz($3, $5, $7);
-	  }
-	| CURDATE optional_braces
-	  { $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; }
-	| CURTIME optional_braces
-	  { $$= new Item_func_curtime_local(); Lex->safe_to_cache_query=0; }
-	| CURTIME '(' expr ')'
+            }
+            $$= new (YYTHD->mem_root) Item_func_interval((Item_row *)$1);
+          }
+	| UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
 	  {
-	    $$= new Item_func_curtime_local($3);
-	    Lex->safe_to_cache_query=0;
+            $$= 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 Item_func_current_user(Lex->current_context());
+            $$= new (YYTHD->mem_root) Item_func_current_user(Lex->current_context());
             Lex->safe_to_cache_query= 0;
           }
-	| DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')'
-	  { $$= new Item_date_add_interval($3,$5,$6,0); }
-	| DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')'
-	  { $$= new Item_date_add_interval($3,$5,$6,1); }
-	| DATABASE '(' ')'
-	  {
-	    $$= new Item_func_database();
-            Lex->safe_to_cache_query=0;
-	  }
 	| DATE_SYM '(' expr ')'
-	  { $$= new Item_date_typecast($3); }
+	  { $$= new (YYTHD->mem_root) Item_date_typecast($3); }
 	| DAY_SYM '(' expr ')'
-	  { $$= new Item_func_dayofmonth($3); }
-	| ELT_FUNC '(' expr ',' expr_list ')'
-	  { $5->push_front($3); $$= new Item_func_elt(*$5); }
-	| MAKE_SET_SYM '(' expr ',' expr_list ')'
-	  { $$= new Item_func_make_set($3, *$5); }
-	| ENCRYPT '(' expr ')'
-	  {
-	    $$= new Item_func_encrypt($3);
-	    Lex->uncacheable(UNCACHEABLE_RAND);
-	  }
-	| ENCRYPT '(' expr ',' expr ')'   { $$= new Item_func_encrypt($3,$5); }
-	| DECODE_SYM '(' expr ',' TEXT_STRING_literal ')'
-	  { $$= new Item_func_decode($3,$5.str); }
-	| ENCODE_SYM '(' expr ',' TEXT_STRING_literal ')'
-	 { $$= new Item_func_encode($3,$5.str); }
-	| DES_DECRYPT_SYM '(' expr ')'
-        { $$= new Item_func_des_decrypt($3); }
-	| DES_DECRYPT_SYM '(' expr ',' expr ')'
-        { $$= new Item_func_des_decrypt($3,$5); }
-	| DES_ENCRYPT_SYM '(' expr ')'
-        { $$= new Item_func_des_encrypt($3); }
-	| DES_ENCRYPT_SYM '(' expr ',' expr ')'
-        { $$= new Item_func_des_encrypt($3,$5); }
-	| EXPORT_SET '(' expr ',' expr ',' expr ')'
-		{ $$= new Item_func_export_set($3, $5, $7); }
-	| EXPORT_SET '(' expr ',' expr ',' expr ',' expr ')'
-		{ $$= new Item_func_export_set($3, $5, $7, $9); }
-	| EXPORT_SET '(' expr ',' expr ',' expr ',' expr ',' expr ')'
-		{ $$= new Item_func_export_set($3, $5, $7, $9, $11); }
-	| FORMAT_SYM '(' expr ',' NUM ')'
-	  { $$= new Item_func_format($3,atoi($5.str)); }
-	| FROM_UNIXTIME '(' expr ')'
-	  { $$= new Item_func_from_unixtime($3); }
-	| FROM_UNIXTIME '(' expr ',' expr ')'
-	  {
-	    $$= new Item_func_date_format (new Item_func_from_unixtime($3),$5,0);
-	  }
-	| FIELD_FUNC '(' expr ',' expr_list ')'
-	  { $5->push_front($3); $$= new Item_func_field(*$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
-	  }
-	| GET_FORMAT '(' date_time_type  ',' expr ')'
-	  { $$= new Item_func_get_format($3, $5); }
+	  { $$= new (YYTHD->mem_root) Item_func_dayofmonth($3); }
 	| HOUR_SYM '(' expr ')'
-	  { $$= new Item_func_hour($3); }
-	| IF '(' expr ',' expr ',' expr ')'
-	  { $$= new Item_func_if($3,$5,$7); }
+	  { $$= new (YYTHD->mem_root) Item_func_hour($3); }
 	| INSERT '(' expr ',' expr ',' expr ',' expr ')'
-	  { $$= new Item_func_insert($3,$5,$7,$9); }
-	| interval_expr interval '+' expr
-	  /* we cannot put interval before - */
-	  { $$= new Item_date_add_interval($4,$1,$2,0); }
-	| interval_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 '(' ')'
 	  {
-            if ($1->type() != Item::ROW_ITEM)
-            {
-              yyerror(ER(ER_SYNTAX_ERROR));
-              YYABORT;
-            }
-            $$= new Item_func_interval((Item_row *)$1);
+            $$= new (YYTHD->mem_root) Item_func_user();
+            Lex->safe_to_cache_query=0;
           }
-	| LAST_INSERT_ID '(' ')'
+	| 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 Item_func_last_insert_id();
-	    Lex->safe_to_cache_query= 0;
-	  }
-	| LAST_INSERT_ID '(' 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 Item_func_last_insert_id($3);
-	    Lex->safe_to_cache_query= 0;
-	  }
-	| LEFT '(' expr ',' expr ')'
-	  { $$= new Item_func_left($3,$5); }
-	| LOCATE '(' expr ',' expr ')'
-	  { $$= new Item_func_locate($5,$3); }
-	| LOCATE '(' expr ',' expr ',' expr ')'
-	  { $$= new Item_func_locate($5,$3,$7); }
-	| GREATEST_SYM '(' expr ',' expr_list ')'
-	  { $5->push_front($3); $$= new Item_func_max(*$5); }
-	| LEAST_SYM '(' expr ',' expr_list ')'
-	  { $5->push_front($3); $$= new Item_func_min(*$5); }
-	| LOG_SYM '(' expr ')'
-	  { $$= new Item_func_log($3); }
-	| LOG_SYM '(' expr ',' expr ')'
-	  { $$= new Item_func_log($3, $5); }
-	| MASTER_POS_WAIT '(' expr ',' expr ')'
+            $$= new (YYTHD->mem_root) Item_func_curdate_local();
+            Lex->safe_to_cache_query=0;
+          }
+	| CURTIME optional_braces
 	  {
-	    $$= new Item_master_pos_wait($3, $5);
-	    Lex->safe_to_cache_query=0;
-		  }
-	| MASTER_POS_WAIT '(' expr ',' expr ',' expr ')'
+            $$= new (YYTHD->mem_root) Item_func_curtime_local();
+            Lex->safe_to_cache_query=0;
+          }
+	| CURTIME '(' expr ')'
 	  {
-	    $$= new Item_master_pos_wait($3, $5, $7);
+	    $$= new (YYTHD->mem_root) Item_func_curtime_local($3);
 	    Lex->safe_to_cache_query=0;
 	  }
-	| MICROSECOND_SYM '(' expr ')'
-	  { $$= new Item_func_microsecond($3); }
-	| MINUTE_SYM '(' expr ')'
-	  { $$= new Item_func_minute($3); }
-	| MOD_SYM '(' expr ',' expr ')'
-	  { $$ = new Item_func_mod( $3, $5); }
-	| MONTH_SYM '(' expr ')'
-	  { $$= new Item_func_month($3); }
+	| 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 Item_func_now_local(); Lex->safe_to_cache_query=0;}
+	  {
+            $$= new (YYTHD->mem_root) Item_func_now_local();
+            Lex->safe_to_cache_query=0;
+          }
 	| NOW_SYM '(' expr ')'
-	  { $$= new Item_func_now_local($3); Lex->safe_to_cache_query=0;}
-	| PASSWORD '(' expr ')'
 	  {
-	    $$= YYTHD->variables.old_passwords ?
-              (Item *) new Item_func_old_password($3) :
-	      (Item *) new Item_func_password($3);
-	  }
-	| OLD_PASSWORD '(' expr ')'
-	  { $$=  new Item_func_old_password($3); }
+            $$= new (YYTHD->mem_root) Item_func_now_local($3);
+            Lex->safe_to_cache_query=0;
+          }
 	| POSITION_SYM '(' bit_expr IN_SYM expr ')'
-	  { $$ = new Item_func_locate($5,$3); }
-	| QUARTER_SYM '(' expr ')'
-	  { $$ = new Item_func_quarter($3); }
-	| RAND '(' expr ')'
-	  { $$= new Item_func_rand($3); Lex->uncacheable(UNCACHEABLE_RAND);}
-	| RAND '(' ')'
-	  { $$= new Item_func_rand(); Lex->uncacheable(UNCACHEABLE_RAND);}
-	| REPLACE '(' expr ',' expr ',' expr ')'
-	  { $$= new Item_func_replace($3,$5,$7); }
-	| RIGHT '(' expr ',' expr ')'
-	  { $$= new Item_func_right($3,$5); }
-	| ROUND '(' expr ')'
-	  { $$= new Item_func_round($3, new Item_int((char*)"0",0,1),0); }
-	| ROUND '(' expr ',' expr ')' { $$= new Item_func_round($3,$5,0); }
-	| ROW_COUNT_SYM '(' ')'
-	  {
-	    $$= new Item_func_row_count();
-	    Lex->safe_to_cache_query= 0;
-	  }
+	  { $$ = new (YYTHD->mem_root) Item_func_locate($5,$3); }
 	| SUBDATE_SYM '(' expr ',' expr ')'
-	  { $$= new Item_date_add_interval($3, $5, INTERVAL_DAY, 1);}
+	  {
+            $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5,
+                                                             INTERVAL_DAY, 1);
+          }
 	| SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')'
-	  { $$= new Item_date_add_interval($3, $6, $7, 1); }
-	| SECOND_SYM '(' expr ')'
-	  { $$= new Item_func_second($3); }
+	  { $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 1); }
 	| SUBSTRING '(' expr ',' expr ',' expr ')'
-	  { $$= new Item_func_substr($3,$5,$7); }
+	  { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); }
 	| SUBSTRING '(' expr ',' expr ')'
-	  { $$= new Item_func_substr($3,$5); }
+	  { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); }
 	| SUBSTRING '(' expr FROM expr FOR_SYM expr ')'
-	  { $$= new Item_func_substr($3,$5,$7); }
+	  { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); }
 	| SUBSTRING '(' expr FROM expr ')'
-	  { $$= new Item_func_substr($3,$5); }
-	| SUBSTRING_INDEX '(' expr ',' expr ',' expr ')'
-	  { $$= new Item_func_substr_index($3,$5,$7); }
+	  { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); }
 	| SYSDATE optional_braces
           {
             if (global_system_variables.sysdate_is_now == 0)
-              $$= new Item_func_sysdate_local();
-            else $$= new Item_func_now_local();
+              $$= 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 Item_func_sysdate_local($3);
-            else $$= new Item_func_now_local($3);
+              $$= 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;
           }
-	| TIME_SYM '(' expr ')'
-	  { $$= new Item_time_typecast($3); }
-	| TIMESTAMP '(' expr ')'
-	  { $$= new Item_datetime_typecast($3); }
-	| TIMESTAMP '(' expr ',' expr ')'
-	  { $$= new Item_func_add_time($3, $5, 1, 0); }
 	| TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')'
-	  { $$= new Item_date_add_interval($7,$5,$3,0); }
+	  { $$= new (YYTHD->mem_root) Item_date_add_interval($7,$5,$3,0); }
 	| TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')'
-	  { $$= new Item_func_timestamp_diff($5,$7,$3); }
-	| TRIM '(' expr ')'
-	  { $$= new Item_func_trim($3); }
-	| TRIM '(' LEADING expr FROM expr ')'
-	  { $$= new Item_func_ltrim($6,$4); }
-	| TRIM '(' TRAILING expr FROM expr ')'
-	  { $$= new Item_func_rtrim($6,$4); }
-	| TRIM '(' BOTH expr FROM expr ')'
-	  { $$= new Item_func_trim($6,$4); }
-	| TRIM '(' LEADING FROM expr ')'
-	 { $$= new Item_func_ltrim($5); }
-	| TRIM '(' TRAILING FROM expr ')'
-	  { $$= new Item_func_rtrim($5); }
-	| TRIM '(' BOTH FROM expr ')'
-	  { $$= new Item_func_trim($5); }
-	| TRIM '(' expr FROM expr ')'
-	  { $$= new Item_func_trim($5,$3); }
-	| TRUNCATE_SYM '(' expr ',' expr ')'
-	  { $$= new Item_func_round($3,$5,1); }
-	| ident '.' ident '(' udf_expr_list ')'
+	  { $$= new (YYTHD->mem_root) Item_func_timestamp_diff($5,$7,$3); }
+	| UTC_DATE_SYM optional_braces
 	  {
-	    LEX *lex= Lex;
-	    sp_name *name= new sp_name($1, $3);
+            $$= 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;
+          }
+        ;
 
-	    name->init_qname(YYTHD);
-	    sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION);
-	    if ($5)
-	      $$= new Item_func_sp(Lex->current_context(), name, *$5);
-	    else
-	      $$= new Item_func_sp(Lex->current_context(), name);
-	    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;
 	  }
-	| IDENT_sys '(' 
+	| 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;
-            if (using_udf_functions &&
-                (udf= find_udf($1.str, $1.length)) &&
-                udf->type == UDFTYPE_AGGREGATE)
+          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())
             {
-              LEX *lex= Lex;
-              if (lex->current_select->inc_in_sum_expr())
-              {
-                yyerror(ER(ER_SYNTAX_ERROR));
-                YYABORT;
-              }
+              yyerror(ER(ER_SYNTAX_ERROR));
+              YYABORT;
             }
-            $<udf>$= udf;
+          }
+          /* Temporary placing the result of find_udf in $3 */
+          $<udf>$= 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 <use> database)
+
+            This will be revised with WL#2128 (SQL PATH)
+          */
+          builder= find_native_function_builder(thd, $1);
+          if (builder)
+          {
+            item= builder->create(thd, $1, $4);
           }
-          udf_expr_list ')'
+          else
           {
 #ifdef HAVE_DLOPEN
+            /* Retrieving the result of find_udf */
             udf_func *udf= $<udf>3;
-            SELECT_LEX *sel= Select;
+            LEX *lex= Lex;
 
             if (udf)
             {
               if (udf->type == UDFTYPE_AGGREGATE)
+              {
                 Select->in_sum_expr--;
-
-              Lex->binlog_row_based_if_mixed= TRUE;
-
-              switch (udf->returns) {
-              case STRING_RESULT:
-                if (udf->type == UDFTYPE_FUNCTION)
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_func_udf_str(udf, *$4);
-                  else
-                    $$ = new Item_func_udf_str(udf);
-                }
-                else
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_sum_udf_str(udf, *$4);
-                  else
-                    $$ = new Item_sum_udf_str(udf);
-                }
-                break;
-              case REAL_RESULT:
-                if (udf->type == UDFTYPE_FUNCTION)
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_func_udf_float(udf, *$4);
-                  else
-                    $$ = new Item_func_udf_float(udf);
-                }
-                else
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_sum_udf_float(udf, *$4);
-                  else
-                    $$ = new Item_sum_udf_float(udf);
-                }
-                break;
-              case INT_RESULT:
-                if (udf->type == UDFTYPE_FUNCTION)
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_func_udf_int(udf, *$4);
-                  else
-                    $$ = new Item_func_udf_int(udf);
-                }
-                else
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_sum_udf_int(udf, *$4);
-                  else
-                    $$ = new Item_sum_udf_int(udf);
-                }
-                break;
-              case DECIMAL_RESULT:
-                if (udf->type == UDFTYPE_FUNCTION)
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_func_udf_decimal(udf, *$4);
-                  else
-                    $$ = new Item_func_udf_decimal(udf);
-                }
-                else
-                {
-                  if ($4 != NULL)
-                    $$ = new Item_sum_udf_decimal(udf, *$4);
-                  else
-                    $$ = new Item_sum_udf_decimal(udf);
-                }
-                break;
-              default:
-                YYABORT;
               }
+
+              item= Create_udf_func::s_singleton.create(thd, udf, $4);
             }
             else
-#endif /* HAVE_DLOPEN */
+#endif
             {
-	      LEX *lex= Lex;
-              THD *thd= lex->thd;
-              LEX_STRING db;
-              if (thd->copy_db_to(&db.str, &db.length))
-                YYABORT;
-              sp_name *name= new sp_name(db, $1);
-              if (name)
-                name->init_qname(thd);
-
-              sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION);
-              if ($4)
-                $$= new Item_func_sp(Lex->current_context(), name, *$4);
-              else
-                $$= new Item_func_sp(Lex->current_context(), name);
-	      lex->safe_to_cache_query=0;
-	    }
+              builder= find_qualified_function_builder(thd);
+              DBUG_ASSERT(builder);
+              item= builder->create(thd, $1, $4);
+            }
           }
-	| UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')'
-	  {
-            $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9);
-	  }
-	| UNIX_TIMESTAMP '(' ')'
-	  {
-	    $$= new Item_func_unix_timestamp();
-	    Lex->safe_to_cache_query=0;
-	  }
-	| UNIX_TIMESTAMP '(' expr ')'
-	  { $$= new Item_func_unix_timestamp($3); }
-	| USER '(' ')'
-	  { $$= new Item_func_user(); Lex->safe_to_cache_query=0; }
-	| UTC_DATE_SYM optional_braces
-	  { $$= new Item_func_curdate_utc(); Lex->safe_to_cache_query=0;}
-	| UTC_TIME_SYM optional_braces
-	  { $$= new Item_func_curtime_utc(); Lex->safe_to_cache_query=0;}
-	| UTC_TIMESTAMP_SYM optional_braces
-	  { $$= new Item_func_now_utc(); Lex->safe_to_cache_query=0;}
-	| WEEK_SYM '(' expr ')'
-	  {
-            $$= new Item_func_week($3,new Item_int((char*) "0",
-				   YYTHD->variables.default_week_format,1));
+
+          if (! ($$= item))
+          {
+            YYABORT;
           }
-	| WEEK_SYM '(' expr ',' expr ')'
-	  { $$= new Item_func_week($3,$5); }
-	| YEAR_SYM '(' expr ')'
-	  { $$= new Item_func_year($3); }
-	| YEARWEEK '(' expr ')'
-	  { $$= new Item_func_yearweek($3,new Item_int((char*) "0",0,1)); }
-	| YEARWEEK '(' expr ',' expr ')'
-	  { $$= new Item_func_yearweek($3, $5); }
-	| BENCHMARK_SYM '(' ulong_num ',' expr ')'
-	  {
-	    $$=new Item_func_benchmark($3,$5);
-	    Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
-	  }
-	| EXTRACT_SYM '(' interval FROM expr ')'
-	{ $$=new Item_extract( $3, $5); };
+        }
+	| ident '.' ident '(' opt_expr_list ')'
+	{
+          THD *thd= YYTHD;
+          Create_qfunc *builder;
+          Item *item= NULL;
 
-geometry_function:
-	  CONTAINS_SYM '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_spatial_rel($3, $5, Item_func::SP_CONTAINS_FUNC)); }
-	| GEOMFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| GEOMFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
-	| GEOMFROMWKB '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_wkb($3)); }
-	| GEOMFROMWKB '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_wkb($3, $5)); }
-	| GEOMETRYCOLLECTION '(' expr_list ')'
-	  { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
-                           Geometry::wkb_geometrycollection,
-                           Geometry::wkb_point)); }
-	| LINESTRING '(' expr_list ')'
-	  { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
-                  Geometry::wkb_linestring, Geometry::wkb_point)); }
- 	| MULTILINESTRING '(' expr_list ')'
-	  { $$= GEOM_NEW( Item_func_spatial_collection(* $3,
-                   Geometry::wkb_multilinestring, Geometry::wkb_linestring)); }
- 	| MLINEFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| MLINEFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
-	| MPOINTFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| MPOINTFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
-	| MPOLYFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| MPOLYFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
-	| MULTIPOINT '(' expr_list ')'
-	  { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
-                  Geometry::wkb_multipoint, Geometry::wkb_point)); }
- 	| MULTIPOLYGON '(' expr_list ')'
-	  { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
-                  Geometry::wkb_multipolygon, Geometry::wkb_polygon)); }
-	| POINT_SYM '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_point($3,$5)); }
- 	| POINTFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| POINTFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
-	| POLYFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| POLYFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
-	| POLYGON '(' expr_list ')'
-	  { $$= GEOM_NEW(Item_func_spatial_collection(* $3,
-	          Geometry::wkb_polygon, Geometry::wkb_linestring)); }
- 	| GEOMCOLLFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| GEOMCOLLFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
- 	| LINEFROMTEXT '(' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3)); }
-	| LINEFROMTEXT '(' expr ',' expr ')'
-	  { $$= GEOM_NEW(Item_func_geometry_from_text($3, $5)); }
-	;
+          /*
+            The following in practice calls:
+            <code>Create_sp_func::create()</code>
+            and builds a stored function.
+
+            However, it's important to maintain the interface between the
+            parser and the implementation in item_create.cc clean,
+            since this will change with WL#2128 (SQL PATH):
+            - INFORMATION_SCHEMA.version() is the SQL 99 syntax for the native
+            funtion version(),
+            - MySQL.version() is the SQL 2003 syntax for the native function
+            version() (a vendor can specify any schema).
+          */
+
+          builder= find_qualified_function_builder(thd);
+          DBUG_ASSERT(builder);
+          item= builder->create(thd, $1, $3, $5);
+
+          if (! ($$= item))
+          {
+            YYABORT;
+          }
+	}
+        ;
 
 fulltext_options:
           opt_natural_language_mode opt_query_expansion
@@ -6684,6 +6622,12 @@
 udf_expr:
 	remember_name expr remember_end select_alias
 	{
+          /*
+           Use Item::name as a storage for the attribute value of user
+           defined function argument. It is safe to use Item::name
+           because the syntax will not allow having an explicit name here.
+           See WL#1017 re. udf attributes.
+          */
 	  if ($4.str)
           {
             $2->is_autogenerated_name= FALSE;
@@ -6756,6 +6700,46 @@
 	    $5->empty();
 	  };
 
+variable:
+          '@'
+          {
+            if (! Lex->parsing_options.allows_variable)
+            {
+              my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+              YYABORT;
+            }
+          }
+          variable_aux
+          {
+            $$= $3;
+          }
+          ;
+
+variable_aux:
+          ident_or_text SET_VAR expr
+          {
+            $$= new Item_func_set_user_var($1, $3);
+            LEX *lex= Lex;
+            lex->uncacheable(UNCACHEABLE_RAND);
+          }
+        | ident_or_text
+          {
+            $$= new Item_func_get_user_var($1);
+            LEX *lex= Lex;
+            lex->uncacheable(UNCACHEABLE_RAND);
+          }
+        | '@' opt_var_ident_type ident_or_text opt_component
+          {
+            if ($3.str && $4.str && check_reserved_words(&$3))
+            {
+              yyerror(ER(ER_SYNTAX_ERROR));
+              YYABORT;
+            }
+            if (!($$= get_system_var(YYTHD, $2, $3, $4)))
+              YYABORT;
+          }
+        ;
+
 opt_distinct:
     /* empty */ { $$ = 0; }
     |DISTINCT   { $$ = 1; };
@@ -6810,6 +6794,11 @@
         | DECIMAL_SYM float_options { $$=ITEM_CAST_DECIMAL; Lex->charset= NULL; }
 	;
 
+opt_expr_list:
+	/* empty */ { $$= NULL; }
+	| expr_list { $$= $1;}
+	;
+
 expr_list:
 	{ Select->expr_list.push_front(new List<Item>); }
 	expr_list2
@@ -6862,7 +6851,7 @@
 /* Warning - may return NULL in case of incomplete SELECT */
 table_ref:
         table_factor            { $$=$1; }
-        | join_table            { $$=$1; }
+        | join_table
           {
 	    LEX *lex= Lex;
             if (!($$= lex->current_select->nest_last_join(lex->thd)))
@@ -6904,29 +6893,33 @@
 	| table_ref normal_join table_ref
           ON
           {
-            YYERROR_UNLESS($1 && ($$=$3));
+            YYERROR_UNLESS($1 && $3);
             /* Change the current name resolution context to a local context. */
             if (push_new_name_resolution_context(YYTHD, $1, $3))
               YYABORT;
+            Select->parsing_place= IN_ON;
           }
           expr
 	  {
             add_join_on($3,$6);
             Lex->pop_context();
+            Select->parsing_place= NO_MATTER;
           }
         | table_ref STRAIGHT_JOIN table_factor
           ON
           {
-            YYERROR_UNLESS($1 && ($$=$3));
+            YYERROR_UNLESS($1 && $3);
             /* Change the current name resolution context to a local context. */
             if (push_new_name_resolution_context(YYTHD, $1, $3))
               YYABORT;
+            Select->parsing_place= IN_ON;
           }
           expr
           {
             $3->straight=1;
             add_join_on($3,$6);
             Lex->pop_context();
+            Select->parsing_place= NO_MATTER;
           }
 	| table_ref normal_join table_ref
 	  USING
@@ -6950,6 +6943,7 @@
             /* Change the current name resolution context to a local context. */
             if (push_new_name_resolution_context(YYTHD, $1, $5))
               YYABORT;
+            Select->parsing_place= IN_ON;
           }
           expr
 	  {
@@ -6957,6 +6951,7 @@
             Lex->pop_context();
             $5->outer_join|=JOIN_TYPE_LEFT;
             $$=$5;
+            Select->parsing_place= NO_MATTER;
           }
 	| table_ref LEFT opt_outer JOIN_SYM table_factor
 	  {
@@ -6981,6 +6976,7 @@
             /* Change the current name resolution context to a local context. */
             if (push_new_name_resolution_context(YYTHD, $1, $5))
               YYABORT;
+            Select->parsing_place= IN_ON;
           }
           expr
           {
@@ -6989,6 +6985,7 @@
               YYABORT;
             add_join_on($$, $8);
             Lex->pop_context();
+            Select->parsing_place= NO_MATTER;
           }
 	| table_ref RIGHT opt_outer JOIN_SYM table_factor
 	  {
@@ -7177,6 +7174,13 @@
           SELECT_SYM
           {
             LEX *lex= Lex;
+
+            if (! lex->parsing_options.allows_derived)
+            {
+              my_error(ER_VIEW_SELECT_DERIVED, MYF(0));
+              YYABORT;
+            }
+
             SELECT_LEX *sel= lex->current_select;
             TABLE_LIST *embedding;
             if (!sel->embedding || sel->end_nested_join(lex->thd))
@@ -7561,6 +7565,13 @@
 	| PROCEDURE ident			/* Procedure name */
 	  {
 	    LEX *lex=Lex;
+
+            if (! lex->parsing_options.allows_select_procedure)
+            {
+              my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "PROCEDURE");
+              YYABORT;
+            }
+
 	    if (&lex->select_lex != lex->current_select)
 	    {
 	      my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "subquery");
@@ -7660,28 +7671,40 @@
            ;
 
 into:
-        INTO OUTFILE TEXT_STRING_filesystem
+        INTO
+	{
+          if (! Lex->parsing_options.allows_select_into)
+          {
+            my_error(ER_VIEW_SELECT_CLAUSE, MYF(0), "INTO");
+            YYABORT;
+          }
+	}
+        into_destination
+        ;
+
+into_destination:
+        OUTFILE TEXT_STRING_filesystem
 	{
           LEX *lex= Lex;
           lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
-          if (!(lex->exchange= new sql_exchange($3.str, 0)) ||
+          if (!(lex->exchange= new sql_exchange($2.str, 0)) ||
               !(lex->result= new select_export(lex->exchange)))
             YYABORT;
 	}
 	opt_field_term opt_line_term
-	| INTO DUMPFILE TEXT_STRING_filesystem
+	| DUMPFILE TEXT_STRING_filesystem
 	{
 	  LEX *lex=Lex;
 	  if (!lex->describe)
 	  {
 	    lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
-	    if (!(lex->exchange= new sql_exchange($3.str,1)))
+	    if (!(lex->exchange= new sql_exchange($2.str,1)))
 	      YYABORT;
 	    if (!(lex->result= new select_dump(lex->exchange)))
 	      YYABORT;
 	  }
 	}
-        | INTO select_var_list_init
+        | select_var_list_init
 	{
 	  Lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
 	}
@@ -7731,7 +7754,7 @@
 	    LEX *lex=Lex;
 	    lex->sql_command= SQLCOM_DROP_DB;
 	    lex->drop_if_exists=$3;
-	    lex->name=$4.str;
+	    lex->name= $4;
 	 }
 	| DROP FUNCTION_SYM if_exists sp_name
 	  {
@@ -7773,11 +7796,12 @@
             Lex->spname= $4;
             Lex->sql_command = SQLCOM_DROP_EVENT;
           }
-        | DROP TRIGGER_SYM sp_name
+        | DROP TRIGGER_SYM if_exists sp_name
           {
             LEX *lex= Lex;
             lex->sql_command= SQLCOM_DROP_TRIGGER;
-            lex->spname= $3;
+            lex->drop_if_exists= $3;
+            lex->spname= $4;
 	  }
         | DROP TABLESPACE tablespace_name opt_ts_engine opt_ts_wait
           {
@@ -8097,14 +8121,17 @@
 	ident opt_wild opt_table_alias
 	{
 	  if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3,
-					 TL_OPTION_UPDATING, Lex->lock_option))
+					 TL_OPTION_UPDATING | 
+                                         TL_OPTION_ALIAS, Lex->lock_option))
 	    YYABORT;
         }
 	| ident '.' ident opt_wild opt_table_alias
 	  {
 	    if (!Select->add_table_to_list(YYTHD,
 					   new Table_ident(YYTHD, $1, $3, 0),
-					   $5, TL_OPTION_UPDATING,
+					   $5, 
+                                           TL_OPTION_UPDATING | 
+                                           TL_OPTION_ALIAS,
 					   Lex->lock_option))
 	      YYABORT;
 	  }
@@ -8382,7 +8409,7 @@
 	  {
 	    Lex->sql_command=SQLCOM_SHOW_CREATE_DB;
 	    Lex->create_info.options=$3;
-	    Lex->name=$4.str;
+	    Lex->name= $4;
 	  }
         | CREATE TABLE_SYM table_ident
           {
@@ -8643,17 +8670,12 @@
 /* kill threads */
 
 kill:
-	KILL_SYM
-        {
-          Lex->sql_command= SQLCOM_KILL;
-          Lex->expr_allows_subselect= FALSE;
-        }
-        kill_option expr
+	KILL_SYM kill_option expr
 	{
 	  LEX *lex=Lex;
 	  lex->value_list.empty();
-	  lex->value_list.push_front($4);
-          Lex->expr_allows_subselect= TRUE;
+	  lex->value_list.push_front($3);
+          lex->sql_command= SQLCOM_KILL;
 	};
 
 kill_option:
@@ -8735,6 +8757,9 @@
 	FROM MASTER_SYM
         {
 	  Lex->sql_command = SQLCOM_LOAD_MASTER_DATA;
+          WARN_DEPRECATED(yythd, "5.2", "LOAD DATA FROM MASTER",
+                          "mysqldump or future "
+                          "BACKUP/RESTORE DATABASE facility");
         };
 
 opt_local:
@@ -8750,6 +8775,8 @@
               Ignore this option in SP to avoid problem with query cache
             */
             if (Lex->sphead != 0)
+              $$= YYTHD->update_lock_default;
+            else
 #endif
               $$= TL_WRITE_CONCURRENT_INSERT;
           }
@@ -8891,8 +8918,13 @@
         {
           THD *thd=YYTHD;
 	  LEX *lex= thd->lex;
-          Item_param *item= new Item_param((uint) (lex->tok_start -
-                                                   (uchar *) thd->query));
+          Item_param *item;
+          if (! lex->parsing_options.allows_variable)
+          {
+            my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+            YYABORT;
+          }
+          item= new Item_param((uint) (lex->tok_start - (uchar *) thd->query));
           if (!($$= item) || lex->param_list.push_back(item))
           {
             my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
@@ -9012,6 +9044,12 @@
 	  if (spc && (spv = spc->find_variable(&$1)))
 	  {
             /* We're compiling a stored procedure and found a variable */
+            if (! lex->parsing_options.allows_variable)
+            {
+              my_error(ER_VIEW_SELECT_VARIABLE, MYF(0));
+              YYABORT;
+            }
+
             Item_splocal *splocal;
             splocal= new Item_splocal($1, spv->offset, spv->type,
                                       lex->tok_start_prev - 
@@ -9021,7 +9059,6 @@
               splocal->m_sp= lex->sphead;
 #endif
 	    $$ = (Item*) splocal;
-            lex->variables_used= 1;
 	    lex->safe_to_cache_query=0;
 	  }
 	  else
@@ -9299,7 +9336,7 @@
 	  $$->host.str= (char *) "%";
 	  $$->host.length= 1;
 
-	  if (check_string_length(system_charset_info, &$$->user,
+	  if (check_string_length(&$$->user,
                                   ER(ER_USERNAME), USERNAME_LENGTH))
 	    YYABORT;
 	}
@@ -9310,9 +9347,9 @@
 	      YYABORT;
 	    $$->user = $1; $$->host=$3;
 
-	    if (check_string_length(system_charset_info, &$$->user,
+	    if (check_string_length(&$$->user,
                                     ER(ER_USERNAME), USERNAME_LENGTH) ||
-	        check_string_length(&my_charset_latin1, &$$->host,
+	        check_string_length(&$$->host,
                                     ER(ER_HOSTNAME), HOSTNAME_LENGTH))
 	      YYABORT;
 	  }
@@ -9379,6 +9416,7 @@
         | USER                  {}
 	| WRAPPER_SYM		{}
         | XA_SYM                {}
+        | UPGRADE_SYM           {}
 	;
 
 /*
@@ -10385,7 +10423,8 @@
 	  {
 	    LEX *lex= Lex;
             THD *thd= lex->thd;
-            if (thd->copy_db_to(&lex->current_select->db, NULL))
+            uint dummy;
+            if (thd->copy_db_to(&lex->current_select->db, &dummy))
               YYABORT;
 	    if (lex->grant == GLOBAL_ACLS)
 	      lex->grant = DB_ACLS & ~GRANT_ACL;
@@ -10739,49 +10778,38 @@
 	| ALL       { $$=0; }
         ;
 
-singlerow_subselect:
-	subselect_start singlerow_subselect_init
-	subselect_end
-	{
-	  $$= $2;
-	};
-
-singlerow_subselect_init:
-	select_init2
-	{
-	  $$= new Item_singlerow_subselect(Lex->current_select->
-					   master_unit()->first_select());
-	};
-
-exists_subselect:
-	subselect_start exists_subselect_init
-	subselect_end
-	{
-	  $$= $2;
-	};
-
-exists_subselect_init:
-	select_init2
-	{
-	  $$= new Item_exists_subselect(Lex->current_select->master_unit()->
-					first_select());
-	};
-
-in_subselect:
-  subselect_start in_subselect_init
-  subselect_end
-  {
-    $$= $2;
-  };
+subselect:
+        SELECT_SYM subselect_start subselect_init subselect_end
+        {
+          $$= $3;
+        }
+        | '(' subselect_start subselect ')'
+          {
+            LEX *lex= Lex;
+	    THD *thd= YYTHD;
+            /*
+              note that a local variable can't be used for
+              $3 as it's used in local variable construction
+              and some compilers can't guarnatee the order
+              in which the local variables are initialized.
+            */
+            List_iterator<Item> it($3->item_list);
+            Item *item;
+            /*
+              we must fill the items list for the "derived table".
+            */
+            while ((item= it++))
+              add_item_to_list(thd, item);
+          }
+          union_clause subselect_end { $$= $3; };
 
-in_subselect_init:
+subselect_init:
   select_init2
   {
     $$= Lex->current_select->master_unit()->first_select();
   };
 
 subselect_start:
-	'(' SELECT_SYM
 	{
 	  LEX *lex=Lex;
           if (!lex->expr_allows_subselect)
@@ -10789,12 +10817,18 @@
             yyerror(ER(ER_SYNTAX_ERROR));
 	    YYABORT;
 	  }
+          /* 
+            we are making a "derived table" for the parenthesis
+            as we need to have a lex level to fit the union 
+            after the parenthesis, e.g. 
+            (SELECT .. ) UNION ...  becomes 
+            SELECT * FROM ((SELECT ...) UNION ...)
+          */
 	  if (mysql_new_select(Lex, 1))
 	    YYABORT;
 	};
 
 subselect_end:
-	')'
 	{
 	  LEX *lex=Lex;
           lex->pop_context();
@@ -10931,6 +10965,24 @@
 	;
 
 view_select:
+        {
+          LEX *lex= Lex;
+          lex->parsing_options.allows_variable= FALSE;
+          lex->parsing_options.allows_select_into= FALSE;
+          lex->parsing_options.allows_select_procedure= FALSE;
+          lex->parsing_options.allows_derived= FALSE;
+        }        
+        view_select_aux
+        {
+          LEX *lex= Lex;
+          lex->parsing_options.allows_variable= TRUE;
+          lex->parsing_options.allows_select_into= TRUE;
+          lex->parsing_options.allows_select_procedure= TRUE;
+          lex->parsing_options.allows_derived= TRUE;
+        }
+        ;
+
+view_select_aux:
 	SELECT_SYM remember_name select_init2
 	{
           THD *thd=YYTHD;

--- 1.97/sql/share/errmsg.txt	2006-12-07 18:27:54 -05:00
+++ 1.98/sql/share/errmsg.txt	2006-12-07 18:27:54 -05:00
@@ -3791,7 +3791,7 @@
         dan "Tabellerne i MERGE er ikke defineret ens"
         nla "Niet alle tabellen in de MERGE tabel hebben identieke gedefinities"
-        eng "All tables in the MERGE table are not identically defined"
+        eng "Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist"
         ger "Nicht alle Tabellen in der MERGE-Tabelle sind gleich definiert"
@@ -5967,33 +5967,59 @@
         eng "Error during starting/stopping of the scheduler. Error code %u"
 ER_PARTITION_MERGE_ERROR
-        eng "%s handler cannot be used in partitioned tables"
-        ger "%s-Handler kann in partitionierten Tabellen nicht verwendet werden"
+        eng "Engine cannot be used in partitioned tables"
+        ger "Engine kann in partitionierten Tabellen nicht verwendet werden"
 ER_CANT_ACTIVATE_LOG
         eng "Cannot activate '%-.64s' log"
         ger "Kann Logdatei '%-.64s' nicht aktivieren"
 ER_RBR_NOT_AVAILABLE
         eng "The server was not built with row-based replication"
+ER_BASE64_DECODE_ERROR
+        eng "Decoding of base64 string failed"
         ger "Der Server hat keine zeilenbasierte Replikation"
 ER_NO_TRIGGERS_ON_SYSTEM_SCHEMA
         eng "Triggers can not be created on system tables"
-ER_CANT_ALTER_LOG_TABLE
-        eng "You can't alter a log table if logging is enabled"
-ER_BAD_LOG_ENGINE
-        eng "One can use only CSV and MyISAM engines for the log tables"
-ER_CANT_DROP_LOG_TABLE
-        eng "Cannot drop log table if log is enabled"
 ER_EVENT_RECURSIVITY_FORBIDDEN
         eng "Recursivity of EVENT DDL statements is forbidden when body is present"
 ER_EVENTS_DB_ERROR
         eng "Cannot proceed because the tables used by events were found damaged at server start"
 ER_ONLY_INTEGERS_ALLOWED
-        eng "Only normal integers allowed as number here"
+        eng "Only integers allowed as number here"
+ER_AUTOINC_READ_FAILED
+        eng "Failed to read auto-increment value from storage engine"
+        ger "Lesen des Autoincrement-Werts von der Speicher-Engine fehlgeschlagen"
 ER_USERNAME
-	eng "user name"
+        eng "user name"
+        ger "Benutzername"
 ER_HOSTNAME
-	eng "host name"
+        eng "host name"
+        ger "Hostname"
 ER_WRONG_STRING_LENGTH
-	eng "String '%-.70s' is too long for %s (should be no longer than %d)"
+        eng "String '%-.70s' is too long for %s (should be no longer than %d)"
+ER_UNSUPORTED_LOG_ENGINE
+        eng "This storage engine cannot be used for log tables""
+ER_BAD_LOG_STATEMENT
+        eng "You cannot '%s' a log table if logging is enabled"
+ER_NON_INSERTABLE_TABLE  
+        eng "The target table %-.100s of the %s is not insertable-into"
+ER_CANT_RENAME_LOG_TABLE
+        eng "Cannot rename '%s'. When logging enabled, rename to/from log table must rename two tables: the log table to an archive table and another table back to '%s'"
+ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT 42000
+        eng "Incorrect parameter count in the call to native function '%-.64s'"
+ER_WRONG_PARAMETERS_TO_NATIVE_FCT 42000
+        eng "Incorrect parameters in the call to native function '%-.64s'"
+ER_WRONG_PARAMETERS_TO_STORED_FCT 42000  
+        eng "Incorrect parameters in the call to stored function '%-.64s'"
+ER_NATIVE_FCT_NAME_COLLISION
+        eng "This function '%-.64s' has the same name as a native function."
+ER_BINLOG_PURGE_EMFILE
+        eng "Too many files opened, please execute the command again"

--- 1.28/mysql-test/lib/init_db.sql	2006-12-07 18:27:54 -05:00
+++ 1.29/mysql-test/lib/init_db.sql	2006-12-07 18:27:54 -05:00
@@ -649,5 +649,4 @@
   PRIMARY KEY  (db, name)
 ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COMMENT 'Events';
 
-CREATE DATABASE IF NOT EXISTS cluster;
-CREATE TABLE IF NOT EXISTS cluster.binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
+CREATE TABLE IF NOT EXISTS mysql.ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;

--- 1.83/libmysqld/Makefile.am	2006-12-07 18:27:54 -05:00
+++ 1.84/libmysqld/Makefile.am	2006-12-07 18:27:54 -05:00
@@ -29,10 +29,11 @@
 			-DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
 			-DLIBDIR="\"$(MYSQLLIBdir)\""
 INCLUDES=		-I$(top_builddir)/include -I$(top_srcdir)/include \
-			-I$(top_builddir)/include -I$(top_srcdir)/include \
-			-I$(top_srcdir)/sql -I$(top_srcdir)/sql/examples \
+			-I$(top_builddir)/sql -I$(top_srcdir)/sql \
+			-I$(top_srcdir)/sql/examples \
 			-I$(top_srcdir)/regex \
-			$(openssl_includes) @ZLIB_INCLUDES@
+			$(openssl_includes) @ZLIB_INCLUDES@ \
+			@condition_dependent_plugin_includes@
 
 noinst_LIBRARIES =	libmysqld_int.a
 pkglib_LIBRARIES =	libmysqld.a
@@ -78,6 +79,8 @@
 libmysqld_a_SOURCES=
 
 sqlstoragesources =	$(EXTRA_libmysqld_a_SOURCES)
+storagesources = @condition_dependent_plugin_modules@
+storagesourceslinks = @condition_dependent_plugin_links@
 
 # automake misses these
 sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
@@ -92,8 +95,8 @@
 		$(yassl_inc_libs)
 
 if HAVE_YASSL
-yassl_inc_libs=	$(top_srcdir)/extra/yassl/src/.libs/libyassl.a \
-		$(top_srcdir)/extra/yassl/taocrypt/src/.libs/libtaocrypt.a
+yassl_inc_libs=	$(top_builddir)/extra/yassl/src/.libs/libyassl.a \
+		$(top_builddir)/extra/yassl/taocrypt/src/.libs/libtaocrypt.a
 endif
 
 # Storage engine specific compilation options
@@ -153,16 +156,28 @@
 #libmysqld_la_LDFLAGS = -version-info @SHARED_LIB_VERSION@
 #CLEANFILES =		$(libmysqld_la_LIBADD) libmysqld.la
 
-# This is called from the toplevel makefile
+# This is called from the toplevel makefile. If we can link now
+# to an existing file in source, we do that, else we assume it
+# will show up in the build tree eventually (generated file).
 link_sources:
 	  set -x; \
 	  for f in $(sqlsources); do \
 	    rm -f $$f; \
-	    @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
+	    if test -e $(top_srcdir)/sql/$$f ; \
+            then \
+	      @LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
+            else \
+	      @LN_CP_F@ $(top_builddir)/sql/$$f $$f; \
+            fi ; \
 	  done; \
 	  for f in $(libmysqlsources); do \
 	    rm -f $$f; \
-	    @LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \
+	    if test -e $(top_srcdir)/libmysql/$$f ; \
+	    then \
+	      @LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \
+	    else \
+	      @LN_CP_F@ $(top_builddir)/libmysql/$$f $$f; \
+	    fi ; \
 	  done; \
 	  if test -n "$(sqlstoragesources)" ; \
 	  then \
@@ -171,12 +186,19 @@
 	      @LN_CP_F@ `find $(srcdir)/../sql -name "$$f"` "$$f"; \
 	    done; \
 	  fi; \
+	  if test -n "$(storagesources)" ; \
+	  then \
+	    rm -f $(storagesources); \
+	    for f in $(storagesourceslinks); do \
+	      @LN_CP_F@ $(top_srcdir)/$$f . ; \
+	    done; \
+	  fi; \
 	  rm -f client_settings.h; \
 	  @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h
 
 
 clean-local:
-	rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) | sed "s;\.lo;.c;g"` \
+	rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) $(storagesources) | sed "s;\.lo;.c;g"` \
 	       $(top_srcdir)/linked_libmysqld_sources; \
 	rm -f client_settings.h
 

--- 1.60/storage/federated/ha_federated.cc	2006-12-07 18:27:54 -05:00
+++ 1.61/storage/federated/ha_federated.cc	2006-12-07 18:27:54 -05:00
@@ -350,7 +350,6 @@
 /* Variables for federated share methods */
 static HASH federated_open_tables;              // To track open tables
 pthread_mutex_t federated_mutex;                // To init the hash
-static int federated_init= FALSE;               // Checking the state of hash
 
 /* Variables used when chopping off trailing characters */
 static const uint sizeof_trailing_comma= sizeof(", ") - 1;
@@ -359,19 +358,21 @@
 static const uint sizeof_trailing_where= sizeof(" WHERE ") - 1;
 
 /* Static declaration for handerton */
-static handler *federated_create_handler(TABLE_SHARE *table,
+static handler *federated_create_handler(handlerton *hton,
+                                         TABLE_SHARE *table,
                                          MEM_ROOT *mem_root);
-static int federated_commit(THD *thd, bool all);
-static int federated_rollback(THD *thd, bool all);
+static int federated_commit(handlerton *hton, THD *thd, bool all);
+static int federated_rollback(handlerton *hton, THD *thd, bool all);
+static int federated_db_init(void);
 
-/* Federated storage engine handlerton */
 
-handlerton *federated_hton;
+/* Federated storage engine handlerton */
 
-static handler *federated_create_handler(TABLE_SHARE *table,
+static handler *federated_create_handler(handlerton *hton, 
+                                         TABLE_SHARE *table,
                                          MEM_ROOT *mem_root)
 {
-  return new (mem_root) ha_federated(table);
+  return new (mem_root) ha_federated(hton, table);
 }
 
 
@@ -399,13 +400,12 @@
 int federated_db_init(void *p)
 {
   DBUG_ENTER("federated_db_init");
-  federated_hton= (handlerton *)p;
+  handlerton *federated_hton= (handlerton *)p;
   federated_hton->state= SHOW_OPTION_YES;
   federated_hton->db_type= DB_TYPE_FEDERATED_DB;
   federated_hton->commit= federated_commit;
   federated_hton->rollback= federated_rollback;
   federated_hton->create= federated_create_handler;
-  federated_hton->panic= federated_db_end;
   federated_hton->flags= HTON_ALTER_NOT_SUPPORTED;
 
   if (pthread_mutex_init(&federated_mutex, MY_MUTEX_INIT_FAST))
@@ -413,13 +413,11 @@
   if (!hash_init(&federated_open_tables, &my_charset_bin, 32, 0, 0,
                     (hash_get_key) federated_get_key, 0, 0))
   {
-    federated_init= TRUE;
     DBUG_RETURN(FALSE);
   }
 
   VOID(pthread_mutex_destroy(&federated_mutex));
 error:
-  have_federated_db= SHOW_OPTION_DISABLED;	// If we couldn't use handler
   DBUG_RETURN(TRUE);
 }
 
@@ -434,14 +432,11 @@
     FALSE       OK
 */
 
-int federated_db_end(ha_panic_function type)
+int federated_done(void *p)
 {
-  if (federated_init)
-  {
-    hash_free(&federated_open_tables);
-    VOID(pthread_mutex_destroy(&federated_mutex));
-  }
-  federated_init= 0;
+  hash_free(&federated_open_tables);
+  VOID(pthread_mutex_destroy(&federated_mutex));
+
   return 0;
 }
 
@@ -846,8 +841,9 @@
 ** FEDERATED tables
 *****************************************************************************/
 
-ha_federated::ha_federated(TABLE_SHARE *table_arg)
-  :handler(federated_hton, table_arg),
+ha_federated::ha_federated(handlerton *hton,
+                           TABLE_SHARE *table_arg)
+  :handler(hton, table_arg),
   mysql(0), stored_result(0)
 {
   trx_next= 0;
@@ -1658,7 +1654,7 @@
       0    otherwise
 */
 
-inline uint field_in_record_is_null(TABLE *table,
+static inline uint field_in_record_is_null(TABLE *table,
                                     Field *field,
                                     char *record)
 {
@@ -1874,7 +1870,7 @@
 
   thd->first_successful_insert_id_in_cur_stmt= 
     mysql->last_used_con->insert_id;
-  DBUG_PRINT("info",("last_insert_id %d", stats.auto_increment_value));
+  DBUG_PRINT("info",("last_insert_id: %ld", (long) stats.auto_increment_value));
 
   DBUG_VOID_RETURN;
 }
@@ -1980,6 +1976,7 @@
   String where_string(where_buffer,
                       sizeof(where_buffer),
                       &my_charset_bin);
+  byte *record= table->record[0];
   DBUG_ENTER("ha_federated::update_row");
   /*
     set string lengths to 0 to avoid misc chars in string
@@ -2038,7 +2035,7 @@
         bool needs_quote= (*field)->str_needs_quotes();
         where_string.append(STRING_WITH_LEN(" = "));
         (*field)->val_str(&field_value,
-                          (char*) (old_data + (*field)->offset()));
+                          (char*) (old_data + (*field)->offset(record)));
         if (needs_quote)
           where_string.append('\'');
         field_value.print(&where_string);
@@ -2143,11 +2140,11 @@
   {
     DBUG_RETURN(stash_remote_error());
   }
-  stats.deleted+= (ha_rows)mysql->affected_rows;
-  stats.records-= (ha_rows)mysql->affected_rows;
+  stats.deleted+= (ha_rows) mysql->affected_rows;
+  stats.records-= (ha_rows) mysql->affected_rows;
   DBUG_PRINT("info",
-             ("rows deleted %d rows deleted for all time %d",
-             int(mysql->affected_rows), stats.deleted));
+             ("rows deleted %ld  rows deleted for all time %ld",
+              (long) mysql->affected_rows, (long) stats.deleted));
 
   DBUG_RETURN(0);
 }
@@ -2280,7 +2277,7 @@
 int ha_federated::index_init(uint keynr, bool sorted)
 {
   DBUG_ENTER("ha_federated::index_init");
-  DBUG_PRINT("info", ("table: '%s'  key: %u", table->s->table_name, keynr));
+  DBUG_PRINT("info", ("table: '%s'  key: %u", table->s->table_name.str, keynr));
   active_index= keynr;
   DBUG_RETURN(0);
 }
@@ -2614,7 +2611,7 @@
 
 */
 
-void ha_federated::info(uint flag)
+int ha_federated::info(uint flag)
 {
   char error_buffer[FEDERATED_QUERY_BUFFER_SIZE];
   char status_buf[FEDERATED_QUERY_BUFFER_SIZE];
@@ -2695,7 +2692,7 @@
   if (result)
     mysql_free_result(result);
 
-  DBUG_VOID_RETURN;
+  DBUG_RETURN(0);
 
 error:
   if (result)
@@ -2704,7 +2701,7 @@
   my_sprintf(error_buffer, (error_buffer, ": %d : %s",
                             mysql_errno(mysql), mysql_error(mysql)));
   my_error(error_code, MYF(0), error_buffer);
-  DBUG_VOID_RETURN;
+  DBUG_RETURN(error_code);
 }
 
 
@@ -2864,7 +2861,7 @@
 int ha_federated::external_lock(THD *thd, int lock_type)
 {
   int error= 0;
-  ha_federated *trx= (ha_federated *)thd->ha_data[federated_hton->slot];
+  ha_federated *trx= (ha_federated *)thd->ha_data[ht->slot];
   DBUG_ENTER("ha_federated::external_lock");
 
   if (lock_type != F_UNLCK)
@@ -2882,7 +2879,7 @@
         DBUG_PRINT("info", ("error setting autocommit TRUE: %d", error));
         DBUG_RETURN(error);
       }
-      trans_register_ha(thd, FALSE, federated_hton);
+      trans_register_ha(thd, FALSE, ht);
     }
     else 
     { 
@@ -2898,8 +2895,8 @@
           DBUG_PRINT("info", ("error setting autocommit FALSE: %d", error));
           DBUG_RETURN(error);
         }
-        thd->ha_data[federated_hton->slot]= this;
-        trans_register_ha(thd, TRUE, federated_hton);
+        thd->ha_data[ht->slot]= this;
+        trans_register_ha(thd, TRUE, ht);
         /*
           Send a lock table to the remote end.
           We do not support this at the moment
@@ -2924,10 +2921,10 @@
 }
 
 
-static int federated_commit(THD *thd, bool all)
+static int federated_commit(handlerton *hton, THD *thd, bool all)
 {
   int return_val= 0;
-  ha_federated *trx= (ha_federated *)thd->ha_data[federated_hton->slot];
+  ha_federated *trx= (ha_federated *)thd->ha_data[hton->slot];
   DBUG_ENTER("federated_commit");
 
   if (all)
@@ -2942,7 +2939,7 @@
       if (error && !return_val);
         return_val= error;
     }
-    thd->ha_data[federated_hton->slot]= NULL;
+    thd->ha_data[hton->slot]= NULL;
   }
 
   DBUG_PRINT("info", ("error val: %d", return_val));
@@ -2950,10 +2947,10 @@
 }
 
 
-static int federated_rollback(THD *thd, bool all)
+static int federated_rollback(handlerton *hton, THD *thd, bool all)
 {
   int return_val= 0;
-  ha_federated *trx= (ha_federated *)thd->ha_data[federated_hton->slot];
+  ha_federated *trx= (ha_federated *)thd->ha_data[hton->slot];
   DBUG_ENTER("federated_rollback");
 
   if (all)
@@ -2968,7 +2965,7 @@
       if (error && !return_val)
         return_val= error;
     }
-    thd->ha_data[federated_hton->slot]= NULL;
+    thd->ha_data[hton->slot]= NULL;
   }
 
   DBUG_PRINT("info", ("error val: %d", return_val));
@@ -3010,7 +3007,7 @@
 }
 
 struct st_mysql_storage_engine federated_storage_engine=
-{ MYSQL_HANDLERTON_INTERFACE_VERSION, federated_hton };
+{ MYSQL_HANDLERTON_INTERFACE_VERSION };
 
 mysql_declare_plugin(federated)
 {
@@ -3019,8 +3016,9 @@
   "FEDERATED",
   "Patrick Galbraith and Brian Aker, MySQL AB",
   "Federated MySQL storage engine",
+  PLUGIN_LICENSE_GPL,
   federated_db_init, /* Plugin Init */
-  NULL, /* Plugin Deinit */
+  federated_done, /* Plugin Deinit */
   0x0100 /* 1.0 */,
   NULL,                       /* status variables                */
   NULL,                       /* system variables                */

--- 1.31/storage/federated/ha_federated.h	2006-12-07 18:27:54 -05:00
+++ 1.32/storage/federated/ha_federated.h	2006-12-07 18:27:54 -05:00
@@ -100,7 +100,7 @@
   int stash_remote_error();
 
 public:
-  ha_federated(TABLE_SHARE *table_arg);
+  ha_federated(handlerton *hton, TABLE_SHARE *table_arg);
   ~ha_federated() {}
   /* The name that will be used for display purposes */
   const char *table_type() const { return "FEDERATED"; }
@@ -212,7 +212,7 @@
   int rnd_next(byte *buf);                                      //required
   int rnd_pos(byte *buf, byte *pos);                            //required
   void position(const byte *record);                            //required
-  void info(uint);                                              //required
+  int info(uint);                                              //required
 
   void update_auto_increment(void);
   int repair(THD* thd, HA_CHECK_OPT* check_opt);
@@ -241,7 +241,4 @@
                                      ha_rkey_function find_flag,
                                      MYSQL_RES **result);
 };
-
-int federated_db_init(void);
-int federated_db_end(ha_panic_function type);
 

--- 1.26/mysql-test/r/connect.result	2006-12-07 18:27:54 -05:00
+++ 1.27/mysql-test/r/connect.result	2006-12-07 18:27:54 -05:00
@@ -15,6 +15,7 @@
 plugin
 proc
 procs_priv
+servers
 slow_log
 tables_priv
 time_zone
@@ -47,6 +48,7 @@
 plugin
 proc
 procs_priv
+servers
 slow_log
 tables_priv
 time_zone
@@ -87,6 +89,7 @@
 plugin
 proc
 procs_priv
+servers
 slow_log
 tables_priv
 time_zone

--- 1.43/scripts/mysql_create_system_tables.sh	2006-12-07 18:27:54 -05:00
+++ 1.44/scripts/mysql_create_system_tables.sh	2006-12-07 18:27:54 -05:00
@@ -901,8 +901,7 @@
 $c_gl
 $c_sl
 $c_ev
-CREATE DATABASE IF NOT EXISTS cluster;
-CREATE TABLE IF NOT EXISTS cluster.binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
+CREATE TABLE IF NOT EXISTS mysql.ndb_binlog_index (Position BIGINT UNSIGNED NOT NULL, File VARCHAR(255) NOT NULL, epoch BIGINT UNSIGNED NOT NULL, inserts BIGINT UNSIGNED NOT NULL, updates BIGINT UNSIGNED NOT NULL, deletes BIGINT UNSIGNED NOT NULL, schemaops BIGINT UNSIGNED NOT NULL, PRIMARY KEY(epoch)) ENGINE=MYISAM;
 
 END_OF_DATA
 
Thread
bk commit into 5.2 tree (patg:1.2352)Patrick Galbraith8 Dec