diff options
Diffstat (limited to 'sql')
236 files changed, 13731 insertions, 1058 deletions
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 4cdc4c01c4e..5593231b34a 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -1,3 +1,18 @@ +# Copyright (C) 2006 MySQL AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX -DUSE_SYMDIR") SET(CMAKE_C_FLAGS_DEBUG @@ -54,7 +69,7 @@ ADD_EXECUTABLE(mysqld ../sql-common/client.c derror.cc des_key_file.cc event_queue.cc event_db_repository.cc sql_tablespace.cc events.cc ../sql-common/my_user.c partition_info.cc rpl_utility.cc rpl_injector.cc sql_locale.cc - rpl_rli.cc rpl_mi.cc + rpl_rli.cc rpl_mi.cc sql_servers.cc ${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc ${PROJECT_SOURCE_DIR}/sql/sql_yacc.h ${PROJECT_SOURCE_DIR}/include/mysqld_error.h diff --git a/sql/Makefile.am b/sql/Makefile.am index 7020ba469cc..6cb9467c32c 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -1,9 +1,8 @@ -# Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +# Copyright (C) 2000-2006 MySQL AB # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -68,7 +67,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ event_db_repository.h event_queue.h \ sql_plugin.h authors.h sql_partition.h event_data_objects.h \ partition_info.h partition_element.h event_scheduler.h \ - contributors.h + contributors.h sql_servers.h mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ @@ -106,7 +105,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc sql_partition.cc \ event_scheduler.cc event_data_objects.cc \ event_queue.cc event_db_repository.cc events.cc \ sql_plugin.cc sql_binlog.cc \ - sql_builtin.cc sql_tablespace.cc partition_info.cc + sql_builtin.cc sql_tablespace.cc partition_info.cc \ + sql_servers.cc gen_lex_hash_SOURCES = gen_lex_hash.cc diff --git a/sql/authors.h b/sql/authors.h index 980ec7670de..48b807c7884 100644 --- a/sql/authors.h +++ b/sql/authors.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2005-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Structure of the name list */ diff --git a/sql/client_settings.h b/sql/client_settings.h index a8cd36af102..f0742cd8046 100644 --- a/sql/client_settings.h +++ b/sql/client_settings.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/contributors.h b/sql/contributors.h index dca232b9b69..87001e29d88 100644 --- a/sql/contributors.h +++ b/sql/contributors.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* Structure of the name list */ diff --git a/sql/custom_conf.h b/sql/custom_conf.h index 19ced12bfbb..137b7e9eef2 100644 --- a/sql/custom_conf.h +++ b/sql/custom_conf.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/derror.cc b/sql/derror.cc index bee818a14c1..0e74d411b1f 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/des_key_file.cc b/sql/des_key_file.cc index 77cb0c8de0f..d99d712b45a 100644 --- a/sql/des_key_file.cc +++ b/sql/des_key_file.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2001-2003, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/discover.cc b/sql/discover.cc index 938a05ff4a7..395bfbfff45 100644 --- a/sql/discover.cc +++ b/sql/discover.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index 6c37b6f1d29..54b043bd916 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_data_objects.h b/sql/event_data_objects.h index 2da39c2158b..e00b0b94eaf 100644 --- a/sql/event_data_objects.h +++ b/sql/event_data_objects.h @@ -4,8 +4,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 367c5bae579..bcc7d476fff 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_db_repository.h b/sql/event_db_repository.h index ed74edd7e19..1457fb64e2e 100644 --- a/sql/event_db_repository.h +++ b/sql/event_db_repository.h @@ -4,8 +4,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_queue.cc b/sql/event_queue.cc index 9f7c1c9a9b2..9a740114193 100644 --- a/sql/event_queue.cc +++ b/sql/event_queue.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_queue.h b/sql/event_queue.h index 5b70506d388..9f48da4914f 100644 --- a/sql/event_queue.h +++ b/sql/event_queue.h @@ -4,8 +4,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 1e9526b3364..a47576cf0c0 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/event_scheduler.h b/sql/event_scheduler.h index dffaf8c056c..18625ef35f3 100644 --- a/sql/event_scheduler.h +++ b/sql/event_scheduler.h @@ -4,8 +4,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/events.cc b/sql/events.cc index 3dbc6fd27e1..e6224915d6b 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/events.h b/sql/events.h index 79c4a419388..621ab0ffca5 100644 --- a/sql/events.h +++ b/sql/events.h @@ -4,8 +4,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/examples/CMakeLists.txt b/sql/examples/CMakeLists.txt index d3cc430ef40..1a22e9a3efd 100755 --- a/sql/examples/CMakeLists.txt +++ b/sql/examples/CMakeLists.txt @@ -1,3 +1,18 @@ +# Copyright (C) 2006 MySQL AB +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DSAFEMALLOC -DSAFE_MUTEX") diff --git a/sql/field.cc b/sql/field.cc index 4245d401f53..ef084367d32 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1609,10 +1608,11 @@ void Field_null::sql_type(String &res) const This is an number stored as a pre-space (or pre-zero) string ****************************************************************************/ -void +int Field_decimal::reset(void) { Field_decimal::store(STRING_WITH_LEN("0"),&my_charset_bin); + return 0; } void Field_decimal::overflow(bool negative) @@ -2257,9 +2257,10 @@ Field_new_decimal::Field_new_decimal(uint32 len_arg, } -void Field_new_decimal::reset(void) +int Field_new_decimal::reset(void) { store_value(&decimal_zero); + return 0; } @@ -8725,7 +8726,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP. */ if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) && - (fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP) + (fld_type_modifier & NOT_NULL_FLAG) && fld_type != MYSQL_TYPE_TIMESTAMP) flags|= NO_DEFAULT_VALUE_FLAG; if (fld_length && !(length= (uint) atoi(fld_length))) @@ -8733,34 +8734,34 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1; switch (fld_type) { - case FIELD_TYPE_TINY: + case MYSQL_TYPE_TINY: if (!fld_length) length= MAX_TINYINT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; - case FIELD_TYPE_SHORT: + case MYSQL_TYPE_SHORT: if (!fld_length) length= MAX_SMALLINT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; - case FIELD_TYPE_INT24: + case MYSQL_TYPE_INT24: if (!fld_length) length= MAX_MEDIUMINT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; - case FIELD_TYPE_LONG: + case MYSQL_TYPE_LONG: if (!fld_length) length= MAX_INT_WIDTH+sign_len; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; - case FIELD_TYPE_LONGLONG: + case MYSQL_TYPE_LONGLONG: if (!fld_length) length= MAX_BIGINT_WIDTH; allowed_type_modifier= AUTO_INCREMENT_FLAG; break; - case FIELD_TYPE_NULL: + case MYSQL_TYPE_NULL: break; - case FIELD_TYPE_NEWDECIMAL: + case MYSQL_TYPE_NEWDECIMAL: if (!fld_length && !decimals) length= 10; if (length > DECIMAL_MAX_PRECISION) @@ -8789,11 +8790,11 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, break; case MYSQL_TYPE_STRING: break; - case FIELD_TYPE_BLOB: - case FIELD_TYPE_TINY_BLOB: - case FIELD_TYPE_LONG_BLOB: - case FIELD_TYPE_MEDIUM_BLOB: - case FIELD_TYPE_GEOMETRY: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_GEOMETRY: if (fld_default_value) { /* Allow empty as default value. */ @@ -8825,12 +8826,12 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, } flags|= BLOB_FLAG; break; - case FIELD_TYPE_YEAR: + case MYSQL_TYPE_YEAR: if (!fld_length || length != 2) length= 4; /* Default length */ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; break; - case FIELD_TYPE_FLOAT: + case MYSQL_TYPE_FLOAT: /* change FLOAT(precision) to FLOAT or DOUBLE */ allowed_type_modifier= AUTO_INCREMENT_FLAG; if (fld_length && !fld_decimals) @@ -8843,7 +8844,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, } else if (tmp_length > PRECISION_FOR_FLOAT) { - sql_type= FIELD_TYPE_DOUBLE; + sql_type= MYSQL_TYPE_DOUBLE; length= DBL_DIG+7; /* -[digits].E+### */ } else @@ -8863,7 +8864,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, DBUG_RETURN(TRUE); } break; - case FIELD_TYPE_DOUBLE: + case MYSQL_TYPE_DOUBLE: allowed_type_modifier= AUTO_INCREMENT_FLAG; if (!fld_length && !fld_decimals) { @@ -8877,7 +8878,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, DBUG_RETURN(TRUE); } break; - case FIELD_TYPE_TIMESTAMP: + case MYSQL_TYPE_TIMESTAMP: if (!fld_length) length= 14; /* Full date YYYYMMDDHHMMSS */ else if (length != 19) @@ -8928,21 +8929,21 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, Field::NONE)); } break; - case FIELD_TYPE_DATE: + case MYSQL_TYPE_DATE: /* Old date type. */ if (protocol_version != PROTOCOL_VERSION-1) - sql_type= FIELD_TYPE_NEWDATE; + sql_type= MYSQL_TYPE_NEWDATE; /* fall trough */ - case FIELD_TYPE_NEWDATE: + case MYSQL_TYPE_NEWDATE: length= 10; break; - case FIELD_TYPE_TIME: + case MYSQL_TYPE_TIME: length= 10; break; - case FIELD_TYPE_DATETIME: + case MYSQL_TYPE_DATETIME: length= 19; break; - case FIELD_TYPE_SET: + case MYSQL_TYPE_SET: { if (fld_interval_list->elements > sizeof(longlong)*8) { @@ -8963,7 +8964,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, length= 1; break; } - case FIELD_TYPE_ENUM: + case MYSQL_TYPE_ENUM: { /* Should be safe. */ pack_length= get_enum_pack_length(fld_interval_list->elements); @@ -8972,7 +8973,7 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, String *tmp; while ((tmp= it++)) interval_list.push_back(tmp); - length= 1; /* See comment for FIELD_TYPE_SET above. */ + length= 1; /* See comment for MYSQL_TYPE_SET above. */ break; } case MYSQL_TYPE_VAR_STRING: @@ -8991,19 +8992,19 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, pack_length= (length + 7) / 8; break; } - case FIELD_TYPE_DECIMAL: + case MYSQL_TYPE_DECIMAL: DBUG_ASSERT(0); /* Was obsolete */ } /* Remember the value of length */ char_length= length; if (!(flags & BLOB_FLAG) && - ((length > max_field_charlength && fld_type != FIELD_TYPE_SET && - fld_type != FIELD_TYPE_ENUM && + ((length > max_field_charlength && fld_type != MYSQL_TYPE_SET && + fld_type != MYSQL_TYPE_ENUM && (fld_type != MYSQL_TYPE_VARCHAR || fld_default_value)) || (!length && fld_type != MYSQL_TYPE_STRING && - fld_type != MYSQL_TYPE_VARCHAR && fld_type != FIELD_TYPE_GEOMETRY))) + fld_type != MYSQL_TYPE_VARCHAR && fld_type != MYSQL_TYPE_GEOMETRY))) { my_error((fld_type == MYSQL_TYPE_VAR_STRING || fld_type == MYSQL_TYPE_VARCHAR || @@ -9028,13 +9029,13 @@ enum_field_types get_blob_type_from_length(ulong length) { enum_field_types type; if (length < 256) - type= FIELD_TYPE_TINY_BLOB; + type= MYSQL_TYPE_TINY_BLOB; else if (length < 65536) - type= FIELD_TYPE_BLOB; + type= MYSQL_TYPE_BLOB; else if (length < 256L*256L*256L) - type= FIELD_TYPE_MEDIUM_BLOB; + type= MYSQL_TYPE_MEDIUM_BLOB; else - type= FIELD_TYPE_LONG_BLOB; + type= MYSQL_TYPE_LONG_BLOB; return type; } @@ -9048,32 +9049,32 @@ uint32 calc_pack_length(enum_field_types type,uint32 length) switch (type) { case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: - case FIELD_TYPE_DECIMAL: return (length); + case MYSQL_TYPE_DECIMAL: return (length); case MYSQL_TYPE_VARCHAR: return (length + (length < 256 ? 1: 2)); - case FIELD_TYPE_YEAR: - case FIELD_TYPE_TINY : return 1; - case FIELD_TYPE_SHORT : return 2; - case FIELD_TYPE_INT24: - case FIELD_TYPE_NEWDATE: - case FIELD_TYPE_TIME: return 3; - case FIELD_TYPE_TIMESTAMP: - case FIELD_TYPE_DATE: - case FIELD_TYPE_LONG : return 4; - case FIELD_TYPE_FLOAT : return sizeof(float); - case FIELD_TYPE_DOUBLE: return sizeof(double); - case FIELD_TYPE_DATETIME: - case FIELD_TYPE_LONGLONG: return 8; /* Don't crash if no longlong */ - case FIELD_TYPE_NULL : return 0; - case FIELD_TYPE_TINY_BLOB: return 1+portable_sizeof_char_ptr; - case FIELD_TYPE_BLOB: return 2+portable_sizeof_char_ptr; - case FIELD_TYPE_MEDIUM_BLOB: return 3+portable_sizeof_char_ptr; - case FIELD_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr; - case FIELD_TYPE_GEOMETRY: return 4+portable_sizeof_char_ptr; - case FIELD_TYPE_SET: - case FIELD_TYPE_ENUM: - case FIELD_TYPE_NEWDECIMAL: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_TINY : return 1; + case MYSQL_TYPE_SHORT : return 2; + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_TIME: return 3; + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_LONG : return 4; + case MYSQL_TYPE_FLOAT : return sizeof(float); + case MYSQL_TYPE_DOUBLE: return sizeof(double); + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_LONGLONG: return 8; /* Don't crash if no longlong */ + case MYSQL_TYPE_NULL : return 0; + case MYSQL_TYPE_TINY_BLOB: return 1+portable_sizeof_char_ptr; + case MYSQL_TYPE_BLOB: return 2+portable_sizeof_char_ptr; + case MYSQL_TYPE_MEDIUM_BLOB: return 3+portable_sizeof_char_ptr; + case MYSQL_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr; + case MYSQL_TYPE_GEOMETRY: return 4+portable_sizeof_char_ptr; + case MYSQL_TYPE_SET: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_NEWDECIMAL: abort(); return 0; // This shouldn't happen - case FIELD_TYPE_BIT: return length / 8; + case MYSQL_TYPE_BIT: return length / 8; default: return 0; } @@ -9083,11 +9084,11 @@ uint32 calc_pack_length(enum_field_types type,uint32 length) uint pack_length_to_packflag(uint type) { switch (type) { - case 1: return f_settype((uint) FIELD_TYPE_TINY); - case 2: return f_settype((uint) FIELD_TYPE_SHORT); - case 3: return f_settype((uint) FIELD_TYPE_INT24); - case 4: return f_settype((uint) FIELD_TYPE_LONG); - case 8: return f_settype((uint) FIELD_TYPE_LONGLONG); + case 1: return f_settype((uint) MYSQL_TYPE_TINY); + case 2: return f_settype((uint) MYSQL_TYPE_SHORT); + case 3: return f_settype((uint) MYSQL_TYPE_INT24); + case 4: return f_settype((uint) MYSQL_TYPE_LONG); + case 8: return f_settype((uint) MYSQL_TYPE_LONGLONG); } return 0; // This shouldn't happen } @@ -9107,7 +9108,7 @@ Field *make_field(TABLE_SHARE *share, char *ptr, uint32 field_length, uchar bit_offset; LINT_INIT(bit_ptr); LINT_INIT(bit_offset); - if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag)) + if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) { bit_ptr= null_pos; bit_offset= null_bit; @@ -9129,11 +9130,11 @@ Field *make_field(TABLE_SHARE *share, char *ptr, uint32 field_length, } switch (field_type) { - case FIELD_TYPE_DATE: - case FIELD_TYPE_NEWDATE: - case FIELD_TYPE_TIME: - case FIELD_TYPE_DATETIME: - case FIELD_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_TIMESTAMP: field_charset= &my_charset_bin; default: break; } @@ -9143,7 +9144,7 @@ Field *make_field(TABLE_SHARE *share, char *ptr, uint32 field_length, if (!f_is_packed(pack_flag)) { if (field_type == MYSQL_TYPE_STRING || - field_type == FIELD_TYPE_DECIMAL || // 3.23 or 4.0 string + field_type == MYSQL_TYPE_DECIMAL || // 3.23 or 4.0 string field_type == MYSQL_TYPE_VAR_STRING) return new Field_string(ptr,field_length,null_pos,null_bit, unireg_check, field_name, @@ -9186,78 +9187,78 @@ Field *make_field(TABLE_SHARE *share, char *ptr, uint32 field_length, } switch (field_type) { - case FIELD_TYPE_DECIMAL: + case MYSQL_TYPE_DECIMAL: return new Field_decimal(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_decimals(pack_flag), f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); - case FIELD_TYPE_NEWDECIMAL: + case MYSQL_TYPE_NEWDECIMAL: return new Field_new_decimal(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_decimals(pack_flag), f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); - case FIELD_TYPE_FLOAT: + case MYSQL_TYPE_FLOAT: return new Field_float(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_decimals(pack_flag), f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag)== 0); - case FIELD_TYPE_DOUBLE: + case MYSQL_TYPE_DOUBLE: return new Field_double(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_decimals(pack_flag), f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag)== 0); - case FIELD_TYPE_TINY: + case MYSQL_TYPE_TINY: return new Field_tiny(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); - case FIELD_TYPE_SHORT: + case MYSQL_TYPE_SHORT: return new Field_short(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); - case FIELD_TYPE_INT24: + case MYSQL_TYPE_INT24: return new Field_medium(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); - case FIELD_TYPE_LONG: + case MYSQL_TYPE_LONG: return new Field_long(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); - case FIELD_TYPE_LONGLONG: + case MYSQL_TYPE_LONGLONG: return new Field_longlong(ptr,field_length,null_pos,null_bit, unireg_check, field_name, f_is_zerofill(pack_flag) != 0, f_is_dec(pack_flag) == 0); - case FIELD_TYPE_TIMESTAMP: + case MYSQL_TYPE_TIMESTAMP: return new Field_timestamp(ptr,field_length, null_pos, null_bit, unireg_check, field_name, share, field_charset); - case FIELD_TYPE_YEAR: + case MYSQL_TYPE_YEAR: return new Field_year(ptr,field_length,null_pos,null_bit, unireg_check, field_name); - case FIELD_TYPE_DATE: + case MYSQL_TYPE_DATE: return new Field_date(ptr,null_pos,null_bit, unireg_check, field_name, field_charset); - case FIELD_TYPE_NEWDATE: + case MYSQL_TYPE_NEWDATE: return new Field_newdate(ptr,null_pos,null_bit, unireg_check, field_name, field_charset); - case FIELD_TYPE_TIME: + case MYSQL_TYPE_TIME: return new Field_time(ptr,null_pos,null_bit, unireg_check, field_name, field_charset); - case FIELD_TYPE_DATETIME: + case MYSQL_TYPE_DATETIME: return new Field_datetime(ptr,null_pos,null_bit, unireg_check, field_name, field_charset); - case FIELD_TYPE_NULL: + case MYSQL_TYPE_NULL: return new Field_null(ptr, field_length, unireg_check, field_name, field_charset); - case FIELD_TYPE_BIT: + case MYSQL_TYPE_BIT: return f_bit_as_char(pack_flag) ? new Field_bit_as_char(ptr, field_length, null_pos, null_bit, unireg_check, field_name) : @@ -9293,12 +9294,12 @@ create_field::create_field(Field *old_field,Field *orig_field) portable_sizeof_char_ptr); switch (sql_type) { - case FIELD_TYPE_BLOB: + case MYSQL_TYPE_BLOB: switch (pack_length - portable_sizeof_char_ptr) { - case 1: sql_type= FIELD_TYPE_TINY_BLOB; break; - case 2: sql_type= FIELD_TYPE_BLOB; break; - case 3: sql_type= FIELD_TYPE_MEDIUM_BLOB; break; - default: sql_type= FIELD_TYPE_LONG_BLOB; break; + case 1: sql_type= MYSQL_TYPE_TINY_BLOB; break; + case 2: sql_type= MYSQL_TYPE_BLOB; break; + case 3: sql_type= MYSQL_TYPE_MEDIUM_BLOB; break; + default: sql_type= MYSQL_TYPE_LONG_BLOB; break; } length/= charset->mbmaxlen; key_length/= charset->mbmaxlen; @@ -9317,7 +9318,7 @@ create_field::create_field(Field *old_field,Field *orig_field) length= (length+charset->mbmaxlen-1) / charset->mbmaxlen; break; #ifdef HAVE_SPATIAL - case FIELD_TYPE_GEOMETRY: + case MYSQL_TYPE_GEOMETRY: geom_type= ((Field_geom*)old_field)->geom_type; break; #endif @@ -9334,7 +9335,7 @@ create_field::create_field(Field *old_field,Field *orig_field) if (!(flags & (NO_DEFAULT_VALUE_FLAG | BLOB_FLAG)) && old_field->ptr && orig_field && - (sql_type != FIELD_TYPE_TIMESTAMP || /* set def only if */ + (sql_type != MYSQL_TYPE_TIMESTAMP || /* set def only if */ old_field->table->timestamp_field != old_field || /* timestamp field */ unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */ { diff --git a/sql/field.h b/sql/field.h index 3e2be248627..bf68c37aec3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -155,7 +154,7 @@ public: */ virtual uint32 data_length() { return pack_length(); } virtual uint32 sort_length() const { return pack_length(); } - virtual void reset(void) { bzero(ptr,pack_length()); } + virtual int reset(void) { bzero(ptr,pack_length()); return 0; } virtual void reset_fields() {} virtual void set_default() { @@ -518,13 +517,13 @@ public: unireg_check_arg, field_name_arg, dec_arg, zero_arg, unsigned_arg) {} - enum_field_types type() const { return FIELD_TYPE_DECIMAL;} + enum_field_types type() const { return MYSQL_TYPE_DECIMAL;} enum ha_base_keytype key_type() const { return zerofill ? HA_KEYTYPE_BINARY : HA_KEYTYPE_NUM; } - void reset(void); - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); + int reset(void); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -556,10 +555,10 @@ public: Field_new_decimal(uint32 len_arg, bool maybe_null_arg, const char *field_name_arg, uint8 dec_arg, bool unsigned_arg); - enum_field_types type() const { return FIELD_TYPE_NEWDECIMAL;} + enum_field_types type() const { return MYSQL_TYPE_NEWDECIMAL;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_BINARY; } Item_result result_type () const { return DECIMAL_RESULT; } - void reset(void); + int reset(void); bool store_value(const my_decimal *decimal_value); void set_value_on_overflow(my_decimal *decimal_value, bool sign); int store(const char *to, uint length, CHARSET_INFO *charset); @@ -593,13 +592,13 @@ public: 0, zero_arg,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_TINY;} + enum_field_types type() const { return MYSQL_TYPE_TINY;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_BINARY : HA_KEYTYPE_INT8; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); + int reset(void) { ptr[0]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -628,13 +627,13 @@ public: NONE, field_name_arg, 0, 0, unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_SHORT;} + enum_field_types type() const { return MYSQL_TYPE_SHORT;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_USHORT_INT : HA_KEYTYPE_SHORT_INT;} - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=ptr[1]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); + int reset(void) { ptr[0]=ptr[1]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -658,13 +657,13 @@ public: 0, zero_arg,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_INT24;} + enum_field_types type() const { return MYSQL_TYPE_INT24;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_UINT24 : HA_KEYTYPE_INT24; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } + int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -693,13 +692,13 @@ public: NONE, field_name_arg,0,0,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_LONG;} + enum_field_types type() const { return MYSQL_TYPE_LONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONG_INT : HA_KEYTYPE_LONG_INT; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); + int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; } double val_real(void); longlong val_int(void); bool send_binary(Protocol *protocol); @@ -730,13 +729,17 @@ public: NONE, field_name_arg,0,0,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } - enum_field_types type() const { return FIELD_TYPE_LONGLONG;} + enum_field_types type() const { return MYSQL_TYPE_LONGLONG;} enum ha_base_keytype key_type() const { return unsigned_flag ? HA_KEYTYPE_ULONGLONG : HA_KEYTYPE_LONGLONG; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); + int reset(void) + { + ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; + return 0; + } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -766,12 +769,12 @@ public: :Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0, NONE, field_name_arg, dec_arg, 0, 0) {} - enum_field_types type() const { return FIELD_TYPE_FLOAT;} + enum_field_types type() const { return MYSQL_TYPE_FLOAT;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_FLOAT; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); - void reset(void) { bzero(ptr,sizeof(float)); } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); + int reset(void) { bzero(ptr,sizeof(float)); return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -799,12 +802,12 @@ public: :Field_real((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0, (uint) 0, NONE, field_name_arg, dec_arg, 0, 0) {} - enum_field_types type() const { return FIELD_TYPE_DOUBLE;} + enum_field_types type() const { return MYSQL_TYPE_DOUBLE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_DOUBLE; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); - void reset(void) { bzero(ptr,sizeof(double)); } + int reset(void) { bzero(ptr,sizeof(double)); return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -828,13 +831,13 @@ public: :Field_str(ptr_arg, len_arg, null, 1, unireg_check_arg, field_name_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_NULL;} + enum_field_types type() const { return MYSQL_TYPE_NULL;} int store(const char *to, uint length, CHARSET_INFO *cs) { null[0]=1; return 0; } - int store(double nr) { null[0]=1; return 0; } - int store(longlong nr, bool unsigned_val) { null[0]=1; return 0; } - int store_decimal(const my_decimal *d) { null[0]=1; return 0; } - void reset(void) {} + int store(double nr) { null[0]=1; return 0; } + int store(longlong nr, bool unsigned_val) { null[0]=1; return 0; } + int store_decimal(const my_decimal *d) { null[0]=1; return 0; } + int reset(void) { return 0; } double val_real(void) { return 0.0;} longlong val_int(void) { return 0;} my_decimal *val_decimal(my_decimal *) { return 0; } @@ -857,13 +860,13 @@ public: TABLE_SHARE *share, CHARSET_INFO *cs); Field_timestamp(bool maybe_null_arg, const char *field_name_arg, CHARSET_INFO *cs); - enum_field_types type() const { return FIELD_TYPE_TIMESTAMP;} + enum_field_types type() const { return MYSQL_TYPE_TIMESTAMP;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } + int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -910,7 +913,7 @@ public: :Field_tiny(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, 1, 1) {} - enum_field_types type() const { return FIELD_TYPE_YEAR;} + enum_field_types type() const { return MYSQL_TYPE_YEAR;} int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); @@ -935,13 +938,13 @@ public: CHARSET_INFO *cs) :Field_str((char*) 0,10, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_DATE;} + enum_field_types type() const { return MYSQL_TYPE_DATE;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONG_INT; } enum Item_result cmp_type () const { return INT_RESULT; } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); + int reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -963,15 +966,15 @@ public: :Field_str(ptr_arg, 10, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_DATE;} - enum_field_types real_type() const { return FIELD_TYPE_NEWDATE; } + enum_field_types type() const { return MYSQL_TYPE_DATE;} + enum_field_types real_type() const { return MYSQL_TYPE_NEWDATE; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_UINT24; } enum Item_result cmp_type () const { return INT_RESULT; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); int store_time(TIME *ltime, timestamp_type type); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } + int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -999,14 +1002,14 @@ public: CHARSET_INFO *cs) :Field_str((char*) 0,8, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_TIME;} + enum_field_types type() const { return MYSQL_TYPE_TIME;} enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum Item_result cmp_type () const { return INT_RESULT; } int store_time(TIME *ltime, timestamp_type type); - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); - int store(longlong nr, bool unsigned_val); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(double nr); + int store(longlong nr, bool unsigned_val); + int reset(void) { ptr[0]=ptr[1]=ptr[2]=0; return 0; } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -1034,7 +1037,7 @@ public: CHARSET_INFO *cs) :Field_str((char*) 0,19, maybe_null_arg ? (uchar*) "": 0,0, NONE, field_name_arg, cs) {} - enum_field_types type() const { return FIELD_TYPE_DATETIME;} + enum_field_types type() const { return MYSQL_TYPE_DATETIME;} #ifdef HAVE_LONG_LONG enum ha_base_keytype key_type() const { return HA_KEYTYPE_ULONGLONG; } #endif @@ -1044,7 +1047,11 @@ public: int store(double nr); int store(longlong nr, bool unsigned_val); int store_time(TIME *ltime, timestamp_type type); - void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; } + int reset(void) + { + ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; + return 0; + } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -1087,9 +1094,13 @@ public: enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; } bool zero_pack() const { return 0; } - void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); } - int store(const char *to,uint length,CHARSET_INFO *charset); - int store(longlong nr, bool unsigned_val); + int reset(void) + { + charset()->cset->fill(charset(),ptr,field_length,' '); + return 0; + } + int store(const char *to,uint length,CHARSET_INFO *charset); + int store(longlong nr, bool unsigned_val); int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */ double val_real(void); longlong val_int(void); @@ -1106,7 +1117,7 @@ public: uint packed_col_length(const char *to, uint length); uint max_packed_col_length(uint max_length); uint size_of() const { return sizeof(*this); } - enum_field_types real_type() const { return FIELD_TYPE_STRING; } + enum_field_types real_type() const { return MYSQL_TYPE_STRING; } bool has_charset(void) const { return charset() == &my_charset_bin ? FALSE : TRUE; } Field *new_field(MEM_ROOT *root, struct st_table *new_table, bool keep_type); @@ -1141,7 +1152,7 @@ public: enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } enum ha_base_keytype key_type() const; bool zero_pack() const { return 0; } - void reset(void) { bzero(ptr,field_length+length_bytes); } + int reset(void) { bzero(ptr,field_length+length_bytes); return 0; } uint32 pack_length() const { return (uint32) field_length+length_bytes; } uint32 key_length() const { return (uint32) field_length; } uint32 sort_length() const @@ -1223,7 +1234,7 @@ public: char_length <= 16777215 ? 3 : 4; } } - enum_field_types type() const { return FIELD_TYPE_BLOB;} + enum_field_types type() const { return MYSQL_TYPE_BLOB;} enum ha_base_keytype key_type() const { return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; } int store(const char *to,uint length,CHARSET_INFO *charset); @@ -1249,7 +1260,7 @@ public: { return (uint32) (((ulonglong) 1 << (packlength*8)) -1); } - void reset(void) { bzero(ptr, packlength+sizeof(char*)); } + int reset(void) { bzero(ptr, packlength+sizeof(char*)); return 0; } void reset_fields() { bzero((char*) &value,sizeof(value)); } void store_length(uint32 number); inline uint32 get_length(uint row_offset=0) @@ -1325,7 +1336,7 @@ public: :Field_blob(len_arg, maybe_null_arg, field_name_arg, &my_charset_bin) { geom_type= geom_type_arg; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; } - enum_field_types type() const { return FIELD_TYPE_GEOMETRY; } + enum_field_types type() const { return MYSQL_TYPE_GEOMETRY; } void sql_type(String &str) const; int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); @@ -1333,6 +1344,7 @@ public: int store_decimal(const my_decimal *); void get_key_image(char *buff,uint length,imagetype type); uint size_of() const { return sizeof(*this); } + int reset(void) { return !maybe_null(); } }; #endif /*HAVE_SPATIAL*/ @@ -1354,7 +1366,7 @@ public: { flags|=ENUM_FLAG; } - enum_field_types type() const { return FIELD_TYPE_STRING; } + enum_field_types type() const { return MYSQL_TYPE_STRING; } enum Item_result cmp_type () const { return INT_RESULT; } enum Item_result cast_to_int_type () const { return INT_RESULT; } enum ha_base_keytype key_type() const; @@ -1370,7 +1382,7 @@ public: void store_type(ulonglong value); void sql_type(String &str) const; uint size_of() const { return sizeof(*this); } - enum_field_types real_type() const { return FIELD_TYPE_ENUM; } + enum_field_types real_type() const { return MYSQL_TYPE_ENUM; } virtual bool zero_pack() const { return 0; } bool optimize_range(uint idx, uint part) { return 0; } bool eq_def(Field *field); @@ -1400,7 +1412,7 @@ public: virtual bool zero_pack() const { return 1; } String *val_str(String*,String *); void sql_type(String &str) const; - enum_field_types real_type() const { return FIELD_TYPE_SET; } + enum_field_types real_type() const { return MYSQL_TYPE_SET; } bool has_charset(void) const { return TRUE; } }; @@ -1428,13 +1440,13 @@ public: Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg, enum utype unireg_check_arg, const char *field_name_arg); - enum_field_types type() const { return FIELD_TYPE_BIT; } + enum_field_types type() const { return MYSQL_TYPE_BIT; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; } uint32 key_length() const { return (uint32) (field_length + 7) / 8; } uint32 max_length() { return field_length; } uint size_of() const { return sizeof(*this); } Item_result result_type () const { return INT_RESULT; } - void reset(void) { bzero(ptr, bytes_in_rec); } + int reset(void) { bzero(ptr, bytes_in_rec); return 0; } int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 5fde5ecb2e8..2670de0387b 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -165,7 +164,7 @@ set_field_to_null_with_conversions(Field *field, bool no_conversions) when set to NULL (TIMESTAMP fields which allow setting to NULL are handled by first check). */ - if (field->type() == FIELD_TYPE_TIMESTAMP) + if (field->type() == MYSQL_TYPE_TIMESTAMP) { ((Field_timestamp*) field)->set_time(); return 0; // Ok to set time to NULL @@ -500,7 +499,7 @@ void Copy_field::set(char *to,Field *from) void Copy_field::set(Field *to,Field *from,bool save) { - if (to->type() == FIELD_TYPE_NULL) + if (to->type() == MYSQL_TYPE_NULL) { to_null_ptr=0; // For easy debugging to_ptr=0; @@ -534,7 +533,7 @@ void Copy_field::set(Field *to,Field *from,bool save) } else { - if (to_field->type() == FIELD_TYPE_TIMESTAMP) + if (to_field->type() == MYSQL_TYPE_TIMESTAMP) do_copy= do_copy_timestamp; // Automatic timestamp else if (to_field == to_field->table->next_number_field) do_copy= do_copy_next_number; @@ -578,8 +577,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) } else { - if (to->real_type() == FIELD_TYPE_BIT || - from->real_type() == FIELD_TYPE_BIT) + if (to->real_type() == MYSQL_TYPE_BIT || + from->real_type() == MYSQL_TYPE_BIT) return do_field_int; // Check if identical fields if (from->result_type() == STRING_RESULT) @@ -601,17 +600,17 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) !compatible_db_low_byte_first || ((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && - to->type() == FIELD_TYPE_DATE || - to->type() == FIELD_TYPE_DATETIME)) + to->type() == MYSQL_TYPE_DATE || + to->type() == MYSQL_TYPE_DATETIME)) { - if (from->real_type() == FIELD_TYPE_ENUM || - from->real_type() == FIELD_TYPE_SET) + if (from->real_type() == MYSQL_TYPE_ENUM || + from->real_type() == MYSQL_TYPE_SET) if (to->result_type() != STRING_RESULT) return do_field_int; // Convert SET to number return do_field_string; } - if (to->real_type() == FIELD_TYPE_ENUM || - to->real_type() == FIELD_TYPE_SET) + if (to->real_type() == MYSQL_TYPE_ENUM || + to->real_type() == MYSQL_TYPE_SET) { if (!to->eq_def(from)) return do_field_string; @@ -644,7 +643,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) to_length != from_length || !compatible_db_low_byte_first) { - if (to->real_type() == FIELD_TYPE_DECIMAL || + if (to->real_type() == MYSQL_TYPE_DECIMAL || to->result_type() == STRING_RESULT) return do_field_string; if (to->result_type() == INT_RESULT) @@ -655,7 +654,7 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) { if (!to->eq_def(from) || !compatible_db_low_byte_first) { - if (to->real_type() == FIELD_TYPE_DECIMAL) + if (to->real_type() == MYSQL_TYPE_DECIMAL) return do_field_string; if (to->result_type() == INT_RESULT) return do_field_int; @@ -682,22 +681,22 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*) void field_conv(Field *to,Field *from) { if (to->real_type() == from->real_type() && - !(to->type() == FIELD_TYPE_BLOB && to->table->copy_blobs)) + !(to->type() == MYSQL_TYPE_BLOB && to->table->copy_blobs)) { if (to->pack_length() == from->pack_length() && !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && - to->real_type() != FIELD_TYPE_ENUM && - to->real_type() != FIELD_TYPE_SET && - to->real_type() != FIELD_TYPE_BIT && - (to->real_type() != FIELD_TYPE_NEWDECIMAL || + to->real_type() != MYSQL_TYPE_ENUM && + to->real_type() != MYSQL_TYPE_SET && + to->real_type() != MYSQL_TYPE_BIT && + (to->real_type() != MYSQL_TYPE_NEWDECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) && from->charset() == to->charset() && to->table->s->db_low_byte_first == from->table->s->db_low_byte_first && (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || - to->type() != FIELD_TYPE_DATE && - to->type() != FIELD_TYPE_DATETIME) && + to->type() != MYSQL_TYPE_DATE && + to->type() != MYSQL_TYPE_DATETIME) && (from->real_type() != MYSQL_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes)) @@ -710,7 +709,7 @@ void field_conv(Field *to,Field *from) return; } } - if (to->type() == FIELD_TYPE_BLOB) + if (to->type() == MYSQL_TYPE_BLOB) { // Be sure the value is stored Field_blob *blob=(Field_blob*) to; from->val_str(&blob->value); @@ -728,9 +727,9 @@ void field_conv(Field *to,Field *from) } if ((from->result_type() == STRING_RESULT && (to->result_type() == STRING_RESULT || - (from->real_type() != FIELD_TYPE_ENUM && - from->real_type() != FIELD_TYPE_SET))) || - to->type() == FIELD_TYPE_DECIMAL) + (from->real_type() != MYSQL_TYPE_ENUM && + from->real_type() != MYSQL_TYPE_SET))) || + to->type() == MYSQL_TYPE_DECIMAL) { char buff[MAX_FIELD_WIDTH]; String result(buff,sizeof(buff),from->charset()); diff --git a/sql/filesort.cc b/sql/filesort.cc index 5f8153e64e7..46ef9c9a553 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/frm_crypt.cc b/sql/frm_crypt.cc index 8dd70900648..590205e83ab 100644 --- a/sql/frm_crypt.cc +++ b/sql/frm_crypt.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 2674b2e65f7..7abdb5f488c 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/gstream.cc b/sql/gstream.cc index 4083cb2fe71..46e12b6ef3b 100644 --- a/sql/gstream.cc +++ b/sql/gstream.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/gstream.h b/sql/gstream.h index bfbf28851ce..10274635413 100644 --- a/sql/gstream.h +++ b/sql/gstream.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 0362b8bf215..5614cc3ecd8 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -134,7 +133,6 @@ static uint ndbcluster_alter_table_flags(uint flags) } static int ndbcluster_inited= 0; -int ndbcluster_util_inited= 0; static Ndb* g_ndb= NULL; Ndb_cluster_connection* g_ndb_cluster_connection= NULL; @@ -158,6 +156,7 @@ static int ndb_get_table_statistics(ha_ndbcluster*, bool, Ndb*, const NDBTAB *, // Util thread variables pthread_t ndb_util_thread; +int ndb_util_thread_running= 0; pthread_mutex_t LOCK_ndb_util_thread; pthread_cond_t COND_ndb_util_thread; pthread_handler_t ndb_util_thread_func(void *arg); @@ -3478,8 +3477,9 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, { if (m_active_cursor && (error= close_scan())) DBUG_RETURN(error); - DBUG_RETURN(pk_read(start_key->key, start_key->length, buf, - part_spec.start_part)); + error= pk_read(start_key->key, start_key->length, buf, + part_spec.start_part); + DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error); } break; case UNIQUE_ORDERED_INDEX: @@ -3490,7 +3490,9 @@ int ha_ndbcluster::read_range_first_to_buf(const key_range *start_key, { if (m_active_cursor && (error= close_scan())) DBUG_RETURN(error); - DBUG_RETURN(unique_index_read(start_key->key, start_key->length, buf)); + + error= unique_index_read(start_key->key, start_key->length, buf); + DBUG_RETURN(error == HA_ERR_KEY_NOT_FOUND ? HA_ERR_END_OF_FILE : error); } else if (type == UNIQUE_INDEX) DBUG_RETURN(unique_index_scan(key_info, @@ -4804,7 +4806,7 @@ int ha_ndbcluster::create(const char *name, if ((my_errno= create_ndb_column(col, field, info))) DBUG_RETURN(my_errno); - if (info->store_on_disk || getenv("NDB_DEFAULT_DISK")) + if (info->storage_media == HA_SM_DISK || getenv("NDB_DEFAULT_DISK")) col.setStorageType(NdbDictionary::Column::StorageTypeDisk); else col.setStorageType(NdbDictionary::Column::StorageTypeMemory); @@ -4824,7 +4826,7 @@ int ha_ndbcluster::create(const char *name, NdbDictionary::Column::StorageTypeMemory); } - if (info->store_on_disk) + if (info->storage_media == HA_SM_DISK) { if (info->tablespace) tab.setTablespace(info->tablespace); @@ -4833,8 +4835,18 @@ int ha_ndbcluster::create(const char *name, } else if (info->tablespace) { + if (info->storage_media == HA_SM_MEMORY) + { + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_ILLEGAL_HA_CREATE_OPTION, + ER(ER_ILLEGAL_HA_CREATE_OPTION), + ndbcluster_hton_name, + "TABLESPACE currently only supported for " + "STORAGE DISK"); + DBUG_RETURN(HA_ERR_UNSUPPORTED); + } tab.setTablespace(info->tablespace); - info->store_on_disk = true; //if use tablespace, that also means store on disk + info->storage_media = HA_SM_DISK; //if use tablespace, that also means store on disk } // No primary key, create shadow key as 64 bit, auto increment @@ -6717,6 +6729,12 @@ static int ndbcluster_init(void *p) goto ndbcluster_init_error; } + /* Wait for the util thread to start */ + pthread_mutex_lock(&LOCK_ndb_util_thread); + while (!ndb_util_thread_running) + pthread_cond_wait(&COND_ndb_util_thread, &LOCK_ndb_util_thread); + pthread_mutex_unlock(&LOCK_ndb_util_thread); + ndbcluster_inited= 1; DBUG_RETURN(FALSE); @@ -6739,6 +6757,27 @@ static int ndbcluster_end(handlerton *hton, ha_panic_function type) if (!ndbcluster_inited) DBUG_RETURN(0); + ndbcluster_inited= 0; + + /* wait for util thread to finish */ + pthread_mutex_lock(&LOCK_ndb_util_thread); + if (ndb_util_thread_running > 0) + { + pthread_cond_signal(&COND_ndb_util_thread); + pthread_mutex_unlock(&LOCK_ndb_util_thread); + + pthread_mutex_lock(&LOCK_ndb_util_thread); + while (ndb_util_thread_running > 0) + { + struct timespec abstime; + set_timespec(abstime, 1); + pthread_cond_timedwait(&COND_ndb_util_thread, + &LOCK_ndb_util_thread, + &abstime); + } + } + pthread_mutex_unlock(&LOCK_ndb_util_thread); + #ifdef HAVE_NDB_BINLOG { @@ -6785,7 +6824,6 @@ static int ndbcluster_end(handlerton *hton, ha_panic_function type) pthread_mutex_destroy(&ndbcluster_mutex); pthread_mutex_destroy(&LOCK_ndb_util_thread); pthread_cond_destroy(&COND_ndb_util_thread); - ndbcluster_inited= 0; DBUG_RETURN(0); } @@ -7299,7 +7337,7 @@ static void print_share(const char* where, NDB_SHARE* share) fprintf(DBUG_FILE, "%s %s.%s: use_count: %u, commit_count: %llu\n", where, share->db, share->table_name, share->use_count, - share->commit_count); + (long long unsigned int) share->commit_count); fprintf(DBUG_FILE, " - key: %s, key_length: %d\n", share->key, share->key_length); @@ -8331,6 +8369,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) { thd->cleanup(); delete thd; + ndb_util_thread_running= 0; DBUG_RETURN(NULL); } thd->init_for_queries(); @@ -8343,6 +8382,9 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) thd->main_security_ctx.priv_user = 0; thd->current_stmt_binlog_row_based= TRUE; // If in mixed mode + ndb_util_thread_running= 1; + pthread_cond_signal(&COND_ndb_util_thread); + /* wait for mysql server to start */ @@ -8351,8 +8393,6 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) pthread_cond_wait(&COND_server_started, &LOCK_server_started); pthread_mutex_unlock(&LOCK_server_started); - ndbcluster_util_inited= 1; - /* Wait for cluster to start */ @@ -8534,6 +8574,9 @@ ndb_util_thread_end: net_end(&thd->net); thd->cleanup(); delete thd; + pthread_mutex_lock(&LOCK_ndb_util_thread); + ndb_util_thread_running= 0; + pthread_mutex_unlock(&LOCK_ndb_util_thread); DBUG_PRINT("exit", ("ndb_util_thread")); my_thread_end(); pthread_exit(0); @@ -9946,7 +9989,7 @@ int ha_ndbcluster::generate_scan_filter_from_key(NdbScanOperation *op, /* get table space info for SHOW CREATE TABLE */ -char* ha_ndbcluster::get_tablespace_name(THD *thd) +char* ha_ndbcluster::get_tablespace_name(THD *thd, char* name, uint name_len) { Ndb *ndb= check_ndb_in_thd(thd); NDBDICT *ndbdict= ndb->getDictionary(); @@ -9964,7 +10007,13 @@ char* ha_ndbcluster::get_tablespace_name(THD *thd) ndberr= ndbdict->getNdbError(); if(ndberr.classification != NdbError::NoError) goto err; - return (my_strdup(ts.getName(), MYF(0))); + if (name) + { + strxnmov(name, name_len, ts.getName(), NullS); + return name; + } + else + return (my_strdup(ts.getName(), MYF(0))); } err: if (ndberr.status == NdbError::TemporaryError) diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index ed9e5ea41cc..50f24c7a4cf 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -824,7 +823,7 @@ private: uint set_up_partition_info(partition_info *part_info, TABLE *table, void *tab); - char* get_tablespace_name(THD *thd); + char* get_tablespace_name(THD *thd, char *name, uint name_len); int set_range_data(void *tab, partition_info* part_info); int set_list_data(void *tab, partition_info* part_info); int complemented_read(const byte *old_data, byte *new_data, diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 490114bf4a9..38b640d5f55 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -81,6 +80,8 @@ THD *injector_thd= 0; static Ndb *injector_ndb= 0; static Ndb *schema_ndb= 0; +static int ndbcluster_binlog_inited= 0; + /* Mutex and condition used for interacting between client sql thread and injector thread @@ -558,29 +559,28 @@ ndbcluster_binlog_log_query(handlerton *hton, THD *thd, enum_binlog_command binl DBUG_VOID_RETURN; } + /* - End use of the NDB Cluster table handler - - free all global variables allocated by - ndbcluster_init() + End use of the NDB Cluster binlog + - wait for binlog thread to shutdown */ static int ndbcluster_binlog_end(THD *thd) { - DBUG_ENTER("ndb_binlog_end"); + DBUG_ENTER("ndbcluster_binlog_end"); - if (!ndbcluster_util_inited) + if (!ndbcluster_binlog_inited) DBUG_RETURN(0); - - // Kill ndb utility thread - (void) pthread_mutex_lock(&LOCK_ndb_util_thread); - DBUG_PRINT("exit",("killing ndb util thread: %lx", ndb_util_thread)); - (void) pthread_cond_signal(&COND_ndb_util_thread); - (void) pthread_mutex_unlock(&LOCK_ndb_util_thread); + ndbcluster_binlog_inited= 0; #ifdef HAVE_NDB_BINLOG /* wait for injector thread to finish */ + pthread_mutex_lock(&injector_mutex); if (ndb_binlog_thread_running > 0) { + pthread_cond_signal(&injector_cond); + pthread_mutex_unlock(&injector_mutex); + pthread_mutex_lock(&injector_mutex); while (ndb_binlog_thread_running > 0) { @@ -588,8 +588,9 @@ static int ndbcluster_binlog_end(THD *thd) set_timespec(abstime, 1); pthread_cond_timedwait(&injector_cond, &injector_mutex, &abstime); } - pthread_mutex_unlock(&injector_mutex); } + pthread_mutex_unlock(&injector_mutex); + /* remove all shares */ { @@ -617,8 +618,10 @@ static int ndbcluster_binlog_end(THD *thd) } pthread_mutex_unlock(&ndbcluster_mutex); } + + pthread_mutex_destroy(&injector_mutex); + pthread_cond_destroy(&injector_cond); #endif - ndbcluster_util_inited= 0; DBUG_RETURN(0); } @@ -2286,31 +2289,21 @@ int ndbcluster_binlog_start() DBUG_RETURN(-1); } - /* - Wait for the ndb injector thread to finish starting up. - */ + ndbcluster_binlog_inited= 1; + + /* Wait for the injector thread to start */ pthread_mutex_lock(&injector_mutex); while (!ndb_binlog_thread_running) pthread_cond_wait(&injector_cond, &injector_mutex); pthread_mutex_unlock(&injector_mutex); - + if (ndb_binlog_thread_running < 0) DBUG_RETURN(-1); + DBUG_RETURN(0); } -static void ndbcluster_binlog_close_connection(THD *thd) -{ - DBUG_ENTER("ndbcluster_binlog_close_connection"); - const char *save_info= thd->proc_info; - thd->proc_info= "ndbcluster_binlog_close_connection"; - do_ndbcluster_binlog_close_connection= BCCC_exit; - while (ndb_binlog_thread_running > 0) - sleep(1); - thd->proc_info= save_info; - DBUG_VOID_RETURN; -} /************************************************************** Internal helper functions for creating/dropping ndb events @@ -3542,7 +3535,7 @@ restart: if (abort_loop) goto err; schema_res= s_ndb->pollEvents(100, &schema_gci); - } while (ndb_latest_received_binlog_epoch == schema_gci); + } while (schema_gci == 0 || ndb_latest_received_binlog_epoch == schema_gci); if (ndb_binlog_running) { Uint64 gci= i_ndb->getLatestGCI(); @@ -3953,15 +3946,12 @@ restart: goto restart; } err: + sql_print_information("Stopping Cluster Binlog"); DBUG_PRINT("info",("Shutting down cluster binlog thread")); thd->proc_info= "Shutting down"; close_thread_tables(thd); pthread_mutex_lock(&injector_mutex); /* don't mess with the injector_ndb anymore from other threads */ - uint ndb_obj_cnt= 1; // g_ndb - ndb_obj_cnt+= injector_ndb == 0 ? 0 : 1; - ndb_obj_cnt+= schema_ndb == 0 ? 0 : 1; - ndb_obj_cnt+= ndbcluster_util_inited ? 1 : 0; injector_thd= 0; injector_ndb= 0; p_latest_trans_gci= 0; @@ -3969,29 +3959,6 @@ err: pthread_mutex_unlock(&injector_mutex); thd->db= 0; // as not to try to free memory - if (!ndb_extra_logging) - sql_print_information("Stopping Cluster Binlog"); - else - sql_print_information("Stopping Cluster Binlog: %u(%u)", - g_ndb_cluster_connection->get_active_ndb_objects(), - ndb_obj_cnt); - - /** - * Add extra wait loop to make user "user" ndb-object go away... - * otherwise user thread can have ongoing SUB_DATA - */ - int sleep_cnt= 0; - while (sleep_cnt < 300 && - g_ndb_cluster_connection->get_active_ndb_objects() > ndb_obj_cnt) - { - my_sleep(10000); // 10ms - sleep_cnt++; - } - if (ndb_extra_logging) - sql_print_information("Stopping Cluster Binlog: waited %ums %u(%u)", - 10*sleep_cnt, g_ndb_cluster_connection->get_active_ndb_objects(), - ndb_obj_cnt); - if (ndb_apply_status_share) { free_share(&ndb_apply_status_share); @@ -4047,8 +4014,8 @@ err: hash_free(&ndb_schema_objects); - // Placed here to avoid a memory leak; TODO: check if needed net_end(&thd->net); + thd->cleanup(); delete thd; ndb_binlog_thread_running= -1; diff --git a/sql/ha_ndbcluster_binlog.h b/sql/ha_ndbcluster_binlog.h index 18b94bb8f2a..44183c6de9d 100644 --- a/sql/ha_ndbcluster_binlog.h +++ b/sql/ha_ndbcluster_binlog.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/ha_ndbcluster_tables.h b/sql/ha_ndbcluster_tables.h index 2b1bdbc2b89..9f7b9146d91 100644 --- a/sql/ha_ndbcluster_tables.h +++ b/sql/ha_ndbcluster_tables.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 7cd33dd5726..feb08f474b7 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 40af30bf08c..4fdf325fa06 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/handler.cc b/sql/handler.cc index 63b1cd07a85..3d47a6a2eaf 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -2291,7 +2290,7 @@ int handler::ha_check_for_upgrade(HA_CHECK_OPT *check_opt) if (!keypart->fieldnr) continue; Field *field= table->field[keypart->fieldnr-1]; - if (field->type() == FIELD_TYPE_BLOB) + if (field->type() == MYSQL_TYPE_BLOB) { if (check_opt->sql_flags & TT_FOR_UPGRADE) check_opt->flags= T_MEDIUM; @@ -2313,7 +2312,7 @@ int handler::check_old_types() /* check for bad DECIMAL field */ for (field= table->field; (*field); field++) { - if ((*field)->type() == FIELD_TYPE_NEWDECIMAL) + if ((*field)->type() == MYSQL_TYPE_NEWDECIMAL) { return HA_ADMIN_NEEDS_ALTER; } diff --git a/sql/handler.h b/sql/handler.h index f27912f4d1e..82970cc1ac6 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000,2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -764,7 +763,7 @@ typedef struct st_ha_create_information bool table_existed; /* 1 in create if table existed */ bool frm_only; /* 1 if no ha_create_table() */ bool varchar; /* 1 if table has a VARCHAR */ - bool store_on_disk; /* 1 if table stored on disk */ + enum ha_storage_media storage_media; /* DEFAULT, DISK or MEMORY */ } HA_CREATE_INFO; @@ -1410,7 +1409,7 @@ public: { return FALSE; } virtual char* get_foreign_key_create_info() { return(NULL);} /* gets foreign key create string from InnoDB */ - virtual char* get_tablespace_name(THD *thd) + virtual char* get_tablespace_name(THD *thd, char *name, uint name_len) { return(NULL);} /* gets tablespace name from handler */ /* used in ALTER TABLE; 1 if changing storage engine is allowed */ virtual bool can_switch_engines() { return 1; } diff --git a/sql/hash_filo.cc b/sql/hash_filo.cc index ec200768222..9303120e18a 100644 --- a/sql/hash_filo.cc +++ b/sql/hash_filo.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/hash_filo.h b/sql/hash_filo.h index fc48c3b1540..c25af67b572 100644 --- a/sql/hash_filo.h +++ b/sql/hash_filo.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/hostname.cc b/sql/hostname.cc index 52c4107372f..049220c6b6f 100644 --- a/sql/hostname.cc +++ b/sql/hostname.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/init.cc b/sql/init.cc index 9f975296cb6..e129f98547e 100644 --- a/sql/init.cc +++ b/sql/init.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item.cc b/sql/item.cc index e2ab28dd452..309fdcfa030 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -4092,11 +4091,11 @@ void Item::make_field(Send_field *tmp_field) enum_field_types Item::string_field_type() const { - enum_field_types type= FIELD_TYPE_VAR_STRING; + enum_field_types type= MYSQL_TYPE_VAR_STRING; if (max_length >= 16777216) - type= FIELD_TYPE_LONG_BLOB; + type= MYSQL_TYPE_LONG_BLOB; else if (max_length >= 65536) - type= FIELD_TYPE_MEDIUM_BLOB; + type= MYSQL_TYPE_MEDIUM_BLOB; return type; } @@ -4111,9 +4110,9 @@ enum_field_types Item::field_type() const { switch (result_type()) { case STRING_RESULT: return string_field_type(); - case INT_RESULT: return FIELD_TYPE_LONGLONG; - case DECIMAL_RESULT: return FIELD_TYPE_NEWDECIMAL; - case REAL_RESULT: return FIELD_TYPE_DOUBLE; + case INT_RESULT: return MYSQL_TYPE_LONGLONG; + case DECIMAL_RESULT: return MYSQL_TYPE_NEWDECIMAL; + case REAL_RESULT: return MYSQL_TYPE_DOUBLE; case ROW_RESULT: default: DBUG_ASSERT(0); diff --git a/sql/item.h b/sql/item.h index 3eacae1682c..8c97010389e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_buff.cc b/sql/item_buff.cc index 37f9ca7ce6c..c162b84f457 100644 --- a/sql/item_buff.cc +++ b/sql/item_buff.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b1b73a523be..d7942fe0800 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000-2003 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -797,7 +796,8 @@ bool Item_in_optimizer::fix_left(THD *thd, Item **ref) } not_null_tables_cache= args[0]->not_null_tables(); with_sum_func= args[0]->with_sum_func; - const_item_cache= args[0]->const_item(); + if ((const_item_cache= args[0]->const_item())) + cache->store(args[0]); return 0; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 51cf5667c95..3d02e73f6e4 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_create.cc b/sql/item_create.cc index 80b5e946ae7..b7656fc8c4f 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_create.h b/sql/item_create.h index c20e36af04f..985c4428d8f 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_func.cc b/sql/item_func.cc index 0f5faf93cc3..4e3d47dc414 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -2513,7 +2512,7 @@ void Item_func_find_in_set::fix_length_and_dec() if (args[0]->const_item() && args[1]->type() == FIELD_ITEM) { Field *field= ((Item_field*) args[1])->field; - if (field->real_type() == FIELD_TYPE_SET) + if (field->real_type() == MYSQL_TYPE_SET) { String *find=args[0]->val_str(&value); if (find) @@ -3403,7 +3402,11 @@ longlong Item_func_release_lock::val_int() } else { +#ifdef EMBEDDED_LIBRARY + if (ull->locked && pthread_equal(current_thd->real_id,ull->thread)) +#else if (ull->locked && pthread_equal(pthread_self(),ull->thread)) +#endif { result=1; // Release is ok item_user_lock_release(ull); @@ -3683,8 +3686,9 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry)); if (entry->value == pos) entry->value=0; - if (!(entry->value=(char*) my_realloc(entry->value, length, - MYF(MY_ALLOW_ZERO_PTR)))) + entry->value= (char*) my_realloc(entry->value, length, + MYF(MY_ALLOW_ZERO_PTR | MY_WME)); + if (!entry->value) return 1; } } diff --git a/sql/item_func.h b/sql/item_func.h index 9130ef0a0c4..6d8e0bec7a6 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc index ef71dc9b8b5..1b8c8d6a161 100644 --- a/sql/item_geofunc.cc +++ b/sql/item_geofunc.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2003-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_geofunc.h b/sql/item_geofunc.h index 42f11820869..5361a02aa83 100644 --- a/sql/item_geofunc.h +++ b/sql/item_geofunc.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_row.cc b/sql/item_row.cc index 6e71ae0d4db..956556ca783 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_row.h b/sql/item_row.h index 39913086e8d..503e48ca16b 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index e8c87893471..89a85a19f56 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1166,7 +1165,8 @@ String *Item_func_substr::val_str(String *str) /* if "unsigned_flag" is set, we have a *huge* positive number. */ /* Assumes that the maximum length of a String is < INT_MAX32. */ - if ((args[1]->unsigned_flag) || (start < INT_MIN32) || (start > INT_MAX32)) + if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) || + (args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32))) return &my_empty_string; start= ((start < 0) ? res->numchars() + start : start - 1); @@ -1811,8 +1811,13 @@ bool Item_func_current_user::fix_fields(THD *thd, Item **ref) if (Item_func_sysconst::fix_fields(thd, ref)) return TRUE; - Security_context *ctx= (context->security_ctx + Security_context *ctx= +#ifndef NO_EMBEDDED_ACCESS_CHECKS + (context->security_ctx ? context->security_ctx : thd->security_ctx); +#else + thd->security_ctx; +#endif /*NO_EMBEDDED_ACCESS_CHECKS*/ return init(ctx->priv_user, ctx->priv_host); } @@ -2272,25 +2277,23 @@ String *Item_func_repeat::val_str(String *str) uint length,tot_length; char *to; /* must be longlong to avoid truncation */ - longlong tmp_count= args[1]->val_int(); - long count= (long) tmp_count; + longlong count= args[1]->val_int(); String *res= args[0]->val_str(str); - /* Assumes that the maximum length of a String is < INT_MAX32. */ - /* Bounds check on count: If this is triggered, we will error. */ - if ((tmp_count > INT_MAX32) || args[1]->unsigned_flag) - count= INT_MAX32; - if (args[0]->null_value || args[1]->null_value) goto err; // string and/or delim are null null_value= 0; - if ((tmp_count <= 0) && !args[1]->unsigned_flag) // For nicer SQL code + if ((count <= 0) && !args[1]->unsigned_flag) // For nicer SQL code return &my_empty_string; + /* Assumes that the maximum length of a String is < INT_MAX32. */ + /* Bounds check on count: If this is triggered, we will error. */ + if ((ulonglong) count > INT_MAX32) + count= INT_MAX32; if (count == 1) // To avoid reallocs return res; length=res->length(); // Safe length check - if (length > current_thd->variables.max_allowed_packet/count) + if (length > current_thd->variables.max_allowed_packet / (uint) count) { push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_ALLOWED_PACKET_OVERFLOWED, @@ -2364,15 +2367,14 @@ String *Item_func_rpad::val_str(String *str) String *res= args[0]->val_str(str); String *rpad= args[2]->val_str(&rpad_str); + if (!res || args[1]->null_value || !rpad || + ((count < 0) && !args[1]->unsigned_flag)) + goto err; + null_value=0; /* Assumes that the maximum length of a String is < INT_MAX32. */ /* Set here so that rest of code sees out-of-bound value as such. */ - if ((count > INT_MAX32) || args[1]->unsigned_flag) + if ((ulonglong) count > INT_MAX32) count= INT_MAX32; - - if (!res || args[1]->null_value || !rpad || count < 0) - goto err; - null_value=0; - if (count <= (res_char_length= res->numchars())) { // String to pad is big enough res->length(res->charpos((int) count)); // Shorten result if longer @@ -2466,14 +2468,15 @@ String *Item_func_lpad::val_str(String *str) String *res= args[0]->val_str(&tmp_value); String *pad= args[2]->val_str(&lpad_str); + if (!res || args[1]->null_value || !pad || + ((count < 0) && !args[1]->unsigned_flag)) + goto err; + null_value=0; /* Assumes that the maximum length of a String is < INT_MAX32. */ /* Set here so that rest of code sees out-of-bound value as such. */ - if ((count > INT_MAX32) || args[1]->unsigned_flag) + if ((ulonglong) count > INT_MAX32) count= INT_MAX32; - if (!res || args[1]->null_value || !pad || count < 0) - goto err; - null_value=0; res_char_length= res->numchars(); if (count <= res_char_length) diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 3b171b5d50f..ae11e001551 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index da491b91143..0074e33cdea 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1674,7 +1673,7 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row) Item *sel_item; List_iterator_fast<Item> li(item_list); res_type= STRING_RESULT; - res_field_type= FIELD_TYPE_VAR_STRING; + res_field_type= MYSQL_TYPE_VAR_STRING; for (uint i= 0; (sel_item= li++); i++) { item->max_length= sel_item->max_length; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index c274b5ca31b..a5068ff20e0 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -323,7 +322,7 @@ public: result= res; item= si; res_type= STRING_RESULT; - res_field_type= FIELD_TYPE_VAR_STRING; + res_field_type= MYSQL_TYPE_VAR_STRING; maybe_null= 0; } virtual ~subselect_engine() {}; // to satisfy compiler diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 7ea13e61c23..624e3c74202 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_sum.h b/sql/item_sum.h index 33bd23602b2..fdc13a36874 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -804,7 +803,7 @@ protected: public: Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par), sum(0.0), sum_int(0), - hybrid_type(INT_RESULT), hybrid_field_type(FIELD_TYPE_LONGLONG), + hybrid_type(INT_RESULT), hybrid_field_type(MYSQL_TYPE_LONGLONG), cmp_sign(sign), used_table_cache(~(table_map) 0), was_values(TRUE) { collation.set(&my_charset_bin); } @@ -1187,7 +1186,7 @@ public: enum_field_types field_type() const { if (max_length/collation.collation->mbmaxlen > CONVERT_IF_BIGGER_TO_BLOB ) - return FIELD_TYPE_BLOB; + return MYSQL_TYPE_BLOB; else return MYSQL_TYPE_VARCHAR; } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index ff688e15307..8fb0549fb94 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1185,7 +1184,7 @@ longlong Item_func_unix_timestamp::val_int() if (args[0]->type() == FIELD_ITEM) { // Optimize timestamp field Field *field=((Item_field*) args[0])->field; - if (field->type() == FIELD_TYPE_TIMESTAMP) + if (field->type() == MYSQL_TYPE_TIMESTAMP) return ((Field_timestamp*) field)->get_timestamp(&null_value); } diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 360307a677f..e53826ce3df 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/item_xmlfunc.cc b/sql/item_xmlfunc.cc index 966bae43984..3da68cf43c2 100644 --- a/sql/item_xmlfunc.cc +++ b/sql/item_xmlfunc.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2005-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,8 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef __GNUC__ #pragma implementation diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h index 6fa33081373..9f2860ef403 100644 --- a/sql/item_xmlfunc.h +++ b/sql/item_xmlfunc.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/key.cc b/sql/key.cc index dceeab1c011..bd614b10a70 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/lex.h b/sql/lex.h index aff8149efd0..2bf0e08c825 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -229,6 +228,7 @@ static SYMBOL symbols[] = { { "HAVING", SYM(HAVING)}, { "HELP", SYM(HELP_SYM)}, { "HIGH_PRIORITY", SYM(HIGH_PRIORITY)}, + { "HOST", SYM(HOST_SYM)}, { "HOSTS", SYM(HOSTS_SYM)}, { "HOUR", SYM(HOUR_SYM)}, { "HOUR_MICROSECOND", SYM(HOUR_MICROSECOND_SYM)}, @@ -368,6 +368,7 @@ static SYMBOL symbols[] = { { "ONE_SHOT", SYM(ONE_SHOT_SYM)}, { "OPEN", SYM(OPEN_SYM)}, { "OPTIMIZE", SYM(OPTIMIZE)}, + { "OPTIONS", SYM(OPTIONS_SYM)}, { "OPTION", SYM(OPTION)}, { "OPTIONALLY", SYM(OPTIONALLY)}, { "OR", SYM(OR_SYM)}, @@ -375,6 +376,7 @@ static SYMBOL symbols[] = { { "OUT", SYM(OUT_SYM)}, { "OUTER", SYM(OUTER)}, { "OUTFILE", SYM(OUTFILE)}, + { "OWNER", SYM(OWNER_SYM)}, { "PACK_KEYS", SYM(PACK_KEYS_SYM)}, { "PARSER", SYM(PARSER_SYM)}, { "PARTIAL", SYM(PARTIAL)}, @@ -387,6 +389,7 @@ static SYMBOL symbols[] = { { "PLUGINS", SYM(PLUGINS_SYM)}, { "POINT", SYM(POINT_SYM)}, { "POLYGON", SYM(POLYGON)}, + { "PORT", SYM(PORT_SYM)}, { "PRECISION", SYM(PRECISION)}, { "PREPARE", SYM(PREPARE_SYM)}, { "PRESERVE", SYM(PRESERVE_SYM)}, @@ -456,6 +459,7 @@ static SYMBOL symbols[] = { { "SERIAL", SYM(SERIAL_SYM)}, { "SERIALIZABLE", SYM(SERIALIZABLE_SYM)}, { "SESSION", SYM(SESSION_SYM)}, + { "SERVER", SYM(SERVER_SYM)}, { "SET", SYM(SET)}, { "SHARE", SYM(SHARE_SYM)}, { "SHOW", SYM(SHOW)}, @@ -465,6 +469,7 @@ static SYMBOL symbols[] = { { "SLAVE", SYM(SLAVE)}, { "SNAPSHOT", SYM(SNAPSHOT_SYM)}, { "SMALLINT", SYM(SMALLINT)}, + { "SOCKET", SYM(SOCKET_SYM)}, { "SOME", SYM(ANY_SYM)}, { "SONAME", SYM(SONAME_SYM)}, { "SOUNDS", SYM(SOUNDS_SYM)}, @@ -569,6 +574,7 @@ static SYMBOL symbols[] = { { "VIEW", SYM(VIEW_SYM)}, { "WITH", SYM(WITH)}, { "WORK", SYM(WORK_SYM)}, + { "WRAPPER", SYM(WRAPPER_SYM)}, { "WRITE", SYM(WRITE_SYM)}, { "X509", SYM(X509_SYM)}, { "XOR", SYM(XOR)}, diff --git a/sql/lex_symbol.h b/sql/lex_symbol.h index 5ba785d16f3..000c0709071 100644 --- a/sql/lex_symbol.h +++ b/sql/lex_symbol.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/lock.cc b/sql/lock.cc index be267f8d160..533307c6b85 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/log.cc b/sql/log.cc index 5a6130057ff..150c4a58c63 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/log.h b/sql/log.h index f481d3448e0..13795f30647 100644 --- a/sql/log.h +++ b/sql/log.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/log_event.cc b/sql/log_event.cc index 44cba324a02..d93845603fd 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -5558,8 +5557,8 @@ unpack_row(RELAY_LOG_INFO *rli, if (bitmap_is_set(cols, field_ptr - begin_ptr)) { - DBUG_ASSERT(table->record[0] <= f->ptr); - DBUG_ASSERT(f->ptr < (table->record[0] + table->s->reclength + + DBUG_ASSERT((const char *)table->record[0] <= f->ptr); + DBUG_ASSERT(f->ptr < ((const char *)table->record[0] + table->s->reclength + (f->pack_length_in_rec() == 0))); DBUG_PRINT("info", ("unpacking column '%s' to 0x%lx", f->field_name, @@ -6581,7 +6580,7 @@ copy_extra_record_fields(TABLE *table, /* Nothing to do */ break; - case FIELD_TYPE_BIT: + case MYSQL_TYPE_BIT: Field_bit *f= static_cast<Field_bit*>(*field_ptr); my_ptrdiff_t const offset= table->record[1] - table->record[0]; uchar const bits= @@ -6843,8 +6842,8 @@ static int find_and_fetch_row(TABLE *table, byte *key) trigger false warnings. */ #ifndef HAVE_purify - DBUG_DUMP("table->record[0]", table->record[0], table->s->reclength); - DBUG_DUMP("table->record[1]", table->record[1], table->s->reclength); + DBUG_DUMP("table->record[0]", (const char *)table->record[0], table->s->reclength); + DBUG_DUMP("table->record[1]", (const char *)table->record[1], table->s->reclength); #endif /* @@ -6870,8 +6869,8 @@ static int find_and_fetch_row(TABLE *table, byte *key) trigger false warnings. */ #ifndef HAVE_purify - DBUG_DUMP("table->record[0]", table->record[0], table->s->reclength); - DBUG_DUMP("table->record[1]", table->record[1], table->s->reclength); + DBUG_DUMP("table->record[0]", (const char *)table->record[0], table->s->reclength); + DBUG_DUMP("table->record[1]", (const char *)table->record[1], table->s->reclength); #endif /* Below is a minor "optimization". If the key (i.e., key number diff --git a/sql/log_event.h b/sql/log_event.h index 4b74bf7c7ee..fd924537919 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/matherr.c b/sql/matherr.c index ea0c15d2feb..4998d8b4961 100644 --- a/sql/matherr.c +++ b/sql/matherr.c @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc index 71c8d588de7..f237f15dbc9 100644 --- a/sql/mf_iocache.cc +++ b/sql/mf_iocache.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc index 30a271df064..511942e9a5d 100644 --- a/sql/my_decimal.cc +++ b/sql/my_decimal.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2005-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/my_decimal.h b/sql/my_decimal.h index 9e2dea26700..cefc5ee00fd 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2005-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/my_lock.c b/sql/my_lock.c index 69884df22f8..f66d7282f72 100644 --- a/sql/my_lock.c +++ b/sql/my_lock.c @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 09c40147a08..305cf78593e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -625,6 +624,7 @@ Item *negate_expression(THD *thd, Item *expr); #include "sql_acl.h" #include "tztime.h" #ifdef MYSQL_SERVER +#include "sql_servers.h" #include "opt_range.h" #ifdef HAVE_QUERY_CACHE diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 96dfb3d01ec..72add4d3aa4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -391,6 +390,7 @@ extern my_bool innobase_log_archive, innobase_use_large_pages, innobase_use_native_aio, innobase_file_per_table, innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout, innobase_create_status_file; extern "C" { extern ulong srv_max_buf_pool_modified_pct; @@ -1180,6 +1180,7 @@ void clean_up(bool print_message) my_tz_free(); my_database_names_free(); #ifndef NO_EMBEDDED_ACCESS_CHECKS + servers_free(1); acl_free(1); grant_free(); #endif @@ -3655,6 +3656,9 @@ we force server id to 2, but this MySQL server will not act as a slave."); if (!opt_noacl) (void) grant_init(); + if (!opt_bootstrap) + servers_init(0); + if (!opt_noacl) { #ifdef HAVE_DLOPEN @@ -4869,7 +4873,8 @@ enum options_mysqld OPT_PORT_OPEN_TIMEOUT, OPT_GENERAL_LOG, OPT_SLOW_LOG, - OPT_MERGE + OPT_MERGE, + OPT_INNODB_ROLLBACK_ON_TIMEOUT }; @@ -5162,6 +5167,10 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite, (gptr*) &srv_max_purge_lag, (gptr*) &srv_max_purge_lag, 0, GET_LONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1L, 0}, + {"innodb_rollback_on_timeout", OPT_INNODB_ROLLBACK_ON_TIMEOUT, + "Roll back the complete transaction on lock wait timeout, for 4.x compatibility (disabled by default)", + (gptr*) &innobase_rollback_on_timeout, (gptr*) &innobase_rollback_on_timeout, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_status_file", OPT_INNODB_STATUS_FILE, "Enable SHOW INNODB STATUS output in the innodb_status.<pid> file", (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file, @@ -8149,7 +8158,8 @@ my_bool innobase_log_archive, innobase_use_doublewrite, innobase_use_checksums, innobase_file_per_table, - innobase_locks_unsafe_for_binlog; + innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout; extern "C" { ulong srv_max_buf_pool_modified_pct; diff --git a/sql/mysqld_suffix.h b/sql/mysqld_suffix.h index 405c5d855b7..b348f272db1 100644 --- a/sql/mysqld_suffix.h +++ b/sql/mysqld_suffix.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 6f8993f584d..8e9dadc1dbf 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/opt_range.cc b/sql/opt_range.cc index fa575e73c39..7f58e0359c4 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1002,6 +1001,11 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT() if (file) { range_end(); + if (head->key_read) + { + head->key_read= 0; + file->extra(HA_EXTRA_NO_KEYREAD); + } if (free_file) { DBUG_PRINT("info", ("Freeing separate handler 0x%lx (free: %d)", (long) file, @@ -1010,10 +1014,6 @@ QUICK_RANGE_SELECT::~QUICK_RANGE_SELECT() file->close(); delete file; } - else - { - file->extra(HA_EXTRA_NO_KEYREAD); - } } delete_dynamic(&ranges); /* ranges are allocated in alloc */ free_root(&alloc,MYF(0)); @@ -1195,7 +1195,11 @@ end: org_file= head->file; head->file= file; /* We don't have to set 'head->keyread' here as the 'file' is unique */ - head->mark_columns_used_by_index(index); + if (!head->no_keyread) + { + head->key_read= 1; + head->mark_columns_used_by_index(index); + } head->prepare_for_position(); head->file= org_file; bitmap_copy(&column_bitmap, head->read_set); @@ -3132,7 +3136,7 @@ static bool fields_ok_for_partition_index(Field **pfield) for (; (*pfield); pfield++) { enum_field_types ftype= (*pfield)->real_type(); - if (ftype == FIELD_TYPE_ENUM || ftype == FIELD_TYPE_GEOMETRY) + if (ftype == MYSQL_TYPE_ENUM || ftype == MYSQL_TYPE_GEOMETRY) return FALSE; } return TRUE; @@ -3231,7 +3235,7 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) key_part->store_length= (uint16) (*field)->pack_length(); if ((*field)->real_maybe_null()) key_part->store_length+= HA_KEY_NULL_LENGTH; - if ((*field)->type() == FIELD_TYPE_BLOB || + if ((*field)->type() == MYSQL_TYPE_BLOB || (*field)->real_type() == MYSQL_TYPE_VARCHAR) key_part->store_length+= HA_KEY_BLOB_LENGTH; @@ -5589,8 +5593,8 @@ get_mm_leaf(RANGE_OPT_PARAM *param, COND *conf_func, Field *field, /* For comparison purposes allow invalid dates like 2000-01-32 */ orig_sql_mode= field->table->in_use->variables.sql_mode; if (value->real_item()->type() == Item::STRING_ITEM && - (field->type() == FIELD_TYPE_DATE || - field->type() == FIELD_TYPE_DATETIME)) + (field->type() == MYSQL_TYPE_DATE || + field->type() == MYSQL_TYPE_DATETIME)) field->table->in_use->variables.sql_mode|= MODE_INVALID_DATES; err= value->save_in_field_no_warnings(field, 1); if (err > 0 && field->cmp_type() != value->result_type()) diff --git a/sql/opt_range.h b/sql/opt_range.h index 170766c7c10..525a0adcff7 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index cb8b53ac6a7..90a3ff66a22 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 0a2d4012af4..c36e16e0553 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/parse_file.h b/sql/parse_file.h index 0a02bf7eb75..21873b32904 100644 --- a/sql/parse_file.h +++ b/sql/parse_file.h @@ -3,8 +3,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/partition_element.h b/sql/partition_element.h index 1e2769bc21a..c056d40b85b 100644 --- a/sql/partition_element.h +++ b/sql/partition_element.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000,200666666 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /** * An enum and a struct to handle partitioning and subpartitioning. diff --git a/sql/partition_info.cc b/sql/partition_info.cc index 9d5b6d0494a..76630e8530b 100644 --- a/sql/partition_info.cc +++ b/sql/partition_info.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/partition_info.h b/sql/partition_info.h index 09d827d44c4..8bcc769054f 100644 --- a/sql/partition_info.h +++ b/sql/partition_info.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000,2006 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class implementation */ diff --git a/sql/password.c b/sql/password.c index c6d904bc45b..0e4bd6347e2 100644 --- a/sql/password.c +++ b/sql/password.c @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/procedure.cc b/sql/procedure.cc index 554e2cd0565..bbfabc46608 100644 --- a/sql/procedure.cc +++ b/sql/procedure.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2002, 2004-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/procedure.h b/sql/procedure.h index 5c8a3387eec..6a731766046 100644 --- a/sql/procedure.h +++ b/sql/procedure.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/protocol.cc b/sql/protocol.cc index 6fe4e34d5a9..da46405dea2 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/protocol.h b/sql/protocol.h index 7e2bc1516ec..0e00a7c21e0 100644 --- a/sql/protocol.h +++ b/sql/protocol.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2002-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/records.cc b/sql/records.cc index f8b6a7d1df9..0923ab1d75e 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 762fcfb7a6a..48bc0f0f5b8 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha +/* Copyright (C) 2001-2006 MySQL AB & Sasha This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/repl_failsafe.h b/sql/repl_failsafe.h index 19849e63af9..561db00d841 100644 --- a/sql/repl_failsafe.h +++ b/sql/repl_failsafe.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha +/* Copyright (C) 2001-2005 MySQL AB & Sasha This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_filter.cc b/sql/rpl_filter.cc index c01b5189887..f76f798f6a6 100644 --- a/sql/rpl_filter.cc +++ b/sql/rpl_filter.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_filter.h b/sql/rpl_filter.h index 718fd401c56..396207d3a28 100644 --- a/sql/rpl_filter.h +++ b/sql/rpl_filter.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_injector.cc b/sql/rpl_injector.cc index 3a0fca4dfa5..292e6262382 100644 --- a/sql/rpl_injector.cc +++ b/sql/rpl_injector.cc @@ -1,10 +1,8 @@ -/* - Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_priv.h" #include "rpl_injector.h" diff --git a/sql/rpl_injector.h b/sql/rpl_injector.h index 17251f54746..381da7c33a5 100644 --- a/sql/rpl_injector.h +++ b/sql/rpl_injector.h @@ -1,10 +1,8 @@ -/* - Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef INJECTOR_H #define INJECTOR_H diff --git a/sql/rpl_mi.cc b/sql/rpl_mi.cc index c89c8aa131e..1c426eff768 100644 --- a/sql/rpl_mi.cc +++ b/sql/rpl_mi.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_mi.h b/sql/rpl_mi.h index f0a7d6681fe..ae77e64d93a 100644 --- a/sql/rpl_mi.h +++ b/sql/rpl_mi.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_rli.cc b/sql/rpl_rli.cc index a2edb9dc8a8..6a7b22bf23d 100644 --- a/sql/rpl_rli.cc +++ b/sql/rpl_rli.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_rli.h b/sql/rpl_rli.h index d737055baf2..cb9894a2125 100644 --- a/sql/rpl_rli.h +++ b/sql/rpl_rli.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc index 97f0066233c..7df4bcbdde7 100644 --- a/sql/rpl_tblmap.cc +++ b/sql/rpl_tblmap.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_tblmap.h b/sql/rpl_tblmap.h index 23864bd329e..dbc968d0f67 100644 --- a/sql/rpl_tblmap.h +++ b/sql/rpl_tblmap.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/rpl_utility.cc b/sql/rpl_utility.cc index 4bed1343e55..65a44a4947b 100644 --- a/sql/rpl_utility.cc +++ b/sql/rpl_utility.cc @@ -1,9 +1,8 @@ -/* Copyright 2006 MySQL AB. All rights reserved. +/* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "rpl_utility.h" diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index df0b0cd2ee1..34cebf93ddb 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -1,9 +1,8 @@ -/* Copyright 2006 MySQL AB. All rights reserved. +/* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef RPL_UTILITY_H #define RPL_UTILITY_H diff --git a/sql/set_var.cc b/sql/set_var.cc index cf8751bb895..0111e10d889 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -78,7 +77,8 @@ extern my_bool innobase_log_archive, innobase_use_doublewrite, innobase_use_checksums, innobase_file_per_table, - innobase_locks_unsafe_for_binlog; + innobase_locks_unsafe_for_binlog, + innobase_rollback_on_timeout; extern "C" { extern ulong srv_max_buf_pool_modified_pct; @@ -825,6 +825,7 @@ SHOW_VAR init_vars[]= { {sys_innodb_max_purge_lag.name, (char*) &sys_innodb_max_purge_lag, SHOW_SYS}, {"innodb_mirrored_log_groups", (char*) &innobase_mirrored_log_groups, SHOW_LONG}, {"innodb_open_files", (char*) &innobase_open_files, SHOW_LONG }, + {"innodb_rollback_on_timeout", (char*) &innobase_rollback_on_timeout, SHOW_MY_BOOL}, {sys_innodb_support_xa.name, (char*) &sys_innodb_support_xa, SHOW_SYS}, {sys_innodb_sync_spin_loops.name, (char*) &sys_innodb_sync_spin_loops, SHOW_SYS}, {sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS}, @@ -3904,7 +3905,7 @@ bool sys_var_opt_readonly::update(THD *thd, set_var *var) can cause to wait on a read lock, it's required for the client application to unlock everything, and acceptable for the server to wait on all locks. */ - if (close_cached_tables(thd, true, NULL, false)) + if (result= close_cached_tables(thd, true, NULL, false)) goto end_with_read_lock; if (result= make_global_read_lock_block_commit(thd)) diff --git a/sql/set_var.h b/sql/set_var.h index 14792f4a7c8..f957ec931d6 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2002-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/Makefile.am b/sql/share/Makefile.am index 6d905ba35dc..68b393e619f 100644 --- a/sql/share/Makefile.am +++ b/sql/share/Makefile.am @@ -2,8 +2,7 @@ # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. +# the Free Software Foundation; version 2 of the License. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/Index.xml b/sql/share/charsets/Index.xml index 3f1a25072b7..80b844e2f19 100644 --- a/sql/share/charsets/Index.xml +++ b/sql/share/charsets/Index.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/armscii8.xml b/sql/share/charsets/armscii8.xml index d0ab428345f..714e57bb12e 100644 --- a/sql/share/charsets/armscii8.xml +++ b/sql/share/charsets/armscii8.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/ascii.xml b/sql/share/charsets/ascii.xml index 3813bd42601..97006c53680 100644 --- a/sql/share/charsets/ascii.xml +++ b/sql/share/charsets/ascii.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/cp1250.xml b/sql/share/charsets/cp1250.xml index b83d0faeca8..bd0d7d3f3c0 100644 --- a/sql/share/charsets/cp1250.xml +++ b/sql/share/charsets/cp1250.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/cp1251.xml b/sql/share/charsets/cp1251.xml index 7f94788c0d0..b80db9f8ec0 100644 --- a/sql/share/charsets/cp1251.xml +++ b/sql/share/charsets/cp1251.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/cp1256.xml b/sql/share/charsets/cp1256.xml index 69eb6a68238..64cb253145c 100644 --- a/sql/share/charsets/cp1256.xml +++ b/sql/share/charsets/cp1256.xml @@ -9,8 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/cp1257.xml b/sql/share/charsets/cp1257.xml index 93a1bd47a77..0c2688c264e 100644 --- a/sql/share/charsets/cp1257.xml +++ b/sql/share/charsets/cp1257.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/cp850.xml b/sql/share/charsets/cp850.xml index 79497aa17f1..4076a5f6a56 100644 --- a/sql/share/charsets/cp850.xml +++ b/sql/share/charsets/cp850.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/cp852.xml b/sql/share/charsets/cp852.xml index 73a81e54b02..25b622d2a4b 100644 --- a/sql/share/charsets/cp852.xml +++ b/sql/share/charsets/cp852.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/cp866.xml b/sql/share/charsets/cp866.xml index 1a72b396c7c..fa2e1865de6 100644 --- a/sql/share/charsets/cp866.xml +++ b/sql/share/charsets/cp866.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/dec8.xml b/sql/share/charsets/dec8.xml index 2cb28cb0f4f..2cd52de464a 100644 --- a/sql/share/charsets/dec8.xml +++ b/sql/share/charsets/dec8.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/geostd8.xml b/sql/share/charsets/geostd8.xml index c09aa078fb7..5e3816975d6 100644 --- a/sql/share/charsets/geostd8.xml +++ b/sql/share/charsets/geostd8.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/greek.xml b/sql/share/charsets/greek.xml index 1cfe6b49610..000019a8ce0 100644 --- a/sql/share/charsets/greek.xml +++ b/sql/share/charsets/greek.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/hebrew.xml b/sql/share/charsets/hebrew.xml index 5bcf222a728..bdfa82bb791 100644 --- a/sql/share/charsets/hebrew.xml +++ b/sql/share/charsets/hebrew.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/hp8.xml b/sql/share/charsets/hp8.xml index 35224f8c544..3ab383ef386 100644 --- a/sql/share/charsets/hp8.xml +++ b/sql/share/charsets/hp8.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/keybcs2.xml b/sql/share/charsets/keybcs2.xml index 6332891ef23..7335a0f428d 100644 --- a/sql/share/charsets/keybcs2.xml +++ b/sql/share/charsets/keybcs2.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/koi8r.xml b/sql/share/charsets/koi8r.xml index 033597e9bfc..2d8473f6440 100644 --- a/sql/share/charsets/koi8r.xml +++ b/sql/share/charsets/koi8r.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/koi8u.xml b/sql/share/charsets/koi8u.xml index 4f5fa35af3d..16177627ffe 100644 --- a/sql/share/charsets/koi8u.xml +++ b/sql/share/charsets/koi8u.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/latin1.xml b/sql/share/charsets/latin1.xml index 5814a17b0e1..88ceff440d5 100644 --- a/sql/share/charsets/latin1.xml +++ b/sql/share/charsets/latin1.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/latin2.xml b/sql/share/charsets/latin2.xml index 7f00148a1df..6b887b927a4 100644 --- a/sql/share/charsets/latin2.xml +++ b/sql/share/charsets/latin2.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/latin5.xml b/sql/share/charsets/latin5.xml index 5004f045889..9c23200a46d 100644 --- a/sql/share/charsets/latin5.xml +++ b/sql/share/charsets/latin5.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/latin7.xml b/sql/share/charsets/latin7.xml index dd87a1a2d89..02d3ff8b17e 100644 --- a/sql/share/charsets/latin7.xml +++ b/sql/share/charsets/latin7.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/macce.xml b/sql/share/charsets/macce.xml index 61f6d79b34f..21e303609cf 100644 --- a/sql/share/charsets/macce.xml +++ b/sql/share/charsets/macce.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/macroman.xml b/sql/share/charsets/macroman.xml index 36c8e8cf13a..2b43fe73b07 100644 --- a/sql/share/charsets/macroman.xml +++ b/sql/share/charsets/macroman.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/charsets/swe7.xml b/sql/share/charsets/swe7.xml index 2b8ff4edcce..17fa6b7d9bc 100644 --- a/sql/share/charsets/swe7.xml +++ b/sql/share/charsets/swe7.xml @@ -7,8 +7,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt index c64f4da045e..671dbbd9c03 100644 --- a/sql/share/errmsg.txt +++ b/sql/share/errmsg.txt @@ -78,7 +78,7 @@ ER_CANT_CREATE_TABLE cze "Nemohu vytvo-Bøit tabulku '%-.64s' (chybový kód: %d)" dan "Kan ikke oprette tabellen '%-.64s' (Fejlkode: %d)" nla "Kan tabel '%-.64s' niet aanmaken (Errcode: %d)" - eng "Can't create table '%-.64s' (errno: %d)" + eng "Can't create table '%-.200s' (errno: %d)" jps "'%-.64s' ƒe[ƒuƒ‹‚ªì‚ê‚Ü‚¹‚ñ.(errno: %d)", est "Ei suuda luua tabelit '%-.64s' (veakood: %d)" fre "Ne peut créer la table '%-.64s' (Errcode: %d)" @@ -574,7 +574,7 @@ ER_ERROR_ON_RENAME cze "Chyba p-Bøi pøejmenování '%-.64s' na '%-.64s' (chybový kód: %d)" dan "Fejl ved omdøbning af '%-.64s' til '%-.64s' (Fejlkode: %d)" nla "Fout bij het hernoemen van '%-.64s' naar '%-.64s' (Errcode: %d)" - eng "Error on rename of '%-.64s' to '%-.64s' (errno: %d)" + eng "Error on rename of '%-.150s' to '%-.150s' (errno: %d)" jps "'%-.64s' ‚ð '%-.64s' ‚É rename ‚Å‚«‚Ü‚¹‚ñ (errno: %d)", est "Viga faili '%-.64s' ümbernimetamisel '%-.64s'-ks (veakood: %d)" fre "Erreur en renommant '%-.64s' en '%-.64s' (Errcode: %d)" @@ -5607,6 +5607,8 @@ ER_SP_RECURSION_LIMIT ER_SP_PROC_TABLE_CORRUPT eng "Failed to load routine %-.64s. The table mysql.proc is missing, corrupt, or contains bad data (internal code %d)" ger "Routine %-64s konnte nicht geladen werden. Die Tabelle mysql.proc fehlt, ist beschädigt, oder enthält fehlerhaften Daten (interner Code: %d)" +ER_FOREIGN_SERVER_EXISTS + eng "The foreign server, %s, you are trying to create already exists." ER_SP_WRONG_NAME 42000 eng "Incorrect routine name '%-.64s'" ger "Ungültiger Routinenname '%-.64s'" @@ -5847,6 +5849,9 @@ ER_BINLOG_ROW_WRONG_TABLE_DEF ER_BINLOG_ROW_RBR_TO_SBR eng "Slave running with --log-slave-updates must use row-based binary logging to be able to replicate row-based binary log events" ger "Slave, die mit --log-slave-updates laufen, müssen zeilenbasiertes Loggen verwenden, um zeilenbasierte Binärlog-Ereignisse loggen zu können" +ER_FOREIGN_SERVER_DOESNT_EXIST + eng "The foreign server name you are trying to reference does not exist. Data source error: %-.64s" + ger "Die externe Verbindung, auf die Sie zugreifen wollen, existiert nicht. Datenquellenfehlermeldung: %-.64s" ER_EVENT_ALREADY_EXISTS eng "Event '%-.64s' already exists" ger "Event '%-.64s' existiert bereits" diff --git a/sql/slave.cc b/sql/slave.cc index 67e8ba20c4f..88e501143bc 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/slave.h b/sql/slave.h index 24ba09d78d3..43eb71be601 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp.cc b/sql/sp.cc index 9e53aff742e..14703e3aa42 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -48,7 +47,7 @@ enum { MYSQL_PROC_FIELD_DB = 0, MYSQL_PROC_FIELD_NAME, - MYSQL_PROC_FIELD_TYPE, + MYSQL_PROC_MYSQL_TYPE, MYSQL_PROC_FIELD_SPECIFIC_NAME, MYSQL_PROC_FIELD_LANGUAGE, MYSQL_PROC_FIELD_ACCESS, @@ -534,7 +533,7 @@ db_create_routine(THD *thd, int type, sp_head *sp) store(sp->m_db.str, sp->m_db.length, system_charset_info); table->field[MYSQL_PROC_FIELD_NAME]-> store(sp->m_name.str, sp->m_name.length, system_charset_info); - table->field[MYSQL_PROC_FIELD_TYPE]-> + table->field[MYSQL_PROC_MYSQL_TYPE]-> store((longlong)type, TRUE); table->field[MYSQL_PROC_FIELD_SPECIFIC_NAME]-> store(sp->m_name.str, sp->m_name.length, system_charset_info); @@ -734,7 +733,7 @@ print_field_values(THD *thd, TABLE *table, { Protocol *protocol= thd->protocol; - if (table->field[MYSQL_PROC_FIELD_TYPE]->val_int() == type) + if (table->field[MYSQL_PROC_MYSQL_TYPE]->val_int() == type) { String db_string; String name_string; @@ -3,8 +3,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index f5912caddaf..de4e1efd496 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_cache.h b/sql/sp_cache.h index 1021d17b9e2..9d34c9a2fb5 100644 --- a/sql/sp_cache.h +++ b/sql/sp_cache.h @@ -3,8 +3,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8a47c02c198..2b65e2b345f 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_head.h b/sql/sp_head.h index 382e6be08a1..0085608ae40 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -3,8 +3,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc index b0b65d5313b..6229cf14604 100644 --- a/sql/sp_pcontext.cc +++ b/sql/sp_pcontext.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h index 2ee77696efb..b2cdd5e689c 100644 --- a/sql/sp_pcontext.h +++ b/sql/sp_pcontext.h @@ -3,8 +3,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 67ee5459bb4..e49c4eb1240 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index 5e03aa60d23..fbf479f52aa 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -3,8 +3,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/spatial.cc b/sql/spatial.cc index 02f1525f2ad..22df69a978b 100644 --- a/sql/spatial.cc +++ b/sql/spatial.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/spatial.h b/sql/spatial.h index 36949ff5014..afce9b2d98f 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2002-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 721b6b5a003..4d1451f6bce 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -761,7 +760,7 @@ static ulong get_access(TABLE *form, uint fieldnr, uint *next_field) Field **pos; for (pos=form->field+fieldnr, bit=1; - *pos && (*pos)->real_type() == FIELD_TYPE_ENUM && + *pos && (*pos)->real_type() == MYSQL_TYPE_ENUM && ((Field_enum*) (*pos))->typelib->count == 2 ; pos++, fieldnr++, bit<<=1) { @@ -1969,7 +1968,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, ulong priv; uint next_field; for (tmp_field= table->field+3, priv = SELECT_ACL; - *tmp_field && (*tmp_field)->real_type() == FIELD_TYPE_ENUM && + *tmp_field && (*tmp_field)->real_type() == MYSQL_TYPE_ENUM && ((Field_enum*) (*tmp_field))->typelib->count == 2 ; tmp_field++, priv <<= 1) { diff --git a/sql/sql_acl.h b/sql/sql_acl.h index e1153522ed5..86d2cabc703 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index 264e3e2b988..54ced074dd3 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -140,7 +139,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result, case INT_RESULT: // Check if fieldtype is ulonglong if (item->type() == Item::FIELD_ITEM && - ((Item_field*) item)->field->type() == FIELD_TYPE_LONGLONG && + ((Item_field*) item)->field->type() == MYSQL_TYPE_LONGLONG && ((Field_longlong*) ((Item_field*) item)->field)->unsigned_flag) new_field= new field_ulonglong(item, pc); else @@ -755,26 +754,26 @@ bool analyse::end_of_records() { switch (((Item_field*) (*f)->item)->field->real_type()) { - case FIELD_TYPE_TIMESTAMP: + case MYSQL_TYPE_TIMESTAMP: ans.append(STRING_WITH_LEN("TIMESTAMP")); break; - case FIELD_TYPE_DATETIME: + case MYSQL_TYPE_DATETIME: ans.append(STRING_WITH_LEN("DATETIME")); break; - case FIELD_TYPE_DATE: - case FIELD_TYPE_NEWDATE: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_NEWDATE: ans.append(STRING_WITH_LEN("DATE")); break; - case FIELD_TYPE_SET: + case MYSQL_TYPE_SET: ans.append(STRING_WITH_LEN("SET")); break; - case FIELD_TYPE_YEAR: + case MYSQL_TYPE_YEAR: ans.append(STRING_WITH_LEN("YEAR")); break; - case FIELD_TYPE_TIME: + case MYSQL_TYPE_TIME: ans.append(STRING_WITH_LEN("TIME")); break; - case FIELD_TYPE_DECIMAL: + case MYSQL_TYPE_DECIMAL: ans.append(STRING_WITH_LEN("DECIMAL")); // if item is FIELD_ITEM, it _must_be_ Field_num in this case if (((Field_num*) ((Item_field*) (*f)->item)->field)->zerofill) diff --git a/sql/sql_analyse.h b/sql/sql_analyse.h index 0e7bd1b722a..ac671b85e1e 100644 --- a/sql/sql_analyse.h +++ b/sql/sql_analyse.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2003, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_array.h b/sql/sql_array.h index c68caf74b25..e2e12bee241 100644 --- a/sql/sql_array.h +++ b/sql/sql_array.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3fd09d909a4..7614506f77f 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_binlog.cc b/sql/sql_binlog.cc index 37094b992e5..d8f12375258 100644 --- a/sql/sql_binlog.cc +++ b/sql/sql_binlog.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2005-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -12,7 +11,7 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include "mysql_priv.h" #include "base64.h" diff --git a/sql/sql_bitmap.h b/sql/sql_bitmap.h index 3a7fa4b661a..9a765120895 100644 --- a/sql/sql_bitmap.h +++ b/sql/sql_bitmap.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_builtin.cc.in b/sql/sql_builtin.cc.in index 18705aa3dfb..3becdbaccfe 100644 --- a/sql/sql_builtin.cc.in +++ b/sql/sql_builtin.cc.in @@ -1,3 +1,17 @@ +/* Copyright (C) 2006 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <mysql/plugin.h> diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 1b9af26530e..8c0cb72e1f4 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_cache.h b/sql/sql_cache.h index a66067159e2..0fbc06ce919 100644 --- a/sql/sql_cache.h +++ b/sql/sql_cache.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2001-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_class.cc b/sql/sql_class.cc index c5dc76848d1..9e3c2442f57 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_class.h b/sql/sql_class.h index 36cafae0907..8c86a66392a 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_client.cc b/sql/sql_client.cc index 49d0d3087ad..d6f1183806e 100644 --- a/sql/sql_client.cc +++ b/sql/sql_client.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_crypt.cc b/sql/sql_crypt.cc index 4e73941fb49..ebd424f00f0 100644 --- a/sql/sql_crypt.cc +++ b/sql/sql_crypt.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2003, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_crypt.h b/sql/sql_crypt.h index 25bc2d29e1d..f3db9adde25 100644 --- a/sql/sql_crypt.h +++ b/sql/sql_crypt.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 46fae3ffb99..d31c0af1163 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2005-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_cursor.h b/sql/sql_cursor.h index d1156dfba8d..6edd6b24b36 100644 --- a/sql/sql_cursor.h +++ b/sql/sql_cursor.h @@ -1,11 +1,8 @@ -#ifndef _sql_cursor_h_ -#define _sql_cursor_h_ -/* Copyright (C) 2005 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -16,6 +13,9 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#ifndef _sql_cursor_h_ +#define _sql_cursor_h_ + #ifdef USE_PRAGMA_INTERFACE #pragma interface /* gcc class interface */ #endif diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 4f9e19732fd..4fd35b7e6e8 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index df24dad2d4c..df313d8040c 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 5a9871c07c5..92a6e24bc80 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_do.cc b/sql/sql_do.cc index 98483ce2de6..a3eb93f87da 100644 --- a/sql/sql_do.cc +++ b/sql/sql_do.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_error.cc b/sql/sql_error.cc index dc7a437d7d1..70882d8f4e8 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_error.h b/sql/sql_error.h index f4a7b14ba1a..f98264dce50 100644 --- a/sql/sql_error.h +++ b/sql/sql_error.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 5951acdcc40..91e61be0478 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -1,8 +1,7 @@ /* Copyright (C) 2000-2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 69d21f8b7bb..7b7f7602163 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 191fc60dfd5..ccacd71a614 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1292,7 +1291,7 @@ int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, { if (!bitmap_is_set(write_set, (*field)->field_index) && ((*field)->flags & NO_DEFAULT_VALUE_FLAG) && - ((*field)->real_type() != FIELD_TYPE_ENUM)) + ((*field)->real_type() != MYSQL_TYPE_ENUM)) { bool view= FALSE; if (table_list) @@ -1808,8 +1807,6 @@ void kill_delayed_threads(void) delayed_insert *tmp; while ((tmp=it++)) { - /* Ensure that the thread doesn't kill itself while we are looking at it */ - pthread_mutex_lock(&tmp->mutex); tmp->thd.killed= THD::KILL_CONNECTION; if (tmp->thd.mysys_var) { @@ -1828,7 +1825,6 @@ void kill_delayed_threads(void) } pthread_mutex_unlock(&tmp->thd.mysys_var->mutex); } - pthread_mutex_unlock(&tmp->mutex); } VOID(pthread_mutex_unlock(&LOCK_delayed_insert)); // For unlink from list } @@ -2928,7 +2924,9 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, save us from that ? */ table->reginfo.lock_type=TL_WRITE; +#ifdef HAVE_ROW_BASED_REPLICATION hooks->prelock(&table, 1); // Call prelock hooks +#endif if (! ((*lock)= mysql_lock_tables(thd, &table, 1, MYSQL_LOCK_IGNORE_FLUSH, ¬_used))) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index c497cf6814b..1c399503498 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -183,6 +182,21 @@ void lex_start(THD *thd, const uchar *buf, uint length) lex->nest_level=0 ; lex->allow_sum_func= 0; lex->in_sum_func= NULL; + /* + ok, there must be a better solution for this, long-term + I tried "bzero" in the sql_yacc.yy code, but that for + some reason made the values zero, even if they were set + */ + lex->server_options.server_name= 0; + lex->server_options.server_name_length= 0; + lex->server_options.host= 0; + lex->server_options.db= 0; + lex->server_options.username= 0; + lex->server_options.password= 0; + lex->server_options.scheme= 0; + lex->server_options.socket= 0; + lex->server_options.owner= 0; + lex->server_options.port= -1; DBUG_VOID_RETURN; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index ad2a301c259..fd76ec7ac51 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -111,6 +110,7 @@ enum enum_sql_command { SQLCOM_SHOW_AUTHORS, SQLCOM_BINLOG_BASE64_EVENT, SQLCOM_SHOW_PLUGINS, SQLCOM_SHOW_CONTRIBUTORS, + SQLCOM_CREATE_SERVER, SQLCOM_DROP_SERVER, SQLCOM_ALTER_SERVER, SQLCOM_CREATE_EVENT, SQLCOM_ALTER_EVENT, SQLCOM_DROP_EVENT, SQLCOM_SHOW_CREATE_EVENT, SQLCOM_SHOW_EVENTS, @@ -174,6 +174,14 @@ enum enum_drop_mode typedef List<Item> List_item; +/* SERVERS CACHE CHANGES */ +typedef struct st_lex_server_options +{ + long port; + uint server_name_length; + char *server_name, *host, *db, *username, *password, *scheme, *socket, *owner; +} LEX_SERVER_OPTIONS; + typedef struct st_lex_master_info { char *host, *user, *password, *log_file_name; @@ -976,6 +984,7 @@ typedef struct st_lex : public Query_tables_list HA_CREATE_INFO create_info; KEY_CREATE_INFO key_create_info; LEX_MASTER_INFO mi; // used by CHANGE MASTER + LEX_SERVER_OPTIONS server_options; USER_RESOURCES mqh; ulong type; /* diff --git a/sql/sql_list.cc b/sql/sql_list.cc index d57a7dfe4e3..01ab9b91424 100644 --- a/sql/sql_list.cc +++ b/sql/sql_list.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2003, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_list.h b/sql/sql_list.h index 070fd1e3d9a..d16fbaf2e50 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_load.cc b/sql/sql_load.cc index b85610eaa6f..81dd710dbcb 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -710,13 +709,18 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, if (item->type() == Item::FIELD_ITEM) { Field *field= ((Item_field *)item)->field; - field->reset(); + if (field->reset()) + { + my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name, + thd->row_count); + DBUG_RETURN(1); + } field->set_null(); if (field == table->next_number_field) table->auto_increment_field_not_null= TRUE; if (!field->maybe_null()) { - if (field->type() == FIELD_TYPE_TIMESTAMP) + if (field->type() == MYSQL_TYPE_TIMESTAMP) ((Field_timestamp*) field)->set_time(); else if (field != table->next_number_field) field->set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, @@ -759,6 +763,13 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, { if (item->type() == Item::FIELD_ITEM) { + Field *field= ((Item_field *)item)->field; + if (field->reset()) + { + my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0),field->field_name, + thd->row_count); + DBUG_RETURN(1); + } /* QQ: We probably should not throw warning for each field. But how about intention to always have the same number diff --git a/sql/sql_locale.cc b/sql/sql_locale.cc index b947b9dfa98..217c09d9e00 100644 --- a/sql/sql_locale.cc +++ b/sql/sql_locale.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_manager.cc b/sql/sql_manager.cc index b3c67ab5db7..b0ca7667a62 100644 --- a/sql/sql_manager.cc +++ b/sql/sql_manager.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000, 2002, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_map.cc b/sql/sql_map.cc index 8376b3bbfcc..36a47f1aefc 100644 --- a/sql/sql_map.cc +++ b/sql/sql_map.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2004-2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_map.h b/sql/sql_map.h index bfa6011ac54..d8eb64995aa 100644 --- a/sql/sql_map.h +++ b/sql/sql_map.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2005 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_olap.cc b/sql/sql_olap.cc index 3d06030536f..818825d566b 100644 --- a/sql/sql_olap.cc +++ b/sql/sql_olap.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1c46c3189d9..33ae6d96c91 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -5189,6 +5188,58 @@ create_sp_error: #endif /* EMBEDDED_LIBRARY */ break; } + case SQLCOM_CREATE_SERVER: + { + int error; + LEX *lex= thd->lex; + DBUG_PRINT("info", ("case SQLCOM_CREATE_SERVER")); + if ((error= create_server(thd, &lex->server_options))) + { + DBUG_PRINT("info", ("problem creating server <%s>", + lex->server_options.server_name)); + my_error(error, MYF(0), lex->server_options.server_name); + break; + } + send_ok(thd, 1); + break; + } + case SQLCOM_ALTER_SERVER: + { + int error; + LEX *lex= thd->lex; + DBUG_PRINT("info", ("case SQLCOM_ALTER_SERVER")); + if ((error= alter_server(thd, &lex->server_options))) + { + DBUG_PRINT("info", ("problem altering server <%s>", + lex->server_options.server_name)); + my_error(error, MYF(0), lex->server_options.server_name); + break; + } + send_ok(thd, 1); + break; + } + case SQLCOM_DROP_SERVER: + { + int err_code; + LEX *lex= thd->lex; + DBUG_PRINT("info", ("case SQLCOM_DROP_SERVER")); + if ((err_code= drop_server(thd, &lex->server_options))) + { + if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_EXISTS) + { + DBUG_PRINT("info", ("problem dropping server %s", + lex->server_options.server_name)); + my_error(err_code, MYF(0), lex->server_options.server_name); + } + else + { + send_ok(thd, 0); + } + break; + } + send_ok(thd, 1); + break; + } default: #ifndef EMBEDDED_LIBRARY DBUG_ASSERT(0); /* Impossible */ @@ -6214,7 +6265,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, */ if (default_value->type() == Item::FUNC_ITEM && !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC && - type == FIELD_TYPE_TIMESTAMP)) + type == MYSQL_TYPE_TIMESTAMP)) { my_error(ER_INVALID_DEFAULT, MYF(0), field_name); DBUG_RETURN(1); @@ -6236,13 +6287,13 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, } } - if (on_update_value && type != FIELD_TYPE_TIMESTAMP) + if (on_update_value && type != MYSQL_TYPE_TIMESTAMP) { my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name); DBUG_RETURN(1); } - if (type == FIELD_TYPE_TIMESTAMP && length) + if (type == MYSQL_TYPE_TIMESTAMP && length) { /* Display widths are no longer supported for TIMSTAMP as of MySQL 4.1. In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4), @@ -7307,6 +7358,7 @@ bool mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys) bzero((char*) &create_info,sizeof(create_info)); create_info.db_type= 0; create_info.default_table_charset= thd->variables.collation_database; + create_info.row_type= ROW_TYPE_NOT_USED; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name, &create_info, table_list, fields, keys, 0, (ORDER*)0, @@ -7323,6 +7375,7 @@ bool mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info) bzero((char*) &create_info,sizeof(create_info)); create_info.db_type= 0; create_info.default_table_charset= thd->variables.collation_database; + create_info.row_type= ROW_TYPE_NOT_USED; alter_info->clear(); alter_info->flags= ALTER_DROP_INDEX; DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->table_name, diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index dcc35293b84..520ad7e8cf9 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_partition.h b/sql/sql_partition.h index 4372c26a851..7ed43527688 100644 --- a/sql/sql_partition.h +++ b/sql/sql_partition.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 8cd4c661fb8..1d711b7835c 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -951,29 +950,28 @@ my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, state_mask= ~state_mask; // do it only once rw_rdlock(&THR_LOCK_plugin); + total= type == MYSQL_ANY_PLUGIN ? plugin_array.elements + : plugin_hash[type].records; + /* + Do the alloca out here in case we do have a working alloca: + leaving the nested stack frame invalidates alloca allocation. + */ + plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); if (type == MYSQL_ANY_PLUGIN) { - total=plugin_array.elements; - plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); for (idx= 0; idx < total; idx++) { plugin= dynamic_element(&plugin_array, idx, struct st_plugin_int *); - if (plugin->state & state_mask) - continue; - plugins[idx]= plugin; + plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL; } } else { - HASH *hash= &plugin_hash[type]; - total=hash->records; - plugins=(struct st_plugin_int **)my_alloca(total*sizeof(*plugins)); + HASH *hash= plugin_hash + type; for (idx= 0; idx < total; idx++) { plugin= (struct st_plugin_int *) hash_element(hash, idx); - if (plugin->state & state_mask) - continue; - plugins[idx]= plugin; + plugins[idx]= !(plugin->state & state_mask) ? plugin : NULL; } } rw_unlock(&THR_LOCK_plugin); @@ -984,7 +982,7 @@ my_bool plugin_foreach_with_mask(THD *thd, plugin_foreach_func *func, { rw_rdlock(&THR_LOCK_plugin); for (uint i=idx; i < total; i++) - if (plugins[i]->state & state_mask) + if (plugins[i] && plugins[i]->state & state_mask) plugins[i]=0; rw_unlock(&THR_LOCK_plugin); } diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index fa3440f7f68..d86d9332a92 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 7741ae13a17..249d69d174a 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1254,7 +1253,6 @@ static int mysql_test_select(Prepared_statement *stmt, lex->select_lex.context.resolve_in_select_list= TRUE; -#ifndef NO_EMBEDDED_ACCESS_CHECKS ulong privilege= lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL; if (tables) { @@ -1263,7 +1261,6 @@ static int mysql_test_select(Prepared_statement *stmt, } else if (check_access(thd, privilege, any_db,0,0,0,0)) goto error; -#endif if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) { diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index c37227e7d28..f34ec83b29c 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 92c8aca0e0c..a7b168fe47f 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha +/* Copyright (C) 2000-2006 MySQL AB & Sasha This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_repl.h b/sql/sql_repl.h index 789de64da85..b106391245d 100644 --- a/sql/sql_repl.h +++ b/sql/sql_repl.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB & Sasha +/* Copyright (C) 2000-2006 MySQL AB & Sasha This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 9a64055f2e3..5da48c69e9e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000-2004 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -8550,8 +8549,8 @@ remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value) thd->substitute_null_with_insert_id= FALSE; } /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */ - else if (((field->type() == FIELD_TYPE_DATE) || - (field->type() == FIELD_TYPE_DATETIME)) && + else if (((field->type() == MYSQL_TYPE_DATE) || + (field->type() == MYSQL_TYPE_DATETIME)) && (field->flags & NOT_NULL_FLAG) && !field->table->maybe_null) { @@ -8926,7 +8925,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, field->result_field= result; } else if (table_cant_handle_bit_fields && field->field->type() == - FIELD_TYPE_BIT) + MYSQL_TYPE_BIT) { *from_field= field->field; result= create_tmp_field_from_item(thd, item, table, copy_func, @@ -9243,7 +9242,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, *blob_field++= fieldnr; blob_count++; } - if (new_field->type() == FIELD_TYPE_BIT) + if (new_field->type() == MYSQL_TYPE_BIT) total_uneven_bit_length+= new_field->field_length & 7; *(reg_field++)= new_field; if (new_field->real_type() == MYSQL_TYPE_STRING || @@ -9305,7 +9304,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, reclength+=new_field->pack_length(); if (!(new_field->flags & NOT_NULL_FLAG)) null_count++; - if (new_field->type() == FIELD_TYPE_BIT) + if (new_field->type() == MYSQL_TYPE_BIT) total_uneven_bit_length+= new_field->field_length & 7; if (new_field->flags & BLOB_FLAG) { @@ -9450,7 +9449,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, } else field->move_field((char*) pos,(uchar*) 0,0); - if (field->type() == FIELD_TYPE_BIT) + if (field->type() == MYSQL_TYPE_BIT) { /* We have to reserve place for extra bits among null bits */ ((Field_bit*) field)->set_bit_ptr(null_flags + null_count / 8, @@ -11746,7 +11745,7 @@ static bool test_if_ref(Item_field *left_item,Item *right_item) if (field->binary() && field->real_type() != MYSQL_TYPE_STRING && field->real_type() != MYSQL_TYPE_VARCHAR && - (field->type() != FIELD_TYPE_FLOAT || field->decimals() == 0)) + (field->type() != MYSQL_TYPE_FLOAT || field->decimals() == 0)) { return !store_val_in_field(field, right_item, CHECK_FIELD_WARN); } @@ -13661,11 +13660,11 @@ calc_group_buffer(JOIN *join,ORDER *group) if (field) { enum_field_types type; - if ((type= field->type()) == FIELD_TYPE_BLOB) + if ((type= field->type()) == MYSQL_TYPE_BLOB) key_length+=MAX_BLOB_WIDTH; // Can't be used as a key else if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_VAR_STRING) key_length+= field->field_length + HA_KEY_BLOB_LENGTH; - else if (type == FIELD_TYPE_BIT) + else if (type == MYSQL_TYPE_BIT) { /* Bit is usually stored as a longlong key for group fields */ key_length+= 8; // Big enough diff --git a/sql/sql_select.h b/sql/sql_select.h index 323df568271..6ab4463605b 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -502,7 +501,7 @@ public: store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length) :null_ptr(null), err(0), null_key(0) { - if (field_arg->type() == FIELD_TYPE_BLOB) + if (field_arg->type() == MYSQL_TYPE_BLOB) { /* Key segments are always packed with a 2 byte length prefix */ to_field= new Field_varstring(ptr, length, 2, (uchar*) null, 1, diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc new file mode 100644 index 00000000000..0ec7c54487a --- /dev/null +++ b/sql/sql_servers.cc @@ -0,0 +1,1239 @@ +/* Copyright (C) 2000-2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + +/* + The servers are saved in the system table "servers" +*/ + +#include "mysql_priv.h" +#include "hash_filo.h" +#include <m_ctype.h> +#include <stdarg.h> +#include "sp_head.h" +#include "sp.h" + +HASH servers_cache; +pthread_mutex_t servers_cache_mutex; // To init the hash +uint servers_cache_initialised=FALSE; +/* Version of server table. incremented by servers_load */ +static uint servers_version=0; +static MEM_ROOT mem; +static rw_lock_t THR_LOCK_servers; +static bool initialized=0; + +static byte *servers_cache_get_key(FOREIGN_SERVER *server, uint *length, + my_bool not_used __attribute__((unused))) +{ + DBUG_ENTER("servers_cache_get_key"); + DBUG_PRINT("info", ("server_name_length %d server_name %s", + server->server_name_length, + server->server_name)); + + *length= (uint) server->server_name_length; + DBUG_RETURN((byte*) server->server_name); +} + +/* + Initialize structures responsible for servers used in federated + server scheme information for them from the server + table in the 'mysql' database. + + SYNOPSIS + servers_init() + dont_read_server_table TRUE if we want to skip loading data from + server table and disable privilege checking. + + NOTES + This function is mostly responsible for preparatory steps, main work + on initialization and grants loading is done in servers_reload(). + + RETURN VALUES + 0 ok + 1 Could not initialize servers +*/ + +my_bool servers_init(bool dont_read_servers_table) +{ + THD *thd; + my_bool return_val= 0; + DBUG_ENTER("servers_init"); + + /* init the mutex */ + if (pthread_mutex_init(&servers_cache_mutex, MY_MUTEX_INIT_FAST)) + DBUG_RETURN(1); + + if (my_rwlock_init(&THR_LOCK_servers, NULL)) + DBUG_RETURN(1); + + /* initialise our servers cache */ + if (hash_init(&servers_cache, system_charset_info, 32, 0, 0, + (hash_get_key) servers_cache_get_key, 0, 0)) + { + return_val= 1; /* we failed, out of memory? */ + goto end; + } + + /* Initialize the mem root for data */ + init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0); + + /* + at this point, the cache is initialised, let it be known + */ + servers_cache_initialised= TRUE; + + if (dont_read_servers_table) + goto end; + + /* + To be able to run this from boot, we allocate a temporary THD + */ + if (!(thd=new THD)) + DBUG_RETURN(1); + thd->thread_stack= (char*) &thd; + thd->store_globals(); + /* + It is safe to call servers_reload() since servers_* arrays and hashes which + will be freed there are global static objects and thus are initialized + by zeros at startup. + */ + return_val= servers_reload(thd); + delete thd; + /* Remember that we don't have a THD */ + my_pthread_setspecific_ptr(THR_THD, 0); + +end: + DBUG_RETURN(return_val); +} + +/* + Initialize server structures + + SYNOPSIS + servers_load() + thd Current thread + tables List containing open "mysql.servers" + + RETURN VALUES + FALSE Success + TRUE Error +*/ + +static my_bool servers_load(THD *thd, TABLE_LIST *tables) +{ + TABLE *table; + READ_RECORD read_record_info; + my_bool return_val= TRUE; + DBUG_ENTER("servers_load"); + + if (!servers_cache_initialised) + DBUG_RETURN(0); + + /* need to figure out how to utilise this variable */ + servers_version++; /* servers updated */ + + /* first, send all cached rows to sleep with the fishes, oblivion! + I expect this crappy comment replaced */ + free_root(&mem, MYF(MY_MARK_BLOCKS_FREE)); + my_hash_reset(&servers_cache); + + init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0); + while (!(read_record_info.read_record(&read_record_info))) + { + /* return_val is already TRUE, so no need to set */ + if ((get_server_from_table_to_cache(table))) + goto end; + } + + return_val=0; + +end: + end_read_record(&read_record_info); + DBUG_RETURN(return_val); +} + + +/* + Forget current servers cache and read new servers + from the conneciton table. + + SYNOPSIS + servers_reload() + thd Current thread + + NOTE + All tables of calling thread which were open and locked by LOCK TABLES + statement will be unlocked and closed. + This function is also used for initialization of structures responsible + for user/db-level privilege checking. + + RETURN VALUE + FALSE Success + TRUE Failure +*/ + +my_bool servers_reload(THD *thd) +{ + TABLE_LIST tables[1]; + my_bool return_val= 1; + DBUG_ENTER("servers_reload"); + + if (thd->locked_tables) + { // Can't have locked tables here + thd->lock=thd->locked_tables; + thd->locked_tables=0; + close_thread_tables(thd); + } + + /* + To avoid deadlocks we should obtain table locks before + obtaining servers_cache->lock mutex. + */ + bzero((char*) tables, sizeof(tables)); + tables[0].alias= tables[0].table_name= (char*) "servers"; + tables[0].db= (char*) "mysql"; + tables[0].lock_type= TL_READ; + + if (simple_open_n_lock_tables(thd, tables)) + { + sql_print_error("Fatal error: Can't open and lock privilege tables: %s", + thd->net.last_error); + goto end; + } + + DBUG_PRINT("info", ("locking servers_cache")); + VOID(pthread_mutex_lock(&servers_cache_mutex)); + + //old_servers_cache= servers_cache; + //old_mem=mem; + + if ((return_val= servers_load(thd, tables))) + { // Error. Revert to old list + /* blast, for now, we have no servers, discuss later way to preserve */ + + DBUG_PRINT("error",("Reverting to old privileges")); + servers_free(); + } + + DBUG_PRINT("info", ("unlocking servers_cache")); + VOID(pthread_mutex_unlock(&servers_cache_mutex)); + +end: + close_thread_tables(thd); + DBUG_RETURN(return_val); +} + +/* + Initialize structures responsible for servers used in federated + server scheme information for them from the server + table in the 'mysql' database. + + SYNOPSIS + get_server_from_table_to_cache() + TABLE *table open table pointer + + + NOTES + This function takes a TABLE pointer (pointing to an opened + table). With this open table, a FOREIGN_SERVER struct pointer + is allocated into root memory, then each member of the FOREIGN_SERVER + struct is populated. A char pointer takes the return value of get_field + for each column we're interested in obtaining, and if that pointer + isn't 0x0, the FOREIGN_SERVER member is set to that value, otherwise, + is set to the value of an empty string, since get_field would set it to + 0x0 if the column's value is empty, even if the default value for that + column is NOT NULL. + + RETURN VALUES + 0 ok + 1 could not insert server struct into global servers cache +*/ + +my_bool get_server_from_table_to_cache(TABLE *table) +{ + /* alloc a server struct */ + char *ptr; + char *blank= (char*)""; + FOREIGN_SERVER *server= (FOREIGN_SERVER *)alloc_root(&mem, + sizeof(FOREIGN_SERVER)); + DBUG_ENTER("get_server_from_table_to_cache"); + table->use_all_columns(); + + /* get each field into the server struct ptr */ + server->server_name= get_field(&mem, table->field[0]); + server->server_name_length= strlen(server->server_name); + ptr= get_field(&mem, table->field[1]); + server->host= ptr ? ptr : blank; + ptr= get_field(&mem, table->field[2]); + server->db= ptr ? ptr : blank; + ptr= get_field(&mem, table->field[3]); + server->username= ptr ? ptr : blank; + ptr= get_field(&mem, table->field[4]); + server->password= ptr ? ptr : blank; + ptr= get_field(&mem, table->field[5]); + server->sport= ptr ? ptr : blank; + + server->port= server->sport ? atoi(server->sport) : 0; + + ptr= get_field(&mem, table->field[6]); + server->socket= ptr && strlen(ptr) ? ptr : NULL; + ptr= get_field(&mem, table->field[7]); + server->scheme= ptr ? ptr : blank; + ptr= get_field(&mem, table->field[8]); + server->owner= ptr ? ptr : blank; + DBUG_PRINT("info", ("server->server_name %s", server->server_name)); + DBUG_PRINT("info", ("server->host %s", server->host)); + DBUG_PRINT("info", ("server->db %s", server->db)); + DBUG_PRINT("info", ("server->username %s", server->username)); + DBUG_PRINT("info", ("server->password %s", server->password)); + DBUG_PRINT("info", ("server->socket %s", server->socket)); + if (my_hash_insert(&servers_cache, (byte*) server)) + { + DBUG_PRINT("info", ("had a problem inserting server %s at %lx", + server->server_name, (long unsigned int) server)); + // error handling needed here + DBUG_RETURN(TRUE); + } + DBUG_RETURN(FALSE); +} + +/* + SYNOPSIS + server_exists_in_table() + THD *thd - thread pointer + LEX_SERVER_OPTIONS *server_options - pointer to Lex->server_options + + NOTES + This function takes a LEX_SERVER_OPTIONS struct, which is very much the + same type of structure as a FOREIGN_SERVER, it contains the values parsed + in any one of the [CREATE|DELETE|DROP] SERVER statements. Using the + member "server_name", index_read_idx either founds the record and returns + 1, or doesn't find the record, and returns 0 + + RETURN VALUES + 0 record not found + 1 record found +*/ + +my_bool server_exists_in_table(THD *thd, LEX_SERVER_OPTIONS *server_options) +{ + byte server_key[MAX_KEY_LENGTH]; + int result= 1; + int error= 0; + TABLE_LIST tables; + TABLE *table; + + DBUG_ENTER("server_exists"); + + bzero((char*) &tables, sizeof(tables)); + tables.db= (char*) "mysql"; + tables.alias= tables.table_name= (char*) "servers"; + + table->use_all_columns(); + + /* need to open before acquiring THR_LOCK_plugin or it will deadlock */ + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + DBUG_RETURN(TRUE); + + rw_wrlock(&THR_LOCK_servers); + VOID(pthread_mutex_lock(&servers_cache_mutex)); + + /* set the field that's the PK to the value we're looking for */ + table->field[0]->store(server_options->server_name, + server_options->server_name_length, + system_charset_info); + + if ((error= table->file->index_read_idx(table->record[0], 0, + (byte *)table->field[0]->ptr, + table->key_info[0].key_length, + HA_READ_KEY_EXACT))) + { + if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + { + table->file->print_error(error, MYF(0)); + result= -1; + } + result= 0; + DBUG_PRINT("info",("record for server '%s' not found!", + server_options->server_name)); + } + + VOID(pthread_mutex_unlock(&servers_cache_mutex)); + rw_unlock(&THR_LOCK_servers); + DBUG_RETURN(result); +} + +/* + SYNOPSIS + insert_server() + THD *thd - thread pointer + FOREIGN_SERVER *server - pointer to prepared FOREIGN_SERVER struct + + NOTES + This function takes a server object that is has all members properly + prepared, ready to be inserted both into the mysql.servers table and + the servers cache. + + RETURN VALUES + 0 - no error + other - error code +*/ + +int insert_server(THD *thd, FOREIGN_SERVER *server) +{ + byte server_key[MAX_KEY_LENGTH]; + int error= 0; + TABLE_LIST tables; + TABLE *table; + + DBUG_ENTER("insert_server"); + + bzero((char*) &tables, sizeof(tables)); + tables.db= (char*) "mysql"; + tables.alias= tables.table_name= (char*) "servers"; + + /* need to open before acquiring THR_LOCK_plugin or it will deadlock */ + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + DBUG_RETURN(TRUE); + + /* lock mutex to make sure no changes happen */ + VOID(pthread_mutex_lock(&servers_cache_mutex)); + + /* lock table */ + rw_wrlock(&THR_LOCK_servers); + + /* insert the server into the table */ + if ((error= insert_server_record(table, server))) + goto end; + + /* insert the server into the cache */ + if ((error= insert_server_record_into_cache(server))) + goto end; + +end: + /* unlock the table */ + rw_unlock(&THR_LOCK_servers); + VOID(pthread_mutex_unlock(&servers_cache_mutex)); + DBUG_RETURN(error); +} + +/* + SYNOPSIS + int insert_server_record_into_cache() + FOREIGN_SERVER *server + + NOTES + This function takes a FOREIGN_SERVER pointer to an allocated (root mem) + and inserts it into the global servers cache + + RETURN VALUE + 0 - no error + >0 - error code + +*/ + +int insert_server_record_into_cache(FOREIGN_SERVER *server) +{ + int error=0; + DBUG_ENTER("insert_server_record_into_cache"); + /* + We succeded in insertion of the server to the table, now insert + the server to the cache + */ + DBUG_PRINT("info", ("inserting server %s at %lx, length %d", + server->server_name, (long unsigned int) server, + server->server_name_length)); + if (my_hash_insert(&servers_cache, (byte*) server)) + { + DBUG_PRINT("info", ("had a problem inserting server %s at %lx", + server->server_name, (long unsigned int) server)); + // error handling needed here + error= 1; + } + DBUG_RETURN(error); +} + +/* + SYNOPSIS + store_server_fields() + TABLE *table + FOREIGN_SERVER *server + + NOTES + This function takes an opened table object, and a pointer to an + allocated FOREIGN_SERVER struct, and then stores each member of + the FOREIGN_SERVER to the appropriate fields in the table, in + advance of insertion into the mysql.servers table + + RETURN VALUE + VOID + +*/ + +void store_server_fields(TABLE *table, FOREIGN_SERVER *server) +{ + + table->use_all_columns(); + /* + "server" has already been prepped by prepare_server_struct_for_<> + so, all we need to do is check if the value is set (> -1 for port) + + If this happens to be an update, only the server members that + have changed will be set. If an insert, then all will be set, + even if with empty strings + */ + if (server->host) + table->field[1]->store(server->host, + (uint) strlen(server->host), system_charset_info); + if (server->db) + table->field[2]->store(server->db, + (uint) strlen(server->db), system_charset_info); + if (server->username) + table->field[3]->store(server->username, + (uint) strlen(server->username), system_charset_info); + if (server->password) + table->field[4]->store(server->password, + (uint) strlen(server->password), system_charset_info); + if (server->port > -1) + table->field[5]->store(server->port); + + if (server->socket) + table->field[6]->store(server->socket, + (uint) strlen(server->socket), system_charset_info); + if (server->scheme) + table->field[7]->store(server->scheme, + (uint) strlen(server->scheme), system_charset_info); + if (server->owner) + table->field[8]->store(server->owner, + (uint) strlen(server->owner), system_charset_info); +} + +/* + SYNOPSIS + insert_server_record() + TABLE *table + FOREIGN_SERVER *server + + NOTES + This function takes the arguments of an open table object and a pointer + to an allocated FOREIGN_SERVER struct. It stores the server_name into + the first field of the table (the primary key, server_name column). With + this, index_read_idx is called, if the record is found, an error is set + to ER_FOREIGN_SERVER_EXISTS (the server with that server name exists in the + table), if not, then store_server_fields stores all fields of the + FOREIGN_SERVER to the table, then ha_write_row is inserted. If an error + is encountered in either index_read_idx or ha_write_row, then that error + is returned + + RETURN VALUE + 0 - no errors + >0 - error code + + */ + +int insert_server_record(TABLE *table, FOREIGN_SERVER *server) +{ + int error; + DBUG_ENTER("insert_server_record"); + table->use_all_columns(); + + /* set the field that's the PK to the value we're looking for */ + table->field[0]->store(server->server_name, + server->server_name_length, + system_charset_info); + + /* read index until record is that specified in server_name */ + if ((error= table->file->index_read_idx(table->record[0], 0, + (byte *)table->field[0]->ptr, + table->key_info[0].key_length, + HA_READ_KEY_EXACT))) + { + /* if not found, err */ + if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + { + table->file->print_error(error, MYF(0)); + error= 1; + } + /* store each field to be inserted */ + store_server_fields(table, server); + + DBUG_PRINT("info",("record for server '%s' not found!", + server->server_name)); + /* write/insert the new server */ + if ((error=table->file->ha_write_row(table->record[0]))) + { + table->file->print_error(error, MYF(0)); + } + else + error= 0; + } + else + error= ER_FOREIGN_SERVER_EXISTS; + DBUG_RETURN(error); +} + +/* + SYNOPSIS + drop_server() + THD *thd + LEX_SERVER_OPTIONS *server_options + + NOTES + This function takes as its arguments a THD object pointer and a pointer + to a LEX_SERVER_OPTIONS struct from the parser. The member 'server_name' + of this LEX_SERVER_OPTIONS struct contains the value of the server to be + deleted. The mysql.servers table is opened via open_ltable, a table object + returned, the servers cache mutex locked, then delete_server_record is + called with this table object and LEX_SERVER_OPTIONS server_name and + server_name_length passed, containing the name of the server to be + dropped/deleted, then delete_server_record_in_cache is called to delete + the server from the servers cache. + + RETURN VALUE + 0 - no error + > 0 - error code +*/ + +int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options) +{ + byte server_key[MAX_KEY_LENGTH]; + int error= 0; + TABLE_LIST tables; + TABLE *table; + + DBUG_ENTER("drop_server"); + DBUG_PRINT("info", ("server name server->server_name %s", + server_options->server_name)); + + bzero((char*) &tables, sizeof(tables)); + tables.db= (char*) "mysql"; + tables.alias= tables.table_name= (char*) "servers"; + + /* need to open before acquiring THR_LOCK_plugin or it will deadlock */ + if (! (table= open_ltable(thd, &tables, TL_WRITE))) + DBUG_RETURN(TRUE); + + rw_wrlock(&THR_LOCK_servers); + VOID(pthread_mutex_lock(&servers_cache_mutex)); + + + if ((error= delete_server_record(table, + server_options->server_name, + server_options->server_name_length))) + goto end; + + + if ((error= delete_server_record_in_cache(server_options))) + goto end; + +end: + VOID(pthread_mutex_unlock(&servers_cache_mutex)); + rw_unlock(&THR_LOCK_servers); + DBUG_RETURN(error); +} +/* + + SYNOPSIS + delete_server_record_in_cache() + LEX_SERVER_OPTIONS *server_options + + NOTES + This function's argument is a LEX_SERVER_OPTIONS struct pointer. This + function uses the "server_name" and "server_name_length" members of the + lex->server_options to search for the server in the servers_cache. Upon + returned the server (pointer to a FOREIGN_SERVER struct), it then deletes + that server from the servers_cache hash. + + RETURN VALUE + 0 - no error + +*/ + +int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options) +{ + + int error= 0; + FOREIGN_SERVER *server; + DBUG_ENTER("delete_server_record_in_cache"); + + DBUG_PRINT("info",("trying to obtain server name %s length %d", + server_options->server_name, + server_options->server_name_length)); + + + if (!(server= (FOREIGN_SERVER *) hash_search(&servers_cache, + (byte*) server_options->server_name, + server_options->server_name_length))) + { + DBUG_PRINT("info", ("server_name %s length %d not found!", + server_options->server_name, + server_options->server_name_length)); + // what should be done if not found in the cache? + } + /* + We succeded in deletion of the server to the table, now delete + the server from the cache + */ + DBUG_PRINT("info",("deleting server %s length %d", + server->server_name, + server->server_name_length)); + + if (server) + VOID(hash_delete(&servers_cache, (byte*) server)); + + servers_version++; /* servers updated */ + + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + update_server() + THD *thd + FOREIGN_SERVER *existing + FOREIGN_SERVER *altered + + NOTES + This function takes as arguments a THD object pointer, and two pointers, + one pointing to the existing FOREIGN_SERVER struct "existing" (which is + the current record as it is) and another pointer pointing to the + FOREIGN_SERVER struct with the members containing the modified/altered + values that need to be updated in both the mysql.servers table and the + servers_cache. It opens a table, passes the table and the altered + FOREIGN_SERVER pointer, which will be used to update the mysql.servers + table for the particular server via the call to update_server_record, + and in the servers_cache via update_server_record_in_cache. + + RETURN VALUE + 0 - no error + >0 - error code + +*/ + +int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered) +{ + int error= 0; + TABLE *table; + TABLE_LIST tables; + DBUG_ENTER("update_server"); + + bzero((char*) &tables, sizeof(tables)); + tables.db= (char*)"mysql"; + tables.alias= tables.table_name= (char*)"servers"; + + if (!(table= open_ltable(thd, &tables, TL_WRITE))) + DBUG_RETURN(1); + + rw_wrlock(&THR_LOCK_servers); + if ((error= update_server_record(table, altered))) + goto end; + + update_server_record_in_cache(existing, altered); + +end: + rw_unlock(&THR_LOCK_servers); + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + update_server_record_in_cache() + FOREIGN_SERVER *existing + FOREIGN_SERVER *altered + + NOTES + This function takes as an argument the FOREIGN_SERVER structi pointer + for the existing server and the FOREIGN_SERVER struct populated with only + the members which have been updated. It then "merges" the "altered" struct + members to the existing server, the existing server then represents an + updated server. Then, the existing record is deleted from the servers_cache + HASH, then the updated record inserted, in essence replacing the old + record. + + RETURN VALUE + 0 - no error + 1 - error + +*/ + +int update_server_record_in_cache(FOREIGN_SERVER *existing, + FOREIGN_SERVER *altered) +{ + int error= 0; + DBUG_ENTER("update_server_record_in_cache"); + + /* + update the members that haven't been change in the altered server struct + with the values of the existing server struct + */ + merge_server_struct(existing, altered); + + /* + delete the existing server struct from the server cache + */ + VOID(hash_delete(&servers_cache, (byte*)existing)); + + /* + Insert the altered server struct into the server cache + */ + if (my_hash_insert(&servers_cache, (byte*)altered)) + { + DBUG_PRINT("info", ("had a problem inserting server %s at %lx", + altered->server_name, (long unsigned int) altered)); + error= 1; + } + + servers_version++; /* servers updated */ + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + merge_server_struct() + FOREIGN_SERVER *from + FOREIGN_SERVER *to + + NOTES + This function takes as its arguments two pointers each to an allocated + FOREIGN_SERVER struct. The first FOREIGN_SERVER struct represents the struct + that we will obtain values from (hence the name "from"), the second + FOREIGN_SERVER struct represents which FOREIGN_SERVER struct we will be + "copying" any members that have a value to (hence the name "to") + + RETURN VALUE + VOID + +*/ + +void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to) +{ + DBUG_ENTER("merge_server_struct"); + if (!to->host) + to->host= strdup_root(&mem, from->host); + if (!to->db) + to->db= strdup_root(&mem, from->db); + if (!to->username) + to->username= strdup_root(&mem, from->username); + if (!to->password) + to->password= strdup_root(&mem, from->password); + if (to->port == -1) + to->port= from->port; + if (!to->socket) + to->socket= strdup_root(&mem, from->socket); + if (!to->scheme) + to->scheme= strdup_root(&mem, from->scheme); + if (!to->owner) + to->owner= strdup_root(&mem, from->owner); + + DBUG_VOID_RETURN; +} + +/* + + SYNOPSIS + update_server_record() + TABLE *table + FOREIGN_SERVER *server + + NOTES + This function takes as its arguments an open TABLE pointer, and a pointer + to an allocated FOREIGN_SERVER structure representing an updated record + which needs to be inserted. The primary key, server_name is stored to field + 0, then index_read_idx is called to read the index to that record, the + record then being ready to be updated, if found. If not found an error is + set and error message printed. If the record is found, store_record is + called, then store_server_fields stores each field from the the members of + the updated FOREIGN_SERVER struct. + + RETURN VALUE + 0 - no error + +*/ + +int update_server_record(TABLE *table, FOREIGN_SERVER *server) +{ + int error=0; + DBUG_ENTER("update_server_record"); + table->use_all_columns(); + /* set the field that's the PK to the value we're looking for */ + table->field[0]->store(server->server_name, + server->server_name_length, + system_charset_info); + + if ((error= table->file->index_read_idx(table->record[0], 0, + (byte *)table->field[0]->ptr, + table->key_info[0].key_length, + HA_READ_KEY_EXACT))) + { + if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + { + table->file->print_error(error, MYF(0)); + error= 1; + } + DBUG_PRINT("info",("server not found!")); + error= ER_FOREIGN_SERVER_DOESNT_EXIST; + } + else + { + /* ok, so we can update since the record exists in the table */ + store_record(table,record[1]); + store_server_fields(table, server); + if ((error=table->file->ha_update_row(table->record[1],table->record[0]))) + { + DBUG_PRINT("info",("problems with ha_update_row %d", error)); + goto end; + } + } + +end: + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + delete_server_record() + TABLE *table + char *server_name + int server_name_length + + NOTES + + RETURN VALUE + 0 - no error + +*/ + +int delete_server_record(TABLE *table, + char *server_name, + int server_name_length) +{ + int error= 0; + DBUG_ENTER("delete_server_record"); + table->use_all_columns(); + + /* set the field that's the PK to the value we're looking for */ + table->field[0]->store(server_name, server_name_length, system_charset_info); + + if ((error= table->file->index_read_idx(table->record[0], 0, + (byte *)table->field[0]->ptr, + table->key_info[0].key_length, + HA_READ_KEY_EXACT))) + { + if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) + { + table->file->print_error(error, MYF(0)); + error= 1; + } + DBUG_PRINT("info",("server not found!")); + error= ER_FOREIGN_SERVER_DOESNT_EXIST; + } + else + { + if ((error= table->file->ha_delete_row(table->record[0]))) + table->file->print_error(error, MYF(0)); + } + + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + create_server() + THD *thd + LEX_SERVER_OPTIONS *server_options + + NOTES + + RETURN VALUE + 0 - no error + +*/ + +int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options) +{ + int error; + FOREIGN_SERVER *server; + + DBUG_ENTER("create_server"); + DBUG_PRINT("info", ("server_options->server_name %s", + server_options->server_name)); + + server= (FOREIGN_SERVER *)alloc_root(&mem, + sizeof(FOREIGN_SERVER)); + + if ((error= prepare_server_struct_for_insert(server_options, server))) + goto end; + + if ((error= insert_server(thd, server))) + goto end; + + DBUG_PRINT("info", ("error returned %d", error)); + +end: + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + alter_server() + THD *thd + LEX_SERVER_OPTIONS *server_options + + NOTES + + RETURN VALUE + 0 - no error + +*/ + +int alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options) +{ + int error= 0; + FOREIGN_SERVER *altered, *existing; + DBUG_ENTER("alter_server"); + DBUG_PRINT("info", ("server_options->server_name %s", + server_options->server_name)); + + altered= (FOREIGN_SERVER *)alloc_root(&mem, + sizeof(FOREIGN_SERVER)); + + VOID(pthread_mutex_lock(&servers_cache_mutex)); + + if (!(existing= (FOREIGN_SERVER *) hash_search(&servers_cache, + (byte*) server_options->server_name, + server_options->server_name_length))) + { + error= ER_FOREIGN_SERVER_DOESNT_EXIST; + goto end; + } + + if ((error= prepare_server_struct_for_update(server_options, existing, altered))) + goto end; + + if ((error= update_server(thd, existing, altered))) + goto end; + +end: + DBUG_PRINT("info", ("error returned %d", error)); + VOID(pthread_mutex_unlock(&servers_cache_mutex)); + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + prepare_server_struct_for_insert() + LEX_SERVER_OPTIONS *server_options + FOREIGN_SERVER *server + + NOTES + + RETURN VALUE + 0 - no error + +*/ + +int prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options, + FOREIGN_SERVER *server) +{ + int error; + char *unset_ptr= (char*)""; + DBUG_ENTER("prepare_server_struct"); + + error= 0; + + /* these two MUST be set */ + server->server_name= strdup_root(&mem, server_options->server_name); + server->server_name_length= server_options->server_name_length; + + server->host= server_options->host ? + strdup_root(&mem, server_options->host) : unset_ptr; + + server->db= server_options->db ? + strdup_root(&mem, server_options->db) : unset_ptr; + + server->username= server_options->username ? + strdup_root(&mem, server_options->username) : unset_ptr; + + server->password= server_options->password ? + strdup_root(&mem, server_options->password) : unset_ptr; + + /* set to 0 if not specified */ + server->port= server_options->port > -1 ? + server_options->port : 0; + + server->socket= server_options->socket ? + strdup_root(&mem, server_options->socket) : unset_ptr; + + server->scheme= server_options->scheme ? + strdup_root(&mem, server_options->scheme) : unset_ptr; + + server->owner= server_options->owner ? + strdup_root(&mem, server_options->owner) : unset_ptr; + + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + prepare_server_struct_for_update() + LEX_SERVER_OPTIONS *server_options + + NOTES + + RETURN VALUE + 0 - no error + +*/ + +int prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options, + FOREIGN_SERVER *existing, + FOREIGN_SERVER *altered) +{ + int error; + DBUG_ENTER("prepare_server_struct_for_update"); + error= 0; + + altered->server_name= strdup_root(&mem, server_options->server_name); + altered->server_name_length= server_options->server_name_length; + DBUG_PRINT("info", ("existing name %s altered name %s", + existing->server_name, altered->server_name)); + + /* + The logic here is this: is this value set AND is it different + than the existing value? + */ + altered->host= + (server_options->host && (strcmp(server_options->host, existing->host))) ? + strdup_root(&mem, server_options->host) : 0; + + altered->db= + (server_options->db && (strcmp(server_options->db, existing->db))) ? + strdup_root(&mem, server_options->db) : 0; + + altered->username= + (server_options->username && + (strcmp(server_options->username, existing->username))) ? + strdup_root(&mem, server_options->username) : 0; + + altered->password= + (server_options->password && + (strcmp(server_options->password, existing->password))) ? + strdup_root(&mem, server_options->password) : 0; + + /* + port is initialised to -1, so if unset, it will be -1 + */ + altered->port= (server_options->port > -1 && + server_options->port != existing->port) ? + server_options->port : -1; + + altered->socket= + (server_options->socket && + (strcmp(server_options->socket, existing->socket))) ? + strdup_root(&mem, server_options->socket) : 0; + + altered->scheme= + (server_options->scheme && + (strcmp(server_options->scheme, existing->scheme))) ? + strdup_root(&mem, server_options->scheme) : 0; + + altered->owner= + (server_options->owner && + (strcmp(server_options->owner, existing->owner))) ? + strdup_root(&mem, server_options->owner) : 0; + + DBUG_RETURN(error); +} + +/* + + SYNOPSIS + servers_free() + bool end + + NOTES + + RETURN VALUE + void + +*/ + +void servers_free(bool end) +{ + DBUG_ENTER("servers_free"); + if (!servers_cache_initialised) + DBUG_VOID_RETURN; + VOID(pthread_mutex_destroy(&servers_cache_mutex)); + servers_cache_initialised=0; + free_root(&mem,MYF(0)); + hash_free(&servers_cache); + DBUG_VOID_RETURN; +} + + + +/* + + SYNOPSIS + get_server_by_name() + const char *server_name + + NOTES + + RETURN VALUE + FOREIGN_SERVER * + +*/ + +FOREIGN_SERVER *get_server_by_name(const char *server_name) +{ + ulong error_num=0; + uint i, server_name_length; + FOREIGN_SERVER *server= 0; + DBUG_ENTER("get_server_by_name"); + DBUG_PRINT("info", ("server_name %s", server_name)); + + server_name_length= strlen(server_name); + + if (! server_name || !strlen(server_name)) + { + DBUG_PRINT("info", ("server_name not defined!")); + error_num= 1; + DBUG_RETURN((FOREIGN_SERVER *)NULL); + } + + DBUG_PRINT("info", ("locking servers_cache")); + VOID(pthread_mutex_lock(&servers_cache_mutex)); + if (!(server= (FOREIGN_SERVER *) hash_search(&servers_cache, + (byte*) server_name, + server_name_length))) + { + DBUG_PRINT("info", ("server_name %s length %d not found!", + server_name, server_name_length)); + server= (FOREIGN_SERVER *) NULL; + } + DBUG_PRINT("info", ("unlocking servers_cache")); + VOID(pthread_mutex_unlock(&servers_cache_mutex)); + DBUG_RETURN(server); + +} diff --git a/sql/sql_servers.h b/sql/sql_servers.h new file mode 100644 index 00000000000..36fb4d07d1b --- /dev/null +++ b/sql/sql_servers.h @@ -0,0 +1,65 @@ +/* Copyright (C) 2006 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "slave.h" // for tables_ok(), rpl_filter + +/* structs */ +typedef struct st_federated_server +{ + char *server_name; + long port; + uint server_name_length; + char *db, *scheme, *username, *password, *socket, *owner, *host, *sport; +} FOREIGN_SERVER; + +/* cache handlers */ +my_bool servers_init(bool dont_read_server_table); +static my_bool servers_load(THD *thd, TABLE_LIST *tables); +my_bool servers_reload(THD *thd); +my_bool get_server_from_table_to_cache(TABLE *table); +void servers_free(bool end=0); + +/* insert functions */ +int create_server(THD *thd, LEX_SERVER_OPTIONS *server_options); +int insert_server(THD *thd, FOREIGN_SERVER *server_options); +int insert_server_record(TABLE *table, FOREIGN_SERVER *server); +int insert_server_record_into_cache(FOREIGN_SERVER *server); +void store_server_fields_for_insert(TABLE *table, FOREIGN_SERVER *server); +void store_server_fields_for_insert(TABLE *table, + FOREIGN_SERVER *existing, + FOREIGN_SERVER *altered); +int prepare_server_struct_for_insert(LEX_SERVER_OPTIONS *server_options, + FOREIGN_SERVER *server); + +/* drop functions */ +int drop_server(THD *thd, LEX_SERVER_OPTIONS *server_options); +int delete_server_record(TABLE *table, + char *server_name, + int server_name_length); +int delete_server_record_in_cache(LEX_SERVER_OPTIONS *server_options); + +/* update functions */ +int alter_server(THD *thd, LEX_SERVER_OPTIONS *server_options); +int prepare_server_struct_for_update(LEX_SERVER_OPTIONS *server_options, + FOREIGN_SERVER *existing, + FOREIGN_SERVER *altered); +int update_server(THD *thd, FOREIGN_SERVER *existing, FOREIGN_SERVER *altered); +int update_server_record(TABLE *table, FOREIGN_SERVER *server); +int update_server_record_in_cache(FOREIGN_SERVER *existing, + FOREIGN_SERVER *altered); +/* utility functions */ +void merge_server_struct(FOREIGN_SERVER *from, FOREIGN_SERVER *to); +FOREIGN_SERVER *get_server_by_name(const char *server_name); +my_bool server_exists_in_table(THD *thd, char *server_name); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0ebccba43ca..c4bb6a8fc92 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1116,7 +1115,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, if (flags & NOT_NULL_FLAG) packet->append(STRING_WITH_LEN(" NOT NULL")); - else if (field->type() == FIELD_TYPE_TIMESTAMP) + else if (field->type() == MYSQL_TYPE_TIMESTAMP) { /* TIMESTAMP field require explicit NULL flag, because unlike @@ -1132,7 +1131,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, has_now_default= table->timestamp_field == field && field->unireg_check != Field::TIMESTAMP_UN_FIELD; - has_default= (field->type() != FIELD_TYPE_BLOB && + has_default= (field->type() != MYSQL_TYPE_BLOB && !(field->flags & NO_DEFAULT_VALUE_FLAG) && field->unireg_check != Field::NEXT_NUMBER && !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) @@ -1267,7 +1266,7 @@ int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet, to the CREATE TABLE statement */ - if ((for_str= file->get_tablespace_name(thd))) + if ((for_str= file->get_tablespace_name(thd,0,0))) { packet->append(STRING_WITH_LEN(" /*!50100 TABLESPACE ")); packet->append(for_str, strlen(for_str)); @@ -1625,7 +1624,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) field_list.push_back(field=new Item_empty_string("db",NAME_LEN)); field->maybe_null=1; field_list.push_back(new Item_empty_string("Command",16)); - field_list.push_back(new Item_return_int("Time",7, FIELD_TYPE_LONG)); + field_list.push_back(new Item_return_int("Time",7, MYSQL_TYPE_LONG)); field_list.push_back(field=new Item_empty_string("State",30)); field->maybe_null=1; field_list.push_back(field=new Item_empty_string("Info",max_query_length)); @@ -3098,7 +3097,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, pos=(byte*) ((flags & NOT_NULL_FLAG) ? "NO" : "YES"); table->field[6]->store((const char*) pos, strlen((const char*) pos), cs); - is_blob= (field->type() == FIELD_TYPE_BLOB); + is_blob= (field->type() == MYSQL_TYPE_BLOB); if (field->has_charset() || is_blob || field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type field->real_type() == MYSQL_TYPE_STRING) // For binary type @@ -3122,25 +3121,25 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables, decimals= field->decimals(); switch (field->type()) { - case FIELD_TYPE_NEWDECIMAL: + case MYSQL_TYPE_NEWDECIMAL: field_length= ((Field_new_decimal*) field)->precision; break; - case FIELD_TYPE_DECIMAL: + case MYSQL_TYPE_DECIMAL: field_length= field->field_length - (decimals ? 2 : 1); break; - case FIELD_TYPE_TINY: - case FIELD_TYPE_SHORT: - case FIELD_TYPE_LONG: - case FIELD_TYPE_LONGLONG: - case FIELD_TYPE_INT24: + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_INT24: field_length= field->max_length() - 1; break; - case FIELD_TYPE_BIT: + case MYSQL_TYPE_BIT: field_length= field->max_length(); decimals= -1; // return NULL break; - case FIELD_TYPE_FLOAT: - case FIELD_TYPE_DOUBLE: + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: field_length= field->field_length; if (decimals == NOT_FIXED_DEC) decimals= -1; // return NULL @@ -3974,7 +3973,7 @@ static void store_schema_partitions_record(THD *thd, TABLE *schema_table, strlen(part_elem->tablespace_name), cs); else { - char *ts= showing_table->file->get_tablespace_name(thd); + char *ts= showing_table->file->get_tablespace_name(thd,0,0); if(ts) { table->field[24]->store(ts, strlen(ts), cs); diff --git a/sql/sql_show.h b/sql/sql_show.h index 29cd52eb9fd..d5c3f3bf675 100644 --- a/sql/sql_show.h +++ b/sql/sql_show.h @@ -1,3 +1,17 @@ +/* Copyright (C) 2006 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef SQL_SHOW_H #define SQL_SHOW_H diff --git a/sql/sql_sort.h b/sql/sql_sort.h index 1831c4a2f3d..da28ca07e2c 100644 --- a/sql/sql_sort.h +++ b/sql/sql_sort.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_state.c b/sql/sql_state.c index 355b847f239..511dc65917b 100644 --- a/sql/sql_state.c +++ b/sql/sql_state.c @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 29b53560067..b307953addc 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_string.h b/sql/sql_string.h index 6481c20d042..08c3a4cb60d 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c8f6e09fecb..35a5547a730 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -2024,10 +2023,10 @@ int prepare_create_field(create_field *sql_field, DBUG_ASSERT(sql_field->charset); switch (sql_field->sql_type) { - case FIELD_TYPE_BLOB: - case FIELD_TYPE_MEDIUM_BLOB: - case FIELD_TYPE_TINY_BLOB: - case FIELD_TYPE_LONG_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_LONG_BLOB: sql_field->pack_flag=FIELDFLAG_BLOB | pack_length_to_packflag(sql_field->pack_length - portable_sizeof_char_ptr); @@ -2037,7 +2036,7 @@ int prepare_create_field(create_field *sql_field, sql_field->unireg_check=Field::BLOB_FIELD; (*blob_columns)++; break; - case FIELD_TYPE_GEOMETRY: + case MYSQL_TYPE_GEOMETRY: #ifdef HAVE_SPATIAL if (!(table_flags & HA_CAN_GEOMETRY)) { @@ -2077,12 +2076,12 @@ int prepare_create_field(create_field *sql_field, } #endif /* fall through */ - case FIELD_TYPE_STRING: + case MYSQL_TYPE_STRING: sql_field->pack_flag=0; if (sql_field->charset->state & MY_CS_BINSORT) sql_field->pack_flag|=FIELDFLAG_BINARY; break; - case FIELD_TYPE_ENUM: + case MYSQL_TYPE_ENUM: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | FIELDFLAG_INTERVAL; if (sql_field->charset->state & MY_CS_BINSORT) @@ -2092,7 +2091,7 @@ int prepare_create_field(create_field *sql_field, sql_field->interval, sql_field->charset); break; - case FIELD_TYPE_SET: + case MYSQL_TYPE_SET: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | FIELDFLAG_BITFIELD; if (sql_field->charset->state & MY_CS_BINSORT) @@ -2102,19 +2101,19 @@ int prepare_create_field(create_field *sql_field, sql_field->interval, sql_field->charset); break; - case FIELD_TYPE_DATE: // Rest of string types - case FIELD_TYPE_NEWDATE: - case FIELD_TYPE_TIME: - case FIELD_TYPE_DATETIME: - case FIELD_TYPE_NULL: + case MYSQL_TYPE_DATE: // Rest of string types + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_NULL: sql_field->pack_flag=f_settype((uint) sql_field->sql_type); break; - case FIELD_TYPE_BIT: + case MYSQL_TYPE_BIT: /* We have sql_field->pack_flag already set here, see mysql_prepare_table(). */ break; - case FIELD_TYPE_NEWDECIMAL: + case MYSQL_TYPE_NEWDECIMAL: sql_field->pack_flag=(FIELDFLAG_NUMBER | (sql_field->flags & UNSIGNED_FLAG ? 0 : FIELDFLAG_DECIMAL) | @@ -2122,7 +2121,7 @@ int prepare_create_field(create_field *sql_field, FIELDFLAG_ZEROFILL : 0) | (sql_field->decimals << FIELDFLAG_DEC_SHIFT)); break; - case FIELD_TYPE_TIMESTAMP: + case MYSQL_TYPE_TIMESTAMP: /* We should replace old TIMESTAMP fields with their newer analogs */ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD) { @@ -2247,10 +2246,10 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, */ if (sql_field->def && save_cs != sql_field->def->collation.collation && - (sql_field->sql_type == FIELD_TYPE_VAR_STRING || - sql_field->sql_type == FIELD_TYPE_STRING || - sql_field->sql_type == FIELD_TYPE_SET || - sql_field->sql_type == FIELD_TYPE_ENUM)) + (sql_field->sql_type == MYSQL_TYPE_VAR_STRING || + sql_field->sql_type == MYSQL_TYPE_STRING || + sql_field->sql_type == MYSQL_TYPE_SET || + sql_field->sql_type == MYSQL_TYPE_ENUM)) { Query_arena backup_arena; bool need_to_change_arena= !thd->stmt_arena->is_conventional(); @@ -2275,8 +2274,8 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, } } - if (sql_field->sql_type == FIELD_TYPE_SET || - sql_field->sql_type == FIELD_TYPE_ENUM) + if (sql_field->sql_type == MYSQL_TYPE_SET || + sql_field->sql_type == MYSQL_TYPE_ENUM) { uint32 dummy; CHARSET_INFO *cs= sql_field->charset; @@ -2322,7 +2321,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, interval->type_lengths[i]); interval->type_lengths[i]= lengthsp; ((uchar *)interval->type_names[i])[lengthsp]= '\0'; - if (sql_field->sql_type == FIELD_TYPE_SET) + if (sql_field->sql_type == MYSQL_TYPE_SET) { if (cs->coll->instr(cs, interval->type_names[i], interval->type_lengths[i], @@ -2336,7 +2335,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, sql_field->interval_list.empty(); // Don't need interval_list anymore } - if (sql_field->sql_type == FIELD_TYPE_SET) + if (sql_field->sql_type == MYSQL_TYPE_SET) { uint32 field_length; if (sql_field->def != NULL) @@ -2372,10 +2371,10 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, calculate_interval_lengths(cs, interval, &dummy, &field_length); sql_field->length= field_length + (interval->count - 1); } - else /* FIELD_TYPE_ENUM */ + else /* MYSQL_TYPE_ENUM */ { uint32 field_length; - DBUG_ASSERT(sql_field->sql_type == FIELD_TYPE_ENUM); + DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM); if (sql_field->def != NULL) { String str, *def= sql_field->def->val_str(&str); @@ -2405,7 +2404,7 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1); } - if (sql_field->sql_type == FIELD_TYPE_BIT) + if (sql_field->sql_type == MYSQL_TYPE_BIT) { sql_field->pack_flag= FIELDFLAG_NUMBER; if (file->ha_table_flags() & HA_CAN_BIT_FIELD) @@ -3061,7 +3060,7 @@ static bool prepare_blob_field(THD *thd, create_field *sql_field) MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen); DBUG_RETURN(1); } - sql_field->sql_type= FIELD_TYPE_BLOB; + sql_field->sql_type= MYSQL_TYPE_BLOB; sql_field->flags|= BLOB_FLAG; sprintf(warn_buff, ER(ER_AUTO_CONVERT), sql_field->field_name, (sql_field->charset == &my_charset_bin) ? "VARBINARY" : "VARCHAR", @@ -3072,7 +3071,7 @@ static bool prepare_blob_field(THD *thd, create_field *sql_field) if ((sql_field->flags & BLOB_FLAG) && sql_field->length) { - if (sql_field->sql_type == FIELD_TYPE_BLOB) + if (sql_field->sql_type == MYSQL_TYPE_BLOB) { /* The user has given a length to the blob column */ sql_field->sql_type= get_blob_type_from_length(sql_field->length); @@ -3100,11 +3099,11 @@ static bool prepare_blob_field(THD *thd, create_field *sql_field) void sp_prepare_create_field(THD *thd, create_field *sql_field) { - if (sql_field->sql_type == FIELD_TYPE_SET || - sql_field->sql_type == FIELD_TYPE_ENUM) + if (sql_field->sql_type == MYSQL_TYPE_SET || + sql_field->sql_type == MYSQL_TYPE_ENUM) { uint32 field_length, dummy; - if (sql_field->sql_type == FIELD_TYPE_SET) + if (sql_field->sql_type == MYSQL_TYPE_SET) { calculate_interval_lengths(sql_field->charset, sql_field->interval, &dummy, @@ -3112,7 +3111,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) sql_field->length= field_length + (sql_field->interval->count - 1); } - else /* FIELD_TYPE_ENUM */ + else /* MYSQL_TYPE_ENUM */ { calculate_interval_lengths(sql_field->charset, sql_field->interval, @@ -3122,7 +3121,7 @@ void sp_prepare_create_field(THD *thd, create_field *sql_field) set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1); } - if (sql_field->sql_type == FIELD_TYPE_BIT) + if (sql_field->sql_type == MYSQL_TYPE_BIT) { sql_field->pack_flag= FIELDFLAG_NUMBER | FIELDFLAG_TREAT_BIT_AS_CHAR; @@ -5307,7 +5306,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, int error; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; - char index_file[FN_REFLEN], data_file[FN_REFLEN]; + char index_file[FN_REFLEN], data_file[FN_REFLEN], tablespace[FN_LEN]; char path[FN_REFLEN]; char reg_path[FN_REFLEN+1]; ha_rows copied,deleted; @@ -5406,16 +5405,19 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, { my_message(ER_LOCK_OR_ACTIVE_TRANSACTION, ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0)); - DBUG_RETURN(1); + DBUG_RETURN(TRUE); } if (wait_if_global_read_lock(thd,0,1)) - DBUG_RETURN(1); + DBUG_RETURN(TRUE); VOID(pthread_mutex_lock(&LOCK_open)); if (lock_table_names(thd, table_list)) + { + error= TRUE; goto view_err; + } - error=0; + error= FALSE; if (!do_rename(thd, table_list, new_db, new_name, new_name, 1)) { if (mysql_bin_log.is_open()) @@ -5556,6 +5558,10 @@ view_err: error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; + default: + DBUG_ASSERT(FALSE); + error= 0; + break; } if (error == HA_ERR_WRONG_COMMAND) { @@ -5630,6 +5636,15 @@ view_err: if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) create_info->key_block_size= table->s->key_block_size; + if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY) + { + /* + Regular alter table of disk stored table (no tablespace/storage change) + Copy tablespace name + */ + if ((table->file->get_tablespace_name(thd, tablespace, FN_LEN))) + create_info->tablespace= tablespace; + } restore_record(table, s->default_values); // Empty record for DEFAULT List_iterator<Alter_drop> drop_it(alter_info->drop_list); List_iterator<create_field> def_it(fields); @@ -5703,7 +5718,7 @@ view_err: } if (alter) { - if (def->sql_type == FIELD_TYPE_BLOB) + if (def->sql_type == MYSQL_TYPE_BLOB) { my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change); DBUG_RETURN(TRUE); @@ -6973,7 +6988,7 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, for (uint i= 0; i < t->s->fields; i++ ) { Field *f= t->field[i]; - if ((f->type() == FIELD_TYPE_BLOB) || + if ((f->type() == MYSQL_TYPE_BLOB) || (f->type() == MYSQL_TYPE_VARCHAR)) { String tmp; diff --git a/sql/sql_tablespace.cc b/sql/sql_tablespace.cc index 470fa5bc862..84391a54642 100644 --- a/sql/sql_tablespace.cc +++ b/sql/sql_tablespace.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 219ca8260ed..4fc5bde8fdc 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 8ca72eab8bf..3f9058f74c2 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 09576f5e523..3892e964aa7 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index f0d31965573..adda7316e3a 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_udf.h b/sql/sql_udf.h index 21cf735f5ab..3cd9343610c 100644 --- a/sql/sql_udf.h +++ b/sql/sql_udf.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2003-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 0715a0c4296..e9e244676d1 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_update.cc b/sql/sql_update.cc index a379ea66db6..9952a4f534b 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 7a8a85dceed..a699a801e2b 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_view.h b/sql/sql_view.h index fc480167216..d3c83c82f44 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -3,8 +3,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 12617d8679e..841c0f19c1e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -544,6 +543,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token HELP_SYM %token HEX_NUM %token HIGH_PRIORITY +%token HOST_SYM %token HOSTS_SYM %token HOUR_MICROSECOND_SYM %token HOUR_MINUTE_SYM @@ -686,6 +686,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token ONE_SYM %token OPEN_SYM /* SQL-2003-R */ %token OPTIMIZE +%token OPTIONS_SYM %token OPTION /* SQL-2003-N */ %token OPTIONALLY %token OR2_SYM @@ -695,6 +696,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token OUTER %token OUTFILE %token OUT_SYM /* SQL-2003-R */ +%token OWNER_SYM %token PACK_KEYS_SYM %token PARAM_MARKER %token PARSER_SYM @@ -708,6 +710,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token PLUGIN_SYM %token POINT_SYM %token POLYGON +%token PORT_SYM %token POSITION_SYM /* SQL-2003-N */ %token PRECISION /* SQL-2003-R */ %token PREPARE_SYM /* SQL-2003-R */ @@ -776,6 +779,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SERIALIZABLE_SYM /* SQL-2003-N */ %token SERIAL_SYM %token SESSION_SYM /* SQL-2003-N */ +%token SERVER_SYM +%token SERVER_OPTIONS %token SET /* SQL-2003-R */ %token SET_VAR %token SHARE_SYM @@ -788,6 +793,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token SLAVE %token SMALLINT /* SQL-2003-R */ %token SNAPSHOT_SYM +%token SOCKET_SYM %token SONAME_SYM %token SOUNDS_SYM %token SPATIAL_SYM @@ -894,6 +900,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token WHILE_SYM %token WITH /* SQL-2003-R */ %token WORK_SYM /* SQL-2003-N */ +%token WRAPPER_SYM %token WRITE_SYM /* SQL-2003-N */ %token X509_SYM %token XA_SYM @@ -1089,6 +1096,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); view_check_option trigger_tail sp_tail install uninstall partition_entry binlog_base64_event init_key_options key_options key_opts key_opt key_using_alg + server_def server_options_list server_option END_OF_INPUT %type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt @@ -1483,8 +1491,61 @@ create: { Lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE; } + | CREATE server_def + { + Lex->sql_command= SQLCOM_CREATE_SERVER; + } ; +server_def: + SERVER_SYM ident_or_text FOREIGN DATA_SYM WRAPPER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')' + { + Lex->server_options.server_name= $2.str; + Lex->server_options.server_name_length= $2.length; + Lex->server_options.scheme= $6.str; + } + ; +server_options_list: + server_option + | server_options_list ',' server_option + ; + +server_option: + USER TEXT_STRING_sys + { + Lex->server_options.username= $2.str; + } + | + HOST_SYM TEXT_STRING_sys + { + Lex->server_options.host= $2.str; + } + | + DATABASE TEXT_STRING_sys + { + Lex->server_options.db= $2.str; + } + | + OWNER_SYM TEXT_STRING_sys + { + Lex->server_options.owner= $2.str; + } + | + PASSWORD TEXT_STRING_sys + { + Lex->server_options.password= $2.str; + } + | + SOCKET_SYM TEXT_STRING_sys + { + Lex->server_options.socket= $2.str; + } + | + PORT_SYM ulong_num + { + Lex->server_options.port= $2; + } + ; event_tail: EVENT_SYM opt_if_not_exists sp_name @@ -1811,7 +1872,7 @@ create_function_tail: When collation support in SP is implemented, then this test should be removed. */ - if (($8 == FIELD_TYPE_STRING || $8 == MYSQL_TYPE_VARCHAR) + if (($8 == MYSQL_TYPE_STRING || $8 == MYSQL_TYPE_VARCHAR) && (lex->type & BINCMP_FLAG)) { my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation"); @@ -4124,8 +4185,8 @@ create_table_option: | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR; } | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR; } | TABLESPACE ident {Lex->create_info.tablespace= $2.str;} - | STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;} - | STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;} + | STORAGE_SYM DISK_SYM {Lex->create_info.storage_media= HA_SM_DISK;} + | STORAGE_SYM MEMORY_SYM {Lex->create_info.storage_media= HA_SM_MEMORY;} | CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; } | KEY_BLOCK_SIZE opt_equal ulong_num { @@ -4322,31 +4383,31 @@ field_spec: type: int_type opt_len field_options { $$=$1; } | real_type opt_precision field_options { $$=$1; } - | FLOAT_SYM float_options field_options { $$=FIELD_TYPE_FLOAT; } + | FLOAT_SYM float_options field_options { $$=MYSQL_TYPE_FLOAT; } | BIT_SYM { Lex->length= (char*) "1"; - $$=FIELD_TYPE_BIT; } + $$=MYSQL_TYPE_BIT; } | BIT_SYM '(' NUM ')' { Lex->length= $3.str; - $$=FIELD_TYPE_BIT; } + $$=MYSQL_TYPE_BIT; } | BOOL_SYM { Lex->length=(char*) "1"; - $$=FIELD_TYPE_TINY; } + $$=MYSQL_TYPE_TINY; } | BOOLEAN_SYM { Lex->length=(char*) "1"; - $$=FIELD_TYPE_TINY; } + $$=MYSQL_TYPE_TINY; } | char '(' NUM ')' opt_binary { Lex->length=$3.str; - $$=FIELD_TYPE_STRING; } + $$=MYSQL_TYPE_STRING; } | char opt_binary { Lex->length=(char*) "1"; - $$=FIELD_TYPE_STRING; } + $$=MYSQL_TYPE_STRING; } | nchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str; - $$=FIELD_TYPE_STRING; + $$=MYSQL_TYPE_STRING; Lex->charset=national_charset_info; } | nchar opt_bin_mod { Lex->length=(char*) "1"; - $$=FIELD_TYPE_STRING; + $$=MYSQL_TYPE_STRING; Lex->charset=national_charset_info; } | BINARY '(' NUM ')' { Lex->length=$3.str; Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_STRING; } + $$=MYSQL_TYPE_STRING; } | BINARY { Lex->length= (char*) "1"; Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_STRING; } + $$=MYSQL_TYPE_STRING; } | varchar '(' NUM ')' opt_binary { Lex->length=$3.str; $$= MYSQL_TYPE_VARCHAR; } | nvarchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str; @@ -4355,33 +4416,33 @@ type: | VARBINARY '(' NUM ')' { Lex->length=$3.str; Lex->charset=&my_charset_bin; $$= MYSQL_TYPE_VARCHAR; } - | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } - | DATE_SYM { $$=FIELD_TYPE_DATE; } - | TIME_SYM { $$=FIELD_TYPE_TIME; } + | YEAR_SYM opt_len field_options { $$=MYSQL_TYPE_YEAR; } + | DATE_SYM { $$=MYSQL_TYPE_DATE; } + | TIME_SYM { $$=MYSQL_TYPE_TIME; } | TIMESTAMP opt_len { if (YYTHD->variables.sql_mode & MODE_MAXDB) - $$=FIELD_TYPE_DATETIME; + $$=MYSQL_TYPE_DATETIME; else { /* Unlike other types TIMESTAMP fields are NOT NULL by default. */ Lex->type|= NOT_NULL_FLAG; - $$=FIELD_TYPE_TIMESTAMP; + $$=MYSQL_TYPE_TIMESTAMP; } } - | DATETIME { $$=FIELD_TYPE_DATETIME; } + | DATETIME { $$=MYSQL_TYPE_DATETIME; } | TINYBLOB { Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_TINY_BLOB; } + $$=MYSQL_TYPE_TINY_BLOB; } | BLOB_SYM opt_len { Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_BLOB; } + $$=MYSQL_TYPE_BLOB; } | spatial_type { #ifdef HAVE_SPATIAL Lex->charset=&my_charset_bin; Lex->uint_geom_type= (uint)$1; - $$=FIELD_TYPE_GEOMETRY; + $$=MYSQL_TYPE_GEOMETRY; #else my_error(ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name, sym_group_geom.needed_define); @@ -4389,30 +4450,30 @@ type: #endif } | MEDIUMBLOB { Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_MEDIUM_BLOB; } + $$=MYSQL_TYPE_MEDIUM_BLOB; } | LONGBLOB { Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_LONG_BLOB; } + $$=MYSQL_TYPE_LONG_BLOB; } | LONG_SYM VARBINARY { Lex->charset=&my_charset_bin; - $$=FIELD_TYPE_MEDIUM_BLOB; } - | LONG_SYM varchar opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } - | TINYTEXT opt_binary { $$=FIELD_TYPE_TINY_BLOB; } - | TEXT_SYM opt_len opt_binary { $$=FIELD_TYPE_BLOB; } - | MEDIUMTEXT opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } - | LONGTEXT opt_binary { $$=FIELD_TYPE_LONG_BLOB; } + $$=MYSQL_TYPE_MEDIUM_BLOB; } + | LONG_SYM varchar opt_binary { $$=MYSQL_TYPE_MEDIUM_BLOB; } + | TINYTEXT opt_binary { $$=MYSQL_TYPE_TINY_BLOB; } + | TEXT_SYM opt_len opt_binary { $$=MYSQL_TYPE_BLOB; } + | MEDIUMTEXT opt_binary { $$=MYSQL_TYPE_MEDIUM_BLOB; } + | LONGTEXT opt_binary { $$=MYSQL_TYPE_LONG_BLOB; } | DECIMAL_SYM float_options field_options - { $$=FIELD_TYPE_NEWDECIMAL;} + { $$=MYSQL_TYPE_NEWDECIMAL;} | NUMERIC_SYM float_options field_options - { $$=FIELD_TYPE_NEWDECIMAL;} + { $$=MYSQL_TYPE_NEWDECIMAL;} | FIXED_SYM float_options field_options - { $$=FIELD_TYPE_NEWDECIMAL;} + { $$=MYSQL_TYPE_NEWDECIMAL;} | ENUM {Lex->interval_list.empty();} '(' string_list ')' opt_binary - { $$=FIELD_TYPE_ENUM; } + { $$=MYSQL_TYPE_ENUM; } | SET { Lex->interval_list.empty();} '(' string_list ')' opt_binary - { $$=FIELD_TYPE_SET; } - | LONG_SYM opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } + { $$=MYSQL_TYPE_SET; } + | LONG_SYM opt_binary { $$=MYSQL_TYPE_MEDIUM_BLOB; } | SERIAL_SYM { - $$=FIELD_TYPE_LONGLONG; + $$=MYSQL_TYPE_LONGLONG; Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | UNIQUE_FLAG); } @@ -4454,17 +4515,17 @@ nvarchar: ; int_type: - INT_SYM { $$=FIELD_TYPE_LONG; } - | TINYINT { $$=FIELD_TYPE_TINY; } - | SMALLINT { $$=FIELD_TYPE_SHORT; } - | MEDIUMINT { $$=FIELD_TYPE_INT24; } - | BIGINT { $$=FIELD_TYPE_LONGLONG; }; + INT_SYM { $$=MYSQL_TYPE_LONG; } + | TINYINT { $$=MYSQL_TYPE_TINY; } + | SMALLINT { $$=MYSQL_TYPE_SHORT; } + | MEDIUMINT { $$=MYSQL_TYPE_INT24; } + | BIGINT { $$=MYSQL_TYPE_LONGLONG; }; real_type: REAL { $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ? - FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } - | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } - | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; + MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE; } + | DOUBLE_SYM { $$=MYSQL_TYPE_DOUBLE; } + | DOUBLE_SYM PRECISION { $$=MYSQL_TYPE_DOUBLE; }; float_options: @@ -4867,6 +4928,7 @@ alter: lex->alter_info.reset(); lex->alter_info.flags= 0; lex->no_write_to_binlog= 0; + lex->create_info.storage_media= HA_SM_DEFAULT; } alter_commands {} @@ -5006,6 +5068,13 @@ alter: LEX *lex= Lex; lex->alter_tablespace_info->ts_cmd_type= ALTER_ACCESS_MODE_TABLESPACE; } + | ALTER SERVER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')' + { + LEX *lex= Lex; + Lex->sql_command= SQLCOM_ALTER_SERVER; + Lex->server_options.server_name= $3.str; + Lex->server_options.server_name_length= $3.length; + } ; ev_alter_on_schedule_completion: /* empty */ { $$= 0;} @@ -7910,6 +7979,13 @@ drop: LEX *lex= Lex; lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP; } + | DROP SERVER_SYM if_exists ident_or_text + { + Lex->sql_command = SQLCOM_DROP_SERVER; + Lex->drop_if_exists= $3; + Lex->server_options.server_name= $4.str; + Lex->server_options.server_name_length= $4.length; + } ; table_list: @@ -8508,6 +8584,7 @@ show_param: if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL,0)) YYABORT; lex->only_view= 0; + lex->create_info.storage_media= HA_SM_DEFAULT; } | CREATE VIEW_SYM table_ident { @@ -9476,12 +9553,16 @@ keyword: | FLUSH_SYM {} | HANDLER_SYM {} | HELP_SYM {} + | HOST_SYM {} | INSTALL_SYM {} | LANGUAGE_SYM {} | NO_SYM {} | OPEN_SYM {} + | OPTIONS_SYM {} + | OWNER_SYM {} | PARSER_SYM {} | PARTITION_SYM {} + | PORT_SYM {} | PREPARE_SYM {} | REMOVE_SYM {} | REPAIR {} @@ -9490,7 +9571,9 @@ keyword: | ROLLBACK_SYM {} | SAVEPOINT_SYM {} | SECURITY_SYM {} + | SERVER_SYM {} | SIGNED_SYM {} + | SOCKET_SYM {} | SLAVE {} | SONAME_SYM {} | START_SYM {} @@ -9498,6 +9581,7 @@ keyword: | TRUNCATE_SYM {} | UNICODE_SYM {} | UNINSTALL_SYM {} + | WRAPPER_SYM {} | XA_SYM {} | UPGRADE_SYM {} ; diff --git a/sql/sql_yacc.yy.bak b/sql/sql_yacc.yy.bak new file mode 100644 index 00000000000..574a4ec639b --- /dev/null +++ b/sql/sql_yacc.yy.bak @@ -0,0 +1,11278 @@ +/* Copyright (C) 2000-2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* sql_yacc.yy */ + +%{ +/* thd is passed as an arg to yyparse(), and subsequently to yylex(). +** The type will be void*, so it must be cast to (THD*) when used. +** Use the YYTHD macro for this. +*/ +#define YYPARSE_PARAM yythd +#define YYLEX_PARAM yythd +#define YYTHD ((THD *)yythd) + +#define MYSQL_YACC +#define YYINITDEPTH 100 +#define YYMAXDEPTH 3200 /* Because of 64K stack */ +#define Lex (YYTHD->lex) +#define Select Lex->current_select +#include "mysql_priv.h" +#include "slave.h" +#include "lex_symbol.h" +#include "item_create.h" +#include "sp_head.h" +#include "sp_pcontext.h" +#include "sp_rcontext.h" +#include "sp.h" +#include "event_data_objects.h" +#include <myisam.h> +#include <myisammrg.h> + +int yylex(void *yylval, void *yythd); + +const LEX_STRING null_lex_str={0,0}; + +#define yyoverflow(A,B,C,D,E,F) {ulong val= *(F); if (my_yyoverflow((B), (D), &val)) { yyerror((char*) (A)); return 2; } else { *(F)= (YYSIZE_T)val; }} + +#define YYERROR_UNLESS(A) \ + if (!(A)) \ + { \ + yyerror(ER(ER_SYNTAX_ERROR)); \ + YYABORT; \ + } + +/* Helper for parsing "IS [NOT] truth_value" */ +inline Item *is_truth_value(THD *thd, Item *A, bool v1, bool v2) +{ + Item *v1_t= new (thd->mem_root) Item_int((char *) (v1 ? "TRUE" : "FALSE"), + v1, 1); + Item *v1_f= new (thd->mem_root) Item_int((char *) (v1 ? "FALSE" : "TRUE"), + !v1, 1); + Item *v2_t= new (thd->mem_root) Item_int((char *) (v2 ? "TRUE" : "FALSE"), + v2, 1); + Item *ifnull= new (thd->mem_root) Item_func_ifnull(A, v2_t); + + return new (thd->mem_root) Item_func_if(ifnull, v1_t, v1_f); +} + +#ifndef DBUG_OFF +#define YYDEBUG 1 +#else +#define YYDEBUG 0 +#endif + +#ifndef DBUG_OFF +void turn_parser_debug_on() +{ + /* + MYSQLdebug is in sql/sql_yacc.cc, in bison generated code. + Turning this option on is **VERY** verbose, and should be + used when investigating a syntax error problem only. + + The syntax to run with bison traces is as follows : + - Starting a server manually : + mysqld --debug="d,parser_debug" ... + - Running a test : + mysql-test-run.pl --mysqld="--debug=d,parser_debug" ... + + The result will be in the process stderr (var/log/master.err) + */ + + extern int yydebug; + yydebug= 1; +} +#endif + +static bool is_native_function(THD *thd, const LEX_STRING *name) +{ + if (find_native_function_builder(thd, *name)) + return true; + + if (is_lex_native_function(name)) + return true; + + return false; +} + +%} +%union { + int num; + ulong ulong_num; + ulonglong ulonglong_number; + longlong longlong_number; + LEX_STRING lex_str; + LEX_STRING *lex_str_ptr; + LEX_SYMBOL symbol; + Table_ident *table; + char *simple_string; + Item *item; + Item_num *item_num; + List<Item> *item_list; + List<String> *string_list; + String *string; + key_part_spec *key_part; + TABLE_LIST *table_list; + udf_func *udf; + LEX_USER *lex_user; + struct sys_var_with_base variable; + enum enum_var_type var_type; + Key::Keytype key_type; + enum ha_key_alg key_alg; + handlerton *db_type; + enum row_type row_type; + enum ha_rkey_function ha_rkey_mode; + enum enum_tx_isolation tx_isolation; + enum Cast_target cast_type; + enum Item_udftype udf_type; + CHARSET_INFO *charset; + thr_lock_type lock_type; + interval_type interval, interval_time_st; + timestamp_type date_time_type; + st_select_lex *select_lex; + chooser_compare_func_creator boolfunc2creator; + struct sp_cond_type *spcondtype; + struct { int vars, conds, hndlrs, curs; } spblock; + sp_name *spname; + struct st_lex *lex; + sp_head *sphead; + struct p_elem_val *p_elem_value; +} + +%{ +bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); +%} + +%pure_parser /* We have threads */ + +/* + Comments for TOKENS. + For each token, please include in the same line a comment that contains + the following tags: + SQL-2003-R : Reserved keyword as per SQL-2003 + SQL-2003-N : Non Reserved keyword as per SQL-2003 + SQL-1999-R : Reserved keyword as per SQL-1999 + SQL-1999-N : Non Reserved keyword as per SQL-1999 + MYSQL : MySQL extention (unspecified) + MYSQL-FUNC : MySQL extention, function + INTERNAL : Not a real token, lex optimization + OPERATOR : SQL operator + FUTURE-USE : Reserved for futur use + + This makes the code grep-able, and helps maintenance. +*/ + +%token ABORT_SYM /* INTERNAL (used in lex) */ +%token ACCESSIBLE_SYM +%token ACTION /* SQL-2003-N */ +%token ADD /* SQL-2003-R */ +%token ADDDATE_SYM /* MYSQL-FUNC */ +%token AFTER_SYM /* SQL-2003-N */ +%token AGAINST +%token AGGREGATE_SYM +%token ALGORITHM_SYM +%token ALL /* SQL-2003-R */ +%token ALTER /* SQL-2003-R */ +%token ANALYZE_SYM +%token AND_AND_SYM /* OPERATOR */ +%token AND_SYM /* SQL-2003-R */ +%token ANY_SYM /* SQL-2003-R */ +%token AS /* SQL-2003-R */ +%token ASC /* SQL-2003-N */ +%token ASCII_SYM /* MYSQL-FUNC */ +%token ASENSITIVE_SYM /* FUTURE-USE */ +%token AT_SYM /* SQL-2003-R */ +%token AUTHORS_SYM +%token AUTOEXTEND_SIZE_SYM +%token AUTO_INC +%token AVG_ROW_LENGTH +%token AVG_SYM /* SQL-2003-N */ +%token BACKUP_SYM +%token BEFORE_SYM /* SQL-2003-N */ +%token BEGIN_SYM /* SQL-2003-R */ +%token BETWEEN_SYM /* SQL-2003-R */ +%token BIGINT /* SQL-2003-R */ +%token BINARY /* SQL-2003-R */ +%token BINLOG_SYM +%token BIN_NUM +%token BIT_AND /* MYSQL-FUNC */ +%token BIT_OR /* MYSQL-FUNC */ +%token BIT_SYM /* MYSQL-FUNC */ +%token BIT_XOR /* MYSQL-FUNC */ +%token BLOB_SYM /* SQL-2003-R */ +%token BOOLEAN_SYM /* SQL-2003-R */ +%token BOOL_SYM +%token BOTH /* SQL-2003-R */ +%token BTREE_SYM +%token BY /* SQL-2003-R */ +%token BYTE_SYM +%token CACHE_SYM +%token CALL_SYM /* SQL-2003-R */ +%token CASCADE /* SQL-2003-N */ +%token CASCADED /* SQL-2003-R */ +%token CASE_SYM /* SQL-2003-R */ +%token CAST_SYM /* SQL-2003-R */ +%token CHAIN_SYM /* SQL-2003-N */ +%token CHANGE +%token CHANGED +%token CHARSET +%token CHAR_SYM /* SQL-2003-R */ +%token CHECKSUM_SYM +%token CHECK_SYM /* SQL-2003-R */ +%token CIPHER_SYM +%token CLIENT_SYM +%token CLOSE_SYM /* SQL-2003-R */ +%token COALESCE /* SQL-2003-N */ +%token CODE_SYM +%token COLLATE_SYM /* SQL-2003-R */ +%token COLLATION_SYM /* SQL-2003-N */ +%token COLUMNS +%token COLUMN_SYM /* SQL-2003-R */ +%token COMMENT_SYM +%token COMMITTED_SYM /* SQL-2003-N */ +%token COMMIT_SYM /* SQL-2003-R */ +%token COMPACT_SYM +%token COMPLETION_SYM +%token COMPRESSED_SYM +%token CONCURRENT +%token CONDITION_SYM /* SQL-2003-N */ +%token CONNECTION_SYM +%token CONSISTENT_SYM +%token CONSTRAINT /* SQL-2003-R */ +%token CONTAINS_SYM /* SQL-2003-N */ +%token CONTINUE_SYM /* SQL-2003-R */ +%token CONTRIBUTORS_SYM +%token CONVERT_SYM /* SQL-2003-N */ +%token COUNT_SYM /* SQL-2003-N */ +%token CREATE /* SQL-2003-R */ +%token CROSS /* SQL-2003-R */ +%token CUBE_SYM /* SQL-2003-R */ +%token CURDATE /* MYSQL-FUNC */ +%token CURRENT_USER /* SQL-2003-R */ +%token CURSOR_SYM /* SQL-2003-R */ +%token CURTIME /* MYSQL-FUNC */ +%token DATABASE +%token DATABASES +%token DATAFILE_SYM +%token DATA_SYM /* SQL-2003-N */ +%token DATETIME +%token DATE_ADD_INTERVAL /* MYSQL-FUNC */ +%token DATE_SUB_INTERVAL /* MYSQL-FUNC */ +%token DATE_SYM /* SQL-2003-R */ +%token DAY_HOUR_SYM +%token DAY_MICROSECOND_SYM +%token DAY_MINUTE_SYM +%token DAY_SECOND_SYM +%token DAY_SYM /* SQL-2003-R */ +%token DEALLOCATE_SYM /* SQL-2003-R */ +%token DECIMAL_NUM +%token DECIMAL_SYM /* SQL-2003-R */ +%token DECLARE_SYM /* SQL-2003-R */ +%token DEFAULT /* SQL-2003-R */ +%token DEFINER_SYM +%token DELAYED_SYM +%token DELAY_KEY_WRITE_SYM +%token DELETE_SYM /* SQL-2003-R */ +%token DESC /* SQL-2003-N */ +%token DESCRIBE /* SQL-2003-R */ +%token DES_KEY_FILE +%token DETERMINISTIC_SYM /* SQL-2003-R */ +%token DIRECTORY_SYM +%token DISABLE_SYM +%token DISCARD +%token DISK_SYM +%token DISTINCT /* SQL-2003-R */ +%token DIV_SYM +%token DOUBLE_SYM /* SQL-2003-R */ +%token DO_SYM +%token DROP /* SQL-2003-R */ +%token DUAL_SYM +%token DUMPFILE +%token DUPLICATE_SYM +%token DYNAMIC_SYM /* SQL-2003-R */ +%token EACH_SYM /* SQL-2003-R */ +%token ELSE /* SQL-2003-R */ +%token ELSEIF_SYM +%token ENABLE_SYM +%token ENCLOSED +%token END /* SQL-2003-R */ +%token ENDS_SYM +%token END_OF_INPUT /* INTERNAL */ +%token ENGINES_SYM +%token ENGINE_SYM +%token ENUM +%token EQ /* OPERATOR */ +%token EQUAL_SYM /* OPERATOR */ +%token ERRORS +%token ESCAPED +%token ESCAPE_SYM /* SQL-2003-R */ +%token EVENTS_SYM +%token EVENT_SYM +%token EVERY_SYM /* SQL-2003-N */ +%token EXECUTE_SYM /* SQL-2003-R */ +%token EXISTS /* SQL-2003-R */ +%token EXIT_SYM +%token EXPANSION_SYM +%token EXTENDED_SYM +%token EXTENT_SIZE_SYM +%token EXTRACT_SYM /* SQL-2003-N */ +%token FALSE_SYM /* SQL-2003-R */ +%token FAST_SYM +%token FETCH_SYM /* SQL-2003-R */ +%token FILE_SYM +%token FIRST_SYM /* SQL-2003-N */ +%token FIXED_SYM +%token FLOAT_NUM +%token FLOAT_SYM /* SQL-2003-R */ +%token FLUSH_SYM +%token FORCE_SYM +%token FOREIGN /* SQL-2003-R */ +%token FOR_SYM /* SQL-2003-R */ +%token FOUND_SYM /* SQL-2003-R */ +%token FRAC_SECOND_SYM +%token FROM +%token FULL /* SQL-2003-R */ +%token FULLTEXT_SYM +%token FUNCTION_SYM /* SQL-2003-R */ +%token GE +%token GEOMETRYCOLLECTION +%token GEOMETRY_SYM +%token GET_FORMAT /* MYSQL-FUNC */ +%token GLOBAL_SYM /* SQL-2003-R */ +%token GRANT /* SQL-2003-R */ +%token GRANTS +%token GROUP /* SQL-2003-R */ +%token GROUP_CONCAT_SYM +%token GROUP_UNIQUE_USERS +%token GT_SYM /* OPERATOR */ +%token HANDLER_SYM +%token HASH_SYM +%token HAVING /* SQL-2003-R */ +%token HELP_SYM +%token HEX_NUM +%token HIGH_PRIORITY +%token HOST_SYM +%token HOSTS_SYM +%token HOUR_MICROSECOND_SYM +%token HOUR_MINUTE_SYM +%token HOUR_SECOND_SYM +%token HOUR_SYM /* SQL-2003-R */ +%token IDENT +%token IDENTIFIED_SYM +%token IDENT_QUOTED +%token IF +%token IGNORE_SYM +%token IMPORT +%token INDEXES +%token INDEX_SYM +%token INFILE +%token INITIAL_SIZE_SYM +%token INNER_SYM /* SQL-2003-R */ +%token INNOBASE_SYM +%token INOUT_SYM /* SQL-2003-R */ +%token INSENSITIVE_SYM /* SQL-2003-R */ +%token INSERT /* SQL-2003-R */ +%token INSERT_METHOD +%token INSTALL_SYM +%token INTERVAL_SYM /* SQL-2003-R */ +%token INTO /* SQL-2003-R */ +%token INT_SYM /* SQL-2003-R */ +%token INVOKER_SYM +%token IN_SYM /* SQL-2003-R */ +%token IS /* SQL-2003-R */ +%token ISOLATION /* SQL-2003-R */ +%token ISSUER_SYM +%token ITERATE_SYM +%token JOIN_SYM /* SQL-2003-R */ +%token KEYS +%token KEY_BLOCK_SIZE +%token KEY_SYM /* SQL-2003-N */ +%token KILL_SYM +%token LANGUAGE_SYM /* SQL-2003-R */ +%token LAST_SYM /* SQL-2003-N */ +%token LE /* OPERATOR */ +%token LEADING /* SQL-2003-R */ +%token LEAVES +%token LEAVE_SYM +%token LEFT /* SQL-2003-R */ +%token LESS_SYM +%token LEVEL_SYM +%token LEX_HOSTNAME +%token LIKE /* SQL-2003-R */ +%token LIMIT +%token LINEAR_SYM +%token LINES +%token LINESTRING +%token LIST_SYM +%token LOAD +%token LOCAL_SYM /* SQL-2003-R */ +%token LOCATOR_SYM /* SQL-2003-N */ +%token LOCKS_SYM +%token LOCK_SYM +%token LOGFILE_SYM +%token LOGS_SYM +%token LONGBLOB +%token LONGTEXT +%token LONG_NUM +%token LONG_SYM +%token LOOP_SYM +%token LOW_PRIORITY +%token LT /* OPERATOR */ +%token MASTER_CONNECT_RETRY_SYM +%token MASTER_HOST_SYM +%token MASTER_LOG_FILE_SYM +%token MASTER_LOG_POS_SYM +%token MASTER_PASSWORD_SYM +%token MASTER_PORT_SYM +%token MASTER_SERVER_ID_SYM +%token MASTER_SSL_CAPATH_SYM +%token MASTER_SSL_CA_SYM +%token MASTER_SSL_CERT_SYM +%token MASTER_SSL_CIPHER_SYM +%token MASTER_SSL_KEY_SYM +%token MASTER_SSL_SYM +%token MASTER_SYM +%token MASTER_USER_SYM +%token MATCH /* SQL-2003-R */ +%token MAX_CONNECTIONS_PER_HOUR +%token MAX_QUERIES_PER_HOUR +%token MAX_ROWS +%token MAX_SIZE_SYM +%token MAX_SYM /* SQL-2003-N */ +%token MAX_UPDATES_PER_HOUR +%token MAX_USER_CONNECTIONS_SYM +%token MAX_VALUE_SYM /* SQL-2003-N */ +%token MEDIUMBLOB +%token MEDIUMINT +%token MEDIUMTEXT +%token MEDIUM_SYM +%token MEMORY_SYM +%token MERGE_SYM /* SQL-2003-R */ +%token MICROSECOND_SYM /* MYSQL-FUNC */ +%token MIGRATE_SYM +%token MINUTE_MICROSECOND_SYM +%token MINUTE_SECOND_SYM +%token MINUTE_SYM /* SQL-2003-R */ +%token MIN_ROWS +%token MIN_SYM /* SQL-2003-N */ +%token MODE_SYM +%token MODIFIES_SYM /* SQL-2003-R */ +%token MODIFY_SYM +%token MOD_SYM /* SQL-2003-N */ +%token MONTH_SYM /* SQL-2003-R */ +%token MULTILINESTRING +%token MULTIPOINT +%token MULTIPOLYGON +%token MUTEX_SYM +%token NAMES_SYM /* SQL-2003-N */ +%token NAME_SYM /* SQL-2003-N */ +%token NATIONAL_SYM /* SQL-2003-R */ +%token NATURAL /* SQL-2003-R */ +%token NCHAR_STRING +%token NCHAR_SYM /* SQL-2003-R */ +%token NDBCLUSTER_SYM +%token NE /* OPERATOR */ +%token NEG +%token NEW_SYM /* SQL-2003-R */ +%token NEXT_SYM /* SQL-2003-N */ +%token NODEGROUP_SYM +%token NONE_SYM /* SQL-2003-R */ +%token NOT2_SYM +%token NOT_SYM /* SQL-2003-R */ +%token NOW_SYM +%token NO_SYM /* SQL-2003-R */ +%token NO_WAIT_SYM +%token NO_WRITE_TO_BINLOG +%token NULL_SYM /* SQL-2003-R */ +%token NUM +%token NUMERIC_SYM /* SQL-2003-R */ +%token NVARCHAR_SYM +%token OFFSET_SYM +%token OLD_PASSWORD +%token ON /* SQL-2003-R */ +%token ONE_SHOT_SYM +%token ONE_SYM +%token OPEN_SYM /* SQL-2003-R */ +%token OPTIMIZE +%token OPTIONS_SYM +%token OPTION /* SQL-2003-N */ +%token OPTIONALLY +%token OR2_SYM +%token ORDER_SYM /* SQL-2003-R */ +%token OR_OR_SYM /* OPERATOR */ +%token OR_SYM /* SQL-2003-R */ +%token OUTER +%token OUTFILE +%token OUT_SYM /* SQL-2003-R */ +%token OWNER_SYM +%token PACK_KEYS_SYM +%token PARAM_MARKER +%token PARSER_SYM +%token PARTIAL /* SQL-2003-N */ +%token PARTITIONING_SYM +%token PARTITIONS_SYM +%token PARTITION_SYM /* SQL-2003-R */ +%token PASSWORD +%token PHASE_SYM +%token PLUGINS_SYM +%token PLUGIN_SYM +%token POINT_SYM +%token POLYGON +%token PORT_SYM +%token POSITION_SYM /* SQL-2003-N */ +%token PRECISION /* SQL-2003-R */ +%token PREPARE_SYM /* SQL-2003-R */ +%token PRESERVE_SYM +%token PREV_SYM +%token PRIMARY_SYM /* SQL-2003-R */ +%token PRIVILEGES /* SQL-2003-N */ +%token PROCEDURE /* SQL-2003-R */ +%token PROCESS +%token PROCESSLIST_SYM +%token PURGE +%token QUARTER_SYM +%token QUERY_SYM +%token QUICK +%token RANGE_SYM /* SQL-2003-R */ +%token READS_SYM /* SQL-2003-R */ +%token READ_ONLY_SYM +%token READ_SYM /* SQL-2003-N */ +%token READ_WRITE_SYM +%token REAL /* SQL-2003-R */ +%token REBUILD_SYM +%token RECOVER_SYM +%token REDOFILE_SYM +%token REDO_BUFFER_SIZE_SYM +%token REDUNDANT_SYM +%token REFERENCES /* SQL-2003-R */ +%token REGEXP +%token RELAY_LOG_FILE_SYM +%token RELAY_LOG_POS_SYM +%token RELAY_THREAD +%token RELEASE_SYM /* SQL-2003-R */ +%token RELOAD +%token REMOVE_SYM +%token RENAME +%token REORGANIZE_SYM +%token REPAIR +%token REPEATABLE_SYM /* SQL-2003-N */ +%token REPEAT_SYM /* MYSQL-FUNC */ +%token REPLACE /* MYSQL-FUNC */ +%token REPLICATION +%token REQUIRE_SYM +%token RESET_SYM +%token RESOURCES +%token RESTORE_SYM +%token RESTRICT +%token RESUME_SYM +%token RETURNS_SYM /* SQL-2003-R */ +%token RETURN_SYM /* SQL-2003-R */ +%token REVOKE /* SQL-2003-R */ +%token RIGHT /* SQL-2003-R */ +%token ROLLBACK_SYM /* SQL-2003-R */ +%token ROLLUP_SYM /* SQL-2003-R */ +%token ROUTINE_SYM /* SQL-2003-N */ +%token ROWS_SYM /* SQL-2003-R */ +%token ROW_FORMAT_SYM +%token ROW_SYM /* SQL-2003-R */ +%token RTREE_SYM +%token SAVEPOINT_SYM /* SQL-2003-R */ +%token SCHEDULE_SYM +%token SECOND_MICROSECOND_SYM +%token SECOND_SYM /* SQL-2003-R */ +%token SECURITY_SYM /* SQL-2003-N */ +%token SELECT_SYM /* SQL-2003-R */ +%token SENSITIVE_SYM /* FUTURE-USE */ +%token SEPARATOR_SYM +%token SERIALIZABLE_SYM /* SQL-2003-N */ +%token SERIAL_SYM +%token SESSION_SYM /* SQL-2003-N */ +%token SERVER_SYM +%token SERVER_OPTIONS +%token SET /* SQL-2003-R */ +%token SET_VAR +%token SHARE_SYM +%token SHIFT_LEFT /* OPERATOR */ +%token SHIFT_RIGHT /* OPERATOR */ +%token SHOW +%token SHUTDOWN +%token SIGNED_SYM +%token SIMPLE_SYM /* SQL-2003-N */ +%token SLAVE +%token SMALLINT /* SQL-2003-R */ +%token SNAPSHOT_SYM +%token SOCKET_SYM +%token SONAME_SYM +%token SOUNDS_SYM +%token SPATIAL_SYM +%token SPECIFIC_SYM /* SQL-2003-R */ +%token SQLEXCEPTION_SYM /* SQL-2003-R */ +%token SQLSTATE_SYM /* SQL-2003-R */ +%token SQLWARNING_SYM /* SQL-2003-R */ +%token SQL_BIG_RESULT +%token SQL_BUFFER_RESULT +%token SQL_CACHE_SYM +%token SQL_CALC_FOUND_ROWS +%token SQL_NO_CACHE_SYM +%token SQL_SMALL_RESULT +%token SQL_SYM /* SQL-2003-R */ +%token SQL_THREAD +%token SSL_SYM +%token STARTING +%token STARTS_SYM +%token START_SYM /* SQL-2003-R */ +%token STATUS_SYM +%token STDDEV_SAMP_SYM /* SQL-2003-N */ +%token STD_SYM +%token STOP_SYM +%token STORAGE_SYM +%token STRAIGHT_JOIN +%token STRING_SYM +%token SUBDATE_SYM +%token SUBJECT_SYM +%token SUBPARTITIONS_SYM +%token SUBPARTITION_SYM +%token SUBSTRING /* SQL-2003-N */ +%token SUM_SYM /* SQL-2003-N */ +%token SUPER_SYM +%token SUSPEND_SYM +%token SYSDATE +%token TABLES +%token TABLESPACE +%token TABLE_REF_PRIORITY +%token TABLE_SYM /* SQL-2003-R */ +%token TEMPORARY /* SQL-2003-N */ +%token TEMPTABLE_SYM +%token TERMINATED +%token TEXT_STRING +%token TEXT_SYM +%token THAN_SYM +%token THEN_SYM /* SQL-2003-R */ +%token TIMESTAMP /* SQL-2003-R */ +%token TIMESTAMP_ADD +%token TIMESTAMP_DIFF +%token TIME_SYM /* SQL-2003-R */ +%token TINYBLOB +%token TINYINT +%token TINYTEXT +%token TO_SYM /* SQL-2003-R */ +%token TRAILING /* SQL-2003-R */ +%token TRANSACTION_SYM +%token TRIGGERS_SYM +%token TRIGGER_SYM /* SQL-2003-R */ +%token TRIM /* SQL-2003-N */ +%token TRUE_SYM /* SQL-2003-R */ +%token TRUNCATE_SYM +%token TYPES_SYM +%token TYPE_SYM /* SQL-2003-N */ +%token UDF_RETURNS_SYM +%token ULONGLONG_NUM +%token UNCOMMITTED_SYM /* SQL-2003-N */ +%token UNDEFINED_SYM +%token UNDERSCORE_CHARSET +%token UNDOFILE_SYM +%token UNDO_BUFFER_SIZE_SYM +%token UNDO_SYM /* FUTURE-USE */ +%token UNICODE_SYM +%token UNINSTALL_SYM +%token UNION_SYM /* SQL-2003-R */ +%token UNIQUE_SYM +%token UNIQUE_USERS +%token UNKNOWN_SYM /* SQL-2003-R */ +%token UNLOCK_SYM +%token UNSIGNED +%token UNTIL_SYM +%token UPDATE_SYM /* SQL-2003-R */ +%token UPGRADE_SYM +%token USAGE /* SQL-2003-N */ +%token USER /* SQL-2003-R */ +%token USE_FRM +%token USE_SYM +%token USING /* SQL-2003-R */ +%token UTC_DATE_SYM +%token UTC_TIMESTAMP_SYM +%token UTC_TIME_SYM +%token VALUES /* SQL-2003-R */ +%token VALUE_SYM /* SQL-2003-R */ +%token VARBINARY +%token VARCHAR /* SQL-2003-R */ +%token VARIABLES +%token VARIANCE_SYM +%token VARYING /* SQL-2003-R */ +%token VAR_SAMP_SYM +%token VIEW_SYM /* SQL-2003-N */ +%token WAIT_SYM +%token WARNINGS +%token WEEK_SYM +%token WHEN_SYM /* SQL-2003-R */ +%token WHERE /* SQL-2003-R */ +%token WHILE_SYM +%token WITH /* SQL-2003-R */ +%token WORK_SYM /* SQL-2003-N */ +%token WRAPPER_SYM +%token WRITE_SYM /* SQL-2003-N */ +%token X509_SYM +%token XA_SYM +%token XOR +%token YEAR_MONTH_SYM +%token YEAR_SYM /* SQL-2003-R */ +%token ZEROFILL + +%left JOIN_SYM INNER_SYM STRAIGHT_JOIN CROSS LEFT RIGHT +/* A dummy token to force the priority of table_ref production in a join. */ +%left TABLE_REF_PRIORITY +%left SET_VAR +%left OR_OR_SYM OR_SYM OR2_SYM XOR +%left AND_SYM AND_AND_SYM +%left BETWEEN_SYM CASE_SYM WHEN_SYM THEN_SYM ELSE +%left EQ EQUAL_SYM GE GT_SYM LE LT NE IS LIKE REGEXP IN_SYM +%left '|' +%left '&' +%left SHIFT_LEFT SHIFT_RIGHT +%left '-' '+' +%left '*' '/' '%' DIV_SYM MOD_SYM +%left '^' +%left NEG '~' +%right NOT_SYM NOT2_SYM +%right BINARY COLLATE_SYM + +%type <lex_str> + IDENT IDENT_QUOTED TEXT_STRING DECIMAL_NUM FLOAT_NUM NUM LONG_NUM HEX_NUM + LEX_HOSTNAME ULONGLONG_NUM field_ident select_alias ident ident_or_text + UNDERSCORE_CHARSET IDENT_sys TEXT_STRING_sys TEXT_STRING_literal + NCHAR_STRING opt_component key_cache_name + sp_opt_label BIN_NUM label_ident TEXT_STRING_filesystem ident_or_empty + +%type <lex_str_ptr> + opt_table_alias + +%type <table> + table_ident table_ident_nodb references xid + +%type <simple_string> + remember_name remember_end opt_ident opt_db text_or_password + opt_constraint constraint + +%type <string> + text_string opt_gconcat_separator + +%type <num> + type int_type real_type order_dir lock_option + udf_type if_exists opt_local opt_table_options table_options + table_option opt_if_not_exists opt_no_write_to_binlog + delete_option opt_temporary all_or_any opt_distinct + opt_ignore_leaves fulltext_options spatial_type union_option + start_transaction_opts opt_chain opt_release + union_opt select_derived_init option_type2 + opt_natural_language_mode opt_query_expansion + opt_ev_status opt_ev_on_completion ev_on_completion opt_ev_comment + ev_alter_on_schedule_completion opt_ev_rename_to opt_ev_sql_stmt + +%type <ulong_num> + ulong_num real_ulong_num merge_insert_types + +%type <ulonglong_number> + ulonglong_num real_ulonglong_num size_number + +%type <p_elem_value> + part_bit_expr + +%type <lock_type> + replace_lock_option opt_low_priority insert_lock_option load_data_lock + +%type <item> + literal text_literal insert_ident order_ident + simple_ident select_item2 expr opt_expr opt_else sum_expr in_sum_expr + variable variable_aux bool_term bool_factor bool_test bool_pri + predicate bit_expr bit_term bit_factor value_expr term factor + table_wild simple_expr udf_expr + expr_or_default set_expr_or_default interval_expr + param_marker geometry_function + signed_literal now_or_signed_literal opt_escape + sp_opt_default + simple_ident_nospvar simple_ident_q + field_or_var limit_option + part_func_expr + function_call_keyword + function_call_nonkeyword + function_call_generic + function_call_conflict + +%type <item_num> + NUM_literal + +%type <item_list> + expr_list udf_expr_list udf_expr_list2 when_list + ident_list ident_list_arg opt_expr_list + +%type <var_type> + option_type opt_var_type opt_var_ident_type + +%type <key_type> + key_type opt_unique_or_fulltext constraint_key_type + +%type <key_alg> + btree_or_rtree + +%type <string_list> + key_usage_list using_list + +%type <key_part> + key_part + +%type <table_list> + join_table_list join_table + table_factor table_ref + select_derived derived_table_list + +%type <date_time_type> date_time_type; +%type <interval> interval + +%type <interval_time_st> interval_time_st + +%type <db_type> storage_engines + +%type <row_type> row_types + +%type <tx_isolation> isolation_types + +%type <ha_rkey_mode> handler_rkey_mode + +%type <cast_type> cast_type + +%type <udf_type> udf_func_type + +%type <symbol> keyword keyword_sp + +%type <lex_user> user grant_user + +%type <charset> + opt_collate + charset_name + charset_name_or_default + old_or_new_charset_name + old_or_new_charset_name_or_default + collation_name + collation_name_or_default + +%type <variable> internal_variable_name + +%type <select_lex> subselect subselect_init + get_select_lex + +%type <boolfunc2creator> comp_op + +%type <NONE> + query verb_clause create change select do drop insert replace insert2 + insert_values update delete truncate rename + show describe load alter optimize keycache preload flush + reset purge begin commit rollback savepoint release + slave master_def master_defs master_file_def slave_until_opts + repair restore backup analyze check start checksum + field_list field_list_item field_spec kill column_def key_def + keycache_list assign_to_keycache preload_list preload_keys + select_item_list select_item values_list no_braces + opt_limit_clause delete_limit_clause fields opt_values values + procedure_list procedure_list2 procedure_item + when_list2 expr_list2 udf_expr_list3 handler + opt_precision opt_ignore opt_column opt_restrict + grant revoke set lock unlock string_list field_options field_option + field_opt_list opt_binary table_lock_list table_lock + ref_list opt_on_delete opt_on_delete_list opt_on_delete_item use + opt_delete_options opt_delete_option varchar nchar nvarchar + opt_outer table_list table_name opt_option opt_place + opt_attribute opt_attribute_list attribute column_list column_list_id + opt_column_list grant_privileges grant_ident grant_list grant_option + object_privilege object_privilege_list user_list rename_list + clear_privileges flush_options flush_option + equal optional_braces opt_key_definition key_usage_list2 + opt_mi_check_type opt_to mi_check_types normal_join + db_to_db table_to_table_list table_to_table opt_table_list opt_as + handler_rkey_function handler_read_or_scan + single_multi table_wild_list table_wild_one opt_wild + union_clause union_list + precision subselect_start opt_and charset + subselect_end select_var_list select_var_list_init help opt_len + opt_extended_describe + prepare prepare_src execute deallocate + statement sp_suid + sp_c_chistics sp_a_chistics sp_chistic sp_c_chistic xa + load_data opt_field_or_var_spec fields_or_vars opt_load_data_set_spec + definer view_replace_or_algorithm view_replace view_algorithm_opt + view_algorithm view_or_trigger_or_sp_or_event + view_or_trigger_or_sp_or_event_tail + view_suid view_tail view_list_opt view_list view_select + view_check_option trigger_tail sp_tail + install uninstall partition_entry binlog_base64_event + init_key_options key_options key_opts key_opt key_using_alg + server_def server_options_list server_option +END_OF_INPUT + +%type <NONE> call sp_proc_stmts sp_proc_stmts1 sp_proc_stmt +%type <NONE> sp_proc_stmt_statement sp_proc_stmt_return +%type <NONE> sp_proc_stmt_if sp_proc_stmt_case_simple sp_proc_stmt_case +%type <NONE> sp_labeled_control sp_proc_stmt_unlabeled sp_proc_stmt_leave +%type <NONE> sp_proc_stmt_iterate +%type <NONE> sp_proc_stmt_open sp_proc_stmt_fetch sp_proc_stmt_close + +%type <num> sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list +%type <spcondtype> sp_cond sp_hcond +%type <spblock> sp_decls sp_decl +%type <lex> sp_cursor_stmt +%type <spname> sp_name + +%type <NONE> + '-' '+' '*' '/' '%' '(' ')' + ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM + THEN_SYM WHEN_SYM DIV_SYM MOD_SYM OR2_SYM AND_AND_SYM +%% + + +query: + END_OF_INPUT + { + THD *thd= YYTHD; + if (!thd->bootstrap && + (!(thd->lex->select_lex.options & OPTION_FOUND_COMMENT))) + { + my_message(ER_EMPTY_QUERY, ER(ER_EMPTY_QUERY), MYF(0)); + YYABORT; + } + else + { + thd->lex->sql_command= SQLCOM_EMPTY_QUERY; + } + } + | verb_clause END_OF_INPUT {}; + +verb_clause: + statement + | begin + ; + +/* Verb clauses, except begin */ +statement: + alter + | analyze + | backup + | binlog_base64_event + | call + | change + | check + | checksum + | commit + | create + | deallocate + | delete + | describe + | do + | drop + | execute + | flush + | grant + | handler + | help + | insert + | install + | kill + | load + | lock + | optimize + | keycache + | partition_entry + | preload + | prepare + | purge + | release + | rename + | repair + | replace + | reset + | restore + | revoke + | rollback + | savepoint + | select + | set + | show + | slave + | start + | truncate + | uninstall + | unlock + | update + | use + | xa + ; + +deallocate: + deallocate_or_drop PREPARE_SYM ident + { + THD *thd=YYTHD; + LEX *lex= thd->lex; + if (lex->stmt_prepare_mode) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->sql_command= SQLCOM_DEALLOCATE_PREPARE; + lex->prepared_stmt_name= $3; + }; + +deallocate_or_drop: + DEALLOCATE_SYM | + DROP + ; + + +prepare: + PREPARE_SYM ident FROM prepare_src + { + THD *thd=YYTHD; + LEX *lex= thd->lex; + if (lex->stmt_prepare_mode) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->sql_command= SQLCOM_PREPARE; + lex->prepared_stmt_name= $2; + }; + +prepare_src: + TEXT_STRING_sys + { + THD *thd=YYTHD; + LEX *lex= thd->lex; + lex->prepared_stmt_code= $1; + lex->prepared_stmt_code_is_varref= FALSE; + } + | '@' ident_or_text + { + THD *thd=YYTHD; + LEX *lex= thd->lex; + lex->prepared_stmt_code= $2; + lex->prepared_stmt_code_is_varref= TRUE; + }; + +execute: + EXECUTE_SYM ident + { + THD *thd=YYTHD; + LEX *lex= thd->lex; + if (lex->stmt_prepare_mode) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->sql_command= SQLCOM_EXECUTE; + lex->prepared_stmt_name= $2; + } + execute_using + {} + ; + +execute_using: + /* nothing */ + | USING execute_var_list + ; + +execute_var_list: + execute_var_list ',' execute_var_ident + | execute_var_ident + ; + +execute_var_ident: '@' ident_or_text + { + LEX *lex=Lex; + LEX_STRING *lexstr= (LEX_STRING*)sql_memdup(&$2, sizeof(LEX_STRING)); + if (!lexstr || lex->prepared_stmt_params.push_back(lexstr)) + YYABORT; + } + ; + +/* help */ + +help: + HELP_SYM + { + if (Lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "HELP"); + YYABORT; + } + } + ident_or_text + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_HELP; + lex->help_arg= $3.str; + }; + +/* change master */ + +change: + CHANGE MASTER_SYM TO_SYM + { + LEX *lex = Lex; + lex->sql_command = SQLCOM_CHANGE_MASTER; + bzero((char*) &lex->mi, sizeof(lex->mi)); + } + master_defs + {} + ; + +master_defs: + master_def + | master_defs ',' master_def; + +master_def: + MASTER_HOST_SYM EQ TEXT_STRING_sys + { + Lex->mi.host = $3.str; + } + | + MASTER_USER_SYM EQ TEXT_STRING_sys + { + Lex->mi.user = $3.str; + } + | + MASTER_PASSWORD_SYM EQ TEXT_STRING_sys + { + Lex->mi.password = $3.str; + } + | + MASTER_PORT_SYM EQ ulong_num + { + Lex->mi.port = $3; + } + | + MASTER_CONNECT_RETRY_SYM EQ ulong_num + { + Lex->mi.connect_retry = $3; + } + | MASTER_SSL_SYM EQ ulong_num + { + Lex->mi.ssl= $3 ? + LEX_MASTER_INFO::SSL_ENABLE : LEX_MASTER_INFO::SSL_DISABLE; + } + | MASTER_SSL_CA_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_ca= $3.str; + } + | MASTER_SSL_CAPATH_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_capath= $3.str; + } + | MASTER_SSL_CERT_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_cert= $3.str; + } + | MASTER_SSL_CIPHER_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_cipher= $3.str; + } + | MASTER_SSL_KEY_SYM EQ TEXT_STRING_sys + { + Lex->mi.ssl_key= $3.str; + } + | + master_file_def + ; + +master_file_def: + MASTER_LOG_FILE_SYM EQ TEXT_STRING_sys + { + Lex->mi.log_file_name = $3.str; + } + | MASTER_LOG_POS_SYM EQ ulonglong_num + { + Lex->mi.pos = $3; + /* + If the user specified a value < BIN_LOG_HEADER_SIZE, adjust it + instead of causing subsequent errors. + We need to do it in this file, because only there we know that + MASTER_LOG_POS has been explicitely specified. On the contrary + in change_master() (sql_repl.cc) we cannot distinguish between 0 + (MASTER_LOG_POS explicitely specified as 0) and 0 (unspecified), + whereas we want to distinguish (specified 0 means "read the binlog + from 0" (4 in fact), unspecified means "don't change the position + (keep the preceding value)"). + */ + Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos); + } + | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys + { + Lex->mi.relay_log_name = $3.str; + } + | RELAY_LOG_POS_SYM EQ ulong_num + { + Lex->mi.relay_log_pos = $3; + /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */ + Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos); + } + ; + +/* create a table */ + +create: + CREATE opt_table_options TABLE_SYM opt_if_not_exists table_ident + { + THD *thd= YYTHD; + LEX *lex=Lex; + lex->sql_command= SQLCOM_CREATE_TABLE; + if (!lex->select_lex.add_table_to_list(thd, $5, NULL, + TL_OPTION_UPDATING, + (using_update_log ? + TL_READ_NO_INSERT: + TL_READ))) + YYABORT; + lex->create_list.empty(); + lex->key_list.empty(); + lex->col_list.empty(); + lex->change=NullS; + bzero((char*) &lex->create_info,sizeof(lex->create_info)); + lex->create_info.options=$2 | $4; + lex->create_info.db_type= lex->thd->variables.table_type; + lex->create_info.default_table_charset= NULL; + lex->name.str= 0; + lex->name.length= 0; + lex->like_name= 0; + } + create2 + { Lex->current_select= &Lex->select_lex; } + | CREATE opt_unique_or_fulltext INDEX_SYM ident key_alg ON + table_ident + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_CREATE_INDEX; + if (!lex->current_select->add_table_to_list(lex->thd, $7, + NULL, + TL_OPTION_UPDATING)) + YYABORT; + lex->create_list.empty(); + lex->key_list.empty(); + lex->col_list.empty(); + lex->change=NullS; + } + '(' key_list ')' key_options + { + LEX *lex=Lex; + if ($2 != Key::FULLTEXT && lex->key_create_info.parser_name.str) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->key_list.push_back(new Key($2, $4.str, &lex->key_create_info, 0, + lex->col_list)); + lex->col_list.empty(); + } + | CREATE DATABASE opt_if_not_exists ident + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + } + opt_create_database_options + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_CREATE_DB; + lex->name= $4; + lex->create_info.options=$3; + } + | CREATE + { + Lex->create_view_mode= VIEW_CREATE_NEW; + Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; + Lex->create_view_suid= TRUE; + } + view_or_trigger_or_sp_or_event + {} + | CREATE USER clear_privileges grant_list + { + Lex->sql_command = SQLCOM_CREATE_USER; + } + | CREATE LOGFILE_SYM GROUP logfile_group_info + { + Lex->alter_tablespace_info->ts_cmd_type= CREATE_LOGFILE_GROUP; + } + | CREATE TABLESPACE tablespace_info + { + Lex->alter_tablespace_info->ts_cmd_type= CREATE_TABLESPACE; + } + | CREATE server_def + { + Lex->sql_command= SQLCOM_CREATE_SERVER; + } + ; +server_def: + SERVER_SYM ident_or_text FOREIGN DATA_SYM WRAPPER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')' + { + Lex->server_options.server_name= $2.str; + Lex->server_options.server_name_length= $2.length; + Lex->server_options.scheme= $6.str; + } + ; + +server_options_list: + server_option + | server_options_list ',' server_option + ; + +server_option: + USER TEXT_STRING_sys + { + Lex->server_options.username= $2.str; + } + | + HOST_SYM TEXT_STRING_sys + { + Lex->server_options.host= $2.str; + } + | + DATABASE TEXT_STRING_sys + { + Lex->server_options.db= $2.str; + } + | + OWNER_SYM TEXT_STRING_sys + { + Lex->server_options.owner= $2.str; + } + | + PASSWORD TEXT_STRING_sys + { + Lex->server_options.password= $2.str; + } + | + SOCKET_SYM TEXT_STRING_sys + { + Lex->server_options.socket= $2.str; + } + | + PORT_SYM ulong_num + { + Lex->server_options.port= $2; + } + ; + +event_tail: + EVENT_SYM opt_if_not_exists sp_name + /* + BE CAREFUL when you add a new rule to update the block where + YYTHD->client_capabilities is set back to original value + */ + { + Lex->create_info.options= $2; + + if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD))) + YYABORT; + Lex->event_parse_data->identifier= $3; + + /* + We have to turn of CLIENT_MULTI_QUERIES while parsing a + stored procedure, otherwise yylex will chop it into pieces + at each ';'. + */ + $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); + + Lex->sql_command= SQLCOM_CREATE_EVENT; + /* We need that for disallowing subqueries */ + } + ON SCHEDULE_SYM ev_schedule_time + opt_ev_on_completion + opt_ev_status + opt_ev_comment + DO_SYM ev_sql_stmt + { + /* + Restore flag if it was cleared above + $1 - EVENT_SYM + $2 - opt_if_not_exists + $3 - sp_name + $4 - the block above + */ + YYTHD->client_capabilities |= $<ulong_num>4; + + /* + sql_command is set here because some rules in ev_sql_stmt + can overwrite it + */ + Lex->sql_command= SQLCOM_CREATE_EVENT; + } + ; + +ev_schedule_time: EVERY_SYM expr interval + { + Lex->event_parse_data->item_expression= $2; + Lex->event_parse_data->interval= $3; + } + ev_starts + ev_ends + | AT_SYM expr + { + Lex->event_parse_data->item_execute_at= $2; + } + ; + +opt_ev_status: /* empty */ { $$= 0; } + | ENABLE_SYM + { + Lex->event_parse_data->status= Event_parse_data::ENABLED; + $$= 1; + } + | DISABLE_SYM + { + Lex->event_parse_data->status= Event_parse_data::DISABLED; + $$= 1; + } + ; + +ev_starts: /* empty */ + { + Lex->event_parse_data->item_starts= new Item_func_now_local(); + } + | STARTS_SYM expr + { + Lex->event_parse_data->item_starts= $2; + } + ; + +ev_ends: /* empty */ + | ENDS_SYM expr + { + Lex->event_parse_data->item_ends= $2; + } + ; + +opt_ev_on_completion: /* empty */ { $$= 0; } + | ev_on_completion + ; + +ev_on_completion: + ON COMPLETION_SYM PRESERVE_SYM + { + Lex->event_parse_data->on_completion= + Event_parse_data::ON_COMPLETION_PRESERVE; + $$= 1; + } + | ON COMPLETION_SYM NOT_SYM PRESERVE_SYM + { + Lex->event_parse_data->on_completion= + Event_parse_data::ON_COMPLETION_DROP; + $$= 1; + } + ; + +opt_ev_comment: /* empty */ { $$= 0; } + | COMMENT_SYM TEXT_STRING_sys + { + Lex->comment= Lex->event_parse_data->comment= $2; + $$= 1; + } + ; + +ev_sql_stmt: + { + LEX *lex= Lex; + + /* + This stops the following : + - CREATE EVENT ... DO CREATE EVENT ...; + - ALTER EVENT ... DO CREATE EVENT ...; + - CREATE EVENT ... DO ALTER EVENT DO ....; + - CREATE PROCEDURE ... BEGIN CREATE EVENT ... END| + This allows: + - CREATE EVENT ... DO DROP EVENT yyy; + - CREATE EVENT ... DO ALTER EVENT yyy; + (the nested ALTER EVENT can have anything but DO clause) + - ALTER EVENT ... DO ALTER EVENT yyy; + (the nested ALTER EVENT can have anything but DO clause) + - ALTER EVENT ... DO DROP EVENT yyy; + - CREATE PROCEDURE ... BEGIN ALTER EVENT ... END| + (the nested ALTER EVENT can have anything but DO clause) + - CREATE PROCEDURE ... BEGIN DROP EVENT ... END| + */ + if (lex->sphead) + { + my_error(ER_EVENT_RECURSIVITY_FORBIDDEN, MYF(0)); + YYABORT; + } + + if (!(lex->sphead= new sp_head())) + YYABORT; + + lex->sphead->reset_thd_mem_root(YYTHD); + lex->sphead->init(lex); + lex->sphead->init_sp_name(YYTHD, Lex->event_parse_data->identifier); + + lex->sphead->m_type= TYPE_ENUM_PROCEDURE; + + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + lex->sphead->m_chistics= &lex->sp_chistics; + + lex->sphead->m_body_begin= lex->ptr; + + Lex->event_parse_data->body_begin= lex->ptr; + + } + ev_sql_stmt_inner + { + LEX *lex=Lex; + + /* return back to the original memory root ASAP */ + lex->sphead->init_strings(YYTHD, lex); + lex->sphead->restore_thd_mem_root(YYTHD); + + lex->sp_chistics.suid= SP_IS_SUID; //always the definer! + + Lex->event_parse_data->init_body(YYTHD); + } + ; + +ev_sql_stmt_inner: + sp_proc_stmt_statement + | sp_proc_stmt_return + | sp_proc_stmt_if + | sp_proc_stmt_case_simple + | sp_proc_stmt_case + | sp_labeled_control + | sp_proc_stmt_unlabeled + | sp_proc_stmt_leave + | sp_proc_stmt_iterate + | sp_proc_stmt_open + | sp_proc_stmt_fetch + | sp_proc_stmt_close + ; + + +clear_privileges: + /* Nothing */ + { + LEX *lex=Lex; + lex->users_list.empty(); + lex->columns.empty(); + lex->grant= lex->grant_tot_col= 0; + lex->all_privileges= 0; + lex->select_lex.db= 0; + lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; + lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; + bzero((char *)&(lex->mqh),sizeof(lex->mqh)); + } + ; + +sp_name: + ident '.' ident + { + if (!$1.str || check_db_name(&$1)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), $1.str); + YYABORT; + } + if (check_routine_name($3)) + { + my_error(ER_SP_WRONG_NAME, MYF(0), $3.str); + YYABORT; + } + $$= new sp_name($1, $3); + $$->init_qname(YYTHD); + } + | ident + { + THD *thd= YYTHD; + LEX_STRING db; + if (check_routine_name($1)) + { + my_error(ER_SP_WRONG_NAME, MYF(0), $1.str); + YYABORT; + } + if (thd->copy_db_to(&db.str, &db.length)) + YYABORT; + $$= new sp_name(db, $1); + if ($$) + $$->init_qname(YYTHD); + } + ; + +create_function_tail: + RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys + { + THD *thd= YYTHD; + LEX *lex=Lex; + if (lex->definer != NULL) + { + /* + DEFINER is a concept meaningful when interpreting SQL code. + UDF functions are compiled. + Using DEFINER with UDF has therefore no semantic, + and is considered a parsing error. + */ + my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER"); + YYABORT; + } + if (is_native_function(thd, & lex->spname->m_name)) + { + my_error(ER_NATIVE_FCT_NAME_COLLISION, MYF(0), + lex->spname->m_name.str); + YYABORT; + } + lex->sql_command = SQLCOM_CREATE_FUNCTION; + lex->udf.name = lex->spname->m_name; + lex->udf.returns=(Item_result) $2; + lex->udf.dl=$4.str; + } + | '(' + { + LEX *lex= Lex; + sp_head *sp; + + /* + First check if AGGREGATE was used, in that case it's a + syntax error. + */ + if (lex->udf.type == UDFTYPE_AGGREGATE) + { + my_error(ER_SP_NO_AGGREGATE, MYF(0)); + YYABORT; + } + + if (lex->sphead) + { + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "FUNCTION"); + YYABORT; + } + /* Order is important here: new - reset - init */ + sp= new sp_head(); + sp->reset_thd_mem_root(YYTHD); + sp->init(lex); + sp->init_sp_name(YYTHD, lex->spname); + + sp->m_type= TYPE_ENUM_FUNCTION; + lex->sphead= sp; + /* + We have to turn off CLIENT_MULTI_QUERIES while parsing a + stored procedure, otherwise yylex will chop it into pieces + at each ';'. + */ + $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; + lex->sphead->m_param_begin= lex->tok_start+1; + } + sp_fdparam_list ')' + { + LEX *lex= Lex; + + lex->sphead->m_param_end= lex->tok_start; + } + RETURNS_SYM + { + LEX *lex= Lex; + lex->charset= NULL; + lex->length= lex->dec= NULL; + lex->interval_list.empty(); + lex->type= 0; + } + type + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + /* + This was disabled in 5.1.12. See bug #20701 + When collation support in SP is implemented, then this test + should be removed. + */ + if (($8 == FIELD_TYPE_STRING || $8 == MYSQL_TYPE_VARCHAR) + && (lex->type & BINCMP_FLAG)) + { + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "return value collation"); + YYABORT; + } + + if (sp->fill_field_definition(YYTHD, lex, + (enum enum_field_types) $8, + &sp->m_return_field_def)) + YYABORT; + + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_c_chistics + { + LEX *lex= Lex; + + lex->sphead->m_chistics= &lex->sp_chistics; + lex->sphead->m_body_begin= lex->tok_start; + } + sp_proc_stmt + { + THD *thd= YYTHD; + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + if (sp->is_not_allowed_in_function("function")) + YYABORT; + + lex->sql_command= SQLCOM_CREATE_SPFUNCTION; + sp->init_strings(thd, lex); + if (!(sp->m_flags & sp_head::HAS_RETURN)) + { + my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str); + YYABORT; + } + if (is_native_function(thd, & sp->m_name)) + { + /* + This warning will be printed when + [1] A client query is parsed, + [2] A stored function is loaded by db_load_routine. + Printing the warning for [2] is intentional, to cover the + following scenario: + - A user define a SF 'foo' using MySQL 5.N + - An application uses select foo(), and works. + - MySQL 5.{N+1} defines a new native function 'foo', as + part of a new feature. + - MySQL 5.{N+1} documentation is updated, and should mention + that there is a potential incompatible change in case of + existing stored function named 'foo'. + - The user deploys 5.{N+1}. At this point, 'select foo()' + means something different, and the user code is most likely + broken (it's only safe if the code is 'select db.foo()'). + With a warning printed when the SF is loaded (which has to occur + before the call), the warning will provide a hint explaining + the root cause of a later failure of 'select foo()'. + With no warning printed, the user code will fail with no + apparent reason. + Printing a warning each time db_load_routine is executed for + an ambiguous function is annoying, since that can happen a lot, + but in practice should not happen unless there *are* name + collisions. + If a collision exists, it should not be silenced but fixed. + */ + push_warning_printf(thd, + MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_NATIVE_FCT_NAME_COLLISION, + ER(ER_NATIVE_FCT_NAME_COLLISION), + sp->m_name.str); + } + /* Restore flag if it was cleared above */ + thd->client_capabilities |= $<ulong_num>2; + sp->restore_thd_mem_root(thd); + } + ; + +sp_a_chistics: + /* Empty */ {} + | sp_a_chistics sp_chistic {} + ; + +sp_c_chistics: + /* Empty */ {} + | sp_c_chistics sp_c_chistic {} + ; + +/* Characteristics for both create and alter */ +sp_chistic: + COMMENT_SYM TEXT_STRING_sys + { Lex->sp_chistics.comment= $2; } + | LANGUAGE_SYM SQL_SYM + { /* Just parse it, we only have one language for now. */ } + | NO_SYM SQL_SYM + { Lex->sp_chistics.daccess= SP_NO_SQL; } + | CONTAINS_SYM SQL_SYM + { Lex->sp_chistics.daccess= SP_CONTAINS_SQL; } + | READS_SYM SQL_SYM DATA_SYM + { Lex->sp_chistics.daccess= SP_READS_SQL_DATA; } + | MODIFIES_SYM SQL_SYM DATA_SYM + { Lex->sp_chistics.daccess= SP_MODIFIES_SQL_DATA; } + | sp_suid + { } + ; + +/* Create characteristics */ +sp_c_chistic: + sp_chistic { } + | DETERMINISTIC_SYM { Lex->sp_chistics.detistic= TRUE; } + | not DETERMINISTIC_SYM { Lex->sp_chistics.detistic= FALSE; } + ; + +sp_suid: + SQL_SYM SECURITY_SYM DEFINER_SYM + { + Lex->sp_chistics.suid= SP_IS_SUID; + } + | SQL_SYM SECURITY_SYM INVOKER_SYM + { + Lex->sp_chistics.suid= SP_IS_NOT_SUID; + } + ; + +call: + CALL_SYM sp_name + { + LEX *lex = Lex; + + lex->sql_command= SQLCOM_CALL; + lex->spname= $2; + lex->value_list.empty(); + sp_add_used_routine(lex, YYTHD, $2, TYPE_ENUM_PROCEDURE); + } + opt_sp_cparam_list {} + ; + +/* CALL parameters */ +opt_sp_cparam_list: + /* Empty */ + | '(' opt_sp_cparams ')' + ; + +opt_sp_cparams: + /* Empty */ + | sp_cparams + ; + +sp_cparams: + sp_cparams ',' expr + { + Lex->value_list.push_back($3); + } + | expr + { + Lex->value_list.push_back($1); + } + ; + +/* Stored FUNCTION parameter declaration list */ +sp_fdparam_list: + /* Empty */ + | sp_fdparams + ; + +sp_fdparams: + sp_fdparams ',' sp_fdparam + | sp_fdparam + ; + +sp_init_param: + /* Empty */ + { + LEX *lex= Lex; + + lex->length= 0; + lex->dec= 0; + lex->type= 0; + + lex->default_value= 0; + lex->on_update_value= 0; + + lex->comment= null_lex_str; + lex->charset= NULL; + + lex->interval_list.empty(); + lex->uint_geom_type= 0; + } + ; + +sp_fdparam: + ident sp_init_param type + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_variable(&$1, TRUE)) + { + my_error(ER_SP_DUP_PARAM, MYF(0), $1.str); + YYABORT; + } + sp_variable_t *spvar= spc->push_variable(&$1, + (enum enum_field_types)$3, + sp_param_in); + + if (lex->sphead->fill_field_definition(YYTHD, lex, + (enum enum_field_types) $3, + &spvar->field_def)) + { + YYABORT; + } + spvar->field_def.field_name= spvar->name.str; + spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL; + } + ; + +/* Stored PROCEDURE parameter declaration list */ +sp_pdparam_list: + /* Empty */ + | sp_pdparams + ; + +sp_pdparams: + sp_pdparams ',' sp_pdparam + | sp_pdparam + ; + +sp_pdparam: + sp_opt_inout sp_init_param ident type + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_variable(&$3, TRUE)) + { + my_error(ER_SP_DUP_PARAM, MYF(0), $3.str); + YYABORT; + } + sp_variable_t *spvar= spc->push_variable(&$3, + (enum enum_field_types)$4, + (sp_param_mode_t)$1); + + if (lex->sphead->fill_field_definition(YYTHD, lex, + (enum enum_field_types) $4, + &spvar->field_def)) + { + YYABORT; + } + spvar->field_def.field_name= spvar->name.str; + spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL; + } + ; + +sp_opt_inout: + /* Empty */ { $$= sp_param_in; } + | IN_SYM { $$= sp_param_in; } + | OUT_SYM { $$= sp_param_out; } + | INOUT_SYM { $$= sp_param_inout; } + ; + +sp_proc_stmts: + /* Empty */ {} + | sp_proc_stmts sp_proc_stmt ';' + ; + +sp_proc_stmts1: + sp_proc_stmt ';' {} + | sp_proc_stmts1 sp_proc_stmt ';' + ; + +sp_decls: + /* Empty */ + { + $$.vars= $$.conds= $$.hndlrs= $$.curs= 0; + } + | sp_decls sp_decl ';' + { + /* We check for declarations out of (standard) order this way + because letting the grammar rules reflect it caused tricky + shift/reduce conflicts with the wrong result. (And we get + better error handling this way.) */ + if (($2.vars || $2.conds) && ($1.curs || $1.hndlrs)) + { /* Variable or condition following cursor or handler */ + my_message(ER_SP_VARCOND_AFTER_CURSHNDLR, + ER(ER_SP_VARCOND_AFTER_CURSHNDLR), MYF(0)); + YYABORT; + } + if ($2.curs && $1.hndlrs) + { /* Cursor following handler */ + my_message(ER_SP_CURSOR_AFTER_HANDLER, + ER(ER_SP_CURSOR_AFTER_HANDLER), MYF(0)); + YYABORT; + } + $$.vars= $1.vars + $2.vars; + $$.conds= $1.conds + $2.conds; + $$.hndlrs= $1.hndlrs + $2.hndlrs; + $$.curs= $1.curs + $2.curs; + } + ; + +sp_decl: + DECLARE_SYM sp_decl_idents + { + LEX *lex= Lex; + + lex->sphead->reset_lex(YYTHD); + lex->spcont->declare_var_boundary($2); + } + type + sp_opt_default + { + LEX *lex= Lex; + sp_pcontext *pctx= lex->spcont; + uint num_vars= pctx->context_var_count(); + enum enum_field_types var_type= (enum enum_field_types) $4; + Item *dflt_value_item= $5; + create_field *create_field_op; + + if (!dflt_value_item) + { + dflt_value_item= new Item_null(); + /* QQ Set to the var_type with null_value? */ + } + + for (uint i = num_vars-$2 ; i < num_vars ; i++) + { + uint var_idx= pctx->var_context2runtime(i); + sp_variable_t *spvar= pctx->find_variable(var_idx); + + if (!spvar) + YYABORT; + + spvar->type= var_type; + spvar->dflt= dflt_value_item; + + if (lex->sphead->fill_field_definition(YYTHD, lex, var_type, + &spvar->field_def)) + { + YYABORT; + } + + spvar->field_def.field_name= spvar->name.str; + spvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL; + + /* The last instruction is responsible for freeing LEX. */ + + lex->sphead->add_instr( + new sp_instr_set(lex->sphead->instructions(), pctx, var_idx, + dflt_value_item, var_type, lex, + (i == num_vars - 1))); + } + + pctx->declare_var_boundary(0); + lex->sphead->restore_lex(YYTHD); + + $$.vars= $2; + $$.conds= $$.hndlrs= $$.curs= 0; + } + | DECLARE_SYM ident CONDITION_SYM FOR_SYM sp_cond + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_cond(&$2, TRUE)) + { + my_error(ER_SP_DUP_COND, MYF(0), $2.str); + YYABORT; + } + YYTHD->lex->spcont->push_cond(&$2, $5); + $$.vars= $$.hndlrs= $$.curs= 0; + $$.conds= 1; + } + | DECLARE_SYM sp_handler_type HANDLER_SYM FOR_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_instr_hpush_jump *i= + new sp_instr_hpush_jump(sp->instructions(), ctx, $2, + ctx->current_var_count()); + + sp->add_instr(i); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + sp->m_flags|= sp_head::IN_HANDLER; + } + sp_hcond_list sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_label_t *hlab= lex->spcont->pop_label(); /* After this hdlr */ + sp_instr_hreturn *i; + + if ($2 == SP_HANDLER_CONTINUE) + { + i= new sp_instr_hreturn(sp->instructions(), ctx, + ctx->current_var_count()); + sp->add_instr(i); + } + else + { /* EXIT or UNDO handler, just jump to the end of the block */ + i= new sp_instr_hreturn(sp->instructions(), ctx, 0); + + sp->add_instr(i); + sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */ + } + lex->sphead->backpatch(hlab); + sp->m_flags&= ~sp_head::IN_HANDLER; + $$.vars= $$.conds= $$.curs= 0; + $$.hndlrs= $6; + ctx->add_handlers($6); + } + | DECLARE_SYM ident CURSOR_SYM FOR_SYM sp_cursor_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + uint offp; + sp_instr_cpush *i; + + if (ctx->find_cursor(&$2, &offp, TRUE)) + { + my_error(ER_SP_DUP_CURS, MYF(0), $2.str); + delete $5; + YYABORT; + } + i= new sp_instr_cpush(sp->instructions(), ctx, $5, + ctx->current_cursor_count()); + sp->add_instr(i); + ctx->push_cursor(&$2); + $$.vars= $$.conds= $$.hndlrs= 0; + $$.curs= 1; + } + ; + +sp_cursor_stmt: + { + Lex->sphead->reset_lex(YYTHD); + + /* + We use statement here just be able to get a better + error message. Using 'select' works too, but will then + result in a generic "syntax error" if a non-select + statement is given. + */ + } + statement + { + LEX *lex= Lex; + + if (lex->sql_command != SQLCOM_SELECT && + !(sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)) + { + my_message(ER_SP_BAD_CURSOR_QUERY, ER(ER_SP_BAD_CURSOR_QUERY), + MYF(0)); + YYABORT; + } + if (lex->result) + { + my_message(ER_SP_BAD_CURSOR_SELECT, ER(ER_SP_BAD_CURSOR_SELECT), + MYF(0)); + YYABORT; + } + lex->sp_lex_in_use= TRUE; + $$= lex; + lex->sphead->restore_lex(YYTHD); + } + ; + +sp_handler_type: + EXIT_SYM { $$= SP_HANDLER_EXIT; } + | CONTINUE_SYM { $$= SP_HANDLER_CONTINUE; } +/* | UNDO_SYM { QQ No yet } */ + ; + +sp_hcond_list: + sp_hcond + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + + if (ctx->find_handler($1)) + { + my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0)); + YYABORT; + } + else + { + sp_instr_hpush_jump *i= + (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($1); + ctx->push_handler($1); + $$= 1; + } + } + | sp_hcond_list ',' sp_hcond + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + + if (ctx->find_handler($3)) + { + my_message(ER_SP_DUP_HANDLER, ER(ER_SP_DUP_HANDLER), MYF(0)); + YYABORT; + } + else + { + sp_instr_hpush_jump *i= + (sp_instr_hpush_jump *)sp->last_instruction(); + + i->add_condition($3); + ctx->push_handler($3); + $$= $1 + 1; + } + } + ; + +sp_cond: + ulong_num + { /* mysql errno */ + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::number; + $$->mysqlerr= $1; + } + | SQLSTATE_SYM opt_value TEXT_STRING_literal + { /* SQLSTATE */ + if (!sp_cond_check(&$3)) + { + my_error(ER_SP_BAD_SQLSTATE, MYF(0), $3.str); + YYABORT; + } + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::state; + memcpy($$->sqlstate, $3.str, 5); + $$->sqlstate[5]= '\0'; + } + ; + +opt_value: + /* Empty */ {} + | VALUE_SYM {} + ; + +sp_hcond: + sp_cond + { + $$= $1; + } + | ident /* CONDITION name */ + { + $$= Lex->spcont->find_cond(&$1); + if ($$ == NULL) + { + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + YYABORT; + } + } + | SQLWARNING_SYM /* SQLSTATEs 01??? */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::warning; + } + | not FOUND_SYM /* SQLSTATEs 02??? */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::notfound; + } + | SQLEXCEPTION_SYM /* All other SQLSTATEs */ + { + $$= (sp_cond_type_t *)YYTHD->alloc(sizeof(sp_cond_type_t)); + $$->type= sp_cond_type_t::exception; + } + ; + +sp_decl_idents: + ident + { + /* NOTE: field definition is filled in sp_decl section. */ + + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_variable(&$1, TRUE)) + { + my_error(ER_SP_DUP_VAR, MYF(0), $1.str); + YYABORT; + } + spc->push_variable(&$1, (enum_field_types)0, sp_param_in); + $$= 1; + } + | sp_decl_idents ',' ident + { + /* NOTE: field definition is filled in sp_decl section. */ + + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + + if (spc->find_variable(&$3, TRUE)) + { + my_error(ER_SP_DUP_VAR, MYF(0), $3.str); + YYABORT; + } + spc->push_variable(&$3, (enum_field_types)0, sp_param_in); + $$= $1 + 1; + } + ; + +sp_opt_default: + /* Empty */ { $$ = NULL; } + | DEFAULT expr { $$ = $2; } + ; + +sp_proc_stmt: + sp_proc_stmt_statement + | sp_proc_stmt_return + | sp_proc_stmt_if + | sp_proc_stmt_case_simple + | sp_proc_stmt_case + | sp_labeled_control + | sp_proc_stmt_unlabeled + | sp_proc_stmt_leave + | sp_proc_stmt_iterate + | sp_proc_stmt_open + | sp_proc_stmt_fetch + | sp_proc_stmt_close + ; + +sp_proc_stmt_if: + IF { Lex->sphead->new_cont_backpatch(NULL); } + sp_if END IF + { Lex->sphead->do_cont_backpatch(); } + ; + +sp_proc_stmt_statement: + { + LEX *lex= Lex; + + lex->sphead->reset_lex(YYTHD); + lex->sphead->m_tmp_query= lex->tok_start; + } + statement + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + sp->m_flags|= sp_get_flags_for_command(lex); + if (lex->sql_command == SQLCOM_CHANGE_DB) + { /* "USE db" doesn't work in a procedure */ + my_error(ER_SP_BADSTATEMENT, MYF(0), "USE"); + YYABORT; + } + /* + Don't add an instruction for SET statements, since all + instructions for them were already added during processing + of "set" rule. + */ + DBUG_ASSERT(lex->sql_command != SQLCOM_SET_OPTION || + lex->var_list.is_empty()); + if (lex->sql_command != SQLCOM_SET_OPTION) + { + sp_instr_stmt *i=new sp_instr_stmt(sp->instructions(), + lex->spcont, lex); + + /* + Extract the query statement from the tokenizer. The + end is either lex->ptr, if there was no lookahead, + lex->tok_end otherwise. + */ + if (yychar == YYEMPTY) + i->m_query.length= lex->ptr - sp->m_tmp_query; + else + i->m_query.length= lex->tok_end - sp->m_tmp_query; + i->m_query.str= strmake_root(YYTHD->mem_root, + (char *)sp->m_tmp_query, + i->m_query.length); + sp->add_instr(i); + } + sp->restore_lex(YYTHD); + } + ; + +sp_proc_stmt_return: + RETURN_SYM + { Lex->sphead->reset_lex(YYTHD); } + expr + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + if (sp->m_type != TYPE_ENUM_FUNCTION) + { + my_message(ER_SP_BADRETURN, ER(ER_SP_BADRETURN), MYF(0)); + YYABORT; + } + else + { + sp_instr_freturn *i; + + i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3, + sp->m_return_field_def.sql_type, lex); + sp->add_instr(i); + sp->m_flags|= sp_head::HAS_RETURN; + } + sp->restore_lex(YYTHD); + } + ; + +sp_proc_stmt_case_simple: + CASE_SYM WHEN_SYM + { + Lex->sphead->m_flags&= ~sp_head::IN_SIMPLE_CASE; + Lex->sphead->new_cont_backpatch(NULL); + } + sp_case END CASE_SYM { Lex->sphead->do_cont_backpatch(); } + ; + +sp_proc_stmt_case: + CASE_SYM + { + Lex->sphead->reset_lex(YYTHD); + Lex->sphead->new_cont_backpatch(NULL); + } + expr WHEN_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *parsing_ctx= lex->spcont; + int case_expr_id= parsing_ctx->register_case_expr(); + sp_instr_set_case_expr *i; + + if (parsing_ctx->push_case_expr_id(case_expr_id)) + YYABORT; + + i= new sp_instr_set_case_expr(sp->instructions(), + parsing_ctx, + case_expr_id, + $3, + lex); + sp->add_cont_backpatch(i); + sp->add_instr(i); + sp->m_flags|= sp_head::IN_SIMPLE_CASE; + sp->restore_lex(YYTHD); + } + sp_case END CASE_SYM + { + Lex->spcont->pop_case_expr_id(); + Lex->sphead->do_cont_backpatch(); + } + ; + +sp_proc_stmt_unlabeled: + { /* Unlabeled controls get a secret label. */ + LEX *lex= Lex; + + lex->spcont->push_label((char *)"", lex->sphead->instructions()); + } + sp_unlabeled_control + { + LEX *lex= Lex; + + lex->sphead->backpatch(lex->spcont->pop_label()); + } + ; + +sp_proc_stmt_leave: + LEAVE_SYM label_ident + { + LEX *lex= Lex; + sp_head *sp = lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($2.str); + + if (! lab) + { + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "LEAVE", $2.str); + YYABORT; + } + else + { + sp_instr_jump *i; + uint ip= sp->instructions(); + uint n; + + n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */ + if (n) + sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); + n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */ + if (n) + sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); + i= new sp_instr_jump(ip, ctx); + sp->push_backpatch(i, lab); /* Jumping forward */ + sp->add_instr(i); + } + } + ; + +sp_proc_stmt_iterate: + ITERATE_SYM label_ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($2.str); + + if (! lab || lab->type != SP_LAB_ITER) + { + my_error(ER_SP_LILABEL_MISMATCH, MYF(0), "ITERATE", $2.str); + YYABORT; + } + else + { + sp_instr_jump *i; + uint ip= sp->instructions(); + uint n; + + n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */ + if (n) + sp->add_instr(new sp_instr_hpop(ip++, ctx, n)); + n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */ + if (n) + sp->add_instr(new sp_instr_cpop(ip++, ctx, n)); + i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */ + sp->add_instr(i); + } + } + ; + +sp_proc_stmt_open: + OPEN_SYM ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_copen *i; + + if (! lex->spcont->find_cursor(&$2, &offset)) + { + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); + YYABORT; + } + i= new sp_instr_copen(sp->instructions(), lex->spcont, offset); + sp->add_instr(i); + } + ; + +sp_proc_stmt_fetch: + FETCH_SYM sp_opt_fetch_noise ident INTO + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_cfetch *i; + + if (! lex->spcont->find_cursor(&$3, &offset)) + { + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $3.str); + YYABORT; + } + i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset); + sp->add_instr(i); + } + sp_fetch_list + { } + ; + +sp_proc_stmt_close: + CLOSE_SYM ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint offset; + sp_instr_cclose *i; + + if (! lex->spcont->find_cursor(&$2, &offset)) + { + my_error(ER_SP_CURSOR_MISMATCH, MYF(0), $2.str); + YYABORT; + } + i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset); + sp->add_instr(i); + } + ; + +sp_opt_fetch_noise: + /* Empty */ + | NEXT_SYM FROM + | FROM + ; + +sp_fetch_list: + ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *spc= lex->spcont; + sp_variable_t *spv; + + if (!spc || !(spv = spc->find_variable(&$1))) + { + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); + YYABORT; + } + else + { + /* An SP local variable */ + sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); + + i->add_to_varlist(spv); + } + } + | + sp_fetch_list ',' ident + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *spc= lex->spcont; + sp_variable_t *spv; + + if (!spc || !(spv = spc->find_variable(&$3))) + { + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $3.str); + YYABORT; + } + else + { + /* An SP local variable */ + sp_instr_cfetch *i= (sp_instr_cfetch *)sp->last_instruction(); + + i->add_to_varlist(spv); + } + } + ; + +sp_if: + { Lex->sphead->reset_lex(YYTHD); } + expr THEN_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx, + $2, lex); + + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + sp->add_cont_backpatch(i); + sp->add_instr(i); + sp->restore_lex(YYTHD); + } + sp_proc_stmts1 + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump *i = new sp_instr_jump(ip, ctx); + + sp->add_instr(i); + sp->backpatch(ctx->pop_label()); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + } + sp_elseifs + { + LEX *lex= Lex; + + lex->sphead->backpatch(lex->spcont->pop_label()); + } + ; + +sp_elseifs: + /* Empty */ + | ELSEIF_SYM sp_if + | ELSE sp_proc_stmts1 + ; + +sp_case: + { Lex->sphead->reset_lex(YYTHD); } + expr THEN_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i; + + if (! (sp->m_flags & sp_head::IN_SIMPLE_CASE)) + i= new sp_instr_jump_if_not(ip, ctx, $2, lex); + else + { /* Simple case: <caseval> = <whenval> */ + + Item_case_expr *var; + Item *expr; + + var= new Item_case_expr(ctx->get_current_case_expr_id()); + +#ifndef DBUG_OFF + if (var) + var->m_sp= sp; +#endif + + expr= new Item_func_eq(var, $2); + + i= new sp_instr_jump_if_not(ip, ctx, expr, lex); + } + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + sp->add_cont_backpatch(i); + sp->add_instr(i); + sp->restore_lex(YYTHD); + } + sp_proc_stmts1 + { + sp_head *sp= Lex->sphead; + sp_pcontext *ctx= Lex->spcont; + uint ip= sp->instructions(); + sp_instr_jump *i = new sp_instr_jump(ip, ctx); + + sp->add_instr(i); + sp->backpatch(ctx->pop_label()); + sp->push_backpatch(i, ctx->push_label((char *)"", 0)); + } + sp_whens + { + LEX *lex= Lex; + + lex->sphead->backpatch(lex->spcont->pop_label()); + } + ; + +sp_whens: + /* Empty */ + { + sp_head *sp= Lex->sphead; + uint ip= sp->instructions(); + sp_instr_error *i= new sp_instr_error(ip, Lex->spcont, + ER_SP_CASE_NOT_FOUND); + + sp->add_instr(i); + } + | ELSE sp_proc_stmts1 {} + | WHEN_SYM sp_case {} + ; + +sp_labeled_control: + label_ident ':' + { + LEX *lex= Lex; + sp_pcontext *ctx= lex->spcont; + sp_label_t *lab= ctx->find_label($1.str); + + if (lab) + { + my_error(ER_SP_LABEL_REDEFINE, MYF(0), $1.str); + YYABORT; + } + else + { + lab= lex->spcont->push_label($1.str, + lex->sphead->instructions()); + lab->type= SP_LAB_ITER; + } + } + sp_unlabeled_control sp_opt_label + { + LEX *lex= Lex; + + if ($5.str) + { + sp_label_t *lab= lex->spcont->find_label($5.str); + + if (!lab || + my_strcasecmp(system_charset_info, $5.str, lab->name) != 0) + { + my_error(ER_SP_LABEL_MISMATCH, MYF(0), $5.str); + YYABORT; + } + } + lex->sphead->backpatch(lex->spcont->pop_label()); + } + ; + +sp_opt_label: + /* Empty */ { $$= null_lex_str; } + | label_ident { $$= $1; } + ; + +sp_unlabeled_control: + BEGIN_SYM + { /* QQ This is just a dummy for grouping declarations and statements + together. No [[NOT] ATOMIC] yet, and we need to figure out how + make it coexist with the existing BEGIN COMMIT/ROLLBACK. */ + LEX *lex= Lex; + sp_label_t *lab= lex->spcont->last_label(); + + lab->type= SP_LAB_BEGIN; + lex->spcont= lex->spcont->push_context(); + } + sp_decls + sp_proc_stmts + END + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + sp_pcontext *ctx= lex->spcont; + + sp->backpatch(ctx->last_label()); /* We always have a label */ + if ($3.hndlrs) + sp->add_instr(new sp_instr_hpop(sp->instructions(), ctx, + $3.hndlrs)); + if ($3.curs) + sp->add_instr(new sp_instr_cpop(sp->instructions(), ctx, + $3.curs)); + lex->spcont= ctx->pop_context(); + } + | LOOP_SYM + sp_proc_stmts1 END LOOP_SYM + { + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); + + lex->sphead->add_instr(i); + } + | WHILE_SYM + { Lex->sphead->reset_lex(YYTHD); } + expr DO_SYM + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + uint ip= sp->instructions(); + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, + $3, lex); + + /* Jumping forward */ + sp->push_backpatch(i, lex->spcont->last_label()); + sp->new_cont_backpatch(i); + sp->add_instr(i); + sp->restore_lex(YYTHD); + } + sp_proc_stmts1 END WHILE_SYM + { + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip); + + lex->sphead->add_instr(i); + lex->sphead->do_cont_backpatch(); + } + | REPEAT_SYM sp_proc_stmts1 UNTIL_SYM + { Lex->sphead->reset_lex(YYTHD); } + expr END REPEAT_SYM + { + LEX *lex= Lex; + uint ip= lex->sphead->instructions(); + sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */ + sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont, + $5, lab->ip, + lex); + lex->sphead->add_instr(i); + lex->sphead->restore_lex(YYTHD); + /* We can shortcut the cont_backpatch here */ + i->m_cont_dest= ip+1; + } + ; + +trg_action_time: + BEFORE_SYM + { Lex->trg_chistics.action_time= TRG_ACTION_BEFORE; } + | AFTER_SYM + { Lex->trg_chistics.action_time= TRG_ACTION_AFTER; } + ; + +trg_event: + INSERT + { Lex->trg_chistics.event= TRG_EVENT_INSERT; } + | UPDATE_SYM + { Lex->trg_chistics.event= TRG_EVENT_UPDATE; } + | DELETE_SYM + { Lex->trg_chistics.event= TRG_EVENT_DELETE; } + ; +/* + This part of the parser contains common code for all TABLESPACE + commands. + CREATE TABLESPACE name ... + ALTER TABLESPACE name CHANGE DATAFILE ... + ALTER TABLESPACE name ADD DATAFILE ... + ALTER TABLESPACE name access_mode + CREATE LOGFILE GROUP name ... + ALTER LOGFILE GROUP name ADD UNDOFILE .. + ALTER LOGFILE GROUP name ADD REDOFILE .. + DROP TABLESPACE name + DROP LOGFILE GROUP name +*/ +change_tablespace_access: + tablespace_name + ts_access_mode + ; + +change_tablespace_info: + tablespace_name + CHANGE ts_datafile + change_ts_option_list + ; + +tablespace_info: + tablespace_name + ADD ts_datafile + opt_logfile_group_name + tablespace_option_list + ; + +opt_logfile_group_name: + /* empty */ {} + | USE_SYM LOGFILE_SYM GROUP ident + { + LEX *lex= Lex; + lex->alter_tablespace_info->logfile_group_name= $4.str; + }; + +alter_tablespace_info: + tablespace_name + ADD ts_datafile + alter_tablespace_option_list + { + Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_ADD_FILE; + } + | + tablespace_name + DROP ts_datafile + alter_tablespace_option_list + { + Lex->alter_tablespace_info->ts_alter_tablespace_type= ALTER_TABLESPACE_DROP_FILE; + }; + +logfile_group_info: + logfile_group_name + add_log_file + logfile_group_option_list + ; + +alter_logfile_group_info: + logfile_group_name + add_log_file + alter_logfile_group_option_list + ; + +add_log_file: + ADD lg_undofile + | ADD lg_redofile + ; + +change_ts_option_list: + /* empty */ {} + change_ts_options + ; + +change_ts_options: + change_ts_option + | change_ts_options change_ts_option + | change_ts_options ',' change_ts_option + ; + +change_ts_option: + opt_ts_initial_size + | opt_ts_autoextend_size + | opt_ts_max_size + ; + +tablespace_option_list: + /* empty */ {} + tablespace_options + ; + +tablespace_options: + tablespace_option + | tablespace_options tablespace_option + | tablespace_options ',' tablespace_option + ; + +tablespace_option: + opt_ts_initial_size + | opt_ts_autoextend_size + | opt_ts_max_size + | opt_ts_extent_size + | opt_ts_nodegroup + | opt_ts_engine + | ts_wait + | opt_ts_comment + ; + +alter_tablespace_option_list: + /* empty */ {} + alter_tablespace_options + ; + +alter_tablespace_options: + alter_tablespace_option + | alter_tablespace_options alter_tablespace_option + | alter_tablespace_options ',' alter_tablespace_option + ; + +alter_tablespace_option: + opt_ts_initial_size + | opt_ts_autoextend_size + | opt_ts_max_size + | opt_ts_engine + | ts_wait + ; + +logfile_group_option_list: + /* empty */ {} + logfile_group_options + ; + +logfile_group_options: + logfile_group_option + | logfile_group_options logfile_group_option + | logfile_group_options ',' logfile_group_option + ; + +logfile_group_option: + opt_ts_initial_size + | opt_ts_undo_buffer_size + | opt_ts_redo_buffer_size + | opt_ts_nodegroup + | opt_ts_engine + | ts_wait + | opt_ts_comment + ; + +alter_logfile_group_option_list: + /* empty */ {} + alter_logfile_group_options + ; + +alter_logfile_group_options: + alter_logfile_group_option + | alter_logfile_group_options alter_logfile_group_option + | alter_logfile_group_options ',' alter_logfile_group_option + ; + +alter_logfile_group_option: + opt_ts_initial_size + | opt_ts_engine + | ts_wait + ; + + +ts_datafile: + DATAFILE_SYM TEXT_STRING_sys + { + LEX *lex= Lex; + lex->alter_tablespace_info->data_file_name= $2.str; + }; + +lg_undofile: + UNDOFILE_SYM TEXT_STRING_sys + { + LEX *lex= Lex; + lex->alter_tablespace_info->undo_file_name= $2.str; + }; + +lg_redofile: + REDOFILE_SYM TEXT_STRING_sys + { + LEX *lex= Lex; + lex->alter_tablespace_info->redo_file_name= $2.str; + }; + +tablespace_name: + ident + { + LEX *lex= Lex; + lex->alter_tablespace_info= new st_alter_tablespace(); + lex->alter_tablespace_info->tablespace_name= $1.str; + lex->sql_command= SQLCOM_ALTER_TABLESPACE; + }; + +logfile_group_name: + ident + { + LEX *lex= Lex; + lex->alter_tablespace_info= new st_alter_tablespace(); + lex->alter_tablespace_info->logfile_group_name= $1.str; + lex->sql_command= SQLCOM_ALTER_TABLESPACE; + }; + +ts_access_mode: + READ_ONLY_SYM + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_access_mode= TS_READ_ONLY; + } + | READ_WRITE_SYM + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_access_mode= TS_READ_WRITE; + } + | NOT_SYM ACCESSIBLE_SYM + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_access_mode= TS_NOT_ACCESSIBLE; + }; + +opt_ts_initial_size: + INITIAL_SIZE_SYM opt_equal size_number + { + LEX *lex= Lex; + lex->alter_tablespace_info->initial_size= $3; + }; + +opt_ts_autoextend_size: + AUTOEXTEND_SIZE_SYM opt_equal size_number + { + LEX *lex= Lex; + lex->alter_tablespace_info->autoextend_size= $3; + }; + +opt_ts_max_size: + MAX_SIZE_SYM opt_equal size_number + { + LEX *lex= Lex; + lex->alter_tablespace_info->max_size= $3; + }; + +opt_ts_extent_size: + EXTENT_SIZE_SYM opt_equal size_number + { + LEX *lex= Lex; + lex->alter_tablespace_info->extent_size= $3; + }; + +opt_ts_undo_buffer_size: + UNDO_BUFFER_SIZE_SYM opt_equal size_number + { + LEX *lex= Lex; + lex->alter_tablespace_info->undo_buffer_size= $3; + }; + +opt_ts_redo_buffer_size: + REDO_BUFFER_SIZE_SYM opt_equal size_number + { + LEX *lex= Lex; + lex->alter_tablespace_info->redo_buffer_size= $3; + }; + +opt_ts_nodegroup: + NODEGROUP_SYM opt_equal real_ulong_num + { + LEX *lex= Lex; + if (lex->alter_tablespace_info->nodegroup_id != UNDEF_NODEGROUP) + { + my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NODEGROUP"); + YYABORT; + } + lex->alter_tablespace_info->nodegroup_id= $3; + }; + +opt_ts_comment: + COMMENT_SYM opt_equal TEXT_STRING_sys + { + LEX *lex= Lex; + if (lex->alter_tablespace_info->ts_comment != NULL) + { + my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"COMMENT"); + YYABORT; + } + lex->alter_tablespace_info->ts_comment= $3.str; + }; + +opt_ts_engine: + opt_storage ENGINE_SYM opt_equal storage_engines + { + LEX *lex= Lex; + if (lex->alter_tablespace_info->storage_engine != NULL) + { + my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0), + "STORAGE ENGINE"); + YYABORT; + } + lex->alter_tablespace_info->storage_engine= $4; + }; + +opt_ts_wait: + /* empty */ + | ts_wait + ; + +ts_wait: + WAIT_SYM + { + LEX *lex= Lex; + lex->alter_tablespace_info->wait_until_completed= TRUE; + } + | NO_WAIT_SYM + { + LEX *lex= Lex; + if (!(lex->alter_tablespace_info->wait_until_completed)) + { + my_error(ER_FILEGROUP_OPTION_ONLY_ONCE,MYF(0),"NO_WAIT"); + YYABORT; + } + lex->alter_tablespace_info->wait_until_completed= FALSE; + }; + +size_number: + real_ulong_num { $$= $1;} + | IDENT + { + ulonglong number, test_number; + uint text_shift_number= 0; + longlong prefix_number; + char *start_ptr= $1.str; + uint str_len= $1.length; + char *end_ptr= start_ptr + str_len; + int error; + prefix_number= my_strtoll10(start_ptr, &end_ptr, &error); + if ((start_ptr + str_len - 1) == end_ptr) + { + switch (end_ptr[0]) + { + case 'g': + case 'G': + text_shift_number+=10; + case 'm': + case 'M': + text_shift_number+=10; + case 'k': + case 'K': + text_shift_number+=10; + break; + default: + { + my_error(ER_WRONG_SIZE_NUMBER, MYF(0)); + YYABORT; + } + } + if (prefix_number >> 31) + { + my_error(ER_SIZE_OVERFLOW_ERROR, MYF(0)); + YYABORT; + } + number= prefix_number << text_shift_number; + } + else + { + my_error(ER_WRONG_SIZE_NUMBER, MYF(0)); + YYABORT; + } + $$= number; + } + ; + +/* + End tablespace part +*/ + +create2: + '(' create2a {} + | opt_create_table_options + opt_partitioning {} + create3 {} + | LIKE table_ident + { + LEX *lex=Lex; + THD *thd= lex->thd; + if (!(lex->like_name= $2)) + YYABORT; + if ($2->db.str == NULL && + thd->copy_db_to(&($2->db.str), &($2->db.length))) + { + YYABORT; + } + } + | '(' LIKE table_ident ')' + { + LEX *lex=Lex; + THD *thd= lex->thd; + if (!(lex->like_name= $3)) + YYABORT; + if ($3->db.str == NULL && + thd->copy_db_to(&($3->db.str), &($3->db.length))) + { + YYABORT; + } + } + ; + +create2a: + field_list ')' opt_create_table_options + opt_partitioning {} + create3 {} + | opt_partitioning {} + create_select ')' + { Select->set_braces(1);} union_opt {} + ; + +create3: + /* empty */ {} + | opt_duplicate opt_as create_select + { Select->set_braces(0);} union_clause {} + | opt_duplicate opt_as '(' create_select ')' + { Select->set_braces(1);} union_opt {} + ; + +/* + This part of the parser is about handling of the partition information. + + It's first version was written by Mikael Ronström with lots of answers to + questions provided by Antony Curtis. + + The partition grammar can be called from three places. + 1) CREATE TABLE ... PARTITION .. + 2) ALTER TABLE table_name PARTITION ... + 3) PARTITION ... + + The first place is called when a new table is created from a MySQL client. + The second place is called when a table is altered with the ALTER TABLE + command from a MySQL client. + The third place is called when opening an frm file and finding partition + info in the .frm file. It is necessary to avoid allowing PARTITION to be + an allowed entry point for SQL client queries. This is arranged by setting + some state variables before arriving here. + + To be able to handle errors we will only set error code in this code + and handle the error condition in the function calling the parser. This + is necessary to ensure we can also handle errors when calling the parser + from the openfrm function. +*/ +opt_partitioning: + /* empty */ {} + | partitioning + ; + +partitioning: + PARTITION_SYM + { +#ifdef WITH_PARTITION_STORAGE_ENGINE + LEX *lex= Lex; + lex->part_info= new partition_info(); + if (!lex->part_info) + { + mem_alloc_error(sizeof(partition_info)); + YYABORT; + } + if (lex->sql_command == SQLCOM_ALTER_TABLE) + { + lex->alter_info.flags|= ALTER_PARTITION; + } +#else + my_error(ER_FEATURE_DISABLED, MYF(0), + "partitioning", "--with-partition"); + YYABORT; +#endif + + } + partition + ; + +partition_entry: + PARTITION_SYM + { + LEX *lex= Lex; + if (!lex->part_info) + { + yyerror(ER(ER_PARTITION_ENTRY_ERROR)); + YYABORT; + } + /* + We enter here when opening the frm file to translate + partition info string into part_info data structure. + */ + } + partition {} + ; + +partition: + BY part_type_def opt_no_parts {} opt_sub_part {} part_defs + ; + +part_type_def: + opt_linear KEY_SYM '(' part_field_list ')' + { + LEX *lex= Lex; + lex->part_info->list_of_part_fields= TRUE; + lex->part_info->part_type= HASH_PARTITION; + } + | opt_linear HASH_SYM + { Lex->part_info->part_type= HASH_PARTITION; } + part_func {} + | RANGE_SYM + { Lex->part_info->part_type= RANGE_PARTITION; } + part_func {} + | LIST_SYM + { Lex->part_info->part_type= LIST_PARTITION; } + part_func {} + ; + +opt_linear: + /* empty */ {} + | LINEAR_SYM + { Lex->part_info->linear_hash_ind= TRUE;} + ; + +part_field_list: + /* empty */ {} + | part_field_item_list {} + ; + +part_field_item_list: + part_field_item {} + | part_field_item_list ',' part_field_item {} + ; + +part_field_item: + ident + { + if (Lex->part_info->part_field_list.push_back($1.str)) + { + mem_alloc_error(1); + YYABORT; + } + } + ; + +part_func: + '(' remember_name part_func_expr remember_end ')' + { + LEX *lex= Lex; + uint expr_len= (uint)($4 - $2) - 1; + lex->part_info->list_of_part_fields= FALSE; + lex->part_info->part_expr= $3; + lex->part_info->part_func_string= (char* ) sql_memdup($2+1, expr_len); + lex->part_info->part_func_len= expr_len; + } + ; + +sub_part_func: + '(' remember_name part_func_expr remember_end ')' + { + LEX *lex= Lex; + uint expr_len= (uint)($4 - $2) - 1; + lex->part_info->list_of_subpart_fields= FALSE; + lex->part_info->subpart_expr= $3; + lex->part_info->subpart_func_string= (char* ) sql_memdup($2+1, expr_len); + lex->part_info->subpart_func_len= expr_len; + } + ; + + +opt_no_parts: + /* empty */ {} + | PARTITIONS_SYM real_ulong_num + { + uint no_parts= $2; + LEX *lex= Lex; + if (no_parts == 0) + { + my_error(ER_NO_PARTS_ERROR, MYF(0), "partitions"); + YYABORT; + } + + lex->part_info->no_parts= no_parts; + lex->part_info->use_default_no_partitions= FALSE; + } + ; + +opt_sub_part: + /* empty */ {} + | SUBPARTITION_SYM BY opt_linear HASH_SYM sub_part_func + { Lex->part_info->subpart_type= HASH_PARTITION; } + opt_no_subparts {} + | SUBPARTITION_SYM BY opt_linear KEY_SYM + '(' sub_part_field_list ')' + { + LEX *lex= Lex; + lex->part_info->subpart_type= HASH_PARTITION; + lex->part_info->list_of_subpart_fields= TRUE; + } + opt_no_subparts {} + ; + +sub_part_field_list: + sub_part_field_item {} + | sub_part_field_list ',' sub_part_field_item {} + ; + +sub_part_field_item: + ident + { + if (Lex->part_info->subpart_field_list.push_back($1.str)) + { + mem_alloc_error(1); + YYABORT; + } + } + ; + +part_func_expr: + bit_expr + { + LEX *lex= Lex; + bool not_corr_func; + not_corr_func= !lex->safe_to_cache_query; + lex->safe_to_cache_query= 1; + if (not_corr_func) + { + yyerror(ER(ER_CONST_EXPR_IN_PARTITION_FUNC_ERROR)); + YYABORT; + } + $$=$1; + } + ; + +opt_no_subparts: + /* empty */ {} + | SUBPARTITIONS_SYM real_ulong_num + { + uint no_parts= $2; + LEX *lex= Lex; + if (no_parts == 0) + { + my_error(ER_NO_PARTS_ERROR, MYF(0), "subpartitions"); + YYABORT; + } + lex->part_info->no_subparts= no_parts; + lex->part_info->use_default_no_subpartitions= FALSE; + } + ; + +part_defs: + /* empty */ + {} + | '(' part_def_list ')' + { + LEX *lex= Lex; + partition_info *part_info= lex->part_info; + uint count_curr_parts= part_info->partitions.elements; + if (part_info->no_parts != 0) + { + if (part_info->no_parts != + count_curr_parts) + { + yyerror(ER(ER_PARTITION_WRONG_NO_PART_ERROR)); + YYABORT; + } + } + else if (count_curr_parts > 0) + { + part_info->no_parts= count_curr_parts; + } + part_info->count_curr_subparts= 0; + } + ; + +part_def_list: + part_definition {} + | part_def_list ',' part_definition {} + ; + +part_definition: + PARTITION_SYM + { + LEX *lex= Lex; + partition_info *part_info= lex->part_info; + partition_element *p_elem= new partition_element(); + uint part_id= part_info->partitions.elements; + + if (!p_elem || part_info->partitions.push_back(p_elem)) + { + mem_alloc_error(sizeof(partition_element)); + YYABORT; + } + p_elem->part_state= PART_NORMAL; + part_info->curr_part_elem= p_elem; + part_info->current_partition= p_elem; + part_info->use_default_partitions= FALSE; + part_info->use_default_no_partitions= FALSE; + } + part_name {} + opt_part_values {} + opt_part_options {} + opt_sub_partition {} + ; + +part_name: + ident + { + LEX *lex= Lex; + partition_info *part_info= lex->part_info; + partition_element *p_elem= part_info->curr_part_elem; + p_elem->partition_name= $1.str; + } + ; + +opt_part_values: + /* empty */ + { + LEX *lex= Lex; + if (!is_partition_management(lex)) + { + if (lex->part_info->part_type == RANGE_PARTITION) + { + my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), + "RANGE", "LESS THAN"); + YYABORT; + } + if (lex->part_info->part_type == LIST_PARTITION) + { + my_error(ER_PARTITION_REQUIRES_VALUES_ERROR, MYF(0), + "LIST", "IN"); + YYABORT; + } + } + else + lex->part_info->part_type= HASH_PARTITION; + } + | VALUES LESS_SYM THAN_SYM part_func_max + { + LEX *lex= Lex; + if (!is_partition_management(lex)) + { + if (Lex->part_info->part_type != RANGE_PARTITION) + { + my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), + "RANGE", "LESS THAN"); + YYABORT; + } + } + else + lex->part_info->part_type= RANGE_PARTITION; + } + | VALUES IN_SYM '(' part_list_func ')' + { + LEX *lex= Lex; + if (!is_partition_management(lex)) + { + if (Lex->part_info->part_type != LIST_PARTITION) + { + my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0), + "LIST", "IN"); + YYABORT; + } + } + else + lex->part_info->part_type= LIST_PARTITION; + } + ; + +part_func_max: + max_value_sym + { + LEX *lex= Lex; + if (lex->part_info->defined_max_value) + { + yyerror(ER(ER_PARTITION_MAXVALUE_ERROR)); + YYABORT; + } + lex->part_info->defined_max_value= TRUE; + lex->part_info->curr_part_elem->max_value= TRUE; + lex->part_info->curr_part_elem->range_value= LONGLONG_MAX; + } + | part_range_func + { + if (Lex->part_info->defined_max_value) + { + yyerror(ER(ER_PARTITION_MAXVALUE_ERROR)); + YYABORT; + } + if (Lex->part_info->curr_part_elem->has_null_value) + { + yyerror(ER(ER_NULL_IN_VALUES_LESS_THAN)); + YYABORT; + } + } + ; + +max_value_sym: + MAX_VALUE_SYM + | '(' MAX_VALUE_SYM ')' + ; + +part_range_func: + '(' part_bit_expr ')' + { + partition_info *part_info= Lex->part_info; + if (!($2->unsigned_flag)) + part_info->curr_part_elem->signed_flag= TRUE; + part_info->curr_part_elem->range_value= $2->value; + } + ; + +part_list_func: + part_list_item {} + | part_list_func ',' part_list_item {} + ; + +part_list_item: + part_bit_expr + { + part_elem_value *value_ptr= $1; + partition_info *part_info= Lex->part_info; + if (!value_ptr->unsigned_flag) + part_info->curr_part_elem->signed_flag= TRUE; + if (!value_ptr->null_value && + part_info->curr_part_elem-> + list_val_list.push_back(value_ptr)) + { + mem_alloc_error(sizeof(part_elem_value)); + YYABORT; + } + } + ; + +part_bit_expr: + bit_expr + { + Item *part_expr= $1; + bool not_corr_func; + int part_expression_ok= 1; + LEX *lex= Lex; + THD *thd= YYTHD; + longlong item_value; + Name_resolution_context *context= &lex->current_select->context; + TABLE_LIST *save_list= context->table_list; + const char *save_where= thd->where; + + context->table_list= 0; + thd->where= "partition function"; + + part_elem_value *value_ptr= + (part_elem_value*)sql_alloc(sizeof(part_elem_value)); + if (!value_ptr) + { + mem_alloc_error(sizeof(part_elem_value)); + YYABORT; + } + if (part_expr->walk(&Item::check_partition_func_processor, 0, + NULL)) + { + my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); + YYABORT; + } + if (part_expr->fix_fields(YYTHD, (Item**)0) || + ((context->table_list= save_list), FALSE) || + (!part_expr->const_item()) || + (!lex->safe_to_cache_query)) + { + my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0)); + YYABORT; + } + thd->where= save_where; + value_ptr->value= part_expr->val_int(); + value_ptr->unsigned_flag= TRUE; + if (!part_expr->unsigned_flag && + value_ptr->value < 0) + value_ptr->unsigned_flag= FALSE; + if ((value_ptr->null_value= part_expr->null_value)) + { + if (Lex->part_info->curr_part_elem->has_null_value) + { + my_error(ER_MULTIPLE_DEF_CONST_IN_LIST_PART_ERROR, MYF(0)); + YYABORT; + } + Lex->part_info->curr_part_elem->has_null_value= TRUE; + } + else if (part_expr->result_type() != INT_RESULT && + !part_expr->null_value) + { + yyerror(ER(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR)); + YYABORT; + } + $$= value_ptr; + } + ; + +opt_sub_partition: + /* empty */ + { + if (Lex->part_info->no_subparts != 0 && + !Lex->part_info->use_default_subpartitions) + { + yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR)); + YYABORT; + } + } + | '(' sub_part_list ')' + { + LEX *lex= Lex; + partition_info *part_info= lex->part_info; + if (part_info->no_subparts != 0) + { + if (part_info->no_subparts != + part_info->count_curr_subparts) + { + yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR)); + YYABORT; + } + } + else if (part_info->count_curr_subparts > 0) + { + if (part_info->partitions.elements > 1) + { + yyerror(ER(ER_PARTITION_WRONG_NO_SUBPART_ERROR)); + YYABORT; + } + part_info->no_subparts= part_info->count_curr_subparts; + } + part_info->count_curr_subparts= 0; + } + ; + +sub_part_list: + sub_part_definition {} + | sub_part_list ',' sub_part_definition {} + ; + +sub_part_definition: + SUBPARTITION_SYM + { + LEX *lex= Lex; + partition_info *part_info= lex->part_info; + partition_element *curr_part= part_info->current_partition; + partition_element *sub_p_elem= new partition_element(curr_part); + if (!sub_p_elem || + curr_part->subpartitions.push_back(sub_p_elem)) + { + mem_alloc_error(sizeof(partition_element)); + YYABORT; + } + part_info->curr_part_elem= sub_p_elem; + part_info->use_default_subpartitions= FALSE; + part_info->use_default_no_subpartitions= FALSE; + part_info->count_curr_subparts++; + } + sub_name opt_part_options {} + ; + +sub_name: + ident_or_text + { Lex->part_info->curr_part_elem->partition_name= $1.str; } + ; + +opt_part_options: + /* empty */ {} + | opt_part_option_list {} + ; + +opt_part_option_list: + opt_part_option_list opt_part_option {} + | opt_part_option {} + ; + +opt_part_option: + TABLESPACE opt_equal ident_or_text + { Lex->part_info->curr_part_elem->tablespace_name= $3.str; } + | opt_storage ENGINE_SYM opt_equal storage_engines + { + LEX *lex= Lex; + lex->part_info->curr_part_elem->engine_type= $4; + lex->part_info->default_engine_type= $4; + } + | NODEGROUP_SYM opt_equal real_ulong_num + { Lex->part_info->curr_part_elem->nodegroup_id= $3; } + | MAX_ROWS opt_equal real_ulonglong_num + { Lex->part_info->curr_part_elem->part_max_rows= $3; } + | MIN_ROWS opt_equal real_ulonglong_num + { Lex->part_info->curr_part_elem->part_min_rows= $3; } + | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys + { Lex->part_info->curr_part_elem->data_file_name= $4.str; } + | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys + { Lex->part_info->curr_part_elem->index_file_name= $4.str; } + | COMMENT_SYM opt_equal TEXT_STRING_sys + { Lex->part_info->curr_part_elem->part_comment= $3.str; } + ; + +/* + End of partition parser part +*/ + +create_select: + SELECT_SYM + { + LEX *lex=Lex; + lex->lock_option= using_update_log ? TL_READ_NO_INSERT : TL_READ; + if (lex->sql_command == SQLCOM_INSERT) + lex->sql_command= SQLCOM_INSERT_SELECT; + else if (lex->sql_command == SQLCOM_REPLACE) + lex->sql_command= SQLCOM_REPLACE_SELECT; + /* + The following work only with the local list, the global list + is created correctly in this case + */ + lex->current_select->table_list.save_and_clear(&lex->save_list); + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + } + select_options select_item_list + { + Select->parsing_place= NO_MATTER; + } + opt_select_from + { + /* + The following work only with the local list, the global list + is created correctly in this case + */ + Lex->current_select->table_list.push_front(&Lex->save_list); + } + ; + +opt_as: + /* empty */ {} + | AS {}; + +opt_create_database_options: + /* empty */ {} + | create_database_options {}; + +create_database_options: + create_database_option {} + | create_database_options create_database_option {}; + +create_database_option: + default_collation {} + | default_charset {}; + +opt_table_options: + /* empty */ { $$= 0; } + | table_options { $$= $1;}; + +table_options: + table_option { $$=$1; } + | table_option table_options { $$= $1 | $2; }; + +table_option: + TEMPORARY { $$=HA_LEX_CREATE_TMP_TABLE; }; + +opt_if_not_exists: + /* empty */ { $$= 0; } + | IF not EXISTS { $$=HA_LEX_CREATE_IF_NOT_EXISTS; }; + +opt_create_table_options: + /* empty */ + | create_table_options; + +create_table_options_space_separated: + create_table_option + | create_table_option create_table_options_space_separated; + +create_table_options: + create_table_option + | create_table_option create_table_options + | create_table_option ',' create_table_options; + +create_table_option: + ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; } + | TYPE_SYM opt_equal storage_engines + { + Lex->create_info.db_type= $3; + WARN_DEPRECATED(yythd, "5.2", "TYPE=storage_engine", + "'ENGINE=storage_engine'"); + Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; + } + | MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;} + | MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;} + | AVG_ROW_LENGTH opt_equal ulong_num { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} + | PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; } + | COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; } + | AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;} + | PACK_KEYS_SYM opt_equal ulong_num + { + switch($3) { + case 0: + Lex->create_info.table_options|= HA_OPTION_NO_PACK_KEYS; + break; + case 1: + Lex->create_info.table_options|= HA_OPTION_PACK_KEYS; + break; + default: + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS; + } + | PACK_KEYS_SYM opt_equal DEFAULT + { + Lex->create_info.table_options&= + ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); + Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS; + } + | CHECKSUM_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; } + | DELAY_KEY_WRITE_SYM opt_equal ulong_num { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; } + | ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; } + | UNION_SYM opt_equal '(' table_list ')' + { + /* Move the union list to the merge_list */ + LEX *lex=Lex; + TABLE_LIST *table_list= lex->select_lex.get_table_list(); + lex->create_info.merge_list= lex->select_lex.table_list; + lex->create_info.merge_list.elements--; + lex->create_info.merge_list.first= + (byte*) (table_list->next_local); + lex->select_lex.table_list.elements=1; + lex->select_lex.table_list.next= + (byte**) &(table_list->next_local); + table_list->next_local= 0; + lex->create_info.used_fields|= HA_CREATE_USED_UNION; + } + | default_charset + | default_collation + | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} + | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR; } + | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR; } + | TABLESPACE ident {Lex->create_info.tablespace= $2.str;} + | STORAGE_SYM DISK_SYM {Lex->create_info.store_on_disk= TRUE;} + | STORAGE_SYM MEMORY_SYM {Lex->create_info.store_on_disk= FALSE;} + | CONNECTION_SYM opt_equal TEXT_STRING_sys { Lex->create_info.connect_string.str= $3.str; Lex->create_info.connect_string.length= $3.length; Lex->create_info.used_fields|= HA_CREATE_USED_CONNECTION; } + | KEY_BLOCK_SIZE opt_equal ulong_num + { + Lex->create_info.used_fields|= HA_CREATE_USED_KEY_BLOCK_SIZE; + Lex->create_info.key_block_size= $3; + } + ; + +default_charset: + opt_default charset opt_equal charset_name_or_default + { + HA_CREATE_INFO *cinfo= &Lex->create_info; + if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !my_charset_same(cinfo->default_table_charset,$4)) + { + my_error(ER_CONFLICTING_DECLARATIONS, MYF(0), + "CHARACTER SET ", cinfo->default_table_charset->csname, + "CHARACTER SET ", $4->csname); + YYABORT; + } + Lex->create_info.default_table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + }; + +default_collation: + opt_default COLLATE_SYM opt_equal collation_name_or_default + { + HA_CREATE_INFO *cinfo= &Lex->create_info; + if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !my_charset_same(cinfo->default_table_charset,$4)) + { + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $4->name, cinfo->default_table_charset->csname); + YYABORT; + } + Lex->create_info.default_table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + }; + +storage_engines: + ident_or_text + { + $$ = ha_resolve_by_name(YYTHD, &$1); + if ($$ == NULL) + if (YYTHD->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION) + { + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), $1.str); + YYABORT; + } + else + { + push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_UNKNOWN_STORAGE_ENGINE, + ER(ER_UNKNOWN_STORAGE_ENGINE), $1.str); + } + }; + +row_types: + DEFAULT { $$= ROW_TYPE_DEFAULT; } + | FIXED_SYM { $$= ROW_TYPE_FIXED; } + | DYNAMIC_SYM { $$= ROW_TYPE_DYNAMIC; } + | COMPRESSED_SYM { $$= ROW_TYPE_COMPRESSED; } + | REDUNDANT_SYM { $$= ROW_TYPE_REDUNDANT; } + | COMPACT_SYM { $$= ROW_TYPE_COMPACT; }; + +merge_insert_types: + NO_SYM { $$= MERGE_INSERT_DISABLED; } + | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; } + | LAST_SYM { $$= MERGE_INSERT_TO_LAST; }; + +opt_select_from: + opt_limit_clause {} + | select_from select_lock_type; + +udf_func_type: + /* empty */ { $$ = UDFTYPE_FUNCTION; } + | AGGREGATE_SYM { $$ = UDFTYPE_AGGREGATE; }; + +udf_type: + STRING_SYM {$$ = (int) STRING_RESULT; } + | REAL {$$ = (int) REAL_RESULT; } + | DECIMAL_SYM {$$ = (int) DECIMAL_RESULT; } + | INT_SYM {$$ = (int) INT_RESULT; }; + +field_list: + field_list_item + | field_list ',' field_list_item; + + +field_list_item: + column_def + | key_def + ; + +column_def: + field_spec opt_check_constraint + | field_spec references + { + Lex->col_list.empty(); /* Alloced by sql_alloc */ + } + ; + +key_def: + key_type opt_ident key_alg '(' key_list ')' key_options + { + LEX *lex=Lex; + if ($1 != Key::FULLTEXT && lex->key_create_info.parser_name.str) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->key_list.push_back(new Key($1,$2, &lex->key_create_info, 0, + lex->col_list)); + lex->col_list.empty(); /* Alloced by sql_alloc */ + } + | opt_constraint constraint_key_type opt_ident key_alg + '(' key_list ')' key_options + { + LEX *lex=Lex; + const char *key_name= $3 ? $3 : $1; + lex->key_list.push_back(new Key($2, key_name, &lex->key_create_info, 0, + lex->col_list)); + lex->col_list.empty(); /* Alloced by sql_alloc */ + } + | opt_constraint FOREIGN KEY_SYM opt_ident '(' key_list ')' references + { + LEX *lex=Lex; + lex->key_list.push_back(new foreign_key($4 ? $4:$1, lex->col_list, + $8, + lex->ref_list, + lex->fk_delete_opt, + lex->fk_update_opt, + lex->fk_match_option)); + lex->key_list.push_back(new Key(Key::MULTIPLE, $4 ? $4 : $1, + &default_key_create_info, 1, + lex->col_list)); + lex->col_list.empty(); /* Alloced by sql_alloc */ + + /* Only used for ALTER TABLE. Ignored otherwise. */ + lex->alter_info.flags|= ALTER_FOREIGN_KEY; + } + | constraint opt_check_constraint + { + Lex->col_list.empty(); /* Alloced by sql_alloc */ + } + | opt_constraint check_constraint + { + Lex->col_list.empty(); /* Alloced by sql_alloc */ + } + ; + +opt_check_constraint: + /* empty */ + | check_constraint + ; + +check_constraint: + CHECK_SYM expr + ; + +opt_constraint: + /* empty */ { $$=(char*) 0; } + | constraint { $$= $1; } + ; + +constraint: + CONSTRAINT opt_ident { $$=$2; } + ; + +field_spec: + field_ident + { + LEX *lex=Lex; + lex->length=lex->dec=0; lex->type=0; + lex->default_value= lex->on_update_value= 0; + lex->comment=null_lex_str; + lex->charset=NULL; + } + type opt_attribute + { + LEX *lex=Lex; + if (add_field_to_list(lex->thd, $1.str, + (enum enum_field_types) $3, + lex->length,lex->dec,lex->type, + lex->default_value, lex->on_update_value, + &lex->comment, + lex->change,&lex->interval_list,lex->charset, + lex->uint_geom_type)) + YYABORT; + }; + +type: + int_type opt_len field_options { $$=$1; } + | real_type opt_precision field_options { $$=$1; } + | FLOAT_SYM float_options field_options { $$=FIELD_TYPE_FLOAT; } + | BIT_SYM { Lex->length= (char*) "1"; + $$=FIELD_TYPE_BIT; } + | BIT_SYM '(' NUM ')' { Lex->length= $3.str; + $$=FIELD_TYPE_BIT; } + | BOOL_SYM { Lex->length=(char*) "1"; + $$=FIELD_TYPE_TINY; } + | BOOLEAN_SYM { Lex->length=(char*) "1"; + $$=FIELD_TYPE_TINY; } + | char '(' NUM ')' opt_binary { Lex->length=$3.str; + $$=FIELD_TYPE_STRING; } + | char opt_binary { Lex->length=(char*) "1"; + $$=FIELD_TYPE_STRING; } + | nchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str; + $$=FIELD_TYPE_STRING; + Lex->charset=national_charset_info; } + | nchar opt_bin_mod { Lex->length=(char*) "1"; + $$=FIELD_TYPE_STRING; + Lex->charset=national_charset_info; } + | BINARY '(' NUM ')' { Lex->length=$3.str; + Lex->charset=&my_charset_bin; + $$=FIELD_TYPE_STRING; } + | BINARY { Lex->length= (char*) "1"; + Lex->charset=&my_charset_bin; + $$=FIELD_TYPE_STRING; } + | varchar '(' NUM ')' opt_binary { Lex->length=$3.str; + $$= MYSQL_TYPE_VARCHAR; } + | nvarchar '(' NUM ')' opt_bin_mod { Lex->length=$3.str; + $$= MYSQL_TYPE_VARCHAR; + Lex->charset=national_charset_info; } + | VARBINARY '(' NUM ')' { Lex->length=$3.str; + Lex->charset=&my_charset_bin; + $$= MYSQL_TYPE_VARCHAR; } + | YEAR_SYM opt_len field_options { $$=FIELD_TYPE_YEAR; } + | DATE_SYM { $$=FIELD_TYPE_DATE; } + | TIME_SYM { $$=FIELD_TYPE_TIME; } + | TIMESTAMP opt_len + { + if (YYTHD->variables.sql_mode & MODE_MAXDB) + $$=FIELD_TYPE_DATETIME; + else + { + /* + Unlike other types TIMESTAMP fields are NOT NULL by default. + */ + Lex->type|= NOT_NULL_FLAG; + $$=FIELD_TYPE_TIMESTAMP; + } + } + | DATETIME { $$=FIELD_TYPE_DATETIME; } + | TINYBLOB { Lex->charset=&my_charset_bin; + $$=FIELD_TYPE_TINY_BLOB; } + | BLOB_SYM opt_len { Lex->charset=&my_charset_bin; + $$=FIELD_TYPE_BLOB; } + | spatial_type + { +#ifdef HAVE_SPATIAL + Lex->charset=&my_charset_bin; + Lex->uint_geom_type= (uint)$1; + $$=FIELD_TYPE_GEOMETRY; +#else + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; +#endif + } + | MEDIUMBLOB { Lex->charset=&my_charset_bin; + $$=FIELD_TYPE_MEDIUM_BLOB; } + | LONGBLOB { Lex->charset=&my_charset_bin; + $$=FIELD_TYPE_LONG_BLOB; } + | LONG_SYM VARBINARY { Lex->charset=&my_charset_bin; + $$=FIELD_TYPE_MEDIUM_BLOB; } + | LONG_SYM varchar opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } + | TINYTEXT opt_binary { $$=FIELD_TYPE_TINY_BLOB; } + | TEXT_SYM opt_len opt_binary { $$=FIELD_TYPE_BLOB; } + | MEDIUMTEXT opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } + | LONGTEXT opt_binary { $$=FIELD_TYPE_LONG_BLOB; } + | DECIMAL_SYM float_options field_options + { $$=FIELD_TYPE_NEWDECIMAL;} + | NUMERIC_SYM float_options field_options + { $$=FIELD_TYPE_NEWDECIMAL;} + | FIXED_SYM float_options field_options + { $$=FIELD_TYPE_NEWDECIMAL;} + | ENUM {Lex->interval_list.empty();} '(' string_list ')' opt_binary + { $$=FIELD_TYPE_ENUM; } + | SET { Lex->interval_list.empty();} '(' string_list ')' opt_binary + { $$=FIELD_TYPE_SET; } + | LONG_SYM opt_binary { $$=FIELD_TYPE_MEDIUM_BLOB; } + | SERIAL_SYM + { + $$=FIELD_TYPE_LONGLONG; + Lex->type|= (AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNSIGNED_FLAG | + UNIQUE_FLAG); + } + ; + +spatial_type: + GEOMETRY_SYM { $$= Field::GEOM_GEOMETRY; } + | GEOMETRYCOLLECTION { $$= Field::GEOM_GEOMETRYCOLLECTION; } + | POINT_SYM { Lex->length= (char*)"21"; + $$= Field::GEOM_POINT; + } + | MULTIPOINT { $$= Field::GEOM_MULTIPOINT; } + | LINESTRING { $$= Field::GEOM_LINESTRING; } + | MULTILINESTRING { $$= Field::GEOM_MULTILINESTRING; } + | POLYGON { $$= Field::GEOM_POLYGON; } + | MULTIPOLYGON { $$= Field::GEOM_MULTIPOLYGON; } + ; + +char: + CHAR_SYM {} + ; + +nchar: + NCHAR_SYM {} + | NATIONAL_SYM CHAR_SYM {} + ; + +varchar: + char VARYING {} + | VARCHAR {} + ; + +nvarchar: + NATIONAL_SYM VARCHAR {} + | NVARCHAR_SYM {} + | NCHAR_SYM VARCHAR {} + | NATIONAL_SYM CHAR_SYM VARYING {} + | NCHAR_SYM VARYING {} + ; + +int_type: + INT_SYM { $$=FIELD_TYPE_LONG; } + | TINYINT { $$=FIELD_TYPE_TINY; } + | SMALLINT { $$=FIELD_TYPE_SHORT; } + | MEDIUMINT { $$=FIELD_TYPE_INT24; } + | BIGINT { $$=FIELD_TYPE_LONGLONG; }; + +real_type: + REAL { $$= YYTHD->variables.sql_mode & MODE_REAL_AS_FLOAT ? + FIELD_TYPE_FLOAT : FIELD_TYPE_DOUBLE; } + | DOUBLE_SYM { $$=FIELD_TYPE_DOUBLE; } + | DOUBLE_SYM PRECISION { $$=FIELD_TYPE_DOUBLE; }; + + +float_options: + /* empty */ { Lex->dec=Lex->length= (char*)0; } + | '(' NUM ')' { Lex->length=$2.str; Lex->dec= (char*)0; } + | precision {}; + +precision: + '(' NUM ',' NUM ')' + { + LEX *lex=Lex; + lex->length=$2.str; lex->dec=$4.str; + }; + +field_options: + /* empty */ {} + | field_opt_list {}; + +field_opt_list: + field_opt_list field_option {} + | field_option {}; + +field_option: + SIGNED_SYM {} + | UNSIGNED { Lex->type|= UNSIGNED_FLAG;} + | ZEROFILL { Lex->type|= UNSIGNED_FLAG | ZEROFILL_FLAG; }; + +opt_len: + /* empty */ { Lex->length=(char*) 0; } /* use default length */ + | '(' NUM ')' { Lex->length= $2.str; }; + +opt_precision: + /* empty */ {} + | precision {}; + +opt_attribute: + /* empty */ {} + | opt_attribute_list {}; + +opt_attribute_list: + opt_attribute_list attribute {} + | attribute; + +attribute: + NULL_SYM { Lex->type&= ~ NOT_NULL_FLAG; } + | not NULL_SYM { Lex->type|= NOT_NULL_FLAG; } + | DEFAULT now_or_signed_literal { Lex->default_value=$2; } + | ON UPDATE_SYM NOW_SYM optional_braces + { Lex->on_update_value= new Item_func_now_local(); } + | AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; } + | SERIAL_SYM DEFAULT VALUE_SYM + { + LEX *lex=Lex; + lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG; + lex->alter_info.flags|= ALTER_ADD_INDEX; + } + | opt_primary KEY_SYM + { + LEX *lex=Lex; + lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; + lex->alter_info.flags|= ALTER_ADD_INDEX; + } + | UNIQUE_SYM + { + LEX *lex=Lex; + lex->type|= UNIQUE_FLAG; + lex->alter_info.flags|= ALTER_ADD_INDEX; + } + | UNIQUE_SYM KEY_SYM + { + LEX *lex=Lex; + lex->type|= UNIQUE_KEY_FLAG; + lex->alter_info.flags|= ALTER_ADD_INDEX; + } + | COMMENT_SYM TEXT_STRING_sys { Lex->comment= $2; } + | COLLATE_SYM collation_name + { + if (Lex->charset && !my_charset_same(Lex->charset,$2)) + { + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $2->name,Lex->charset->csname); + YYABORT; + } + else + { + Lex->charset=$2; + } + } + ; + +now_or_signed_literal: + NOW_SYM optional_braces { $$= new Item_func_now_local(); } + | signed_literal { $$=$1; } + ; + +charset: + CHAR_SYM SET {} + | CHARSET {} + ; + +charset_name: + ident_or_text + { + if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0)))) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); + YYABORT; + } + } + | BINARY { $$= &my_charset_bin; } + ; + +charset_name_or_default: + charset_name { $$=$1; } + | DEFAULT { $$=NULL; } ; + + +old_or_new_charset_name: + ident_or_text + { + if (!($$=get_charset_by_csname($1.str,MY_CS_PRIMARY,MYF(0))) && + !($$=get_old_charset_by_name($1.str))) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), $1.str); + YYABORT; + } + } + | BINARY { $$= &my_charset_bin; } + ; + +old_or_new_charset_name_or_default: + old_or_new_charset_name { $$=$1; } + | DEFAULT { $$=NULL; } ; + +collation_name: + ident_or_text + { + if (!($$=get_charset_by_name($1.str,MYF(0)))) + { + my_error(ER_UNKNOWN_COLLATION, MYF(0), $1.str); + YYABORT; + } + }; + +opt_collate: + /* empty */ { $$=NULL; } + | COLLATE_SYM collation_name_or_default { $$=$2; } + ; + +collation_name_or_default: + collation_name { $$=$1; } + | DEFAULT { $$=NULL; } ; + +opt_default: + /* empty */ {} + | DEFAULT {}; + +opt_binary: + /* empty */ { Lex->charset=NULL; } + | ASCII_SYM opt_bin_mod { Lex->charset=&my_charset_latin1; } + | BYTE_SYM { Lex->charset=&my_charset_bin; } + | UNICODE_SYM opt_bin_mod + { + if (!(Lex->charset=get_charset_by_csname("ucs2", + MY_CS_PRIMARY,MYF(0)))) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2"); + YYABORT; + } + } + | charset charset_name opt_bin_mod { Lex->charset=$2; } + | BINARY opt_bin_charset { Lex->type|= BINCMP_FLAG; }; + +opt_bin_mod: + /* empty */ { } + | BINARY { Lex->type|= BINCMP_FLAG; }; + +opt_bin_charset: + /* empty */ { Lex->charset= NULL; } + | ASCII_SYM { Lex->charset=&my_charset_latin1; } + | UNICODE_SYM + { + if (!(Lex->charset=get_charset_by_csname("ucs2", + MY_CS_PRIMARY,MYF(0)))) + { + my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), "ucs2"); + YYABORT; + } + } + | charset charset_name { Lex->charset=$2; } ; + +opt_primary: + /* empty */ + | PRIMARY_SYM + ; + +references: + REFERENCES table_ident + { + LEX *lex=Lex; + lex->fk_delete_opt= lex->fk_update_opt= lex->fk_match_option= 0; + lex->ref_list.empty(); + } + opt_ref_list + { + $$=$2; + }; + +opt_ref_list: + /* empty */ opt_on_delete {} + | '(' ref_list ')' opt_on_delete {}; + +ref_list: + ref_list ',' ident { Lex->ref_list.push_back(new key_part_spec($3.str)); } + | ident { Lex->ref_list.push_back(new key_part_spec($1.str)); }; + + +opt_on_delete: + /* empty */ {} + | opt_on_delete_list {}; + +opt_on_delete_list: + opt_on_delete_list opt_on_delete_item {} + | opt_on_delete_item {}; + +opt_on_delete_item: + ON DELETE_SYM delete_option { Lex->fk_delete_opt= $3; } + | ON UPDATE_SYM delete_option { Lex->fk_update_opt= $3; } + | MATCH FULL { Lex->fk_match_option= foreign_key::FK_MATCH_FULL; } + | MATCH PARTIAL { Lex->fk_match_option= foreign_key::FK_MATCH_PARTIAL; } + | MATCH SIMPLE_SYM { Lex->fk_match_option= foreign_key::FK_MATCH_SIMPLE; }; + +delete_option: + RESTRICT { $$= (int) foreign_key::FK_OPTION_RESTRICT; } + | CASCADE { $$= (int) foreign_key::FK_OPTION_CASCADE; } + | SET NULL_SYM { $$= (int) foreign_key::FK_OPTION_SET_NULL; } + | NO_SYM ACTION { $$= (int) foreign_key::FK_OPTION_NO_ACTION; } + | SET DEFAULT { $$= (int) foreign_key::FK_OPTION_DEFAULT; }; + +key_type: + key_or_index { $$= Key::MULTIPLE; } + | FULLTEXT_SYM opt_key_or_index { $$= Key::FULLTEXT; } + | SPATIAL_SYM opt_key_or_index + { +#ifdef HAVE_SPATIAL + $$= Key::SPATIAL; +#else + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; +#endif + }; + +constraint_key_type: + PRIMARY_SYM KEY_SYM { $$= Key::PRIMARY; } + | UNIQUE_SYM opt_key_or_index { $$= Key::UNIQUE; }; + +key_or_index: + KEY_SYM {} + | INDEX_SYM {}; + +opt_key_or_index: + /* empty */ {} + | key_or_index + ; + +keys_or_index: + KEYS {} + | INDEX_SYM {} + | INDEXES {}; + +opt_unique_or_fulltext: + /* empty */ { $$= Key::MULTIPLE; } + | UNIQUE_SYM { $$= Key::UNIQUE; } + | FULLTEXT_SYM { $$= Key::FULLTEXT;} + | SPATIAL_SYM + { +#ifdef HAVE_SPATIAL + $$= Key::SPATIAL; +#else + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; +#endif + } + ; + +init_key_options: + { + Lex->key_create_info= default_key_create_info; + } + ; + +/* + For now, key_alg initializies lex->key_create_info. + In the future, when all key options are after key definition, + we can remove key_alg and move init_key_options to key_options +*/ + +key_alg: + /* empty */ init_key_options + | init_key_options key_using_alg + ; + +key_options: + /* empty */ {} + | key_opts + ; + +key_opts: + key_opt + | key_opts key_opt + ; + +key_using_alg: + USING btree_or_rtree { Lex->key_create_info.algorithm= $2; } + | TYPE_SYM btree_or_rtree { Lex->key_create_info.algorithm= $2; } + ; + +key_opt: + key_using_alg + | KEY_BLOCK_SIZE opt_equal ulong_num + { Lex->key_create_info.block_size= $3; } + | WITH PARSER_SYM IDENT_sys + { + if (plugin_is_ready(&$3, MYSQL_FTPARSER_PLUGIN)) + Lex->key_create_info.parser_name= $3; + else + { + my_error(ER_FUNCTION_NOT_DEFINED, MYF(0), $3.str); + YYABORT; + } + } + ; + + +btree_or_rtree: + BTREE_SYM { $$= HA_KEY_ALG_BTREE; } + | RTREE_SYM + { + $$= HA_KEY_ALG_RTREE; + } + | HASH_SYM { $$= HA_KEY_ALG_HASH; }; + +key_list: + key_list ',' key_part order_dir { Lex->col_list.push_back($3); } + | key_part order_dir { Lex->col_list.push_back($1); }; + +key_part: + ident { $$=new key_part_spec($1.str); } + | ident '(' NUM ')' + { + int key_part_len= atoi($3.str); + if (!key_part_len) + { + my_error(ER_KEY_PART_0, MYF(0), $1.str); + } + $$=new key_part_spec($1.str,(uint) key_part_len); + }; + +opt_ident: + /* empty */ { $$=(char*) 0; } /* Defaultlength */ + | field_ident { $$=$1.str; }; + +opt_component: + /* empty */ { $$= null_lex_str; } + | '.' ident { $$= $2; }; + +string_list: + text_string { Lex->interval_list.push_back($1); } + | string_list ',' text_string { Lex->interval_list.push_back($3); }; + +/* +** Alter table +*/ + +alter: + ALTER opt_ignore TABLE_SYM table_ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->name.str= 0; + lex->name.length= 0; + lex->sql_command= SQLCOM_ALTER_TABLE; + lex->duplicates= DUP_ERROR; + if (!lex->select_lex.add_table_to_list(thd, $4, NULL, + TL_OPTION_UPDATING)) + YYABORT; + lex->create_list.empty(); + lex->key_list.empty(); + lex->col_list.empty(); + lex->select_lex.init_order(); + lex->like_name= 0; + lex->select_lex.db= + ((TABLE_LIST*) lex->select_lex.table_list.first)->db; + bzero((char*) &lex->create_info,sizeof(lex->create_info)); + lex->create_info.db_type= 0; + lex->create_info.default_table_charset= NULL; + lex->create_info.row_type= ROW_TYPE_NOT_USED; + lex->alter_info.reset(); + lex->alter_info.flags= 0; + lex->no_write_to_binlog= 0; + } + alter_commands + {} + | ALTER DATABASE ident_or_empty + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + } + opt_create_database_options + { + LEX *lex=Lex; + THD *thd= Lex->thd; + lex->sql_command=SQLCOM_ALTER_DB; + lex->name= $3; + if (lex->name.str == NULL && + thd->copy_db_to(&lex->name.str, &lex->name.length)) + YYABORT; + } + | ALTER PROCEDURE sp_name + { + LEX *lex= Lex; + + if (lex->sphead) + { + my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE"); + YYABORT; + } + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_a_chistics + { + LEX *lex=Lex; + + lex->sql_command= SQLCOM_ALTER_PROCEDURE; + lex->spname= $3; + } + | ALTER FUNCTION_SYM sp_name + { + LEX *lex= Lex; + + if (lex->sphead) + { + my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); + YYABORT; + } + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_a_chistics + { + LEX *lex=Lex; + + lex->sql_command= SQLCOM_ALTER_FUNCTION; + lex->spname= $3; + } + | ALTER view_algorithm_opt definer view_suid + VIEW_SYM table_ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->sql_command= SQLCOM_CREATE_VIEW; + lex->create_view_mode= VIEW_ALTER; + /* first table in list is target VIEW name */ + lex->select_lex.add_table_to_list(thd, $6, NULL, TL_OPTION_UPDATING); + } + view_list_opt AS view_select view_check_option + {} + | ALTER EVENT_SYM sp_name + /* + BE CAREFUL when you add a new rule to update the block where + YYTHD->client_capabilities is set back to original value + */ + { + /* + It is safe to use Lex->spname because + ALTER EVENT xxx RENATE TO yyy DO ALTER EVENT RENAME TO + is not allowed. Lex->spname is used in the case of RENAME TO + If it had to be supported spname had to be added to + Event_parse_data. + */ + + if (!(Lex->event_parse_data= Event_parse_data::new_instance(YYTHD))) + YYABORT; + Lex->event_parse_data->identifier= $3; + + /* + We have to turn off CLIENT_MULTI_QUERIES while parsing a + stored procedure, otherwise yylex will chop it into pieces + at each ';'. + */ + $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; + + Lex->sql_command= SQLCOM_ALTER_EVENT; + } + ev_alter_on_schedule_completion + opt_ev_rename_to + opt_ev_status + opt_ev_comment + opt_ev_sql_stmt + { + /* + $1 - ALTER + $2 - EVENT_SYM + $3 - sp_name + $4 - the block above + */ + YYTHD->client_capabilities |= $<ulong_num>4; + + if (!($5 || $6 || $7 || $8 || $9)) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + /* + sql_command is set here because some rules in ev_sql_stmt + can overwrite it + */ + Lex->sql_command= SQLCOM_ALTER_EVENT; + } + | ALTER TABLESPACE alter_tablespace_info + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_cmd_type= ALTER_TABLESPACE; + } + | ALTER LOGFILE_SYM GROUP alter_logfile_group_info + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_cmd_type= ALTER_LOGFILE_GROUP; + } + | ALTER TABLESPACE change_tablespace_info + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_cmd_type= CHANGE_FILE_TABLESPACE; + } + | ALTER TABLESPACE change_tablespace_access + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_cmd_type= ALTER_ACCESS_MODE_TABLESPACE; + } + | ALTER SERVER_SYM ident_or_text OPTIONS_SYM '(' server_options_list ')' + { + LEX *lex= Lex; + Lex->sql_command= SQLCOM_ALTER_SERVER; + Lex->server_options.server_name= $3.str; + Lex->server_options.server_name_length= $3.length; + } + ; + +ev_alter_on_schedule_completion: /* empty */ { $$= 0;} + | ON SCHEDULE_SYM ev_schedule_time { $$= 1; } + | ev_on_completion { $$= 1; } + | ON SCHEDULE_SYM ev_schedule_time ev_on_completion { $$= 1; } + ; + +opt_ev_rename_to: /* empty */ { $$= 0;} + | RENAME TO_SYM sp_name + { + /* + Use lex's spname to hold the new name. + The original name is in the Event_parse_data object + */ + Lex->spname= $3; + $$= 1; + } + ; + +opt_ev_sql_stmt: /* empty*/ { $$= 0;} + | DO_SYM ev_sql_stmt { $$= 1; } + ; + + +ident_or_empty: + /* empty */ { $$.str= 0; $$.length= 0; } + | ident { $$= $1; }; + +alter_commands: + | DISCARD TABLESPACE { Lex->alter_info.tablespace_op= DISCARD_TABLESPACE; } + | IMPORT TABLESPACE { Lex->alter_info.tablespace_op= IMPORT_TABLESPACE; } + | alter_list + opt_partitioning + | alter_list + remove_partitioning + | remove_partitioning + | partitioning +/* + This part was added for release 5.1 by Mikael Ronström. + From here we insert a number of commands to manage the partitions of a + partitioned table such as adding partitions, dropping partitions, + reorganising partitions in various manners. In future releases the list + will be longer and also include moving partitions to a + new table and so forth. +*/ + | add_partition_rule + | DROP PARTITION_SYM alt_part_name_list + { + Lex->alter_info.flags|= ALTER_DROP_PARTITION; + } + | REBUILD_SYM PARTITION_SYM opt_no_write_to_binlog + all_or_alt_part_name_list + { + LEX *lex= Lex; + lex->alter_info.flags|= ALTER_REBUILD_PARTITION; + lex->no_write_to_binlog= $3; + } + | OPTIMIZE PARTITION_SYM opt_no_write_to_binlog + all_or_alt_part_name_list + { + LEX *lex= Lex; + lex->alter_info.flags|= ALTER_OPTIMIZE_PARTITION; + lex->no_write_to_binlog= $3; + lex->check_opt.init(); + } + opt_no_write_to_binlog opt_mi_check_type + | ANALYZE_SYM PARTITION_SYM opt_no_write_to_binlog + all_or_alt_part_name_list + { + LEX *lex= Lex; + lex->alter_info.flags|= ALTER_ANALYZE_PARTITION; + lex->no_write_to_binlog= $3; + lex->check_opt.init(); + } + opt_mi_check_type + | CHECK_SYM PARTITION_SYM all_or_alt_part_name_list + { + LEX *lex= Lex; + lex->alter_info.flags|= ALTER_CHECK_PARTITION; + lex->check_opt.init(); + } + opt_mi_check_type + | REPAIR PARTITION_SYM opt_no_write_to_binlog + all_or_alt_part_name_list + { + LEX *lex= Lex; + lex->alter_info.flags|= ALTER_REPAIR_PARTITION; + lex->no_write_to_binlog= $3; + lex->check_opt.init(); + } + opt_mi_repair_type + | COALESCE PARTITION_SYM opt_no_write_to_binlog real_ulong_num + { + LEX *lex= Lex; + lex->alter_info.flags|= ALTER_COALESCE_PARTITION; + lex->no_write_to_binlog= $3; + lex->alter_info.no_parts= $4; + } + | reorg_partition_rule + ; + +remove_partitioning: + REMOVE_SYM PARTITIONING_SYM + { + Lex->alter_info.flags|= ALTER_REMOVE_PARTITIONING; + } + ; + +all_or_alt_part_name_list: + ALL + { + Lex->alter_info.flags|= ALTER_ALL_PARTITION; + } + | alt_part_name_list + ; + +add_partition_rule: + ADD PARTITION_SYM opt_no_write_to_binlog + { + LEX *lex= Lex; + lex->part_info= new partition_info(); + if (!lex->part_info) + { + mem_alloc_error(sizeof(partition_info)); + YYABORT; + } + lex->alter_info.flags|= ALTER_ADD_PARTITION; + lex->no_write_to_binlog= $3; + } + add_part_extra + {} + ; + +add_part_extra: + | '(' part_def_list ')' + { + LEX *lex= Lex; + lex->part_info->no_parts= lex->part_info->partitions.elements; + } + | PARTITIONS_SYM real_ulong_num + { + LEX *lex= Lex; + lex->part_info->no_parts= $2; + } + ; + +reorg_partition_rule: + REORGANIZE_SYM PARTITION_SYM opt_no_write_to_binlog + { + LEX *lex= Lex; + lex->part_info= new partition_info(); + if (!lex->part_info) + { + mem_alloc_error(sizeof(partition_info)); + YYABORT; + } + lex->no_write_to_binlog= $3; + } + reorg_parts_rule + ; + +reorg_parts_rule: + /* empty */ + { + Lex->alter_info.flags|= ALTER_TABLE_REORG; + } + | + alt_part_name_list + { + Lex->alter_info.flags|= ALTER_REORGANIZE_PARTITION; + } + INTO '(' part_def_list ')' + { + LEX *lex= Lex; + lex->part_info->no_parts= lex->part_info->partitions.elements; + } + ; + +alt_part_name_list: + alt_part_name_item {} + | alt_part_name_list ',' alt_part_name_item {} + ; + +alt_part_name_item: + ident + { + if (Lex->alter_info.partition_names.push_back($1.str)) + { + mem_alloc_error(1); + YYABORT; + } + } + ; + +/* + End of management of partition commands +*/ + +alter_list: + alter_list_item + | alter_list ',' alter_list_item + ; + +add_column: + ADD opt_column + { + LEX *lex=Lex; + lex->change=0; + lex->alter_info.flags|= ALTER_ADD_COLUMN; + }; + +alter_list_item: + add_column column_def opt_place { } + | ADD key_def + { + Lex->alter_info.flags|= ALTER_ADD_INDEX; + } + | add_column '(' field_list ')' + { + Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX; + } + | CHANGE opt_column field_ident + { + LEX *lex=Lex; + lex->change= $3.str; + lex->alter_info.flags|= ALTER_CHANGE_COLUMN; + } + field_spec opt_place + | MODIFY_SYM opt_column field_ident + { + LEX *lex=Lex; + lex->length=lex->dec=0; lex->type=0; + lex->default_value= lex->on_update_value= 0; + lex->comment=null_lex_str; + lex->charset= NULL; + lex->alter_info.flags|= ALTER_CHANGE_COLUMN; + } + type opt_attribute + { + LEX *lex=Lex; + if (add_field_to_list(lex->thd,$3.str, + (enum enum_field_types) $5, + lex->length,lex->dec,lex->type, + lex->default_value, lex->on_update_value, + &lex->comment, + $3.str, &lex->interval_list, lex->charset, + lex->uint_geom_type)) + YYABORT; + } + opt_place + | DROP opt_column field_ident opt_restrict + { + LEX *lex=Lex; + lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::COLUMN, + $3.str)); + lex->alter_info.flags|= ALTER_DROP_COLUMN; + } + | DROP FOREIGN KEY_SYM opt_ident + { + Lex->alter_info.flags|= ALTER_DROP_INDEX | ALTER_FOREIGN_KEY; + } + | DROP PRIMARY_SYM KEY_SYM + { + LEX *lex=Lex; + lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, + primary_key_name)); + lex->alter_info.flags|= ALTER_DROP_INDEX; + } + | DROP key_or_index field_ident + { + LEX *lex=Lex; + lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, + $3.str)); + lex->alter_info.flags|= ALTER_DROP_INDEX; + } + | DISABLE_SYM KEYS + { + LEX *lex=Lex; + lex->alter_info.keys_onoff= DISABLE; + lex->alter_info.flags|= ALTER_KEYS_ONOFF; + } + | ENABLE_SYM KEYS + { + LEX *lex=Lex; + lex->alter_info.keys_onoff= ENABLE; + lex->alter_info.flags|= ALTER_KEYS_ONOFF; + } + | ALTER opt_column field_ident SET DEFAULT signed_literal + { + LEX *lex=Lex; + lex->alter_info.alter_list.push_back(new Alter_column($3.str,$6)); + lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT; + } + | ALTER opt_column field_ident DROP DEFAULT + { + LEX *lex=Lex; + lex->alter_info.alter_list.push_back(new Alter_column($3.str, + (Item*) 0)); + lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT; + } + | RENAME opt_to table_ident + { + LEX *lex=Lex; + THD *thd= lex->thd; + uint dummy; + lex->select_lex.db=$3->db.str; + if (lex->select_lex.db == NULL && + thd->copy_db_to(&lex->select_lex.db, &dummy)) + { + YYABORT; + } + if (check_table_name($3->table.str,$3->table.length) || + $3->db.str && check_db_name(&$3->db)) + { + my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str); + YYABORT; + } + lex->name= $3->table; + lex->alter_info.flags|= ALTER_RENAME; + } + | CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate + { + if (!$4) + { + THD *thd= YYTHD; + $4= thd->variables.collation_database; + } + $5= $5 ? $5 : $4; + if (!my_charset_same($4,$5)) + { + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $5->name, $4->csname); + YYABORT; + } + LEX *lex= Lex; + lex->create_info.table_charset= + lex->create_info.default_table_charset= $5; + lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET | + HA_CREATE_USED_DEFAULT_CHARSET); + lex->alter_info.flags|= ALTER_CONVERT; + } + | create_table_options_space_separated + { + LEX *lex=Lex; + lex->alter_info.flags|= ALTER_OPTIONS; + } + | FORCE_SYM + { + Lex->alter_info.flags|= ALTER_FORCE; + } + | order_clause + { + LEX *lex=Lex; + lex->alter_info.flags|= ALTER_ORDER; + }; + +opt_column: + /* empty */ {} + | COLUMN_SYM {}; + +opt_ignore: + /* empty */ { Lex->ignore= 0;} + | IGNORE_SYM { Lex->ignore= 1;} + ; + +opt_restrict: + /* empty */ { Lex->drop_mode= DROP_DEFAULT; } + | RESTRICT { Lex->drop_mode= DROP_RESTRICT; } + | CASCADE { Lex->drop_mode= DROP_CASCADE; } + ; + +opt_place: + /* empty */ {} + | AFTER_SYM ident { store_position_for_column($2.str); } + | FIRST_SYM { store_position_for_column(first_keyword); }; + +opt_to: + /* empty */ {} + | TO_SYM {} + | EQ {} + | AS {}; + +/* + SLAVE START and SLAVE STOP are deprecated. We keep them for compatibility. +*/ + +slave: + START_SYM SLAVE slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_START; + lex->type = 0; + /* We'll use mi structure for UNTIL options */ + bzero((char*) &lex->mi, sizeof(lex->mi)); + /* If you change this code don't forget to update SLAVE START too */ + } + slave_until + {} + | STOP_SYM SLAVE slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_STOP; + lex->type = 0; + /* If you change this code don't forget to update SLAVE STOP too */ + } + | SLAVE START_SYM slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_START; + lex->type = 0; + /* We'll use mi structure for UNTIL options */ + bzero((char*) &lex->mi, sizeof(lex->mi)); + } + slave_until + {} + | SLAVE STOP_SYM slave_thread_opts + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_SLAVE_STOP; + lex->type = 0; + } + ; + + +start: + START_SYM TRANSACTION_SYM start_transaction_opts + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_BEGIN; + lex->start_transaction_opt= $3; + } + ; + +start_transaction_opts: + /*empty*/ { $$ = 0; } + | WITH CONSISTENT_SYM SNAPSHOT_SYM + { + $$= MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT; + } + ; + +slave_thread_opts: + { Lex->slave_thd_opt= 0; } + slave_thread_opt_list + {} + ; + +slave_thread_opt_list: + slave_thread_opt + | slave_thread_opt_list ',' slave_thread_opt + ; + +slave_thread_opt: + /*empty*/ {} + | SQL_THREAD { Lex->slave_thd_opt|=SLAVE_SQL; } + | RELAY_THREAD { Lex->slave_thd_opt|=SLAVE_IO; } + ; + +slave_until: + /*empty*/ {} + | UNTIL_SYM slave_until_opts + { + LEX *lex=Lex; + if ((lex->mi.log_file_name || lex->mi.pos) && + (lex->mi.relay_log_name || lex->mi.relay_log_pos) || + !((lex->mi.log_file_name && lex->mi.pos) || + (lex->mi.relay_log_name && lex->mi.relay_log_pos))) + { + my_message(ER_BAD_SLAVE_UNTIL_COND, + ER(ER_BAD_SLAVE_UNTIL_COND), MYF(0)); + YYABORT; + } + + } + ; + +slave_until_opts: + master_file_def + | slave_until_opts ',' master_file_def ; + + +restore: + RESTORE_SYM table_or_tables + { + Lex->sql_command = SQLCOM_RESTORE_TABLE; + WARN_DEPRECATED(yythd, "5.2", "RESTORE TABLE", + "MySQL Administrator (mysqldump, mysql)"); + } + table_list FROM TEXT_STRING_sys + { + Lex->backup_dir = $6.str; + }; + +backup: + BACKUP_SYM table_or_tables + { + Lex->sql_command = SQLCOM_BACKUP_TABLE; + WARN_DEPRECATED(yythd, "5.2", "BACKUP TABLE", + "MySQL Administrator (mysqldump, mysql)"); + } + table_list TO_SYM TEXT_STRING_sys + { + Lex->backup_dir = $6.str; + }; + +checksum: + CHECKSUM_SYM table_or_tables + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_CHECKSUM; + } + table_list opt_checksum_type + {} + ; + +opt_checksum_type: + /* nothing */ { Lex->check_opt.flags= 0; } + | QUICK { Lex->check_opt.flags= T_QUICK; } + | EXTENDED_SYM { Lex->check_opt.flags= T_EXTEND; } + ; + +repair: + REPAIR opt_no_write_to_binlog table_or_tables + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_REPAIR; + lex->no_write_to_binlog= $2; + lex->check_opt.init(); + } + table_list opt_mi_repair_type + {} + ; + +opt_mi_repair_type: + /* empty */ { Lex->check_opt.flags = T_MEDIUM; } + | mi_repair_types {}; + +mi_repair_types: + mi_repair_type {} + | mi_repair_type mi_repair_types {}; + +mi_repair_type: + QUICK { Lex->check_opt.flags|= T_QUICK; } + | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } + | USE_FRM { Lex->check_opt.sql_flags|= TT_USEFRM; }; + +analyze: + ANALYZE_SYM opt_no_write_to_binlog table_or_tables + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_ANALYZE; + lex->no_write_to_binlog= $2; + lex->check_opt.init(); + } + table_list opt_mi_check_type + {} + ; + +binlog_base64_event: + BINLOG_SYM TEXT_STRING_sys + { + Lex->sql_command = SQLCOM_BINLOG_BASE64_EVENT; + Lex->comment= $2; + } + ; + +check: + CHECK_SYM table_or_tables + { + LEX *lex=Lex; + + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "CHECK"); + YYABORT; + } + lex->sql_command = SQLCOM_CHECK; + lex->check_opt.init(); + } + table_list opt_mi_check_type + {} + ; + +opt_mi_check_type: + /* empty */ { Lex->check_opt.flags = T_MEDIUM; } + | mi_check_types {}; + +mi_check_types: + mi_check_type {} + | mi_check_type mi_check_types {}; + +mi_check_type: + QUICK { Lex->check_opt.flags|= T_QUICK; } + | FAST_SYM { Lex->check_opt.flags|= T_FAST; } + | MEDIUM_SYM { Lex->check_opt.flags|= T_MEDIUM; } + | EXTENDED_SYM { Lex->check_opt.flags|= T_EXTEND; } + | CHANGED { Lex->check_opt.flags|= T_CHECK_ONLY_CHANGED; } + | FOR_SYM UPGRADE_SYM { Lex->check_opt.sql_flags|= TT_FOR_UPGRADE; }; + +optimize: + OPTIMIZE opt_no_write_to_binlog table_or_tables + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_OPTIMIZE; + lex->no_write_to_binlog= $2; + lex->check_opt.init(); + } + table_list opt_mi_check_type + {} + ; + +opt_no_write_to_binlog: + /* empty */ { $$= 0; } + | NO_WRITE_TO_BINLOG { $$= 1; } + | LOCAL_SYM { $$= 1; } + ; + +rename: + RENAME table_or_tables + { + Lex->sql_command= SQLCOM_RENAME_TABLE; + } + table_to_table_list + {} + | RENAME DATABASE + { + Lex->db_list.empty(); + Lex->sql_command= SQLCOM_RENAME_DB; + } + db_to_db + {} + | RENAME USER clear_privileges rename_list + { + Lex->sql_command = SQLCOM_RENAME_USER; + } + ; + +rename_list: + user TO_SYM user + { + if (Lex->users_list.push_back($1) || Lex->users_list.push_back($3)) + YYABORT; + } + | rename_list ',' user TO_SYM user + { + if (Lex->users_list.push_back($3) || Lex->users_list.push_back($5)) + YYABORT; + } + ; + +table_to_table_list: + table_to_table + | table_to_table_list ',' table_to_table; + +table_to_table: + table_ident TO_SYM table_ident + { + LEX *lex=Lex; + SELECT_LEX *sl= lex->current_select; + if (!sl->add_table_to_list(lex->thd, $1,NULL,TL_OPTION_UPDATING, + TL_IGNORE) || + !sl->add_table_to_list(lex->thd, $3,NULL,TL_OPTION_UPDATING, + TL_IGNORE)) + YYABORT; + }; + +db_to_db: + ident TO_SYM ident + { + LEX *lex=Lex; + if (Lex->db_list.push_back((LEX_STRING*) + sql_memdup(&$1, sizeof(LEX_STRING))) || + Lex->db_list.push_back((LEX_STRING*) + sql_memdup(&$3, sizeof(LEX_STRING)))) + YYABORT; + }; + +keycache: + CACHE_SYM INDEX_SYM keycache_list IN_SYM key_cache_name + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_ASSIGN_TO_KEYCACHE; + lex->ident= $5; + } + ; + +keycache_list: + assign_to_keycache + | keycache_list ',' assign_to_keycache; + +assign_to_keycache: + table_ident cache_keys_spec + { + LEX *lex=Lex; + SELECT_LEX *sel= &lex->select_lex; + if (!sel->add_table_to_list(lex->thd, $1, NULL, 0, + TL_READ, + sel->get_use_index(), + (List<String> *)0)) + YYABORT; + } + ; + +key_cache_name: + ident { $$= $1; } + | DEFAULT { $$ = default_key_cache_base; } + ; + +preload: + LOAD INDEX_SYM INTO CACHE_SYM + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_PRELOAD_KEYS; + } + preload_list + {} + ; + +preload_list: + preload_keys + | preload_list ',' preload_keys; + +preload_keys: + table_ident cache_keys_spec opt_ignore_leaves + { + LEX *lex=Lex; + SELECT_LEX *sel= &lex->select_lex; + if (!sel->add_table_to_list(lex->thd, $1, NULL, $3, + TL_READ, + sel->get_use_index(), + (List<String> *)0)) + YYABORT; + } + ; + +cache_keys_spec: + { Select->interval_list.empty(); } + cache_key_list_or_empty + { + LEX *lex=Lex; + SELECT_LEX *sel= &lex->select_lex; + sel->use_index= sel->interval_list; + } + ; + +cache_key_list_or_empty: + /* empty */ { Lex->select_lex.use_index_ptr= 0; } + | opt_key_or_index '(' key_usage_list2 ')' + { + SELECT_LEX *sel= &Lex->select_lex; + sel->use_index_ptr= &sel->use_index; + } + ; + +opt_ignore_leaves: + /* empty */ + { $$= 0; } + | IGNORE_SYM LEAVES { $$= TL_OPTION_IGNORE_LEAVES; } + ; + +/* + Select : retrieve data from table +*/ + + +select: + select_init + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + } + ; + +/* Need select_init2 for subselects. */ +select_init: + SELECT_SYM select_init2 + | + '(' select_paren ')' union_opt; + +select_paren: + SELECT_SYM select_part2 + { + LEX *lex= Lex; + SELECT_LEX * sel= lex->current_select; + if (sel->set_braces(1)) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + if (sel->linkage == UNION_TYPE && + !sel->master_unit()->first_select()->braces && + sel->master_unit()->first_select()->linkage == + UNION_TYPE) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + /* select in braces, can't contain global parameters */ + if (sel->master_unit()->fake_select_lex) + sel->master_unit()->global_parameters= + sel->master_unit()->fake_select_lex; + } + | '(' select_paren ')'; + +select_init2: + select_part2 + { + LEX *lex= Lex; + SELECT_LEX * sel= lex->current_select; + if (lex->current_select->set_braces(0)) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + if (sel->linkage == UNION_TYPE && + sel->master_unit()->first_select()->braces) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + } + union_clause + ; + +select_part2: + { + LEX *lex= Lex; + SELECT_LEX *sel= lex->current_select; + if (sel->linkage != UNION_TYPE) + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + } + select_options select_item_list + { + Select->parsing_place= NO_MATTER; + } + select_into select_lock_type; + +select_into: + opt_order_clause opt_limit_clause {} + | into + | select_from + | into select_from + | select_from into; + +select_from: + FROM join_table_list where_clause group_clause having_clause + opt_order_clause opt_limit_clause procedure_clause + | FROM DUAL_SYM where_clause opt_limit_clause + /* oracle compatibility: oracle always requires FROM clause, + and DUAL is system table without fields. + Is "SELECT 1 FROM DUAL" any better than "SELECT 1" ? + Hmmm :) */ + ; + +select_options: + /* empty*/ + | select_option_list + { + if (Select->options & SELECT_DISTINCT && Select->options & SELECT_ALL) + { + my_error(ER_WRONG_USAGE, MYF(0), "ALL", "DISTINCT"); + YYABORT; + } + } + ; + +select_option_list: + select_option_list select_option + | select_option; + +select_option: + STRAIGHT_JOIN { Select->options|= SELECT_STRAIGHT_JOIN; } + | HIGH_PRIORITY + { + if (check_simple_select()) + YYABORT; + Lex->lock_option= TL_READ_HIGH_PRIORITY; + } + | DISTINCT { Select->options|= SELECT_DISTINCT; } + | SQL_SMALL_RESULT { Select->options|= SELECT_SMALL_RESULT; } + | SQL_BIG_RESULT { Select->options|= SELECT_BIG_RESULT; } + | SQL_BUFFER_RESULT + { + if (check_simple_select()) + YYABORT; + Select->options|= OPTION_BUFFER_RESULT; + } + | SQL_CALC_FOUND_ROWS + { + if (check_simple_select()) + YYABORT; + Select->options|= OPTION_FOUND_ROWS; + } + | SQL_NO_CACHE_SYM + { + Lex->safe_to_cache_query=0; + Lex->select_lex.options&= ~OPTION_TO_QUERY_CACHE; + Lex->select_lex.sql_cache= SELECT_LEX::SQL_NO_CACHE; + } + | SQL_CACHE_SYM + { + /* Honor this flag only if SQL_NO_CACHE wasn't specified. */ + if (Lex->select_lex.sql_cache != SELECT_LEX::SQL_NO_CACHE) + { + Lex->safe_to_cache_query=1; + Lex->select_lex.options|= OPTION_TO_QUERY_CACHE; + Lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE; + } + } + | ALL { Select->options|= SELECT_ALL; } + ; + +select_lock_type: + /* empty */ + | FOR_SYM UPDATE_SYM + { + LEX *lex=Lex; + lex->current_select->set_lock_for_tables(TL_WRITE); + lex->safe_to_cache_query=0; + } + | LOCK_SYM IN_SYM SHARE_SYM MODE_SYM + { + LEX *lex=Lex; + lex->current_select-> + set_lock_for_tables(TL_READ_WITH_SHARED_LOCKS); + lex->safe_to_cache_query=0; + } + ; + +select_item_list: + select_item_list ',' select_item + | select_item + | '*' + { + THD *thd= YYTHD; + if (add_item_to_list(thd, + new Item_field(&thd->lex->current_select-> + context, + NULL, NULL, "*"))) + YYABORT; + (thd->lex->current_select->with_wild)++; + }; + + +select_item: + remember_name select_item2 remember_end select_alias + { + if (add_item_to_list(YYTHD, $2)) + YYABORT; + if ($4.str) + { + $2->is_autogenerated_name= FALSE; + $2->set_name($4.str, $4.length, system_charset_info); + } + else if (!$2->name) { + char *str = $1; + if (str[-1] == '`') + str--; + $2->set_name(str,(uint) ($3 - str), YYTHD->charset()); + } + }; + +remember_name: + { $$=(char*) Lex->tok_start; }; + +remember_end: + { $$=(char*) Lex->tok_end; }; + +select_item2: + table_wild { $$=$1; } /* table.* */ + | expr { $$=$1; }; + +select_alias: + /* empty */ { $$=null_lex_str;} + | AS ident { $$=$2; } + | AS TEXT_STRING_sys { $$=$2; } + | ident { $$=$1; } + | TEXT_STRING_sys { $$=$1; } + ; + +optional_braces: + /* empty */ {} + | '(' ')' {}; + +/* all possible expressions */ +expr: + bool_term { Select->expr_list.push_front(new List<Item>); } + bool_or_expr + { + List<Item> *list= Select->expr_list.pop(); + if (list->elements) + { + list->push_front($1); + $$= new Item_cond_or(*list); + /* optimize construction of logical OR to reduce + amount of objects for complex expressions */ + } + else + $$= $1; + delete list; + } + ; + +bool_or_expr: + /* empty */ + | bool_or_expr or bool_term + { Select->expr_list.head()->push_back($3); } + ; + +bool_term: + bool_term XOR bool_term { $$= new Item_cond_xor($1,$3); } + | bool_factor { Select->expr_list.push_front(new List<Item>); } + bool_and_expr + { + List<Item> *list= Select->expr_list.pop(); + if (list->elements) + { + list->push_front($1); + $$= new Item_cond_and(*list); + /* optimize construction of logical AND to reduce + amount of objects for complex expressions */ + } + else + $$= $1; + delete list; + } + ; + +bool_and_expr: + /* empty */ + | bool_and_expr and bool_factor + { Select->expr_list.head()->push_back($3); } + ; + +bool_factor: + NOT_SYM bool_factor { $$= negate_expression(YYTHD, $2); } + | bool_test ; + +bool_test: + bool_pri IS TRUE_SYM { $$= is_truth_value(YYTHD, $1,1,0); } + | bool_pri IS not TRUE_SYM { $$= is_truth_value(YYTHD, $1,0,0); } + | bool_pri IS FALSE_SYM { $$= is_truth_value(YYTHD, $1,0,1); } + | bool_pri IS not FALSE_SYM { $$= is_truth_value(YYTHD, $1,1,1); } + | bool_pri IS UNKNOWN_SYM { $$= new Item_func_isnull($1); } + | bool_pri IS not UNKNOWN_SYM { $$= new Item_func_isnotnull($1); } + | bool_pri ; + +bool_pri: + bool_pri IS NULL_SYM { $$= new Item_func_isnull($1); } + | bool_pri IS not NULL_SYM { $$= new Item_func_isnotnull($1); } + | bool_pri EQUAL_SYM predicate { $$= new Item_func_equal($1,$3); } + | bool_pri comp_op predicate %prec EQ + { $$= (*$2)(0)->create($1,$3); } + | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ + { $$= all_any_subquery_creator($1, $2, $3, $5); } + | predicate ; + +predicate: + bit_expr IN_SYM '(' subselect ')' + { $$= new Item_in_subselect($1, $4); } + | bit_expr not IN_SYM '(' subselect ')' + { $$= negate_expression(YYTHD, new Item_in_subselect($1, $5)); } + | bit_expr IN_SYM '(' expr ')' + { + $$= new Item_func_eq($1, $4); + } + | bit_expr IN_SYM '(' expr ',' expr_list ')' + { + $6->push_front($4); + $6->push_front($1); + $$= new Item_func_in(*$6); + } + | bit_expr not IN_SYM '(' expr ')' + { + $$= new Item_func_ne($1, $5); + } + | bit_expr not IN_SYM '(' expr ',' expr_list ')' + { + $7->push_front($5); + $7->push_front($1); + Item_func_in *item = new Item_func_in(*$7); + item->negate(); + $$= item; + } + | bit_expr BETWEEN_SYM bit_expr AND_SYM predicate + { $$= new Item_func_between($1,$3,$5); } + | bit_expr not BETWEEN_SYM bit_expr AND_SYM predicate + { + Item_func_between *item= new Item_func_between($1,$4,$6); + item->negate(); + $$= item; + } + | bit_expr SOUNDS_SYM LIKE bit_expr + { $$= new Item_func_eq(new Item_func_soundex($1), + new Item_func_soundex($4)); } + | bit_expr LIKE simple_expr opt_escape + { $$= new Item_func_like($1,$3,$4,Lex->escape_used); } + | bit_expr not LIKE simple_expr opt_escape + { $$= new Item_func_not(new Item_func_like($1,$4,$5, Lex->escape_used)); } + | bit_expr REGEXP bit_expr { $$= new Item_func_regex($1,$3); } + | bit_expr not REGEXP bit_expr + { $$= negate_expression(YYTHD, new Item_func_regex($1,$4)); } + | bit_expr ; + +bit_expr: + bit_expr '|' bit_term { $$= new Item_func_bit_or($1,$3); } + | bit_term ; + +bit_term: + bit_term '&' bit_factor { $$= new Item_func_bit_and($1,$3); } + | bit_factor ; + +bit_factor: + bit_factor SHIFT_LEFT value_expr + { $$= new Item_func_shift_left($1,$3); } + | bit_factor SHIFT_RIGHT value_expr + { $$= new Item_func_shift_right($1,$3); } + | value_expr ; + +value_expr: + value_expr '+' term { $$= new Item_func_plus($1,$3); } + | value_expr '-' term { $$= new Item_func_minus($1,$3); } + | value_expr '+' interval_expr interval + { $$= new Item_date_add_interval($1,$3,$4,0); } + | value_expr '-' interval_expr interval + { $$= new Item_date_add_interval($1,$3,$4,1); } + | term ; + +term: + term '*' factor { $$= new Item_func_mul($1,$3); } + | term '/' factor { $$= new Item_func_div($1,$3); } + | term '%' factor { $$= new Item_func_mod($1,$3); } + | term DIV_SYM factor { $$= new Item_func_int_div($1,$3); } + | term MOD_SYM factor { $$= new Item_func_mod($1,$3); } + | factor ; + +factor: + factor '^' simple_expr { $$= new Item_func_bit_xor($1,$3); } + | simple_expr ; + +or: OR_SYM | OR2_SYM; +and: AND_SYM | AND_AND_SYM; +not: NOT_SYM | NOT2_SYM; +not2: '!' | NOT2_SYM; + +comp_op: EQ { $$ = &comp_eq_creator; } + | GE { $$ = &comp_ge_creator; } + | GT_SYM { $$ = &comp_gt_creator; } + | LE { $$ = &comp_le_creator; } + | LT { $$ = &comp_lt_creator; } + | NE { $$ = &comp_ne_creator; } + ; + +all_or_any: ALL { $$ = 1; } + | ANY_SYM { $$ = 0; } + ; + +interval_expr: + INTERVAL_SYM expr { $$=$2; } + ; + +simple_expr: + simple_ident + | function_call_keyword + | function_call_nonkeyword + | function_call_generic + | function_call_conflict + | simple_expr COLLATE_SYM ident_or_text %prec NEG + { + THD *thd= YYTHD; + Item *i1= new (thd->mem_root) Item_string($3.str, + $3.length, + thd->charset()); + $$= new (thd->mem_root) Item_func_set_collation($1, i1); + } + | literal + | param_marker + | variable + | sum_expr + | simple_expr OR_OR_SYM simple_expr + { $$= new (YYTHD->mem_root) Item_func_concat($1, $3); } + | '+' simple_expr %prec NEG { $$= $2; } + | '-' simple_expr %prec NEG + { $$= new (YYTHD->mem_root) Item_func_neg($2); } + | '~' simple_expr %prec NEG + { $$= new (YYTHD->mem_root) Item_func_bit_neg($2); } + | not2 simple_expr %prec NEG + { $$= negate_expression(YYTHD, $2); } + | '(' subselect ')' + { + $$= new (YYTHD->mem_root) Item_singlerow_subselect($2); + } + | '(' expr ')' { $$= $2; } + | '(' expr ',' expr_list ')' + { + $4->push_front($2); + $$= new (YYTHD->mem_root) Item_row(*$4); + } + | ROW_SYM '(' expr ',' expr_list ')' + { + $5->push_front($3); + $$= new (YYTHD->mem_root) Item_row(*$5); + } + | EXISTS '(' subselect ')' + { + $$= new (YYTHD->mem_root) Item_exists_subselect($3); + } + | '{' ident expr '}' { $$= $3; } + | MATCH ident_list_arg AGAINST '(' bit_expr fulltext_options ')' + { + $2->push_front($5); + Item_func_match *i1= new (YYTHD->mem_root) Item_func_match(*$2, $6); + Select->add_ftfunc_to_list(i1); + $$= i1; + } + | BINARY simple_expr %prec NEG + { + $$= create_func_cast(YYTHD, $2, ITEM_CAST_CHAR, -1, 0, + &my_charset_bin); + } + | CAST_SYM '(' expr AS cast_type ')' + { + LEX *lex= Lex; + $$= create_func_cast(YYTHD, $3, $5, + lex->length ? atoi(lex->length) : -1, + lex->dec ? atoi(lex->dec) : 0, + lex->charset); + if (!$$) + YYABORT; + } + | CASE_SYM opt_expr WHEN_SYM when_list opt_else END + { $$= new (YYTHD->mem_root) Item_func_case(* $4, $2, $5 ); } + | CONVERT_SYM '(' expr ',' cast_type ')' + { + $$= create_func_cast(YYTHD, $3, $5, + Lex->length ? atoi(Lex->length) : -1, + Lex->dec ? atoi(Lex->dec) : 0, + Lex->charset); + if (!$$) + YYABORT; + } + | CONVERT_SYM '(' expr USING charset_name ')' + { $$= new (YYTHD->mem_root) Item_func_conv_charset($3,$5); } + | DEFAULT '(' simple_ident ')' + { + if ($3->is_splocal()) + { + Item_splocal *il= static_cast<Item_splocal *>($3); + + my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str); + YYABORT; + } + $$= new (YYTHD->mem_root) Item_default_value(Lex->current_context(), + $3); + } + | VALUES '(' simple_ident_nospvar ')' + { $$= new (YYTHD->mem_root) Item_insert_value(Lex->current_context(), + $3); } + | interval_expr interval '+' expr + /* we cannot put interval before - */ + { $$= new (YYTHD->mem_root) Item_date_add_interval($4,$1,$2,0); } + | interval_expr + { + if ($1->type() != Item::ROW_ITEM) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + $$= new (YYTHD->mem_root) Item_func_interval((Item_row *)$1); + } + | UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' expr_list ')' + { + $$= new Item_func_unique_users($3,atoi($5.str),atoi($7.str), * $9); + } + ; + +/* + Function call syntax using official SQL 2003 keywords. + Because the function name is an official token, + a dedicated grammar rule is needed in the parser. + There is no potential for conflicts +*/ +function_call_keyword: + CHAR_SYM '(' expr_list ')' + { $$= new (YYTHD->mem_root) Item_func_char(*$3); } + | CHAR_SYM '(' expr_list USING charset_name ')' + { $$= new (YYTHD->mem_root) Item_func_char(*$3, $5); } + | CURRENT_USER optional_braces + { + $$= new (YYTHD->mem_root) Item_func_current_user(Lex->current_context()); + Lex->safe_to_cache_query= 0; + } + | DATE_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_date_typecast($3); } + | DAY_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_dayofmonth($3); } + | HOUR_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_hour($3); } + | INSERT '(' expr ',' expr ',' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_insert($3,$5,$7,$9); } + | LEFT '(' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_left($3,$5); } + | MINUTE_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_minute($3); } + | MONTH_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_month($3); } + | RIGHT '(' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_right($3,$5); } + | SECOND_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_second($3); } + | TIME_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_time_typecast($3); } + | TIMESTAMP '(' expr ')' + { $$= new (YYTHD->mem_root) Item_datetime_typecast($3); } + | TIMESTAMP '(' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_add_time($3, $5, 1, 0); } + | TRIM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_trim($3); } + | TRIM '(' LEADING expr FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_ltrim($6,$4); } + | TRIM '(' TRAILING expr FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_rtrim($6,$4); } + | TRIM '(' BOTH expr FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_trim($6,$4); } + | TRIM '(' LEADING FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_ltrim($5); } + | TRIM '(' TRAILING FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_rtrim($5); } + | TRIM '(' BOTH FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_trim($5); } + | TRIM '(' expr FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_trim($5,$3); } + | USER '(' ')' + { + $$= new (YYTHD->mem_root) Item_func_user(); + Lex->safe_to_cache_query=0; + } + | YEAR_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_year($3); } + ; + +/* + Function calls using non reserved keywords, with special syntaxic forms. + Dedicated grammar rules are needed because of the syntax, + but also have the potential to cause incompatibilities with other + parts of the language. + MAINTAINER: + The only reasons a function should be added here are: + - for compatibility reasons with another SQL syntax (CURDATE), + - for typing reasons (GET_FORMAT) + Any other 'Syntaxic sugar' enhancements should be *STRONGLY* + discouraged. +*/ +function_call_nonkeyword: + ADDDATE_SYM '(' expr ',' expr ')' + { + $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5, + INTERVAL_DAY, 0); + } + | ADDDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' + { $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 0); } + | CURDATE optional_braces + { + $$= new (YYTHD->mem_root) Item_func_curdate_local(); + Lex->safe_to_cache_query=0; + } + | CURTIME optional_braces + { + $$= new (YYTHD->mem_root) Item_func_curtime_local(); + Lex->safe_to_cache_query=0; + } + | CURTIME '(' expr ')' + { + $$= new (YYTHD->mem_root) Item_func_curtime_local($3); + Lex->safe_to_cache_query=0; + } + | DATE_ADD_INTERVAL '(' expr ',' interval_expr interval ')' + { $$= new (YYTHD->mem_root) Item_date_add_interval($3,$5,$6,0); } + | DATE_SUB_INTERVAL '(' expr ',' interval_expr interval ')' + { $$= new (YYTHD->mem_root) Item_date_add_interval($3,$5,$6,1); } + | EXTRACT_SYM '(' interval FROM expr ')' + { $$=new (YYTHD->mem_root) Item_extract( $3, $5); } + | GET_FORMAT '(' date_time_type ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_get_format($3, $5); } + | NOW_SYM optional_braces + { + $$= new (YYTHD->mem_root) Item_func_now_local(); + Lex->safe_to_cache_query=0; + } + | NOW_SYM '(' expr ')' + { + $$= new (YYTHD->mem_root) Item_func_now_local($3); + Lex->safe_to_cache_query=0; + } + | POSITION_SYM '(' bit_expr IN_SYM expr ')' + { $$ = new (YYTHD->mem_root) Item_func_locate($5,$3); } + | SUBDATE_SYM '(' expr ',' expr ')' + { + $$= new (YYTHD->mem_root) Item_date_add_interval($3, $5, + INTERVAL_DAY, 1); + } + | SUBDATE_SYM '(' expr ',' INTERVAL_SYM expr interval ')' + { $$= new (YYTHD->mem_root) Item_date_add_interval($3, $6, $7, 1); } + | SUBSTRING '(' expr ',' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); } + | SUBSTRING '(' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); } + | SUBSTRING '(' expr FROM expr FOR_SYM expr ')' + { $$= new (YYTHD->mem_root) Item_func_substr($3,$5,$7); } + | SUBSTRING '(' expr FROM expr ')' + { $$= new (YYTHD->mem_root) Item_func_substr($3,$5); } + | SYSDATE optional_braces + { + if (global_system_variables.sysdate_is_now == 0) + $$= new (YYTHD->mem_root) Item_func_sysdate_local(); + else + $$= new (YYTHD->mem_root) Item_func_now_local(); + Lex->safe_to_cache_query=0; + } + | SYSDATE '(' expr ')' + { + if (global_system_variables.sysdate_is_now == 0) + $$= new (YYTHD->mem_root) Item_func_sysdate_local($3); + else + $$= new (YYTHD->mem_root) Item_func_now_local($3); + Lex->safe_to_cache_query=0; + } + | TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_date_add_interval($7,$5,$3,0); } + | TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_timestamp_diff($5,$7,$3); } + | UTC_DATE_SYM optional_braces + { + $$= new (YYTHD->mem_root) Item_func_curdate_utc(); + Lex->safe_to_cache_query=0; + } + | UTC_TIME_SYM optional_braces + { + $$= new (YYTHD->mem_root) Item_func_curtime_utc(); + Lex->safe_to_cache_query=0; + } + | UTC_TIMESTAMP_SYM optional_braces + { + $$= new (YYTHD->mem_root) Item_func_now_utc(); + Lex->safe_to_cache_query=0; + } + ; + +/* + Functions calls using a non reserved keywork, and using a regular syntax. + Because the non reserved keyword is used in another part of the grammar, + a dedicated rule is needed here. +*/ +function_call_conflict: + ASCII_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_ascii($3); } + | CHARSET '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_charset($3); } + | COALESCE '(' expr_list ')' + { $$= new (YYTHD->mem_root) Item_func_coalesce(* $3); } + | COLLATION_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_collation($3); } + | DATABASE '(' ')' + { + $$= new (YYTHD->mem_root) Item_func_database(); + Lex->safe_to_cache_query=0; + } + | IF '(' expr ',' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_if($3,$5,$7); } + | MICROSECOND_SYM '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_microsecond($3); } + | MOD_SYM '(' expr ',' expr ')' + { $$ = new (YYTHD->mem_root) Item_func_mod( $3, $5); } + | OLD_PASSWORD '(' expr ')' + { $$= new (YYTHD->mem_root) Item_func_old_password($3); } + | PASSWORD '(' expr ')' + { + THD *thd= YYTHD; + Item* i1; + if (thd->variables.old_passwords) + i1= new (thd->mem_root) Item_func_old_password($3); + else + i1= new (thd->mem_root) Item_func_password($3); + $$= i1; + } + | QUARTER_SYM '(' expr ')' + { $$ = new (YYTHD->mem_root) Item_func_quarter($3); } + | REPEAT_SYM '(' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_repeat($3,$5); } + | REPLACE '(' expr ',' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_replace($3,$5,$7); } + | TRUNCATE_SYM '(' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_round($3,$5,1); } + | WEEK_SYM '(' expr ')' + { + THD *thd= YYTHD; + Item *i1= new (thd->mem_root) Item_int((char*) "0", + thd->variables.default_week_format, + 1); + + $$= new (thd->mem_root) Item_func_week($3, i1); + } + | WEEK_SYM '(' expr ',' expr ')' + { $$= new (YYTHD->mem_root) Item_func_week($3,$5); } + | geometry_function + { +#ifdef HAVE_SPATIAL + $$= $1; +#else + my_error(ER_FEATURE_DISABLED, MYF(0), + sym_group_geom.name, sym_group_geom.needed_define); + YYABORT; +#endif + } + ; + +geometry_function: + CONTAINS_SYM '(' expr ',' expr ')' + { + $$= GEOM_NEW(YYTHD, + Item_func_spatial_rel($3, $5, + Item_func::SP_CONTAINS_FUNC)); + } + | GEOMETRYCOLLECTION '(' expr_list ')' + { + $$= GEOM_NEW(YYTHD, + Item_func_spatial_collection(* $3, + Geometry::wkb_geometrycollection, + Geometry::wkb_point)); + } + | LINESTRING '(' expr_list ')' + { + $$= GEOM_NEW(YYTHD, + Item_func_spatial_collection(* $3, + Geometry::wkb_linestring, + Geometry::wkb_point)); + } + | MULTILINESTRING '(' expr_list ')' + { + $$= GEOM_NEW(YYTHD, + Item_func_spatial_collection(* $3, + Geometry::wkb_multilinestring, + Geometry::wkb_linestring)); + } + | MULTIPOINT '(' expr_list ')' + { + $$= GEOM_NEW(YYTHD, + Item_func_spatial_collection(* $3, + Geometry::wkb_multipoint, + Geometry::wkb_point)); + } + | MULTIPOLYGON '(' expr_list ')' + { + $$= GEOM_NEW(YYTHD, + Item_func_spatial_collection(* $3, + Geometry::wkb_multipolygon, + Geometry::wkb_polygon)); + } + | POINT_SYM '(' expr ',' expr ')' + { $$= GEOM_NEW(YYTHD, Item_func_point($3,$5)); } + | POLYGON '(' expr_list ')' + { + $$= GEOM_NEW(YYTHD, + Item_func_spatial_collection(* $3, + Geometry::wkb_polygon, + Geometry::wkb_linestring)); + } + ; + +/* + Regular function calls. + The function name is *not* a token, and therefore is guaranteed to not + introduce side effects to the language in general. + MAINTAINER: + All the new functions implemented for new features should fit into + this category. The place to implement the function itself is + in sql/item_create.cc +*/ +function_call_generic: + IDENT_sys '(' + { +#ifdef HAVE_DLOPEN + udf_func *udf= 0; + LEX *lex= Lex; + if (using_udf_functions && + (udf= find_udf($1.str, $1.length)) && + udf->type == UDFTYPE_AGGREGATE) + { + if (lex->current_select->inc_in_sum_expr()) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + } + /* Temporary placing the result of find_udf in $3 */ + lex->current_select->udf_list.push_front(udf); +#endif + } + udf_expr_list ')' + { + THD *thd= YYTHD; + LEX *lex= Lex; + Create_func *builder; + Item *item= NULL; + + /* + Implementation note: + names are resolved with the following order: + - MySQL native functions, + - User Defined Functions, + - Stored Functions (assuming the current <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); + } + else + { +#ifdef HAVE_DLOPEN + /* Retrieving the result of find_udf */ + udf_func *udf; + LEX *lex= Lex; + + if (NULL != (udf= lex->current_select->udf_list.pop())) + { + if (udf->type == UDFTYPE_AGGREGATE) + { + Select->in_sum_expr--; + } + + item= Create_udf_func::s_singleton.create(thd, udf, $4); + } + else +#endif + { + builder= find_qualified_function_builder(thd); + DBUG_ASSERT(builder); + item= builder->create(thd, $1, $4); + } + } + + if (! ($$= item)) + { + YYABORT; + } + } + | ident '.' ident '(' opt_expr_list ')' + { + THD *thd= YYTHD; + Create_qfunc *builder; + Item *item= NULL; + + /* + 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 + { $$= $1 | $2; } + | IN_SYM BOOLEAN_SYM MODE_SYM + { $$= FT_BOOL; } + ; + +opt_natural_language_mode: + /* nothing */ { $$= FT_NL; } + | IN_SYM NATURAL LANGUAGE_SYM MODE_SYM { $$= FT_NL; } + ; + +opt_query_expansion: + /* nothing */ { $$= 0; } + | WITH QUERY_SYM EXPANSION_SYM { $$= FT_EXPAND; } + ; + +udf_expr_list: + /* empty */ { $$= NULL; } + | udf_expr_list2 { $$= $1;} + ; + +udf_expr_list2: + { Select->expr_list.push_front(new List<Item>); } + udf_expr_list3 + { $$= Select->expr_list.pop(); } + ; + +udf_expr_list3: + udf_expr + { + Select->expr_list.head()->push_back($1); + } + | udf_expr_list3 ',' udf_expr + { + Select->expr_list.head()->push_back($3); + } + ; + +udf_expr: + remember_name expr remember_end select_alias + { + udf_func *udf= Select->udf_list.head(); + /* + 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) + { + if (!udf) + { + /* + Disallow using AS to specify explicit names for the arguments + of stored routine calls + */ + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + + $2->is_autogenerated_name= FALSE; + $2->set_name($4.str, $4.length, system_charset_info); + } + else if (udf) + $2->set_name($1, (uint) ($3 - $1), YYTHD->charset()); + $$= $2; + } + ; + +sum_expr: + AVG_SYM '(' in_sum_expr ')' + { $$=new Item_sum_avg($3); } + | AVG_SYM '(' DISTINCT in_sum_expr ')' + { $$=new Item_sum_avg_distinct($4); } + | BIT_AND '(' in_sum_expr ')' + { $$=new Item_sum_and($3); } + | BIT_OR '(' in_sum_expr ')' + { $$=new Item_sum_or($3); } + | BIT_XOR '(' in_sum_expr ')' + { $$=new Item_sum_xor($3); } + | COUNT_SYM '(' opt_all '*' ')' + { $$=new Item_sum_count(new Item_int((int32) 0L,1)); } + | COUNT_SYM '(' in_sum_expr ')' + { $$=new Item_sum_count($3); } + | COUNT_SYM '(' DISTINCT + { Select->in_sum_expr++; } + expr_list + { Select->in_sum_expr--; } + ')' + { $$=new Item_sum_count_distinct(* $5); } + | GROUP_UNIQUE_USERS '(' text_literal ',' NUM ',' NUM ',' in_sum_expr ')' + { $$= new Item_sum_unique_users($3,atoi($5.str),atoi($7.str),$9); } + | MIN_SYM '(' in_sum_expr ')' + { $$=new Item_sum_min($3); } +/* + According to ANSI SQL, DISTINCT is allowed and has + no sence inside MIN and MAX grouping functions; so MIN|MAX(DISTINCT ...) + is processed like an ordinary MIN | MAX() + */ + | MIN_SYM '(' DISTINCT in_sum_expr ')' + { $$=new Item_sum_min($4); } + | MAX_SYM '(' in_sum_expr ')' + { $$=new Item_sum_max($3); } + | MAX_SYM '(' DISTINCT in_sum_expr ')' + { $$=new Item_sum_max($4); } + | STD_SYM '(' in_sum_expr ')' + { $$=new Item_sum_std($3, 0); } + | VARIANCE_SYM '(' in_sum_expr ')' + { $$=new Item_sum_variance($3, 0); } + | STDDEV_SAMP_SYM '(' in_sum_expr ')' + { $$=new Item_sum_std($3, 1); } + | VAR_SAMP_SYM '(' in_sum_expr ')' + { $$=new Item_sum_variance($3, 1); } + | SUM_SYM '(' in_sum_expr ')' + { $$=new Item_sum_sum($3); } + | SUM_SYM '(' DISTINCT in_sum_expr ')' + { $$=new Item_sum_sum_distinct($4); } + | GROUP_CONCAT_SYM '(' opt_distinct + { Select->in_sum_expr++; } + expr_list opt_gorder_clause + opt_gconcat_separator + ')' + { + SELECT_LEX *sel= Select; + sel->in_sum_expr--; + $$=new Item_func_group_concat(Lex->current_context(), $3, $5, + sel->gorder_list, $7); + $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; }; + +opt_gconcat_separator: + /* empty */ { $$ = new (YYTHD->mem_root) String(",",1,default_charset_info); } + |SEPARATOR_SYM text_string { $$ = $2; }; + + +opt_gorder_clause: + /* empty */ + { + Select->gorder_list = NULL; + } + | order_clause + { + SELECT_LEX *select= Select; + select->gorder_list= + (SQL_LIST*) sql_memdup((char*) &select->order_list, + sizeof(st_sql_list)); + select->order_list.empty(); + }; + + +in_sum_expr: + opt_all + { + LEX *lex= Lex; + if (lex->current_select->inc_in_sum_expr()) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + } + expr + { + Select->in_sum_expr--; + $$= $3; + }; + +cast_type: + BINARY opt_len { $$=ITEM_CAST_CHAR; Lex->charset= &my_charset_bin; Lex->dec= 0; } + | CHAR_SYM opt_len opt_binary { $$=ITEM_CAST_CHAR; Lex->dec= 0; } + | NCHAR_SYM opt_len { $$=ITEM_CAST_CHAR; Lex->charset= national_charset_info; Lex->dec=0; } + | SIGNED_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } + | SIGNED_SYM INT_SYM { $$=ITEM_CAST_SIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } + | UNSIGNED { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } + | UNSIGNED INT_SYM { $$=ITEM_CAST_UNSIGNED_INT; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } + | DATE_SYM { $$=ITEM_CAST_DATE; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } + | TIME_SYM { $$=ITEM_CAST_TIME; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } + | DATETIME { $$=ITEM_CAST_DATETIME; Lex->charset= NULL; Lex->dec=Lex->length= (char*)0; } + | 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 + { $$= Select->expr_list.pop(); }; + +expr_list2: + expr { Select->expr_list.head()->push_back($1); } + | expr_list2 ',' expr { Select->expr_list.head()->push_back($3); }; + +ident_list_arg: + ident_list { $$= $1; } + | '(' ident_list ')' { $$= $2; }; + +ident_list: + { Select->expr_list.push_front(new List<Item>); } + ident_list2 + { $$= Select->expr_list.pop(); }; + +ident_list2: + simple_ident { Select->expr_list.head()->push_back($1); } + | ident_list2 ',' simple_ident { Select->expr_list.head()->push_back($3); }; + +opt_expr: + /* empty */ { $$= NULL; } + | expr { $$= $1; }; + +opt_else: + /* empty */ { $$= NULL; } + | ELSE expr { $$= $2; }; + +when_list: + { Select->when_list.push_front(new List<Item>); } + when_list2 + { $$= Select->when_list.pop(); }; + +when_list2: + expr THEN_SYM expr + { + SELECT_LEX *sel=Select; + sel->when_list.head()->push_back($1); + sel->when_list.head()->push_back($3); + } + | when_list2 WHEN_SYM expr THEN_SYM expr + { + SELECT_LEX *sel=Select; + sel->when_list.head()->push_back($3); + sel->when_list.head()->push_back($5); + }; + +/* Warning - may return NULL in case of incomplete SELECT */ +table_ref: + table_factor { $$=$1; } + | join_table + { + LEX *lex= Lex; + if (!($$= lex->current_select->nest_last_join(lex->thd))) + YYABORT; + } + ; + +join_table_list: + derived_table_list { YYERROR_UNLESS($$=$1); } + ; + +/* Warning - may return NULL in case of incomplete SELECT */ +derived_table_list: + table_ref { $$=$1; } + | derived_table_list ',' table_ref + { + YYERROR_UNLESS($1 && ($$=$3)); + } + ; + +/* + Notice that JOIN is a left-associative operation, and it must be parsed + as such, that is, the parser must process first the left join operand + then the right one. Such order of processing ensures that the parser + produces correct join trees which is essential for semantic analysis + and subsequent optimization phases. +*/ +join_table: +/* INNER JOIN variants */ + /* + Use %prec to evaluate production 'table_ref' before 'normal_join' + so that [INNER | CROSS] JOIN is properly nested as other + left-associative joins. + */ + table_ref %prec TABLE_REF_PRIORITY normal_join table_ref + { YYERROR_UNLESS($1 && ($$=$3)); } + | table_ref STRAIGHT_JOIN table_factor + { YYERROR_UNLESS($1 && ($$=$3)); $3->straight=1; } + | table_ref normal_join table_ref + ON + { + 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); + /* 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 + { + SELECT_LEX *sel= Select; + YYERROR_UNLESS($1 && $3); + } + '(' using_list ')' + { add_join_natural($1,$3,$7); $$=$3; } + | table_ref NATURAL JOIN_SYM table_factor + { + YYERROR_UNLESS($1 && ($$=$4)); + add_join_natural($1,$4,NULL); + } + +/* LEFT JOIN variants */ + | table_ref LEFT opt_outer JOIN_SYM table_ref + ON + { + YYERROR_UNLESS($1 && $5); + /* 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 + { + add_join_on($5,$8); + Lex->pop_context(); + $5->outer_join|=JOIN_TYPE_LEFT; + $$=$5; + Select->parsing_place= NO_MATTER; + } + | table_ref LEFT opt_outer JOIN_SYM table_factor + { + SELECT_LEX *sel= Select; + YYERROR_UNLESS($1 && $5); + } + USING '(' using_list ')' + { add_join_natural($1,$5,$9); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } + | table_ref NATURAL LEFT opt_outer JOIN_SYM table_factor + { + YYERROR_UNLESS($1 && $6); + add_join_natural($1,$6,NULL); + $6->outer_join|=JOIN_TYPE_LEFT; + $$=$6; + } + +/* RIGHT JOIN variants */ + | table_ref RIGHT opt_outer JOIN_SYM table_ref + ON + { + YYERROR_UNLESS($1 && $5); + /* 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 + { + LEX *lex= Lex; + if (!($$= lex->current_select->convert_right_join())) + YYABORT; + add_join_on($$, $8); + Lex->pop_context(); + Select->parsing_place= NO_MATTER; + } + | table_ref RIGHT opt_outer JOIN_SYM table_factor + { + SELECT_LEX *sel= Select; + YYERROR_UNLESS($1 && $5); + } + USING '(' using_list ')' + { + LEX *lex= Lex; + if (!($$= lex->current_select->convert_right_join())) + YYABORT; + add_join_natural($$,$5,$9); + } + | table_ref NATURAL RIGHT opt_outer JOIN_SYM table_factor + { + YYERROR_UNLESS($1 && $6); + add_join_natural($6,$1,NULL); + LEX *lex= Lex; + if (!($$= lex->current_select->convert_right_join())) + YYABORT; + }; + +normal_join: + JOIN_SYM {} + | INNER_SYM JOIN_SYM {} + | CROSS JOIN_SYM {} + ; + +/* Warning - may return NULL in case of incomplete SELECT */ +table_factor: + { + SELECT_LEX *sel= Select; + sel->use_index_ptr=sel->ignore_index_ptr=0; + sel->table_join_options= 0; + } + table_ident opt_table_alias opt_key_definition + { + LEX *lex= Lex; + SELECT_LEX *sel= lex->current_select; + if (!($$= sel->add_table_to_list(lex->thd, $2, $3, + sel->get_table_join_options(), + lex->lock_option, + sel->get_use_index(), + sel->get_ignore_index()))) + YYABORT; + sel->add_joined_table($$); + } + | '{' ident table_ref LEFT OUTER JOIN_SYM table_ref + ON + { + /* Change the current name resolution context to a local context. */ + if (push_new_name_resolution_context(YYTHD, $3, $7)) + YYABORT; + + } + expr '}' + { + LEX *lex= Lex; + YYERROR_UNLESS($3 && $7); + add_join_on($7,$10); + Lex->pop_context(); + $7->outer_join|=JOIN_TYPE_LEFT; + $$=$7; + if (!($$= lex->current_select->nest_last_join(lex->thd))) + YYABORT; + } + | select_derived_init get_select_lex select_derived2 + { + LEX *lex= Lex; + SELECT_LEX *sel= lex->current_select; + if ($1) + { + if (sel->set_braces(1)) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + /* select in braces, can't contain global parameters */ + if (sel->master_unit()->fake_select_lex) + sel->master_unit()->global_parameters= + sel->master_unit()->fake_select_lex; + } + if ($2->init_nested_join(lex->thd)) + YYABORT; + $$= 0; + /* incomplete derived tables return NULL, we must be + nested in select_derived rule to be here. */ + } + | '(' get_select_lex select_derived union_opt ')' opt_table_alias + { + /* Use $2 instead of Lex->current_select as derived table will + alter value of Lex->current_select. */ + + if (!($3 || $6) && $2->embedding && + !$2->embedding->nested_join->join_list.elements) + { + /* we have a derived table ($3 == NULL) but no alias, + Since we are nested in further parentheses so we + can pass NULL to the outer level parentheses + Permits parsing of "((((select ...))) as xyz)" */ + $$= 0; + } + else + if (!$3) + { + /* Handle case of derived table, alias may be NULL if there + are no outer parentheses, add_table_to_list() will throw + error in this case */ + LEX *lex=Lex; + SELECT_LEX *sel= lex->current_select; + SELECT_LEX_UNIT *unit= sel->master_unit(); + lex->current_select= sel= unit->outer_select(); + if (!($$= sel-> + add_table_to_list(lex->thd, new Table_ident(unit), $6, 0, + TL_READ,(List<String> *)0, + (List<String> *)0))) + + YYABORT; + sel->add_joined_table($$); + lex->pop_context(); + } + else + if ($4 || $6) + { + /* simple nested joins cannot have aliases or unions */ + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + else + $$= $3; + } + ; + +/* handle contents of parentheses in join expression */ +select_derived: + get_select_lex + { + LEX *lex= Lex; + if ($1->init_nested_join(lex->thd)) + YYABORT; + } + derived_table_list + { + LEX *lex= Lex; + /* for normal joins, $3 != NULL and end_nested_join() != NULL, + for derived tables, both must equal NULL */ + + if (!($$= $1->end_nested_join(lex->thd)) && $3) + YYABORT; + if (!$3 && $$) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + } + ; + +select_derived2: + { + LEX *lex= Lex; + lex->derived_tables|= DERIVED_SUBQUERY; + if (!lex->expr_allows_subselect) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || + mysql_new_select(lex, 1)) + YYABORT; + mysql_init_select(lex); + lex->current_select->linkage= DERIVED_TABLE_TYPE; + lex->current_select->parsing_place= SELECT_LIST; + } + select_options select_item_list + { + Select->parsing_place= NO_MATTER; + } + opt_select_from + ; + +get_select_lex: + /* Empty */ { $$= Select; } + ; + +select_derived_init: + 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)) + { + /* we are not in parentheses */ + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + embedding= Select->embedding; + $$= embedding && + !embedding->nested_join->join_list.elements; + /* return true if we are deeply nested */ + } + ; + +opt_outer: + /* empty */ {} + | OUTER {}; + +opt_key_definition: + /* empty */ {} + | USE_SYM key_usage_list + { + SELECT_LEX *sel= Select; + sel->use_index= *$2; + sel->use_index_ptr= &sel->use_index; + } + | FORCE_SYM key_usage_list + { + SELECT_LEX *sel= Select; + sel->use_index= *$2; + sel->use_index_ptr= &sel->use_index; + sel->table_join_options|= TL_OPTION_FORCE_INDEX; + } + | IGNORE_SYM key_usage_list + { + SELECT_LEX *sel= Select; + sel->ignore_index= *$2; + sel->ignore_index_ptr= &sel->ignore_index; + }; + +key_usage_list: + key_or_index { Select->interval_list.empty(); } + '(' key_list_or_empty ')' + { $$= &Select->interval_list; } + ; + +key_list_or_empty: + /* empty */ {} + | key_usage_list2 {} + ; + +key_usage_list2: + key_usage_list2 ',' ident + { Select-> + interval_list.push_back(new (YYTHD->mem_root) String((const char*) $3.str, $3.length, + system_charset_info)); } + | ident + { Select-> + interval_list.push_back(new (YYTHD->mem_root) String((const char*) $1.str, $1.length, + system_charset_info)); } + | PRIMARY_SYM + { Select-> + interval_list.push_back(new (YYTHD->mem_root) String("PRIMARY", 7, + system_charset_info)); }; + +using_list: + ident + { + if (!($$= new List<String>)) + YYABORT; + $$->push_back(new (YYTHD->mem_root) + String((const char *) $1.str, $1.length, + system_charset_info)); + } + | using_list ',' ident + { + $1->push_back(new (YYTHD->mem_root) + String((const char *) $3.str, $3.length, + system_charset_info)); + $$= $1; + }; + +interval: + interval_time_st {} + | DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; } + | DAY_MICROSECOND_SYM { $$=INTERVAL_DAY_MICROSECOND; } + | DAY_MINUTE_SYM { $$=INTERVAL_DAY_MINUTE; } + | DAY_SECOND_SYM { $$=INTERVAL_DAY_SECOND; } + | HOUR_MICROSECOND_SYM { $$=INTERVAL_HOUR_MICROSECOND; } + | HOUR_MINUTE_SYM { $$=INTERVAL_HOUR_MINUTE; } + | HOUR_SECOND_SYM { $$=INTERVAL_HOUR_SECOND; } + | MICROSECOND_SYM { $$=INTERVAL_MICROSECOND; } + | MINUTE_MICROSECOND_SYM { $$=INTERVAL_MINUTE_MICROSECOND; } + | MINUTE_SECOND_SYM { $$=INTERVAL_MINUTE_SECOND; } + | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; } + | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; }; + +interval_time_st: + DAY_SYM { $$=INTERVAL_DAY; } + | WEEK_SYM { $$=INTERVAL_WEEK; } + | HOUR_SYM { $$=INTERVAL_HOUR; } + | FRAC_SECOND_SYM { $$=INTERVAL_MICROSECOND; } + | MINUTE_SYM { $$=INTERVAL_MINUTE; } + | MONTH_SYM { $$=INTERVAL_MONTH; } + | QUARTER_SYM { $$=INTERVAL_QUARTER; } + | SECOND_SYM { $$=INTERVAL_SECOND; } + | YEAR_SYM { $$=INTERVAL_YEAR; } + ; + +date_time_type: + DATE_SYM {$$=MYSQL_TIMESTAMP_DATE;} + | TIME_SYM {$$=MYSQL_TIMESTAMP_TIME;} + | DATETIME {$$=MYSQL_TIMESTAMP_DATETIME;} + | TIMESTAMP {$$=MYSQL_TIMESTAMP_DATETIME;} + ; + +table_alias: + /* empty */ + | AS + | EQ; + +opt_table_alias: + /* empty */ { $$=0; } + | table_alias ident + { $$= (LEX_STRING*) sql_memdup(&$2,sizeof(LEX_STRING)); }; + +opt_all: + /* empty */ + | ALL + ; + +where_clause: + /* empty */ { Select->where= 0; } + | WHERE + { + Select->parsing_place= IN_WHERE; + } + expr + { + SELECT_LEX *select= Select; + select->where= $3; + select->parsing_place= NO_MATTER; + if ($3) + $3->top_level_item(); + } + ; + +having_clause: + /* empty */ + | HAVING + { + Select->parsing_place= IN_HAVING; + } + expr + { + SELECT_LEX *sel= Select; + sel->having= $3; + sel->parsing_place= NO_MATTER; + if ($3) + $3->top_level_item(); + } + ; + +opt_escape: + ESCAPE_SYM simple_expr + { + Lex->escape_used= TRUE; + $$= $2; + } + | /* empty */ + { + Lex->escape_used= FALSE; + $$= ((YYTHD->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES) ? + new Item_string("", 0, &my_charset_latin1) : + new Item_string("\\", 1, &my_charset_latin1)); + } + ; + + +/* + group by statement in select +*/ + +group_clause: + /* empty */ + | GROUP BY group_list olap_opt; + +group_list: + group_list ',' order_ident order_dir + { if (add_group_to_list(YYTHD, $3,(bool) $4)) YYABORT; } + | order_ident order_dir + { if (add_group_to_list(YYTHD, $1,(bool) $2)) YYABORT; }; + +olap_opt: + /* empty */ {} + | WITH CUBE_SYM + { + LEX *lex=Lex; + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + { + my_error(ER_WRONG_USAGE, MYF(0), "WITH CUBE", + "global union parameters"); + YYABORT; + } + lex->current_select->olap= CUBE_TYPE; + my_error(ER_NOT_SUPPORTED_YET, MYF(0), "CUBE"); + YYABORT; /* To be deleted in 5.1 */ + } + | WITH ROLLUP_SYM + { + LEX *lex= Lex; + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + { + my_error(ER_WRONG_USAGE, MYF(0), "WITH ROLLUP", + "global union parameters"); + YYABORT; + } + lex->current_select->olap= ROLLUP_TYPE; + } + ; + +/* + Order by statement in select +*/ + +opt_order_clause: + /* empty */ + | order_clause; + +order_clause: + ORDER_SYM BY + { + LEX *lex=Lex; + SELECT_LEX *sel= lex->current_select; + SELECT_LEX_UNIT *unit= sel-> master_unit(); + if (sel->linkage != GLOBAL_OPTIONS_TYPE && + sel->olap != UNSPECIFIED_OLAP_TYPE) + { + my_error(ER_WRONG_USAGE, MYF(0), + "CUBE/ROLLUP", "ORDER BY"); + YYABORT; + } + if (lex->sql_command != SQLCOM_ALTER_TABLE && !unit->fake_select_lex) + { + /* + A query of the of the form (SELECT ...) ORDER BY order_list is + executed in the same way as the query + SELECT ... ORDER BY order_list + unless the SELECT construct contains ORDER BY or LIMIT clauses. + Otherwise we create a fake SELECT_LEX if it has not been created + yet. + */ + SELECT_LEX *first_sl= unit->first_select(); + if (!first_sl->next_select() && + (first_sl->order_list.elements || + first_sl->select_limit) && + unit->add_fake_select_lex(lex->thd)) + YYABORT; + } + } order_list; + +order_list: + order_list ',' order_ident order_dir + { if (add_order_to_list(YYTHD, $3,(bool) $4)) YYABORT; } + | order_ident order_dir + { if (add_order_to_list(YYTHD, $1,(bool) $2)) YYABORT; }; + +order_dir: + /* empty */ { $$ = 1; } + | ASC { $$ =1; } + | DESC { $$ =0; }; + + +opt_limit_clause_init: + /* empty */ + { + LEX *lex= Lex; + SELECT_LEX *sel= lex->current_select; + sel->offset_limit= 0; + sel->select_limit= 0; + } + | limit_clause {} + ; + +opt_limit_clause: + /* empty */ {} + | limit_clause {} + ; + +limit_clause: + LIMIT limit_options {} + ; + +limit_options: + limit_option + { + SELECT_LEX *sel= Select; + sel->select_limit= $1; + sel->offset_limit= 0; + sel->explicit_limit= 1; + } + | limit_option ',' limit_option + { + SELECT_LEX *sel= Select; + sel->select_limit= $3; + sel->offset_limit= $1; + sel->explicit_limit= 1; + } + | limit_option OFFSET_SYM limit_option + { + SELECT_LEX *sel= Select; + sel->select_limit= $1; + sel->offset_limit= $3; + sel->explicit_limit= 1; + } + ; +limit_option: + param_marker + | ULONGLONG_NUM { $$= new Item_uint($1.str, $1.length); } + | LONG_NUM { $$= new Item_uint($1.str, $1.length); } + | NUM { $$= new Item_uint($1.str, $1.length); } + ; + +delete_limit_clause: + /* empty */ + { + LEX *lex=Lex; + lex->current_select->select_limit= 0; + } + | LIMIT limit_option + { + SELECT_LEX *sel= Select; + sel->select_limit= $2; + sel->explicit_limit= 1; + }; + +ulong_num: + NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | HEX_NUM { $$= (ulong) strtol($1.str, (char**) 0, 16); } + | LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | DECIMAL_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | FLOAT_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + ; + +real_ulong_num: + NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | HEX_NUM { $$= (ulong) strtol($1.str, (char**) 0, 16); } + | LONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | ULONGLONG_NUM { int error; $$= (ulong) my_strtoll10($1.str, (char**) 0, &error); } + | dec_num_error { YYABORT; } + ; + +ulonglong_num: + NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | LONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | DECIMAL_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | FLOAT_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + ; + +real_ulonglong_num: + NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | ULONGLONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | LONG_NUM { int error; $$= (ulonglong) my_strtoll10($1.str, (char**) 0, &error); } + | dec_num_error { YYABORT; } + ; + +dec_num_error: + dec_num + { yyerror(ER(ER_ONLY_INTEGERS_ALLOWED)); } + ; + +dec_num: + DECIMAL_NUM + | FLOAT_NUM + ; + +procedure_clause: + /* empty */ + | 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"); + YYABORT; + } + lex->proc_list.elements=0; + lex->proc_list.first=0; + lex->proc_list.next= (byte**) &lex->proc_list.first; + if (add_proc_to_list(lex->thd, new Item_field(&lex-> + current_select-> + context, + NULL,NULL,$2.str))) + YYABORT; + Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); + } + '(' procedure_list ')'; + + +procedure_list: + /* empty */ {} + | procedure_list2 {}; + +procedure_list2: + procedure_list2 ',' procedure_item + | procedure_item; + +procedure_item: + remember_name expr + { + LEX *lex= Lex; + if (add_proc_to_list(lex->thd, $2)) + YYABORT; + if (!$2->name) + $2->set_name($1,(uint) ((char*) lex->tok_end - $1), + YYTHD->charset()); + } + ; + + +select_var_list_init: + { + LEX *lex=Lex; + if (!lex->describe && (!(lex->result= new select_dumpvar()))) + YYABORT; + } + select_var_list + {} + ; + +select_var_list: + select_var_list ',' select_var_ident + | select_var_ident {} + ; + +select_var_ident: + '@' ident_or_text + { + LEX *lex=Lex; + if (lex->result) + ((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0,(enum_field_types)0)); + else + /* + The parser won't create select_result instance only + if it's an EXPLAIN. + */ + DBUG_ASSERT(lex->describe); + } + | ident_or_text + { + LEX *lex=Lex; + sp_variable_t *t; + + if (!lex->spcont || !(t=lex->spcont->find_variable(&$1))) + { + my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str); + YYABORT; + } + if (lex->result) + { + my_var *var; + ((select_dumpvar *)lex->result)-> + var_list.push_back(var= new my_var($1,1,t->offset,t->type)); +#ifndef DBUG_OFF + if (var) + var->sp= lex->sphead; +#endif + } + else + { + /* + The parser won't create select_result instance only + if it's an EXPLAIN. + */ + DBUG_ASSERT(lex->describe); + } + } + ; + +into: + 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($2.str, 0)) || + !(lex->result= new select_export(lex->exchange))) + YYABORT; + } + opt_field_term opt_line_term + | DUMPFILE TEXT_STRING_filesystem + { + LEX *lex=Lex; + if (!lex->describe) + { + lex->uncacheable(UNCACHEABLE_SIDEEFFECT); + if (!(lex->exchange= new sql_exchange($2.str,1))) + YYABORT; + if (!(lex->result= new select_dump(lex->exchange))) + YYABORT; + } + } + | select_var_list_init + { + Lex->uncacheable(UNCACHEABLE_SIDEEFFECT); + } + ; + +/* + DO statement +*/ + +do: DO_SYM + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_DO; + mysql_init_select(lex); + } + expr_list + { + Lex->insert_list= $3; + } + ; + +/* + Drop : delete tables or index or user +*/ + +drop: + DROP opt_temporary table_or_tables if_exists table_list opt_restrict + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_DROP_TABLE; + lex->drop_temporary= $2; + lex->drop_if_exists= $4; + } + | DROP INDEX_SYM ident ON table_ident {} + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_DROP_INDEX; + lex->alter_info.drop_list.empty(); + lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY, + $3.str)); + if (!lex->current_select->add_table_to_list(lex->thd, $5, NULL, + TL_OPTION_UPDATING)) + YYABORT; + } + | DROP DATABASE if_exists ident + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_DROP_DB; + lex->drop_if_exists=$3; + lex->name= $4; + } + | DROP FUNCTION_SYM if_exists sp_name + { + LEX *lex=Lex; + if (lex->sphead) + { + my_error(ER_SP_NO_DROP_SP, MYF(0), "FUNCTION"); + YYABORT; + } + lex->sql_command = SQLCOM_DROP_FUNCTION; + lex->drop_if_exists= $3; + lex->spname= $4; + } + | DROP PROCEDURE if_exists sp_name + { + LEX *lex=Lex; + if (lex->sphead) + { + my_error(ER_SP_NO_DROP_SP, MYF(0), "PROCEDURE"); + YYABORT; + } + lex->sql_command = SQLCOM_DROP_PROCEDURE; + lex->drop_if_exists= $3; + lex->spname= $4; + } + | DROP USER clear_privileges user_list + { + Lex->sql_command = SQLCOM_DROP_USER; + } + | DROP VIEW_SYM if_exists table_list opt_restrict + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_DROP_VIEW; + lex->drop_if_exists= $3; + } + | DROP EVENT_SYM if_exists sp_name + { + Lex->drop_if_exists= $3; + Lex->spname= $4; + Lex->sql_command = SQLCOM_DROP_EVENT; + } + | DROP TRIGGER_SYM if_exists sp_name + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_DROP_TRIGGER; + lex->drop_if_exists= $3; + lex->spname= $4; + } + | DROP TABLESPACE tablespace_name opt_ts_engine opt_ts_wait + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_cmd_type= DROP_TABLESPACE; + } + | DROP LOGFILE_SYM GROUP logfile_group_name opt_ts_engine opt_ts_wait + { + LEX *lex= Lex; + lex->alter_tablespace_info->ts_cmd_type= DROP_LOGFILE_GROUP; + } + | DROP SERVER_SYM if_exists ident_or_text + { + Lex->sql_command = SQLCOM_DROP_SERVER; + Lex->drop_if_exists= $3; + Lex->server_options.server_name= $4.str; + Lex->server_options.server_name_length= $4.length; + } + ; + +table_list: + table_name + | table_list ',' table_name; + +table_name: + table_ident + { + if (!Select->add_table_to_list(YYTHD, $1, NULL, TL_OPTION_UPDATING)) + YYABORT; + } + ; + +if_exists: + /* empty */ { $$= 0; } + | IF EXISTS { $$= 1; } + ; + +opt_temporary: + /* empty */ { $$= 0; } + | TEMPORARY { $$= 1; } + ; +/* +** Insert : add new data to table +*/ + +insert: + INSERT + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_INSERT; + lex->duplicates= DUP_ERROR; + mysql_init_select(lex); + /* for subselects */ + lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; + } insert_lock_option + opt_ignore insert2 + { + Select->set_lock_for_tables($3); + Lex->current_select= &Lex->select_lex; + } + insert_field_spec opt_insert_update + {} + ; + +replace: + REPLACE + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_REPLACE; + lex->duplicates= DUP_REPLACE; + mysql_init_select(lex); + } + replace_lock_option insert2 + { + Select->set_lock_for_tables($3); + Lex->current_select= &Lex->select_lex; + } + insert_field_spec + {} + ; + +insert_lock_option: + /* empty */ + { +#ifdef HAVE_QUERY_CACHE + /* + If it is SP we do not allow insert optimisation whan result of + insert visible only after the table unlocking but everyone can + read table. + */ + $$= (Lex->sphead ? TL_WRITE :TL_WRITE_CONCURRENT_INSERT); +#else + $$= TL_WRITE_CONCURRENT_INSERT; +#endif + } + | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; } + | DELAYED_SYM { $$= TL_WRITE_DELAYED; } + | HIGH_PRIORITY { $$= TL_WRITE; } + ; + +replace_lock_option: + opt_low_priority { $$= $1; } + | DELAYED_SYM { $$= TL_WRITE_DELAYED; }; + +insert2: + INTO insert_table {} + | insert_table {}; + +insert_table: + table_name + { + LEX *lex=Lex; + lex->field_list.empty(); + lex->many_values.empty(); + lex->insert_list=0; + }; + +insert_field_spec: + insert_values {} + | '(' ')' insert_values {} + | '(' fields ')' insert_values {} + | SET + { + LEX *lex=Lex; + if (!(lex->insert_list = new List_item) || + lex->many_values.push_back(lex->insert_list)) + YYABORT; + } + ident_eq_list; + +fields: + fields ',' insert_ident { Lex->field_list.push_back($3); } + | insert_ident { Lex->field_list.push_back($1); }; + +insert_values: + VALUES values_list {} + | VALUE_SYM values_list {} + | create_select { Select->set_braces(0);} union_clause {} + | '(' create_select ')' { Select->set_braces(1);} union_opt {} + ; + +values_list: + values_list ',' no_braces + | no_braces; + +ident_eq_list: + ident_eq_list ',' ident_eq_value + | + ident_eq_value; + +ident_eq_value: + simple_ident_nospvar equal expr_or_default + { + LEX *lex=Lex; + if (lex->field_list.push_back($1) || + lex->insert_list->push_back($3)) + YYABORT; + }; + +equal: EQ {} + | SET_VAR {} + ; + +opt_equal: + /* empty */ {} + | equal {} + ; + +no_braces: + '(' + { + if (!(Lex->insert_list = new List_item)) + YYABORT; + } + opt_values ')' + { + LEX *lex=Lex; + if (lex->many_values.push_back(lex->insert_list)) + YYABORT; + }; + +opt_values: + /* empty */ {} + | values; + +values: + values ',' expr_or_default + { + if (Lex->insert_list->push_back($3)) + YYABORT; + } + | expr_or_default + { + if (Lex->insert_list->push_back($1)) + YYABORT; + } + ; + +expr_or_default: + expr { $$= $1;} + | DEFAULT {$$= new Item_default_value(Lex->current_context()); } + ; + +opt_insert_update: + /* empty */ + | ON DUPLICATE_SYM { Lex->duplicates= DUP_UPDATE; } + KEY_SYM UPDATE_SYM insert_update_list + ; + +/* Update rows in a table */ + +update: + UPDATE_SYM + { + LEX *lex= Lex; + mysql_init_select(lex); + lex->sql_command= SQLCOM_UPDATE; + lex->lock_option= TL_UNLOCK; /* Will be set later */ + lex->duplicates= DUP_ERROR; + } + opt_low_priority opt_ignore join_table_list + SET update_list + { + LEX *lex= Lex; + if (lex->select_lex.table_list.elements > 1) + lex->sql_command= SQLCOM_UPDATE_MULTI; + else if (lex->select_lex.get_table_list()->derived) + { + /* it is single table update and it is update of derived table */ + my_error(ER_NON_UPDATABLE_TABLE, MYF(0), + lex->select_lex.get_table_list()->alias, "UPDATE"); + YYABORT; + } + /* + In case of multi-update setting write lock for all tables may + be too pessimistic. We will decrease lock level if possible in + mysql_multi_update(). + */ + Select->set_lock_for_tables($3); + } + where_clause opt_order_clause delete_limit_clause {} + ; + +update_list: + update_list ',' update_elem + | update_elem; + +update_elem: + simple_ident_nospvar equal expr_or_default + { + if (add_item_to_list(YYTHD, $1) || add_value_to_list(YYTHD, $3)) + YYABORT; + }; + +insert_update_list: + insert_update_list ',' insert_update_elem + | insert_update_elem; + +insert_update_elem: + simple_ident_nospvar equal expr_or_default + { + LEX *lex= Lex; + if (lex->update_list.push_back($1) || + lex->value_list.push_back($3)) + YYABORT; + }; + +opt_low_priority: + /* empty */ { $$= YYTHD->update_lock_default; } + | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }; + +/* Delete rows from a table */ + +delete: + DELETE_SYM + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_DELETE; + mysql_init_select(lex); + lex->lock_option= lex->thd->update_lock_default; + lex->ignore= 0; + lex->select_lex.init_order(); + } + opt_delete_options single_multi {} + ; + +single_multi: + FROM table_ident + { + if (!Select->add_table_to_list(YYTHD, $2, NULL, TL_OPTION_UPDATING, + Lex->lock_option)) + YYABORT; + } + where_clause opt_order_clause + delete_limit_clause {} + | table_wild_list + { mysql_init_multi_delete(Lex); } + FROM join_table_list where_clause + { + if (multi_delete_set_locks_and_link_aux_tables(Lex)) + YYABORT; + } + | FROM table_wild_list + { mysql_init_multi_delete(Lex); } + USING join_table_list where_clause + { + if (multi_delete_set_locks_and_link_aux_tables(Lex)) + YYABORT; + } + ; + +table_wild_list: + table_wild_one {} + | table_wild_list ',' table_wild_one {}; + +table_wild_one: + ident opt_wild opt_table_alias + { + if (!Select->add_table_to_list(YYTHD, new Table_ident($1), $3, + 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 | + TL_OPTION_ALIAS, + Lex->lock_option)) + YYABORT; + } + ; + +opt_wild: + /* empty */ {} + | '.' '*' {}; + + +opt_delete_options: + /* empty */ {} + | opt_delete_option opt_delete_options {}; + +opt_delete_option: + QUICK { Select->options|= OPTION_QUICK; } + | LOW_PRIORITY { Lex->lock_option= TL_WRITE_LOW_PRIORITY; } + | IGNORE_SYM { Lex->ignore= 1; }; + +truncate: + TRUNCATE_SYM opt_table_sym table_name + { + LEX* lex= Lex; + lex->sql_command= SQLCOM_TRUNCATE; + lex->select_lex.options= 0; + lex->select_lex.sql_cache= SELECT_LEX::SQL_CACHE_UNSPECIFIED; + lex->select_lex.init_order(); + } + ; + +opt_table_sym: + /* empty */ + | TABLE_SYM; + +/* Show things */ + +show: SHOW + { + LEX *lex=Lex; + lex->wild=0; + lex->lock_option= TL_READ; + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + bzero((char*) &lex->create_info,sizeof(lex->create_info)); + } + show_param + {} + ; + +show_param: + DATABASES wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_DATABASES; + if (prepare_schema_table(YYTHD, lex, 0, SCH_SCHEMATA)) + YYABORT; + } + | opt_full TABLES opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_TABLES; + lex->select_lex.db= $3; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_NAMES)) + YYABORT; + } + | opt_full TRIGGERS_SYM opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_TRIGGERS; + lex->select_lex.db= $3; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TRIGGERS)) + YYABORT; + } + | EVENTS_SYM opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_EVENTS; + lex->select_lex.db= $2; + if (prepare_schema_table(YYTHD, lex, 0, SCH_EVENTS)) + YYABORT; + } + | TABLE_SYM STATUS_SYM opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_TABLE_STATUS; + lex->select_lex.db= $3; + if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLES)) + YYABORT; + } + | OPEN_SYM TABLES opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; + lex->select_lex.db= $3; + if (prepare_schema_table(YYTHD, lex, 0, SCH_OPEN_TABLES)) + YYABORT; + } + | opt_full PLUGIN_SYM + { + LEX *lex= Lex; + WARN_DEPRECATED(yythd, "5.2", "SHOW PLUGIN", "'SHOW PLUGINS'"); + lex->sql_command= SQLCOM_SHOW_PLUGINS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS)) + YYABORT; + } + | PLUGINS_SYM + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_PLUGINS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PLUGINS)) + YYABORT; + } + | ENGINE_SYM storage_engines + { Lex->create_info.db_type= $2; } + show_engine_param + | ENGINE_SYM ALL + { Lex->create_info.db_type= NULL; } + show_engine_param + | opt_full COLUMNS from_or_in table_ident opt_db wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_FIELDS; + if ($5) + $4->change_db($5); + if (prepare_schema_table(YYTHD, lex, $4, SCH_COLUMNS)) + YYABORT; + } + | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ + TEXT_STRING_sys AND_SYM MASTER_LOG_POS_SYM EQ ulonglong_num + AND_SYM MASTER_SERVER_ID_SYM EQ + ulong_num + { + Lex->sql_command = SQLCOM_SHOW_NEW_MASTER; + Lex->mi.log_file_name = $8.str; + Lex->mi.pos = $12; + Lex->mi.server_id = $16; + } + | master_or_binary LOGS_SYM + { + Lex->sql_command = SQLCOM_SHOW_BINLOGS; + } + | SLAVE HOSTS_SYM + { + Lex->sql_command = SQLCOM_SHOW_SLAVE_HOSTS; + } + | BINLOG_SYM EVENTS_SYM binlog_in binlog_from + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; + } opt_limit_clause_init + | keys_or_index from_or_in table_ident opt_db where_clause + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_KEYS; + if ($4) + $3->change_db($4); + if (prepare_schema_table(YYTHD, lex, $3, SCH_STATISTICS)) + YYABORT; + } + | COLUMN_SYM TYPES_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_COLUMN_TYPES; + } + | TABLE_SYM TYPES_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES; + WARN_DEPRECATED(yythd, "5.2", "SHOW TABLE TYPES", "'SHOW [STORAGE] ENGINES'"); + } + | opt_storage ENGINES_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_STORAGE_ENGINES; + if (prepare_schema_table(YYTHD, lex, 0, SCH_ENGINES)) + YYABORT; + } + | AUTHORS_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_AUTHORS; + } + | CONTRIBUTORS_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_CONTRIBUTORS; + } + | PRIVILEGES + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_PRIVILEGES; + } + | COUNT_SYM '(' '*' ')' WARNINGS + { (void) create_select_for_variable("warning_count"); } + | COUNT_SYM '(' '*' ')' ERRORS + { (void) create_select_for_variable("error_count"); } + | WARNINGS opt_limit_clause_init + { Lex->sql_command = SQLCOM_SHOW_WARNS;} + | ERRORS opt_limit_clause_init + { Lex->sql_command = SQLCOM_SHOW_ERRORS;} + | opt_var_type STATUS_SYM wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_STATUS; + lex->option_type= $1; + if (prepare_schema_table(YYTHD, lex, 0, SCH_STATUS)) + YYABORT; + } + | INNOBASE_SYM STATUS_SYM + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_SHOW_ENGINE_STATUS; + if (!(lex->create_info.db_type= + ha_resolve_by_legacy_type(YYTHD, DB_TYPE_INNODB))) + { + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB"); + YYABORT; + } + WARN_DEPRECATED(yythd, "5.2", "SHOW INNODB STATUS", "'SHOW ENGINE INNODB STATUS'"); + } + | MUTEX_SYM STATUS_SYM + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_SHOW_ENGINE_MUTEX; + if (!(lex->create_info.db_type= + ha_resolve_by_legacy_type(YYTHD, DB_TYPE_INNODB))) + { + my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), "InnoDB"); + YYABORT; + } + WARN_DEPRECATED(yythd, "5.2", "SHOW MUTEX STATUS", "'SHOW ENGINE INNODB MUTEX'"); + } + | opt_full PROCESSLIST_SYM + { Lex->sql_command= SQLCOM_SHOW_PROCESSLIST;} + | opt_var_type VARIABLES wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_VARIABLES; + lex->option_type= $1; + if (prepare_schema_table(YYTHD, lex, 0, SCH_VARIABLES)) + YYABORT; + } + | charset wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_CHARSETS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_CHARSETS)) + YYABORT; + } + | COLLATION_SYM wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_COLLATIONS; + if (prepare_schema_table(YYTHD, lex, 0, SCH_COLLATIONS)) + YYABORT; + } + | GRANTS + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_GRANTS; + LEX_USER *curr_user; + if (!(curr_user= (LEX_USER*) lex->thd->alloc(sizeof(st_lex_user)))) + YYABORT; + bzero(curr_user, sizeof(st_lex_user)); + lex->grant_user= curr_user; + } + | GRANTS FOR_SYM user + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SHOW_GRANTS; + lex->grant_user=$3; + lex->grant_user->password=null_lex_str; + } + | CREATE DATABASE opt_if_not_exists ident + { + Lex->sql_command=SQLCOM_SHOW_CREATE_DB; + Lex->create_info.options=$3; + Lex->name= $4; + } + | CREATE TABLE_SYM table_ident + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_SHOW_CREATE; + if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL,0)) + YYABORT; + lex->only_view= 0; + } + | CREATE VIEW_SYM table_ident + { + LEX *lex= Lex; + lex->sql_command = SQLCOM_SHOW_CREATE; + if (!lex->select_lex.add_table_to_list(YYTHD, $3, NULL, 0)) + YYABORT; + lex->only_view= 1; + } + | MASTER_SYM STATUS_SYM + { + Lex->sql_command = SQLCOM_SHOW_MASTER_STAT; + } + | SLAVE STATUS_SYM + { + Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT; + } + | CREATE PROCEDURE sp_name + { + LEX *lex= Lex; + + lex->sql_command = SQLCOM_SHOW_CREATE_PROC; + lex->spname= $3; + } + | CREATE FUNCTION_SYM sp_name + { + LEX *lex= Lex; + + lex->sql_command = SQLCOM_SHOW_CREATE_FUNC; + lex->spname= $3; + } + | PROCEDURE STATUS_SYM wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_STATUS_PROC; + if (!sp_add_to_query_tables(YYTHD, lex, "mysql", "proc", TL_READ)) + YYABORT; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES)) + YYABORT; + } + | FUNCTION_SYM STATUS_SYM wild_and_where + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_STATUS_FUNC; + if (!sp_add_to_query_tables(YYTHD, lex, "mysql", "proc", TL_READ)) + YYABORT; + if (prepare_schema_table(YYTHD, lex, 0, SCH_PROCEDURES)) + YYABORT; + } + | PROCEDURE CODE_SYM sp_name + { +#ifdef DBUG_OFF + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; +#else + Lex->sql_command= SQLCOM_SHOW_PROC_CODE; + Lex->spname= $3; +#endif + } + | FUNCTION_SYM CODE_SYM sp_name + { +#ifdef DBUG_OFF + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; +#else + Lex->sql_command= SQLCOM_SHOW_FUNC_CODE; + Lex->spname= $3; +#endif + } + | CREATE EVENT_SYM sp_name + { + Lex->spname= $3; + Lex->sql_command = SQLCOM_SHOW_CREATE_EVENT; + } + ; + +show_engine_param: + STATUS_SYM + { Lex->sql_command= SQLCOM_SHOW_ENGINE_STATUS; } + | MUTEX_SYM + { Lex->sql_command= SQLCOM_SHOW_ENGINE_MUTEX; } + | LOGS_SYM + { Lex->sql_command= SQLCOM_SHOW_ENGINE_LOGS; }; + +master_or_binary: + MASTER_SYM + | BINARY; + +opt_storage: + /* empty */ + | STORAGE_SYM; + +opt_db: + /* empty */ { $$= 0; } + | from_or_in ident { $$= $2.str; }; + +opt_full: + /* empty */ { Lex->verbose=0; } + | FULL { Lex->verbose=1; }; + +from_or_in: + FROM + | IN_SYM; + +binlog_in: + /* empty */ { Lex->mi.log_file_name = 0; } + | IN_SYM TEXT_STRING_sys { Lex->mi.log_file_name = $2.str; }; + +binlog_from: + /* empty */ { Lex->mi.pos = 4; /* skip magic number */ } + | FROM ulonglong_num { Lex->mi.pos = $2; }; + +wild_and_where: + /* empty */ + | LIKE TEXT_STRING_sys + { Lex->wild= new (YYTHD->mem_root) String($2.str, $2.length, + system_charset_info); } + | WHERE expr + { + Select->where= $2; + if ($2) + $2->top_level_item(); + } + ; + + +/* A Oracle compatible synonym for show */ +describe: + describe_command table_ident + { + LEX *lex= Lex; + lex->lock_option= TL_READ; + mysql_init_select(lex); + lex->current_select->parsing_place= SELECT_LIST; + lex->sql_command= SQLCOM_SHOW_FIELDS; + lex->select_lex.db= 0; + lex->verbose= 0; + if (prepare_schema_table(YYTHD, lex, $2, SCH_COLUMNS)) + YYABORT; + } + opt_describe_column {} + | describe_command opt_extended_describe + { Lex->describe|= DESCRIBE_NORMAL; } + select + { + LEX *lex=Lex; + lex->select_lex.options|= SELECT_DESCRIBE; + } + ; + +describe_command: + DESC + | DESCRIBE; + +opt_extended_describe: + /* empty */ {} + | EXTENDED_SYM { Lex->describe|= DESCRIBE_EXTENDED; } + | PARTITIONS_SYM { Lex->describe|= DESCRIBE_PARTITIONS; } + ; + + +opt_describe_column: + /* empty */ {} + | text_string { Lex->wild= $1; } + | ident + { Lex->wild= new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); }; + + +/* flush things */ + +flush: + FLUSH_SYM opt_no_write_to_binlog + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_FLUSH; + lex->type= 0; + lex->no_write_to_binlog= $2; + } + flush_options + {} + ; + +flush_options: + flush_options ',' flush_option + | flush_option; + +flush_option: + table_or_tables { Lex->type|= REFRESH_TABLES; } opt_table_list {} + | TABLES WITH READ_SYM LOCK_SYM { Lex->type|= REFRESH_TABLES | REFRESH_READ_LOCK; } + | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE_FREE; } + | HOSTS_SYM { Lex->type|= REFRESH_HOSTS; } + | PRIVILEGES { Lex->type|= REFRESH_GRANT; } + | LOGS_SYM { Lex->type|= REFRESH_LOG; } + | STATUS_SYM { Lex->type|= REFRESH_STATUS; } + | SLAVE { Lex->type|= REFRESH_SLAVE; } + | MASTER_SYM { Lex->type|= REFRESH_MASTER; } + | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; } + | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }; + +opt_table_list: + /* empty */ {;} + | table_list {;}; + +reset: + RESET_SYM + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_RESET; lex->type=0; + } reset_options + {} + ; + +reset_options: + reset_options ',' reset_option + | reset_option; + +reset_option: + SLAVE { Lex->type|= REFRESH_SLAVE; } + | MASTER_SYM { Lex->type|= REFRESH_MASTER; } + | QUERY_SYM CACHE_SYM { Lex->type|= REFRESH_QUERY_CACHE;}; + +purge: + PURGE + { + LEX *lex=Lex; + lex->type=0; + } purge_options + {} + ; + +purge_options: + master_or_binary LOGS_SYM purge_option + ; + +purge_option: + TO_SYM TEXT_STRING_sys + { + Lex->sql_command = SQLCOM_PURGE; + Lex->to_log = $2.str; + } + | BEFORE_SYM expr + { + LEX *lex= Lex; + lex->value_list.empty(); + lex->value_list.push_front($2); + lex->sql_command= SQLCOM_PURGE_BEFORE; + } + ; + +/* kill threads */ + +kill: + KILL_SYM kill_option expr + { + LEX *lex=Lex; + lex->value_list.empty(); + lex->value_list.push_front($3); + lex->sql_command= SQLCOM_KILL; + }; + +kill_option: + /* empty */ { Lex->type= 0; } + | CONNECTION_SYM { Lex->type= 0; } + | QUERY_SYM { Lex->type= ONLY_KILL_QUERY; } + ; + +/* change database */ + +use: USE_SYM ident + { + LEX *lex=Lex; + lex->sql_command=SQLCOM_CHANGE_DB; + lex->select_lex.db= $2.str; + }; + +/* import, export of files */ + +load: LOAD DATA_SYM + { + LEX *lex=Lex; + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "LOAD DATA"); + YYABORT; + } + lex->fname_start= lex->ptr; + } + load_data + {} + | + LOAD TABLE_SYM table_ident FROM MASTER_SYM + { + LEX *lex=Lex; + WARN_DEPRECATED(yythd, "5.2", "LOAD TABLE FROM MASTER", + "MySQL Administrator (mysqldump, mysql)"); + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "LOAD TABLE"); + YYABORT; + } + lex->sql_command = SQLCOM_LOAD_MASTER_TABLE; + if (!Select->add_table_to_list(YYTHD, $3, NULL, TL_OPTION_UPDATING)) + YYABORT; + }; + +load_data: + load_data_lock opt_local INFILE TEXT_STRING_filesystem + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_LOAD; + lex->lock_option= $1; + lex->local_file= $2; + lex->duplicates= DUP_ERROR; + lex->ignore= 0; + if (!(lex->exchange= new sql_exchange($4.str, 0))) + YYABORT; + } + opt_duplicate INTO + { + LEX *lex=Lex; + lex->fname_end= lex->ptr; + } + TABLE_SYM table_ident + { + LEX *lex=Lex; + if (!Select->add_table_to_list(YYTHD, $10, NULL, TL_OPTION_UPDATING, + lex->lock_option)) + YYABORT; + lex->field_list.empty(); + lex->update_list.empty(); + lex->value_list.empty(); + } + opt_field_term opt_line_term opt_ignore_lines opt_field_or_var_spec + opt_load_data_set_spec + {} + | + 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: + /* empty */ { $$=0;} + | LOCAL_SYM { $$=1;}; + +load_data_lock: + /* empty */ { $$= YYTHD->update_lock_default; } + | CONCURRENT + { +#ifdef HAVE_QUERY_CACHE + /* + 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; + } + | LOW_PRIORITY { $$= TL_WRITE_LOW_PRIORITY; }; + + +opt_duplicate: + /* empty */ { Lex->duplicates=DUP_ERROR; } + | REPLACE { Lex->duplicates=DUP_REPLACE; } + | IGNORE_SYM { Lex->ignore= 1; }; + +opt_field_term: + /* empty */ + | COLUMNS field_term_list; + +field_term_list: + field_term_list field_term + | field_term; + +field_term: + TERMINATED BY text_string + { + DBUG_ASSERT(Lex->exchange != 0); + Lex->exchange->field_term= $3; + } + | OPTIONALLY ENCLOSED BY text_string + { + LEX *lex= Lex; + DBUG_ASSERT(lex->exchange != 0); + lex->exchange->enclosed= $4; + lex->exchange->opt_enclosed= 1; + } + | ENCLOSED BY text_string + { + DBUG_ASSERT(Lex->exchange != 0); + Lex->exchange->enclosed= $3; + } + | ESCAPED BY text_string + { + DBUG_ASSERT(Lex->exchange != 0); + Lex->exchange->escaped= $3; + }; + +opt_line_term: + /* empty */ + | LINES line_term_list; + +line_term_list: + line_term_list line_term + | line_term; + +line_term: + TERMINATED BY text_string + { + DBUG_ASSERT(Lex->exchange != 0); + Lex->exchange->line_term= $3; + } + | STARTING BY text_string + { + DBUG_ASSERT(Lex->exchange != 0); + Lex->exchange->line_start= $3; + }; + +opt_ignore_lines: + /* empty */ + | IGNORE_SYM NUM LINES + { + DBUG_ASSERT(Lex->exchange != 0); + Lex->exchange->skip_lines= atol($2.str); + }; + +opt_field_or_var_spec: + /* empty */ { } + | '(' fields_or_vars ')' { } + | '(' ')' { }; + +fields_or_vars: + fields_or_vars ',' field_or_var + { Lex->field_list.push_back($3); } + | field_or_var + { Lex->field_list.push_back($1); } + ; + +field_or_var: + simple_ident_nospvar {$$= $1;} + | '@' ident_or_text + { $$= new Item_user_var_as_out_param($2); } + ; + +opt_load_data_set_spec: + /* empty */ { } + | SET insert_update_list { }; + + +/* Common definitions */ + +text_literal: + TEXT_STRING_literal + { + THD *thd= YYTHD; + $$ = new Item_string($1.str,$1.length,thd->variables.collation_connection); + } + | NCHAR_STRING + { $$= new Item_string($1.str,$1.length,national_charset_info); } + | UNDERSCORE_CHARSET TEXT_STRING + { $$ = new Item_string($2.str,$2.length,Lex->underscore_charset); } + | text_literal TEXT_STRING_literal + { ((Item_string*) $1)->append($2.str,$2.length); } + ; + +text_string: + TEXT_STRING_literal + { $$= new (YYTHD->mem_root) String($1.str,$1.length,YYTHD->variables.collation_connection); } + | HEX_NUM + { + Item *tmp= new Item_hex_string($1.str, $1.length); + /* + it is OK only emulate fix_fields, because we need only + value of constant + */ + $$= tmp ? + tmp->quick_fix_field(), tmp->val_str((String*) 0) : + (String*) 0; + } + | BIN_NUM + { + Item *tmp= new Item_bin_string($1.str, $1.length); + /* + it is OK only emulate fix_fields, because we need only + value of constant + */ + $$= tmp ? tmp->quick_fix_field(), tmp->val_str((String*) 0) : + (String*) 0; + } + ; + +param_marker: + PARAM_MARKER + { + THD *thd=YYTHD; + LEX *lex= thd->lex; + 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)); + YYABORT; + } + } + ; + +signed_literal: + literal { $$ = $1; } + | '+' NUM_literal { $$ = $2; } + | '-' NUM_literal + { + $2->max_length++; + $$= $2->neg(); + } + ; + + +literal: + text_literal { $$ = $1; } + | NUM_literal { $$ = $1; } + | NULL_SYM { $$ = new Item_null(); + Lex->next_state=MY_LEX_OPERATOR_OR_IDENT;} + | FALSE_SYM { $$= new Item_int((char*) "FALSE",0,1); } + | TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); } + | HEX_NUM { $$ = new Item_hex_string($1.str, $1.length);} + | BIN_NUM { $$= new Item_bin_string($1.str, $1.length); } + | UNDERSCORE_CHARSET HEX_NUM + { + Item *tmp= new Item_hex_string($2.str, $2.length); + /* + it is OK only emulate fix_fieds, because we need only + value of constant + */ + String *str= tmp ? + tmp->quick_fix_field(), tmp->val_str((String*) 0) : + (String*) 0; + $$= new Item_string(str ? str->ptr() : "", + str ? str->length() : 0, + Lex->underscore_charset); + } + | UNDERSCORE_CHARSET BIN_NUM + { + Item *tmp= new Item_bin_string($2.str, $2.length); + /* + it is OK only emulate fix_fieds, because we need only + value of constant + */ + String *str= tmp ? + tmp->quick_fix_field(), tmp->val_str((String*) 0) : + (String*) 0; + $$= new Item_string(str ? str->ptr() : "", + str ? str->length() : 0, + Lex->charset); + } + | DATE_SYM text_literal { $$ = $2; } + | TIME_SYM text_literal { $$ = $2; } + | TIMESTAMP text_literal { $$ = $2; }; + +NUM_literal: + NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } + | LONG_NUM { int error; $$ = new Item_int($1.str, (longlong) my_strtoll10($1.str, NULL, &error), $1.length); } + | ULONGLONG_NUM { $$ = new Item_uint($1.str, $1.length); } + | DECIMAL_NUM + { + $$= new Item_decimal($1.str, $1.length, YYTHD->charset()); + if (YYTHD->net.report_error) + { + YYABORT; + } + } + | FLOAT_NUM + { + $$ = new Item_float($1.str, $1.length); + if (YYTHD->net.report_error) + { + YYABORT; + } + } + ; + +/********************************************************************** +** Creating different items. +**********************************************************************/ + +insert_ident: + simple_ident_nospvar { $$=$1; } + | table_wild { $$=$1; }; + +table_wild: + ident '.' '*' + { + SELECT_LEX *sel= Select; + $$ = new Item_field(Lex->current_context(), NullS, $1.str, "*"); + sel->with_wild++; + } + | ident '.' ident '.' '*' + { + SELECT_LEX *sel= Select; + $$ = new Item_field(Lex->current_context(), (YYTHD->client_capabilities & + CLIENT_NO_SCHEMA ? NullS : $1.str), + $3.str,"*"); + sel->with_wild++; + } + ; + +order_ident: + expr { $$=$1; }; + +simple_ident: + ident + { + sp_variable_t *spv; + LEX *lex = Lex; + sp_pcontext *spc = lex->spcont; + 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 - + lex->sphead->m_tmp_query); +#ifndef DBUG_OFF + if (splocal) + splocal->m_sp= lex->sphead; +#endif + $$ = (Item*) splocal; + lex->safe_to_cache_query=0; + } + else + { + SELECT_LEX *sel=Select; + $$= (sel->parsing_place != IN_HAVING || + sel->get_in_sum_expr() > 0) ? + (Item*) new Item_field(Lex->current_context(), NullS, NullS, $1.str) : + (Item*) new Item_ref(Lex->current_context(), NullS, NullS, $1.str); + } + } + | simple_ident_q { $$= $1; } + ; + +simple_ident_nospvar: + ident + { + SELECT_LEX *sel=Select; + $$= (sel->parsing_place != IN_HAVING || + sel->get_in_sum_expr() > 0) ? + (Item*) new Item_field(Lex->current_context(), NullS, NullS, $1.str) : + (Item*) new Item_ref(Lex->current_context(), NullS, NullS, $1.str); + } + | simple_ident_q { $$= $1; } + ; + +simple_ident_q: + ident '.' ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + + /* + FIXME This will work ok in simple_ident_nospvar case because + we can't meet simple_ident_nospvar in trigger now. But it + should be changed in future. + */ + if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER && + (!my_strcasecmp(system_charset_info, $1.str, "NEW") || + !my_strcasecmp(system_charset_info, $1.str, "OLD"))) + { + Item_trigger_field *trg_fld; + bool new_row= ($1.str[0]=='N' || $1.str[0]=='n'); + + if (lex->trg_chistics.event == TRG_EVENT_INSERT && + !new_row) + { + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "OLD", "on INSERT"); + YYABORT; + } + + if (lex->trg_chistics.event == TRG_EVENT_DELETE && + new_row) + { + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), "NEW", "on DELETE"); + YYABORT; + } + + DBUG_ASSERT(!new_row || + (lex->trg_chistics.event == TRG_EVENT_INSERT || + lex->trg_chistics.event == TRG_EVENT_UPDATE)); + const bool read_only= + !(new_row && lex->trg_chistics.action_time == TRG_ACTION_BEFORE); + if (!(trg_fld= new Item_trigger_field(Lex->current_context(), + new_row ? + Item_trigger_field::NEW_ROW: + Item_trigger_field::OLD_ROW, + $3.str, + SELECT_ACL, + read_only))) + YYABORT; + + /* + Let us add this item to list of all Item_trigger_field objects + in trigger. + */ + lex->trg_table_fields.link_in_list((byte *)trg_fld, + (byte**)&trg_fld->next_trg_field); + + $$= (Item *)trg_fld; + } + else + { + SELECT_LEX *sel= lex->current_select; + if (sel->no_table_names_allowed) + { + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $1.str, thd->where); + } + $$= (sel->parsing_place != IN_HAVING || + sel->get_in_sum_expr() > 0) ? + (Item*) new Item_field(Lex->current_context(), NullS, $1.str, $3.str) : + (Item*) new Item_ref(Lex->current_context(), NullS, $1.str, $3.str); + } + } + | '.' ident '.' ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + SELECT_LEX *sel= lex->current_select; + if (sel->no_table_names_allowed) + { + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $2.str, thd->where); + } + $$= (sel->parsing_place != IN_HAVING || + sel->get_in_sum_expr() > 0) ? + (Item*) new Item_field(Lex->current_context(), NullS, $2.str, $4.str) : + (Item*) new Item_ref(Lex->current_context(), NullS, $2.str, $4.str); + } + | ident '.' ident '.' ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + SELECT_LEX *sel= lex->current_select; + if (sel->no_table_names_allowed) + { + my_error(ER_TABLENAME_NOT_ALLOWED_HERE, + MYF(0), $3.str, thd->where); + } + $$= (sel->parsing_place != IN_HAVING || + sel->get_in_sum_expr() > 0) ? + (Item*) new Item_field(Lex->current_context(), + (YYTHD->client_capabilities & + CLIENT_NO_SCHEMA ? NullS : $1.str), + $3.str, $5.str) : + (Item*) new Item_ref(Lex->current_context(), + (YYTHD->client_capabilities & + CLIENT_NO_SCHEMA ? NullS : $1.str), + $3.str, $5.str); + }; + + +field_ident: + ident { $$=$1;} + | ident '.' ident '.' ident + { + TABLE_LIST *table= (TABLE_LIST*) Select->table_list.first; + if (my_strcasecmp(table_alias_charset, $1.str, table->db)) + { + my_error(ER_WRONG_DB_NAME, MYF(0), $1.str); + YYABORT; + } + if (my_strcasecmp(table_alias_charset, $3.str, + table->table_name)) + { + my_error(ER_WRONG_TABLE_NAME, MYF(0), $3.str); + YYABORT; + } + $$=$5; + } + | ident '.' ident + { + TABLE_LIST *table= (TABLE_LIST*) Select->table_list.first; + if (my_strcasecmp(table_alias_charset, $1.str, table->alias)) + { + my_error(ER_WRONG_TABLE_NAME, MYF(0), $1.str); + YYABORT; + } + $$=$3; + } + | '.' ident { $$=$2;} /* For Delphi */; + +table_ident: + ident { $$=new Table_ident($1); } + | ident '.' ident { $$=new Table_ident(YYTHD, $1,$3,0);} + | '.' ident { $$=new Table_ident($2);} /* For Delphi */ + ; + +table_ident_nodb: + ident { LEX_STRING db={(char*) any_db,3}; $$=new Table_ident(YYTHD, db,$1,0); } + ; + +IDENT_sys: + IDENT { $$= $1; } + | IDENT_QUOTED + { + THD *thd= YYTHD; + if (thd->charset_is_system_charset) + { + CHARSET_INFO *cs= system_charset_info; + int dummy_error; + uint wlen= cs->cset->well_formed_len(cs, $1.str, + $1.str+$1.length, + $1.length, &dummy_error); + if (wlen < $1.length) + { + my_error(ER_INVALID_CHARACTER_STRING, MYF(0), + cs->csname, $1.str + wlen); + YYABORT; + } + $$= $1; + } + else + thd->convert_string(&$$, system_charset_info, + $1.str, $1.length, thd->charset()); + } + ; + +TEXT_STRING_sys: + TEXT_STRING + { + THD *thd= YYTHD; + if (thd->charset_is_system_charset) + $$= $1; + else + thd->convert_string(&$$, system_charset_info, + $1.str, $1.length, thd->charset()); + } + ; + +TEXT_STRING_literal: + TEXT_STRING + { + THD *thd= YYTHD; + if (thd->charset_is_collation_connection) + $$= $1; + else + thd->convert_string(&$$, thd->variables.collation_connection, + $1.str, $1.length, thd->charset()); + } + ; + + +TEXT_STRING_filesystem: + TEXT_STRING + { + THD *thd= YYTHD; + if (thd->charset_is_character_set_filesystem) + $$= $1; + else + thd->convert_string(&$$, thd->variables.character_set_filesystem, + $1.str, $1.length, thd->charset()); + } + ; + +ident: + IDENT_sys { $$=$1; } + | READ_ONLY_SYM + { + THD *thd= YYTHD; + $$.str= thd->strmake("read_only",9); + $$.length= 9; + } + | keyword + { + THD *thd= YYTHD; + $$.str= thd->strmake($1.str, $1.length); + $$.length= $1.length; + } + ; + +label_ident: + IDENT_sys { $$=$1; } + | keyword_sp + { + THD *thd= YYTHD; + $$.str= thd->strmake($1.str, $1.length); + $$.length= $1.length; + } + ; + +ident_or_text: + ident { $$=$1;} + | TEXT_STRING_sys { $$=$1;} + | LEX_HOSTNAME { $$=$1;}; + +user: + ident_or_text + { + THD *thd= YYTHD; + if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) + YYABORT; + $$->user = $1; + $$->host.str= (char *) "%"; + $$->host.length= 1; + + if (check_string_length(&$$->user, + ER(ER_USERNAME), USERNAME_LENGTH)) + YYABORT; + } + | ident_or_text '@' ident_or_text + { + THD *thd= YYTHD; + if (!($$=(LEX_USER*) thd->alloc(sizeof(st_lex_user)))) + YYABORT; + $$->user = $1; $$->host=$3; + + if (check_string_length(&$$->user, + ER(ER_USERNAME), USERNAME_LENGTH) || + check_string_length(&$$->host, + ER(ER_HOSTNAME), HOSTNAME_LENGTH)) + YYABORT; + } + | CURRENT_USER optional_braces + { + if (!($$=(LEX_USER*) YYTHD->alloc(sizeof(st_lex_user)))) + YYABORT; + /* + empty LEX_USER means current_user and + will be handled in the get_current_user() function + later + */ + bzero($$, sizeof(LEX_USER)); + }; + +/* Keyword that we allow for identifiers (except SP labels) */ +keyword: + keyword_sp {} + | ASCII_SYM {} + | BACKUP_SYM {} + | BEGIN_SYM {} + | BYTE_SYM {} + | CACHE_SYM {} + | CHARSET {} + | CHECKSUM_SYM {} + | CLOSE_SYM {} + | COMMENT_SYM {} + | COMMIT_SYM {} + | CONTAINS_SYM {} + | DEALLOCATE_SYM {} + | DO_SYM {} + | END {} + | EXECUTE_SYM {} + | FLUSH_SYM {} + | HANDLER_SYM {} + | HELP_SYM {} + | HOST_SYM {} + | INSTALL_SYM {} + | LANGUAGE_SYM {} + | NO_SYM {} + | OPEN_SYM {} + | OWNER_SYM {} + | PARSER_SYM {} + | PARTITION_SYM {} + | PORT_SYM {} + | PREPARE_SYM {} + | REMOVE_SYM {} + | REPAIR {} + | RESET_SYM {} + | RESTORE_SYM {} + | ROLLBACK_SYM {} + | SAVEPOINT_SYM {} + | SECURITY_SYM {} + | SERVER_SYM {} + | SIGNED_SYM {} + | SOCKET_SYM {} + | SLAVE {} + | SONAME_SYM {} + | START_SYM {} + | STOP_SYM {} + | TRUNCATE_SYM {} + | UNICODE_SYM {} + | UNINSTALL_SYM {} + | USER {} + | WRAPPER_SYM {} + | XA_SYM {} + | UPGRADE_SYM {} + ; + +/* + * Keywords that we allow for labels in SPs. + * Anything that's the beginning of a statement or characteristics + * must be in keyword above, otherwise we get (harmful) shift/reduce + * conflicts. + */ +keyword_sp: + ACTION {} + | ADDDATE_SYM {} + | AFTER_SYM {} + | AGAINST {} + | AGGREGATE_SYM {} + | ALGORITHM_SYM {} + | ANY_SYM {} + | AT_SYM {} + | AUTHORS_SYM {} + | AUTO_INC {} + | AUTOEXTEND_SIZE_SYM {} + | AVG_ROW_LENGTH {} + | AVG_SYM {} + | BINLOG_SYM {} + | BIT_SYM {} + | BOOL_SYM {} + | BOOLEAN_SYM {} + | BTREE_SYM {} + | CASCADED {} + | CHAIN_SYM {} + | CHANGED {} + | CIPHER_SYM {} + | CLIENT_SYM {} + | COALESCE {} + | CODE_SYM {} + | COLLATION_SYM {} + | COLUMNS {} + | COMMITTED_SYM {} + | COMPACT_SYM {} + | COMPLETION_SYM {} + | COMPRESSED_SYM {} + | CONCURRENT {} + | CONSISTENT_SYM {} + | CONTRIBUTORS_SYM {} + | CUBE_SYM {} + | DATA_SYM {} + | DATAFILE_SYM {} + | DATETIME {} + | DATE_SYM {} + | DAY_SYM {} + | DEFINER_SYM {} + | DELAY_KEY_WRITE_SYM {} + | DES_KEY_FILE {} + | DIRECTORY_SYM {} + | DISABLE_SYM {} + | DISCARD {} + | DISK_SYM {} + | DUMPFILE {} + | DUPLICATE_SYM {} + | DYNAMIC_SYM {} + | ENDS_SYM {} + | ENUM {} + | ENGINE_SYM {} + | ENGINES_SYM {} + | ERRORS {} + | ESCAPE_SYM {} + | EVENT_SYM {} + | EVENTS_SYM {} + | EVERY_SYM {} + | EXPANSION_SYM {} + | EXTENDED_SYM {} + | EXTENT_SIZE_SYM {} + | FAST_SYM {} + | FOUND_SYM {} + | ENABLE_SYM {} + | FULL {} + | FILE_SYM {} + | FIRST_SYM {} + | FIXED_SYM {} + | FRAC_SECOND_SYM {} + | GEOMETRY_SYM {} + | GEOMETRYCOLLECTION {} + | GET_FORMAT {} + | GRANTS {} + | GLOBAL_SYM {} + | HASH_SYM {} + | HOSTS_SYM {} + | HOUR_SYM {} + | IDENTIFIED_SYM {} + | INVOKER_SYM {} + | IMPORT {} + | INDEXES {} + | INITIAL_SIZE_SYM {} + | ISOLATION {} + | ISSUER_SYM {} + | INNOBASE_SYM {} + | INSERT_METHOD {} + | KEY_BLOCK_SIZE {} + | LAST_SYM {} + | LEAVES {} + | LESS_SYM {} + | LEVEL_SYM {} + | LINESTRING {} + | LIST_SYM {} + | LOCAL_SYM {} + | LOCKS_SYM {} + | LOGFILE_SYM {} + | LOGS_SYM {} + | MAX_ROWS {} + | MASTER_SYM {} + | MASTER_HOST_SYM {} + | MASTER_PORT_SYM {} + | MASTER_LOG_FILE_SYM {} + | MASTER_LOG_POS_SYM {} + | MASTER_USER_SYM {} + | MASTER_PASSWORD_SYM {} + | MASTER_SERVER_ID_SYM {} + | MASTER_CONNECT_RETRY_SYM {} + | MASTER_SSL_SYM {} + | MASTER_SSL_CA_SYM {} + | MASTER_SSL_CAPATH_SYM {} + | MASTER_SSL_CERT_SYM {} + | MASTER_SSL_CIPHER_SYM {} + | MASTER_SSL_KEY_SYM {} + | MAX_CONNECTIONS_PER_HOUR {} + | MAX_QUERIES_PER_HOUR {} + | MAX_SIZE_SYM {} + | MAX_UPDATES_PER_HOUR {} + | MAX_USER_CONNECTIONS_SYM {} + | MAX_VALUE_SYM {} + | MEDIUM_SYM {} + | MEMORY_SYM {} + | MERGE_SYM {} + | MICROSECOND_SYM {} + | MIGRATE_SYM {} + | MINUTE_SYM {} + | MIN_ROWS {} + | MODIFY_SYM {} + | MODE_SYM {} + | MONTH_SYM {} + | MULTILINESTRING {} + | MULTIPOINT {} + | MULTIPOLYGON {} + | MUTEX_SYM {} + | NAME_SYM {} + | NAMES_SYM {} + | NATIONAL_SYM {} + | NCHAR_SYM {} + | NDBCLUSTER_SYM {} + | NEXT_SYM {} + | NEW_SYM {} + | NO_WAIT_SYM {} + | NODEGROUP_SYM {} + | NONE_SYM {} + | NVARCHAR_SYM {} + | OFFSET_SYM {} + | OLD_PASSWORD {} + | ONE_SHOT_SYM {} + | ONE_SYM {} + | PACK_KEYS_SYM {} + | PARTIAL {} + | PARTITIONING_SYM {} + | PARTITIONS_SYM {} + | PASSWORD {} + | PHASE_SYM {} + | PLUGIN_SYM {} + | PLUGINS_SYM {} + | POINT_SYM {} + | POLYGON {} + | PRESERVE_SYM {} + | PREV_SYM {} + | PRIVILEGES {} + | PROCESS {} + | PROCESSLIST_SYM {} + | QUARTER_SYM {} + | QUERY_SYM {} + | QUICK {} + | REBUILD_SYM {} + | RECOVER_SYM {} + | REDO_BUFFER_SIZE_SYM {} + | REDOFILE_SYM {} + | REDUNDANT_SYM {} + | RELAY_LOG_FILE_SYM {} + | RELAY_LOG_POS_SYM {} + | RELAY_THREAD {} + | RELOAD {} + | REORGANIZE_SYM {} + | REPEATABLE_SYM {} + | REPLICATION {} + | RESOURCES {} + | RESUME_SYM {} + | RETURNS_SYM {} + | ROLLUP_SYM {} + | ROUTINE_SYM {} + | ROWS_SYM {} + | ROW_FORMAT_SYM {} + | ROW_SYM {} + | RTREE_SYM {} + | SCHEDULE_SYM {} + | SECOND_SYM {} + | SERIAL_SYM {} + | SERIALIZABLE_SYM {} + | SESSION_SYM {} + | SIMPLE_SYM {} + | SHARE_SYM {} + | SHUTDOWN {} + | SNAPSHOT_SYM {} + | SOUNDS_SYM {} + | SQL_CACHE_SYM {} + | SQL_BUFFER_RESULT {} + | SQL_NO_CACHE_SYM {} + | SQL_THREAD {} + | STARTS_SYM {} + | STATUS_SYM {} + | STORAGE_SYM {} + | STRING_SYM {} + | SUBDATE_SYM {} + | SUBJECT_SYM {} + | SUBPARTITION_SYM {} + | SUBPARTITIONS_SYM {} + | SUPER_SYM {} + | SUSPEND_SYM {} + | TABLES {} + | TABLESPACE {} + | TEMPORARY {} + | TEMPTABLE_SYM {} + | TEXT_SYM {} + | THAN_SYM {} + | TRANSACTION_SYM {} + | TRIGGERS_SYM {} + | TIMESTAMP {} + | TIMESTAMP_ADD {} + | TIMESTAMP_DIFF {} + | TIME_SYM {} + | TYPES_SYM {} + | TYPE_SYM {} + | UDF_RETURNS_SYM {} + | FUNCTION_SYM {} + | UNCOMMITTED_SYM {} + | UNDEFINED_SYM {} + | UNDO_BUFFER_SIZE_SYM {} + | UNDOFILE_SYM {} + | UNKNOWN_SYM {} + | UNTIL_SYM {} + | USER {} + | USE_FRM {} + | VARIABLES {} + | VIEW_SYM {} + | VALUE_SYM {} + | WARNINGS {} + | WAIT_SYM {} + | WEEK_SYM {} + | WORK_SYM {} + | X509_SYM {} + | YEAR_SYM {} + ; + +/* Option functions */ + +set: + SET opt_option + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SET_OPTION; + mysql_init_select(lex); + lex->option_type=OPT_SESSION; + lex->var_list.empty(); + lex->one_shot_set= 0; + } + option_value_list + {} + ; + +opt_option: + /* empty */ {} + | OPTION {}; + +option_value_list: + option_type_value + | option_value_list ',' option_type_value; + +option_type_value: + { + if (Lex->sphead) + { + /* + If we are in SP we want have own LEX for each assignment. + This is mostly because it is hard for several sp_instr_set + and sp_instr_set_trigger instructions share one LEX. + (Well, it is theoretically possible but adds some extra + overhead on preparation for execution stage and IMO less + robust). + + QQ: May be we should simply prohibit group assignments in SP? + */ + LEX *lex; + Lex->sphead->reset_lex(YYTHD); + lex= Lex; + + /* Set new LEX as if we at start of set rule. */ + lex->sql_command= SQLCOM_SET_OPTION; + mysql_init_select(lex); + lex->option_type=OPT_SESSION; + lex->var_list.empty(); + lex->one_shot_set= 0; + lex->sphead->m_tmp_query= lex->tok_start; + } + } + ext_option_value + { + LEX *lex= Lex; + + if (lex->sphead) + { + sp_head *sp= lex->sphead; + + if (!lex->var_list.is_empty()) + { + /* + We have assignment to user or system variable or + option setting, so we should construct sp_instr_stmt + for it. + */ + LEX_STRING qbuff; + sp_instr_stmt *i; + + if (!(i= new sp_instr_stmt(sp->instructions(), lex->spcont, + lex))) + YYABORT; + + /* + Extract the query statement from the tokenizer. The + end is either lex->ptr, if there was no lookahead, + lex->tok_end otherwise. + */ + if (yychar == YYEMPTY) + qbuff.length= lex->ptr - sp->m_tmp_query; + else + qbuff.length= lex->tok_end - sp->m_tmp_query; + + if (!(qbuff.str= alloc_root(YYTHD->mem_root, qbuff.length + 5))) + YYABORT; + + strmake(strmake(qbuff.str, "SET ", 4), (char *)sp->m_tmp_query, + qbuff.length); + qbuff.length+= 4; + i->m_query= qbuff; + sp->add_instr(i); + } + lex->sphead->restore_lex(YYTHD); + } + }; + +option_type: + option_type2 {} + | GLOBAL_SYM { $$=OPT_GLOBAL; } + | LOCAL_SYM { $$=OPT_SESSION; } + | SESSION_SYM { $$=OPT_SESSION; } + ; + +option_type2: + /* empty */ { $$= OPT_DEFAULT; } + | ONE_SHOT_SYM { Lex->one_shot_set= 1; $$= OPT_SESSION; } + ; + +opt_var_type: + /* empty */ { $$=OPT_SESSION; } + | GLOBAL_SYM { $$=OPT_GLOBAL; } + | LOCAL_SYM { $$=OPT_SESSION; } + | SESSION_SYM { $$=OPT_SESSION; } + ; + +opt_var_ident_type: + /* empty */ { $$=OPT_DEFAULT; } + | GLOBAL_SYM '.' { $$=OPT_GLOBAL; } + | LOCAL_SYM '.' { $$=OPT_SESSION; } + | SESSION_SYM '.' { $$=OPT_SESSION; } + ; + +ext_option_value: + sys_option_value + | option_type2 option_value; + +sys_option_value: + option_type internal_variable_name equal set_expr_or_default + { + LEX *lex=Lex; + + if ($2.var == trg_new_row_fake_var) + { + /* We are in trigger and assigning value to field of new row */ + Item *it; + Item_trigger_field *trg_fld; + sp_instr_set_trigger_field *sp_fld; + LINT_INIT(sp_fld); + if ($1) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + if ($4) + it= $4; + else + { + /* QQ: Shouldn't this be field's default value ? */ + it= new Item_null(); + } + + DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE && + (lex->trg_chistics.event == TRG_EVENT_INSERT || + lex->trg_chistics.event == TRG_EVENT_UPDATE)); + if (!(trg_fld= new Item_trigger_field(Lex->current_context(), + Item_trigger_field::NEW_ROW, + $2.base_name.str, + UPDATE_ACL, FALSE)) || + !(sp_fld= new sp_instr_set_trigger_field(lex->sphead-> + instructions(), + lex->spcont, + trg_fld, + it, lex))) + YYABORT; + + /* + Let us add this item to list of all Item_trigger_field + objects in trigger. + */ + lex->trg_table_fields.link_in_list((byte *)trg_fld, + (byte **)&trg_fld->next_trg_field); + + lex->sphead->add_instr(sp_fld); + } + else if ($2.var) + { /* System variable */ + if ($1) + lex->option_type= $1; + lex->var_list.push_back(new set_var(lex->option_type, $2.var, + &$2.base_name, $4)); + } + else + { + /* An SP local variable */ + sp_pcontext *ctx= lex->spcont; + sp_variable_t *spv; + sp_instr_set *sp_set; + Item *it; + if ($1) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + + spv= ctx->find_variable(&$2.base_name); + + if ($4) + it= $4; + else if (spv->dflt) + it= spv->dflt; + else + it= new Item_null(); + sp_set= new sp_instr_set(lex->sphead->instructions(), ctx, + spv->offset, it, spv->type, lex, TRUE); + lex->sphead->add_instr(sp_set); + } + } + | option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types + { + LEX *lex=Lex; + lex->option_type= $1; + lex->var_list.push_back(new set_var(lex->option_type, + find_sys_var("tx_isolation"), + &null_lex_str, + new Item_int((int32) $5))); + } + ; + +option_value: + '@' ident_or_text equal expr + { + Lex->var_list.push_back(new set_var_user(new Item_func_set_user_var($2,$4))); + } + | '@' '@' opt_var_ident_type internal_variable_name equal set_expr_or_default + { + LEX *lex=Lex; + lex->var_list.push_back(new set_var($3, $4.var, &$4.base_name, $6)); + } + | charset old_or_new_charset_name_or_default + { + THD *thd= YYTHD; + LEX *lex= Lex; + $2= $2 ? $2: global_system_variables.character_set_client; + lex->var_list.push_back(new set_var_collation_client($2,thd->variables.collation_database,$2)); + } + | NAMES_SYM equal expr + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + LEX_STRING names; + + names.str= (char *)"names"; + names.length= 5; + if (spc && spc->find_variable(&names)) + my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str); + else + yyerror(ER(ER_SYNTAX_ERROR)); + + YYABORT; + } + | NAMES_SYM charset_name_or_default opt_collate + { + LEX *lex= Lex; + $2= $2 ? $2 : global_system_variables.character_set_client; + $3= $3 ? $3 : $2; + if (!my_charset_same($2,$3)) + { + my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0), + $3->name, $2->csname); + YYABORT; + } + lex->var_list.push_back(new set_var_collation_client($3,$3,$3)); + } + | PASSWORD equal text_or_password + { + THD *thd=YYTHD; + LEX_USER *user; + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + LEX_STRING pw; + + pw.str= (char *)"password"; + pw.length= 8; + if (spc && spc->find_variable(&pw)) + { + my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str); + YYABORT; + } + if (!(user=(LEX_USER*) thd->alloc(sizeof(LEX_USER)))) + YYABORT; + user->host=null_lex_str; + user->user.str=thd->security_ctx->priv_user; + thd->lex->var_list.push_back(new set_var_password(user, $3)); + } + | PASSWORD FOR_SYM user equal text_or_password + { + Lex->var_list.push_back(new set_var_password($3,$5)); + } + ; + +internal_variable_name: + ident + { + LEX *lex= Lex; + sp_pcontext *spc= lex->spcont; + sp_variable_t *spv; + + /* We have to lookup here since local vars can shadow sysvars */ + if (!spc || !(spv = spc->find_variable(&$1))) + { + /* Not an SP local variable */ + sys_var *tmp=find_sys_var($1.str, $1.length); + if (!tmp) + YYABORT; + $$.var= tmp; + $$.base_name= null_lex_str; + /* + If this is time_zone variable we should open time zone + describing tables + */ + if (tmp == &sys_time_zone && + lex->add_time_zone_tables_to_query_tables(YYTHD)) + YYABORT; + else if (spc && tmp == &sys_autocommit) + { + /* + We don't allow setting AUTOCOMMIT from a stored function + or trigger. + */ + lex->sphead->m_flags|= sp_head::HAS_SET_AUTOCOMMIT_STMT; + } + } + else + { + /* An SP local variable */ + $$.var= NULL; + $$.base_name= $1; + } + } + | ident '.' ident + { + LEX *lex= Lex; + if (check_reserved_words(&$1)) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + if (lex->sphead && lex->sphead->m_type == TYPE_ENUM_TRIGGER && + (!my_strcasecmp(system_charset_info, $1.str, "NEW") || + !my_strcasecmp(system_charset_info, $1.str, "OLD"))) + { + if ($1.str[0]=='O' || $1.str[0]=='o') + { + my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "OLD", ""); + YYABORT; + } + if (lex->trg_chistics.event == TRG_EVENT_DELETE) + { + my_error(ER_TRG_NO_SUCH_ROW_IN_TRG, MYF(0), + "NEW", "on DELETE"); + YYABORT; + } + if (lex->trg_chistics.action_time == TRG_ACTION_AFTER) + { + my_error(ER_TRG_CANT_CHANGE_ROW, MYF(0), "NEW", "after "); + YYABORT; + } + /* This special combination will denote field of NEW row */ + $$.var= trg_new_row_fake_var; + $$.base_name= $3; + } + else + { + sys_var *tmp=find_sys_var($3.str, $3.length); + if (!tmp) + YYABORT; + if (!tmp->is_struct()) + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); + $$.var= tmp; + $$.base_name= $1; + } + } + | DEFAULT '.' ident + { + sys_var *tmp=find_sys_var($3.str, $3.length); + if (!tmp) + YYABORT; + if (!tmp->is_struct()) + my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), $3.str); + $$.var= tmp; + $$.base_name.str= (char*) "default"; + $$.base_name.length= 7; + } + ; + +isolation_types: + READ_SYM UNCOMMITTED_SYM { $$= ISO_READ_UNCOMMITTED; } + | READ_SYM COMMITTED_SYM { $$= ISO_READ_COMMITTED; } + | REPEATABLE_SYM READ_SYM { $$= ISO_REPEATABLE_READ; } + | SERIALIZABLE_SYM { $$= ISO_SERIALIZABLE; } + ; + +text_or_password: + TEXT_STRING { $$=$1.str;} + | PASSWORD '(' TEXT_STRING ')' + { + $$= $3.length ? YYTHD->variables.old_passwords ? + Item_func_old_password::alloc(YYTHD, $3.str) : + Item_func_password::alloc(YYTHD, $3.str) : + $3.str; + } + | OLD_PASSWORD '(' TEXT_STRING ')' + { + $$= $3.length ? Item_func_old_password::alloc(YYTHD, $3.str) : + $3.str; + } + ; + + +set_expr_or_default: + expr { $$=$1; } + | DEFAULT { $$=0; } + | ON { $$=new Item_string("ON", 2, system_charset_info); } + | ALL { $$=new Item_string("ALL", 3, system_charset_info); } + | BINARY { $$=new Item_string("binary", 6, system_charset_info); } + ; + + +/* Lock function */ + +lock: + LOCK_SYM table_or_tables + { + LEX *lex= Lex; + + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "LOCK"); + YYABORT; + } + lex->sql_command= SQLCOM_LOCK_TABLES; + } + table_lock_list + {} + ; + +table_or_tables: + TABLE_SYM + | TABLES; + +table_lock_list: + table_lock + | table_lock_list ',' table_lock; + +table_lock: + table_ident opt_table_alias lock_option + { + if (!Select->add_table_to_list(YYTHD, $1, $2, 0, (thr_lock_type) $3)) + YYABORT; + } + ; + +lock_option: + READ_SYM { $$=TL_READ_NO_INSERT; } + | WRITE_SYM { $$=YYTHD->update_lock_default; } + | LOW_PRIORITY WRITE_SYM { $$=TL_WRITE_LOW_PRIORITY; } + | READ_SYM LOCAL_SYM { $$= TL_READ; } + ; + +unlock: + UNLOCK_SYM + { + LEX *lex= Lex; + + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "UNLOCK"); + YYABORT; + } + lex->sql_command= SQLCOM_UNLOCK_TABLES; + } + table_or_tables + {} + ; + + +/* +** Handler: direct access to ISAM functions +*/ + +handler: + HANDLER_SYM table_ident OPEN_SYM opt_table_alias + { + LEX *lex= Lex; + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER"); + YYABORT; + } + lex->sql_command = SQLCOM_HA_OPEN; + if (!lex->current_select->add_table_to_list(lex->thd, $2, $4, 0)) + YYABORT; + } + | HANDLER_SYM table_ident_nodb CLOSE_SYM + { + LEX *lex= Lex; + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER"); + YYABORT; + } + lex->sql_command = SQLCOM_HA_CLOSE; + if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0)) + YYABORT; + } + | HANDLER_SYM table_ident_nodb READ_SYM + { + LEX *lex=Lex; + if (lex->sphead) + { + my_error(ER_SP_BADSTATEMENT, MYF(0), "HANDLER"); + YYABORT; + } + lex->expr_allows_subselect= FALSE; + lex->sql_command = SQLCOM_HA_READ; + lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ + lex->current_select->select_limit= new Item_int((int32) 1); + lex->current_select->offset_limit= 0; + if (!lex->current_select->add_table_to_list(lex->thd, $2, 0, 0)) + YYABORT; + } + handler_read_or_scan where_clause opt_limit_clause + { + Lex->expr_allows_subselect= TRUE; + } + ; + +handler_read_or_scan: + handler_scan_function { Lex->ident= null_lex_str; } + | ident handler_rkey_function { Lex->ident= $1; } + ; + +handler_scan_function: + FIRST_SYM { Lex->ha_read_mode = RFIRST; } + | NEXT_SYM { Lex->ha_read_mode = RNEXT; } + ; + +handler_rkey_function: + FIRST_SYM { Lex->ha_read_mode = RFIRST; } + | NEXT_SYM { Lex->ha_read_mode = RNEXT; } + | PREV_SYM { Lex->ha_read_mode = RPREV; } + | LAST_SYM { Lex->ha_read_mode = RLAST; } + | handler_rkey_mode + { + LEX *lex=Lex; + lex->ha_read_mode = RKEY; + lex->ha_rkey_mode=$1; + if (!(lex->insert_list = new List_item)) + YYABORT; + } '(' values ')' { } + ; + +handler_rkey_mode: + EQ { $$=HA_READ_KEY_EXACT; } + | GE { $$=HA_READ_KEY_OR_NEXT; } + | LE { $$=HA_READ_KEY_OR_PREV; } + | GT_SYM { $$=HA_READ_AFTER_KEY; } + | LT { $$=HA_READ_BEFORE_KEY; } + ; + +/* GRANT / REVOKE */ + +revoke: + REVOKE clear_privileges revoke_command + {} + ; + +revoke_command: + grant_privileges ON opt_table grant_ident FROM grant_list + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_REVOKE; + lex->type= 0; + } + | + grant_privileges ON FUNCTION_SYM grant_ident FROM grant_list + { + LEX *lex= Lex; + if (lex->columns.elements) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->sql_command= SQLCOM_REVOKE; + lex->type= TYPE_ENUM_FUNCTION; + + } + | + grant_privileges ON PROCEDURE grant_ident FROM grant_list + { + LEX *lex= Lex; + if (lex->columns.elements) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->sql_command= SQLCOM_REVOKE; + lex->type= TYPE_ENUM_PROCEDURE; + } + | + ALL opt_privileges ',' GRANT OPTION FROM grant_list + { + Lex->sql_command = SQLCOM_REVOKE_ALL; + } + ; + +grant: + GRANT clear_privileges grant_command + {} + ; + +grant_command: + grant_privileges ON opt_table grant_ident TO_SYM grant_list + require_clause grant_options + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_GRANT; + lex->type= 0; + } + | + grant_privileges ON FUNCTION_SYM grant_ident TO_SYM grant_list + require_clause grant_options + { + LEX *lex= Lex; + if (lex->columns.elements) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->sql_command= SQLCOM_GRANT; + lex->type= TYPE_ENUM_FUNCTION; + } + | + grant_privileges ON PROCEDURE grant_ident TO_SYM grant_list + require_clause grant_options + { + LEX *lex= Lex; + if (lex->columns.elements) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + lex->sql_command= SQLCOM_GRANT; + lex->type= TYPE_ENUM_PROCEDURE; + } + ; + +opt_table: + /* Empty */ + | TABLE_SYM ; + +grant_privileges: + object_privilege_list { } + | ALL opt_privileges + { + Lex->all_privileges= 1; + Lex->grant= GLOBAL_ACLS; + } + ; + +opt_privileges: + /* empty */ + | PRIVILEGES + ; + +object_privilege_list: + object_privilege + | object_privilege_list ',' object_privilege; + +object_privilege: + SELECT_SYM { Lex->which_columns = SELECT_ACL;} opt_column_list {} + | INSERT { Lex->which_columns = INSERT_ACL;} opt_column_list {} + | UPDATE_SYM { Lex->which_columns = UPDATE_ACL; } opt_column_list {} + | REFERENCES { Lex->which_columns = REFERENCES_ACL;} opt_column_list {} + | DELETE_SYM { Lex->grant |= DELETE_ACL;} + | USAGE {} + | INDEX_SYM { Lex->grant |= INDEX_ACL;} + | ALTER { Lex->grant |= ALTER_ACL;} + | CREATE { Lex->grant |= CREATE_ACL;} + | DROP { Lex->grant |= DROP_ACL;} + | EXECUTE_SYM { Lex->grant |= EXECUTE_ACL;} + | RELOAD { Lex->grant |= RELOAD_ACL;} + | SHUTDOWN { Lex->grant |= SHUTDOWN_ACL;} + | PROCESS { Lex->grant |= PROCESS_ACL;} + | FILE_SYM { Lex->grant |= FILE_ACL;} + | GRANT OPTION { Lex->grant |= GRANT_ACL;} + | SHOW DATABASES { Lex->grant |= SHOW_DB_ACL;} + | SUPER_SYM { Lex->grant |= SUPER_ACL;} + | CREATE TEMPORARY TABLES { Lex->grant |= CREATE_TMP_ACL;} + | LOCK_SYM TABLES { Lex->grant |= LOCK_TABLES_ACL; } + | REPLICATION SLAVE { Lex->grant |= REPL_SLAVE_ACL; } + | REPLICATION CLIENT_SYM { Lex->grant |= REPL_CLIENT_ACL; } + | CREATE VIEW_SYM { Lex->grant |= CREATE_VIEW_ACL; } + | SHOW VIEW_SYM { Lex->grant |= SHOW_VIEW_ACL; } + | CREATE ROUTINE_SYM { Lex->grant |= CREATE_PROC_ACL; } + | ALTER ROUTINE_SYM { Lex->grant |= ALTER_PROC_ACL; } + | CREATE USER { Lex->grant |= CREATE_USER_ACL; } + | EVENT_SYM { Lex->grant |= EVENT_ACL;} + | TRIGGER_SYM { Lex->grant |= TRIGGER_ACL; } + ; + + +opt_and: + /* empty */ {} + | AND_SYM {} + ; + +require_list: + require_list_element opt_and require_list + | require_list_element + ; + +require_list_element: + SUBJECT_SYM TEXT_STRING + { + LEX *lex=Lex; + if (lex->x509_subject) + { + my_error(ER_DUP_ARGUMENT, MYF(0), "SUBJECT"); + YYABORT; + } + lex->x509_subject=$2.str; + } + | ISSUER_SYM TEXT_STRING + { + LEX *lex=Lex; + if (lex->x509_issuer) + { + my_error(ER_DUP_ARGUMENT, MYF(0), "ISSUER"); + YYABORT; + } + lex->x509_issuer=$2.str; + } + | CIPHER_SYM TEXT_STRING + { + LEX *lex=Lex; + if (lex->ssl_cipher) + { + my_error(ER_DUP_ARGUMENT, MYF(0), "CIPHER"); + YYABORT; + } + lex->ssl_cipher=$2.str; + } + ; + +grant_ident: + '*' + { + LEX *lex= Lex; + THD *thd= lex->thd; + uint dummy; + if (thd->copy_db_to(&lex->current_select->db, &dummy)) + YYABORT; + if (lex->grant == GLOBAL_ACLS) + lex->grant = DB_ACLS & ~GRANT_ACL; + else if (lex->columns.elements) + { + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); + YYABORT; + } + } + | ident '.' '*' + { + LEX *lex= Lex; + lex->current_select->db = $1.str; + if (lex->grant == GLOBAL_ACLS) + lex->grant = DB_ACLS & ~GRANT_ACL; + else if (lex->columns.elements) + { + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); + YYABORT; + } + } + | '*' '.' '*' + { + LEX *lex= Lex; + lex->current_select->db = NULL; + if (lex->grant == GLOBAL_ACLS) + lex->grant= GLOBAL_ACLS & ~GRANT_ACL; + else if (lex->columns.elements) + { + my_message(ER_ILLEGAL_GRANT_FOR_TABLE, + ER(ER_ILLEGAL_GRANT_FOR_TABLE), MYF(0)); + YYABORT; + } + } + | table_ident + { + LEX *lex=Lex; + if (!lex->current_select->add_table_to_list(lex->thd, $1,NULL,0)) + YYABORT; + if (lex->grant == GLOBAL_ACLS) + lex->grant = TABLE_ACLS & ~GRANT_ACL; + } + ; + + +user_list: + user { if (Lex->users_list.push_back($1)) YYABORT;} + | user_list ',' user + { + if (Lex->users_list.push_back($3)) + YYABORT; + } + ; + + +grant_list: + grant_user { if (Lex->users_list.push_back($1)) YYABORT;} + | grant_list ',' grant_user + { + if (Lex->users_list.push_back($3)) + YYABORT; + } + ; + + +grant_user: + user IDENTIFIED_SYM BY TEXT_STRING + { + $$=$1; $1->password=$4; + if ($4.length) + { + if (YYTHD->variables.old_passwords) + { + char *buff= + (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1); + if (buff) + make_scrambled_password_323(buff, $4.str); + $1->password.str= buff; + $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; + } + else + { + char *buff= + (char *) YYTHD->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1); + if (buff) + make_scrambled_password(buff, $4.str); + $1->password.str= buff; + $1->password.length= SCRAMBLED_PASSWORD_CHAR_LENGTH; + } + } + } + | user IDENTIFIED_SYM BY PASSWORD TEXT_STRING + { $$= $1; $1->password= $5; } + | user + { $$= $1; $1->password= null_lex_str; } + ; + + +opt_column_list: + /* empty */ + { + LEX *lex=Lex; + lex->grant |= lex->which_columns; + } + | '(' column_list ')'; + +column_list: + column_list ',' column_list_id + | column_list_id; + +column_list_id: + ident + { + String *new_str = new (YYTHD->mem_root) String((const char*) $1.str,$1.length,system_charset_info); + List_iterator <LEX_COLUMN> iter(Lex->columns); + class LEX_COLUMN *point; + LEX *lex=Lex; + while ((point=iter++)) + { + if (!my_strcasecmp(system_charset_info, + point->column.ptr(), new_str->ptr())) + break; + } + lex->grant_tot_col|= lex->which_columns; + if (point) + point->rights |= lex->which_columns; + else + lex->columns.push_back(new LEX_COLUMN (*new_str,lex->which_columns)); + } + ; + + +require_clause: /* empty */ + | REQUIRE_SYM require_list + { + Lex->ssl_type=SSL_TYPE_SPECIFIED; + } + | REQUIRE_SYM SSL_SYM + { + Lex->ssl_type=SSL_TYPE_ANY; + } + | REQUIRE_SYM X509_SYM + { + Lex->ssl_type=SSL_TYPE_X509; + } + | REQUIRE_SYM NONE_SYM + { + Lex->ssl_type=SSL_TYPE_NONE; + } + ; + +grant_options: + /* empty */ {} + | WITH grant_option_list; + +grant_option_list: + grant_option_list grant_option {} + | grant_option {} + ; + +grant_option: + GRANT OPTION { Lex->grant |= GRANT_ACL;} + | MAX_QUERIES_PER_HOUR ulong_num + { + LEX *lex=Lex; + lex->mqh.questions=$2; + lex->mqh.specified_limits|= USER_RESOURCES::QUERIES_PER_HOUR; + } + | MAX_UPDATES_PER_HOUR ulong_num + { + LEX *lex=Lex; + lex->mqh.updates=$2; + lex->mqh.specified_limits|= USER_RESOURCES::UPDATES_PER_HOUR; + } + | MAX_CONNECTIONS_PER_HOUR ulong_num + { + LEX *lex=Lex; + lex->mqh.conn_per_hour= $2; + lex->mqh.specified_limits|= USER_RESOURCES::CONNECTIONS_PER_HOUR; + } + | MAX_USER_CONNECTIONS_SYM ulong_num + { + LEX *lex=Lex; + lex->mqh.user_conn= $2; + lex->mqh.specified_limits|= USER_RESOURCES::USER_CONNECTIONS; + } + ; + +begin: + BEGIN_SYM + { + LEX *lex=Lex; + lex->sql_command = SQLCOM_BEGIN; + lex->start_transaction_opt= 0; + } + opt_work {} + ; + +opt_work: + /* empty */ {} + | WORK_SYM {} + ; + +opt_chain: + /* empty */ { $$= (YYTHD->variables.completion_type == 1); } + | AND_SYM NO_SYM CHAIN_SYM { $$=0; } + | AND_SYM CHAIN_SYM { $$=1; } + ; + +opt_release: + /* empty */ { $$= (YYTHD->variables.completion_type == 2); } + | RELEASE_SYM { $$=1; } + | NO_SYM RELEASE_SYM { $$=0; } + ; + +opt_savepoint: + /* empty */ {} + | SAVEPOINT_SYM {} + ; + +commit: + COMMIT_SYM opt_work opt_chain opt_release + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_COMMIT; + lex->tx_chain= $3; + lex->tx_release= $4; + } + ; + +rollback: + ROLLBACK_SYM opt_work opt_chain opt_release + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_ROLLBACK; + lex->tx_chain= $3; + lex->tx_release= $4; + } + | ROLLBACK_SYM opt_work + TO_SYM opt_savepoint ident + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_ROLLBACK_TO_SAVEPOINT; + lex->ident= $5; + } + ; + +savepoint: + SAVEPOINT_SYM ident + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_SAVEPOINT; + lex->ident= $2; + } + ; + +release: + RELEASE_SYM SAVEPOINT_SYM ident + { + LEX *lex=Lex; + lex->sql_command= SQLCOM_RELEASE_SAVEPOINT; + lex->ident= $3; + } + ; + +/* + UNIONS : glue selects together +*/ + + +union_clause: + /* empty */ {} + | union_list + ; + +union_list: + UNION_SYM union_option + { + LEX *lex=Lex; + if (lex->exchange) + { + /* Only the last SELECT can have INTO...... */ + my_error(ER_WRONG_USAGE, MYF(0), "UNION", "INTO"); + YYABORT; + } + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + { + yyerror(ER(ER_SYNTAX_ERROR)); + YYABORT; + } + /* This counter shouldn't be incremented for UNION parts */ + Lex->nest_level--; + if (mysql_new_select(lex, 0)) + YYABORT; + mysql_init_select(lex); + lex->current_select->linkage=UNION_TYPE; + if ($2) /* UNION DISTINCT - remember position */ + lex->current_select->master_unit()->union_distinct= + lex->current_select; + } + select_init + { + /* + Remove from the name resolution context stack the context of the + last select in the union. + */ + Lex->pop_context(); + } + ; + +union_opt: + /* Empty */ { $$= 0; } + | union_list { $$= 1; } + | union_order_or_limit { $$= 1; } + ; + +union_order_or_limit: + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE); + SELECT_LEX *sel= lex->current_select; + SELECT_LEX_UNIT *unit= sel->master_unit(); + SELECT_LEX *fake= unit->fake_select_lex; + if (fake) + { + unit->global_parameters= fake; + fake->no_table_names_allowed= 1; + lex->current_select= fake; + } + thd->where= "global ORDER clause"; + } + order_or_limit + { + THD *thd= YYTHD; + thd->lex->current_select->no_table_names_allowed= 0; + thd->where= ""; + } + ; + +order_or_limit: + order_clause opt_limit_clause_init + | limit_clause + ; + +union_option: + /* empty */ { $$=1; } + | DISTINCT { $$=1; } + | ALL { $$=0; } + ; + +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; }; + +subselect_init: + select_init2 + { + $$= Lex->current_select->master_unit()->first_select(); + }; + +subselect_start: + { + LEX *lex=Lex; + if (!lex->expr_allows_subselect) + { + 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(); + SELECT_LEX *child= lex->current_select; + lex->current_select = lex->current_select->return_after_parsing(); + lex->nest_level--; + lex->current_select->n_child_sum_items += child->n_sum_items; + }; + +/************************************************************************** + + CREATE VIEW | TRIGGER | PROCEDURE statements. + +**************************************************************************/ + +view_or_trigger_or_sp_or_event: + definer view_or_trigger_or_sp_or_event_tail + {} + | view_replace_or_algorithm definer view_tail + {} + ; + +view_or_trigger_or_sp_or_event_tail: + view_tail + {} + | trigger_tail + {} + | sp_tail + {} + | event_tail + {} + ; + +/************************************************************************** + + DEFINER clause support. + +**************************************************************************/ + +definer: + /* empty */ + { + /* + We have to distinguish missing DEFINER-clause from case when + CURRENT_USER specified as definer explicitly in order to properly + handle CREATE TRIGGER statements which come to replication thread + from older master servers (i.e. to create non-suid trigger in this + case). + */ + YYTHD->lex->definer= 0; + } + | DEFINER_SYM EQ user + { + YYTHD->lex->definer= get_current_user(YYTHD, $3); + } + ; + +/************************************************************************** + + CREATE VIEW statement parts. + +**************************************************************************/ + +view_replace_or_algorithm: + view_replace + {} + | view_replace view_algorithm + {} + | view_algorithm + {} + ; + +view_replace: + OR_SYM REPLACE + { Lex->create_view_mode= VIEW_CREATE_OR_REPLACE; } + ; + +view_algorithm: + ALGORITHM_SYM EQ UNDEFINED_SYM + { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; } + | ALGORITHM_SYM EQ MERGE_SYM + { Lex->create_view_algorithm= VIEW_ALGORITHM_MERGE; } + | ALGORITHM_SYM EQ TEMPTABLE_SYM + { Lex->create_view_algorithm= VIEW_ALGORITHM_TMPTABLE; } + ; + +view_algorithm_opt: + /* empty */ + { Lex->create_view_algorithm= VIEW_ALGORITHM_UNDEFINED; } + | view_algorithm + {} + ; + +view_suid: + /* empty */ + { Lex->create_view_suid= VIEW_SUID_DEFAULT; } + | SQL_SYM SECURITY_SYM DEFINER_SYM + { Lex->create_view_suid= VIEW_SUID_DEFINER; } + | SQL_SYM SECURITY_SYM INVOKER_SYM + { Lex->create_view_suid= VIEW_SUID_INVOKER; } + ; + +view_tail: + view_suid VIEW_SYM table_ident + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + lex->sql_command= SQLCOM_CREATE_VIEW; + /* first table in list is target VIEW name */ + if (!lex->select_lex.add_table_to_list(thd, $3, NULL, TL_OPTION_UPDATING)) + YYABORT; + } + view_list_opt AS view_select view_check_option + {} + ; + +view_list_opt: + /* empty */ + {} + | '(' view_list ')' + ; + +view_list: + ident + { + Lex->view_list.push_back((LEX_STRING*) + sql_memdup(&$1, sizeof(LEX_STRING))); + } + | view_list ',' ident + { + Lex->view_list.push_back((LEX_STRING*) + sql_memdup(&$3, sizeof(LEX_STRING))); + } + ; + +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; + LEX *lex= thd->lex; + char *stmt_beg= (lex->sphead ? + (char *)lex->sphead->m_tmp_query : + thd->query); + lex->create_view_select_start= $2 - stmt_beg; + } + | '(' remember_name select_paren ')' union_opt + { + THD *thd=YYTHD; + LEX *lex= thd->lex; + char *stmt_beg= (lex->sphead ? + (char *)lex->sphead->m_tmp_query : + thd->query); + lex->create_view_select_start= $2 - stmt_beg; + } + ; + +view_check_option: + /* empty */ + { Lex->create_view_check= VIEW_CHECK_NONE; } + | WITH CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_CASCADED; } + | WITH CASCADED CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_CASCADED; } + | WITH LOCAL_SYM CHECK_SYM OPTION + { Lex->create_view_check= VIEW_CHECK_LOCAL; } + ; + +/************************************************************************** + + CREATE TRIGGER statement parts. + +**************************************************************************/ + +trigger_tail: + TRIGGER_SYM remember_name sp_name trg_action_time trg_event + ON remember_name table_ident FOR_SYM remember_name EACH_SYM ROW_SYM + { + LEX *lex= Lex; + sp_head *sp; + + if (lex->sphead) + { + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "TRIGGER"); + YYABORT; + } + + if (!(sp= new sp_head())) + YYABORT; + sp->reset_thd_mem_root(YYTHD); + sp->init(lex); + sp->init_sp_name(YYTHD, $3); + lex->stmt_definition_begin= $2; + lex->ident.str= $7; + lex->ident.length= $10 - $7; + + sp->m_type= TYPE_ENUM_TRIGGER; + lex->sphead= sp; + lex->spname= $3; + /* + We have to turn of CLIENT_MULTI_QUERIES while parsing a + stored procedure, otherwise yylex will chop it into pieces + at each ';'. + */ + $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= ~CLIENT_MULTI_QUERIES; + + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + lex->sphead->m_chistics= &lex->sp_chistics; + lex->sphead->m_body_begin= lex->ptr; + while (my_isspace(system_charset_info, lex->sphead->m_body_begin[0])) + ++lex->sphead->m_body_begin; + } + sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + lex->sql_command= SQLCOM_CREATE_TRIGGER; + sp->init_strings(YYTHD, lex); + /* Restore flag if it was cleared above */ + + YYTHD->client_capabilities |= $<ulong_num>13; + sp->restore_thd_mem_root(YYTHD); + + if (sp->is_not_allowed_in_function("trigger")) + YYABORT; + + /* + We have to do it after parsing trigger body, because some of + sp_proc_stmt alternatives are not saving/restoring LEX, so + lex->query_tables can be wiped out. + */ + if (!lex->select_lex.add_table_to_list(YYTHD, $8, + (LEX_STRING*) 0, + TL_OPTION_UPDATING, + TL_IGNORE)) + YYABORT; + } + ; + +/************************************************************************** + + CREATE FUNCTION | PROCEDURE statements parts. + +**************************************************************************/ + +sp_tail: + udf_func_type remember_name FUNCTION_SYM sp_name + { + LEX *lex=Lex; + lex->udf.type= $1; + lex->stmt_definition_begin= $2; + lex->spname= $4; + } + create_function_tail + {} + | PROCEDURE remember_name sp_name + { + LEX *lex= Lex; + sp_head *sp; + + if (lex->sphead) + { + my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE"); + YYABORT; + } + + lex->stmt_definition_begin= $2; + + /* Order is important here: new - reset - init */ + sp= new sp_head(); + sp->reset_thd_mem_root(YYTHD); + sp->init(lex); + sp->init_sp_name(YYTHD, $3); + + sp->m_type= TYPE_ENUM_PROCEDURE; + lex->sphead= sp; + /* + * We have to turn of CLIENT_MULTI_QUERIES while parsing a + * stored procedure, otherwise yylex will chop it into pieces + * at each ';'. + */ + $<ulong_num>$= YYTHD->client_capabilities & CLIENT_MULTI_QUERIES; + YYTHD->client_capabilities &= (~CLIENT_MULTI_QUERIES); + } + '(' + { + LEX *lex= Lex; + + lex->sphead->m_param_begin= lex->tok_start+1; + } + sp_pdparam_list + ')' + { + LEX *lex= Lex; + + lex->sphead->m_param_end= lex->tok_start; + bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics)); + } + sp_c_chistics + { + LEX *lex= Lex; + + lex->sphead->m_chistics= &lex->sp_chistics; + lex->sphead->m_body_begin= lex->tok_start; + } + sp_proc_stmt + { + LEX *lex= Lex; + sp_head *sp= lex->sphead; + + sp->init_strings(YYTHD, lex); + lex->sql_command= SQLCOM_CREATE_PROCEDURE; + /* + Restore flag if it was cleared above + Be careful with counting. the block where we save the value + is $4. + */ + YYTHD->client_capabilities |= $<ulong_num>4; + sp->restore_thd_mem_root(YYTHD); + } + ; + +/*************************************************************************/ + +xa: XA_SYM begin_or_start xid opt_join_or_resume + { + Lex->sql_command = SQLCOM_XA_START; + } + | XA_SYM END xid opt_suspend + { + Lex->sql_command = SQLCOM_XA_END; + } + | XA_SYM PREPARE_SYM xid + { + Lex->sql_command = SQLCOM_XA_PREPARE; + } + | XA_SYM COMMIT_SYM xid opt_one_phase + { + Lex->sql_command = SQLCOM_XA_COMMIT; + } + | XA_SYM ROLLBACK_SYM xid + { + Lex->sql_command = SQLCOM_XA_ROLLBACK; + } + | XA_SYM RECOVER_SYM + { + Lex->sql_command = SQLCOM_XA_RECOVER; + } + ; + +xid: text_string + { + YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE); + if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID)))) + YYABORT; + Lex->xid->set(1L, $1->ptr(), $1->length(), 0, 0); + } + | text_string ',' text_string + { + YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); + if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID)))) + YYABORT; + Lex->xid->set(1L, $1->ptr(), $1->length(), $3->ptr(), $3->length()); + } + | text_string ',' text_string ',' ulong_num + { + YYERROR_UNLESS($1->length() <= MAXGTRIDSIZE && $3->length() <= MAXBQUALSIZE); + if (!(Lex->xid=(XID *)YYTHD->alloc(sizeof(XID)))) + YYABORT; + Lex->xid->set($5, $1->ptr(), $1->length(), $3->ptr(), $3->length()); + } + ; + +begin_or_start: BEGIN_SYM {} + | START_SYM {} + ; + +opt_join_or_resume: + /* nothing */ { Lex->xa_opt=XA_NONE; } + | JOIN_SYM { Lex->xa_opt=XA_JOIN; } + | RESUME_SYM { Lex->xa_opt=XA_RESUME; } + ; + +opt_one_phase: + /* nothing */ { Lex->xa_opt=XA_NONE; } + | ONE_SYM PHASE_SYM { Lex->xa_opt=XA_ONE_PHASE; } + ; + +opt_suspend: + /* nothing */ { Lex->xa_opt=XA_NONE; } + | SUSPEND_SYM { Lex->xa_opt=XA_SUSPEND; } + opt_migrate + ; + +opt_migrate: + /* nothing */ { } + | FOR_SYM MIGRATE_SYM { Lex->xa_opt=XA_FOR_MIGRATE; } + ; + +install: + INSTALL_SYM PLUGIN_SYM ident SONAME_SYM TEXT_STRING_sys + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_INSTALL_PLUGIN; + lex->comment= $3; + lex->ident= $5; + }; + +uninstall: + UNINSTALL_SYM PLUGIN_SYM ident + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_UNINSTALL_PLUGIN; + lex->comment= $3; + }; diff --git a/sql/stacktrace.c b/sql/stacktrace.c index 77e7707592d..d8e9b7fd883 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/stacktrace.h b/sql/stacktrace.h index 527d10d70a2..f5c92e54e1c 100644 --- a/sql/stacktrace.h +++ b/sql/stacktrace.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/strfunc.cc b/sql/strfunc.cc index 2d2530eb876..71b52a5145d 100644 --- a/sql/strfunc.cc +++ b/sql/strfunc.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/structs.h b/sql/structs.h index 83ae6cac032..377d337dcfa 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/table.cc b/sql/table.cc index 52074ee1e7c..e4e087b0e64 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -877,7 +876,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, field_type=(enum_field_types) (uint) strpos[13]; /* charset and geometry_type share the same byte in frm */ - if (field_type == FIELD_TYPE_GEOMETRY) + if (field_type == MYSQL_TYPE_GEOMETRY) { #ifdef HAVE_SPATIAL geom_type= (Field::geometry_type) strpos[14]; @@ -952,7 +951,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } #ifndef TO_BE_DELETED_ON_PRODUCTION - if (field_type == FIELD_TYPE_NEWDECIMAL && !share->mysql_version) + if (field_type == MYSQL_TYPE_NEWDECIMAL && !share->mysql_version) { /* Fix pack length of old decimal values from 5.0.3 -> 5.0.4 @@ -999,7 +998,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, reg_field->field_index= i; reg_field->comment=comment; - if (field_type == FIELD_TYPE_BIT && !f_bit_as_char(pack_flag)) + if (field_type == MYSQL_TYPE_BIT && !f_bit_as_char(pack_flag)) { if ((null_bit_pos+= field_length & 7) > 7) { @@ -1089,10 +1088,10 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, keyinfo->extra_length+= HA_KEY_NULL_LENGTH; keyinfo->key_length+= HA_KEY_NULL_LENGTH; } - if (field->type() == FIELD_TYPE_BLOB || + if (field->type() == MYSQL_TYPE_BLOB || field->real_type() == MYSQL_TYPE_VARCHAR) { - if (field->type() == FIELD_TYPE_BLOB) + if (field->type() == MYSQL_TYPE_BLOB) key_part->key_part_flag|= HA_BLOB_PART; else key_part->key_part_flag|= HA_VAR_LENGTH_PART; @@ -1144,7 +1143,7 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, if (field->key_length() != key_part->length) { #ifndef TO_BE_DELETED_ON_PRODUCTION - if (field->type() == FIELD_TYPE_NEWDECIMAL) + if (field->type() == MYSQL_TYPE_NEWDECIMAL) { /* Fix a fatal error in decimal key handling that causes crashes diff --git a/sql/table.h b/sql/table.h index 13666c82f4b..80add0e0b91 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index 3a9ca397bba..392db9224c3 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2001, 2003-2004 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/time.cc b/sql/time.cc index 85096cd27ac..4854206b1c8 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/tzfile.h b/sql/tzfile.h index 623cddc1f12..1a57c0c5f69 100644 --- a/sql/tzfile.h +++ b/sql/tzfile.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/tztime.cc b/sql/tztime.cc index c44a907c07b..fe91aa71272 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/tztime.h b/sql/tztime.h index 95184c9b3d1..248a638074b 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/udf_example.c b/sql/udf_example.c index bbab47e253d..2bb4fe92d2f 100644 --- a/sql/udf_example.c +++ b/sql/udf_example.c @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -1087,7 +1086,7 @@ my_bool is_const_init(UDF_INIT *initid, UDF_ARGS *args, char *message) strmov(message, "IS_CONST accepts only one argument"); return 1; } - initid->ptr= (char*)((args->args[0] != NULL) ? 1 : 0); + initid->ptr= (char*)((args->args[0] != NULL) ? 1UL : 0); return 0; } diff --git a/sql/uniques.cc b/sql/uniques.cc index c7bdbdeb207..9eb827f62a3 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -2,8 +2,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of diff --git a/sql/unireg.cc b/sql/unireg.cc index 4514f969913..2699cafa7b7 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -584,7 +583,7 @@ static bool pack_header(uchar *forminfo, enum legacy_db_type table_type, We mark first TIMESTAMP field with NOW() in DEFAULT or ON UPDATE as auto-update field. */ - if (field->sql_type == FIELD_TYPE_TIMESTAMP && + if (field->sql_type == MYSQL_TYPE_TIMESTAMP && MTYP_TYPENR(field->unireg_check) != Field::NONE && !time_stamp_pos) time_stamp_pos= (uint) field->offset+ (uint) data_offset + 1; @@ -743,7 +742,7 @@ static bool pack_fields(File file, List<create_field> &create_fields, int2store(buff+10,field->unireg_check); buff[12]= (uchar) field->interval_id; buff[13]= (uchar) field->sql_type; - if (field->sql_type == FIELD_TYPE_GEOMETRY) + if (field->sql_type == MYSQL_TYPE_GEOMETRY) { buff[14]= (uchar) field->geom_type; #ifndef HAVE_SPATIAL @@ -906,13 +905,13 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type, null_count++; } - if (field->sql_type == FIELD_TYPE_BIT && !f_bit_as_char(field->pack_flag)) + if (field->sql_type == MYSQL_TYPE_BIT && !f_bit_as_char(field->pack_flag)) null_count+= field->length & 7; type= (Field::utype) MTYP_TYPENR(field->unireg_check); if (field->def && - (regfield->real_type() != FIELD_TYPE_YEAR || + (regfield->real_type() != MYSQL_TYPE_YEAR || field->def->val_int() != 0)) { if (field->def->save_in_field(regfield, 1)) @@ -923,7 +922,7 @@ static bool make_empty_rec(THD *thd, File file,enum legacy_db_type table_type, goto err; } } - else if (regfield->real_type() == FIELD_TYPE_ENUM && + else if (regfield->real_type() == MYSQL_TYPE_ENUM && (field->flags & NOT_NULL_FLAG)) { regfield->set_notnull(); diff --git a/sql/unireg.h b/sql/unireg.h index af91793e8fe..d67fa372083 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -1,9 +1,8 @@ -/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB +/* Copyright (C) 2000-2006 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. + the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |