X-Account-Key: account4 X-UIDL: 1153746480.180762 X-Mozilla-Status: 1001 X-Mozilla-Status2: 00000000 X-Mozilla-Keys: Return-Path: Received: from mailget.mysql.com ([unix socket]) by mailget (Cyrus v2.3.1-Invoca-RPM-2.3.1-2.8.fc5) with LMTPA; Wed, 23 Jul 2008 02:22:58 +0200 X-Sieve: CMU Sieve 2.3 Received: from mail.mysql.com (mail.mysql.com [10.100.1.21]) by mailget.mysql.com (8.13.8/8.13.8) with ESMTP id m6N0Mwmk008953 for ; Wed, 23 Jul 2008 02:22:58 +0200 Received: from mailgate-a.mysql.com (mailgate-a.mysql.com [10.128.2.13]) by mail.mysql.com (8.13.3/8.13.3) with ESMTP id m6N0MuoD000576 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 23 Jul 2008 02:22:56 +0200 Received: from lists.mysql.com (lists.mysql.com [10.100.1.37]) by mailgate-a.mysql.com (8.14.1/8.14.1) with SMTP id m6N0Fkul016673 for ; Wed, 23 Jul 2008 02:15:46 +0200 Received: (qmail 21972 invoked by uid 510); 23 Jul 2008 00:22:53 -0000 Mailing-List: contact commits-help@lists.mysql.com; run by ezmlm List-ID: Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Archive: http://lists.mysql.com/commits/50232 Delivered-To: mailing list commits@lists.mysql.com Received: (qmail 21947 invoked by uid 509); 23 Jul 2008 00:22:53 -0000 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit From: Marc Alff Subject: bzr commit into mysql-6.0-wl2110-review branch (marc.alff:2675) WL#2110 To: commits@lists.mysql.com User-Agent: Bazaar (1.4) X-CSetKey: marc.alff@sun.com-20080723002236-h0xi6oq7e58gpj5j X-Worklog: 2110 X-bzr-action: commit X-bzr-revid: marc.alff@sun.com-20080723002236-h0xi6oq7e58gpj5j X-bzr-revno: 2675 Message-Id: <20080723002244.4DF9B1DC614@lambda.WEBLAB> Date: Tue, 22 Jul 2008 18:22:43 -0600 (MDT) X-Cxn-Txn: 56107997,34985335 #At file:///home/malff/BZR-TREE/mysql-6.0-wl2110-review-part1/ 2675 Marc Alff 2008-07-22 WL#2110 (Stored Procedures: Implement SIGNAL) Formal review part 1/10: Parser This patch implements - the SIGNAL statement syntax - the RESIGNAL statement syntax in the parser. added: sql/sql_signal.h modified: sql/lex.h sql/sql_lex.h sql/sql_parse.cc sql/sql_yacc.yy === modified file 'sql/lex.h' --- a/sql/lex.h 2008-07-09 07:12:43 +0000 +++ b/sql/lex.h 2008-07-23 00:22:36 +0000 @@ -96,6 +96,7 @@ static SYMBOL symbols[] = { { "CASCADE", SYM(CASCADE)}, { "CASCADED", SYM(CASCADED)}, { "CASE", SYM(CASE_SYM)}, + { "CATALOG_NAME", SYM(CATALOG_NAME_SYM)}, { "CHAIN", SYM(CHAIN_SYM)}, { "CHANGE", SYM(CHANGE)}, { "CHANGED", SYM(CHANGED)}, @@ -105,6 +106,7 @@ static SYMBOL symbols[] = { { "CHECK", SYM(CHECK_SYM)}, { "CHECKSUM", SYM(CHECKSUM_SYM)}, { "CIPHER", SYM(CIPHER_SYM)}, + { "CLASS_ORIGIN", SYM(CLASS_ORIGIN_SYM)}, { "CLIENT", SYM(CLIENT_SYM)}, { "CLOSE", SYM(CLOSE_SYM)}, { "COALESCE", SYM(COALESCE)}, @@ -112,6 +114,7 @@ static SYMBOL symbols[] = { { "COLLATE", SYM(COLLATE_SYM)}, { "COLLATION", SYM(COLLATION_SYM)}, { "COLUMN", SYM(COLUMN_SYM)}, + { "COLUMN_NAME", SYM(COLUMN_NAME_SYM)}, { "COLUMNS", SYM(COLUMNS)}, { "COMMENT", SYM(COMMENT_SYM)}, { "COMMIT", SYM(COMMIT_SYM)}, @@ -126,6 +129,9 @@ static SYMBOL symbols[] = { { "CONNECTION", SYM(CONNECTION_SYM)}, { "CONSISTENT", SYM(CONSISTENT_SYM)}, { "CONSTRAINT", SYM(CONSTRAINT)}, + { "CONSTRAINT_CATALOG", SYM(CONSTRAINT_CATALOG_SYM)}, + { "CONSTRAINT_NAME", SYM(CONSTRAINT_NAME_SYM)}, + { "CONSTRAINT_SCHEMA", SYM(CONSTRAINT_SCHEMA_SYM)}, { "CONTAINS", SYM(CONTAINS_SYM)}, { "CONTEXT", SYM(CONTEXT_SYM)}, { "CONTINUE", SYM(CONTINUE_SYM)}, @@ -140,6 +146,7 @@ static SYMBOL symbols[] = { { "CURRENT_TIMESTAMP", SYM(NOW_SYM)}, { "CURRENT_USER", SYM(CURRENT_USER)}, { "CURSOR", SYM(CURSOR_SYM)}, + { "CURSOR_NAME", SYM(CURSOR_NAME_SYM)}, { "DATA", SYM(DATA_SYM)}, { "DATABASE", SYM(DATABASE)}, { "DATABASES", SYM(DATABASES)}, @@ -337,6 +344,7 @@ static SYMBOL symbols[] = { { "MEDIUMTEXT", SYM(MEDIUMTEXT)}, { "MEMORY", SYM(MEMORY_SYM)}, { "MERGE", SYM(MERGE_SYM)}, + { "MESSAGE_TEXT", SYM(MESSAGE_TEXT_SYM)}, { "MICROSECOND", SYM(MICROSECOND_SYM)}, { "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */ { "MIGRATE", SYM(MIGRATE_SYM)}, @@ -352,7 +360,8 @@ static SYMBOL symbols[] = { { "MULTILINESTRING", SYM(MULTILINESTRING)}, { "MULTIPOINT", SYM(MULTIPOINT)}, { "MULTIPOLYGON", SYM(MULTIPOLYGON)}, - { "MUTEX", SYM(MUTEX_SYM)}, + { "MUTEX", SYM(MUTEX_SYM)}, + { "MYSQL_ERRNO", SYM(MYSQL_ERRNO_SYM)}, { "NAME", SYM(NAME_SYM)}, { "NAMES", SYM(NAMES_SYM)}, { "NATIONAL", SYM(NATIONAL_SYM)}, @@ -448,6 +457,7 @@ static SYMBOL symbols[] = { { "REPEAT", SYM(REPEAT_SYM)}, { "REQUIRE", SYM(REQUIRE_SYM)}, { "RESET", SYM(RESET_SYM)}, + { "RESIGNAL", SYM(RESIGNAL_SYM)}, { "RESTORE", SYM(RESTORE_SYM)}, { "RESTRICT", SYM(RESTRICT)}, { "RESUME", SYM(RESUME_SYM)}, @@ -467,6 +477,7 @@ static SYMBOL symbols[] = { { "SAVEPOINT", SYM(SAVEPOINT_SYM)}, { "SCHEDULE", SYM(SCHEDULE_SYM)}, { "SCHEMA", SYM(DATABASE)}, + { "SCHEMA_NAME", SYM(SCHEMA_NAME_SYM)}, { "SCHEMAS", SYM(DATABASES)}, { "SECOND", SYM(SECOND_SYM)}, { "SECOND_MICROSECOND", SYM(SECOND_MICROSECOND_SYM)}, @@ -482,6 +493,7 @@ static SYMBOL symbols[] = { { "SHARE", SYM(SHARE_SYM)}, { "SHOW", SYM(SHOW)}, { "SHUTDOWN", SYM(SHUTDOWN)}, + { "SIGNAL", SYM(SIGNAL_SYM)}, { "SIGNED", SYM(SIGNED_SYM)}, { "SIMPLE", SYM(SIMPLE_SYM)}, { "SLAVE", SYM(SLAVE)}, @@ -523,6 +535,7 @@ static SYMBOL symbols[] = { { "STORAGE", SYM(STORAGE_SYM)}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN)}, { "STRING", SYM(STRING_SYM)}, + { "SUBCLASS_ORIGIN", SYM(SUBCLASS_ORIGIN_SYM)}, { "SUBJECT", SYM(SUBJECT_SYM)}, { "SUBPARTITION", SYM(SUBPARTITION_SYM)}, { "SUBPARTITIONS", SYM(SUBPARTITIONS_SYM)}, @@ -531,6 +544,7 @@ static SYMBOL symbols[] = { { "SWAPS", SYM(SWAPS_SYM)}, { "SWITCHES", SYM(SWITCHES_SYM)}, { "TABLE", SYM(TABLE_SYM)}, + { "TABLE_NAME", SYM(TABLE_NAME_SYM)}, { "TABLES", SYM(TABLES)}, { "TABLESPACE", SYM(TABLESPACE)}, { "TABLE_CHECKSUM", SYM(TABLE_CHECKSUM_SYM)}, === modified file 'sql/sql_lex.h' --- a/sql/sql_lex.h 2008-06-25 13:30:04 +0000 +++ b/sql/sql_lex.h 2008-07-23 00:22:36 +0000 @@ -122,6 +122,7 @@ enum enum_sql_command { SQLCOM_BACKUP_TEST, #endif SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES, + SQLCOM_SIGNAL, SQLCOM_RESIGNAL, /* When a command is added here, be sure it's also added in mysqld.cc @@ -1510,6 +1511,56 @@ public: CHARSET_INFO *m_underscore_cs; }; +struct st_lex; + +/** + Abstract representation of a statement. + This class is an interface between the parser and the runtime. + The parser builds the appropriate sub classes of SQLCOM_statement + to represent a SQL statement in the parsed tree. + The execute() method in the sub classes contain the runtime implementation. + Note that this interface is used for SQL statement recently implemented, + the code for older statements tend to load the LEX structure with more + attributes instead. + The recommended way to implement new statements is to sub-class + SQLCOM_statement, as this improves code modularity (see the 'big switch' in + dispatch_command()), and decrease the total size of the LEX structure + (therefore saving memory in stored programs). +*/ +class SQLCOM_statement : public Sql_alloc +{ +public: + /** + Execute this SQL statement. + @param thd the current thread. + @return 0 on success. + */ + virtual int execute(THD *thd) = 0; + +protected: + /** + Constructor. + @param lex the LEX structure that represents parts of this statement. + */ + SQLCOM_statement(struct st_lex *lex) + : m_lex(lex) + {} + + /** Destructor. */ + virtual ~SQLCOM_statement() + {} + +protected: + /** + The legacy LEX structure for this statement. + The LEX structure contains the existing properties of the parsed tree. + TODO: with time, attributes from LEX should move to sub classes of + SQLCOM_statement, so that the parser only builds SQLCOM_statement objects + with the minimum set of attributes, instead of a LEX structure that + contains the collection of every possible attribute. + */ + struct st_lex *m_lex; +}; /* The state of the lex parsing. This is saved in the THD struct */ @@ -1613,6 +1664,9 @@ typedef struct st_lex : public Query_tab */ nesting_map allow_sum_func; enum_sql_command sql_command; + + SQLCOM_statement *m_stmt; + /* Usually `expr` rule of yacc is quite reused but some commands better not support subqueries which comes standard with this rule, like === modified file 'sql/sql_parse.cc' --- a/sql/sql_parse.cc 2008-07-14 14:56:49 +0000 +++ b/sql/sql_parse.cc 2008-07-23 00:22:36 +0000 @@ -1859,8 +1859,18 @@ mysql_execute_command(THD *thd) variables, but for now this is probably good enough. Don't reset warnings when executing a stored routine. */ - if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont) - mysql_reset_errors(thd, 0); + if ((lex->sql_command == SQLCOM_SHOW_WARNS) || + (lex->sql_command == SQLCOM_SHOW_ERRORS)) + { + thd->main_da.m_stmt_area.set_read_only(TRUE); + } + else + { + thd->main_da.m_stmt_area.set_read_only(FALSE); + if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont) + mysql_reset_errors(thd, 0); + thd->main_da.m_stmt_area.m_command_function_cmd= lex->sql_command; + } #ifdef HAVE_REPLICATION if (unlikely(thd->slave_thread)) @@ -1948,7 +1958,7 @@ mysql_execute_command(THD *thd) status_var_increment(thd->status_var.com_stat[lex->sql_command]); DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE); - + switch (lex->sql_command) { case SQLCOM_SHOW_EVENTS: @@ -4177,7 +4187,7 @@ create_sp_error: If warnings have been cleared, we have to clear total_warn_count too, otherwise the clients get confused. */ - if (thd->warn_list.is_empty()) + if (thd->main_da.m_stmt_area.warn_list.is_empty()) thd->total_warn_count= 0; thd->variables.select_limit= select_limit; @@ -4736,6 +4746,11 @@ create_sp_error: my_ok(thd, 1); break; } + case SQLCOM_SIGNAL: + case SQLCOM_RESIGNAL: + DBUG_ASSERT(lex->m_stmt != NULL); + res= lex->m_stmt->execute(thd); + break; default: #ifndef EMBEDDED_LIBRARY DBUG_ASSERT(0); /* Impossible */ @@ -7670,8 +7685,11 @@ bool parse_sql(THD *thd, Lex_input_stream *lip, Object_creation_ctx *creation_ctx) { + Tmp_syn tmp_syn; bool mysql_parse_status; + DBUG_ASSERT(thd->m_lip == NULL); + DBUG_ASSERT(thd->m_tmp_syn == NULL); /* Backup creation context. */ @@ -7684,6 +7702,7 @@ bool parse_sql(THD *thd, lip->set_echo(TRUE); thd->m_lip= lip; + thd->m_tmp_syn= & tmp_syn; /* Parse the query. */ @@ -7696,6 +7715,7 @@ bool parse_sql(THD *thd, /* Reset Lex_input_stream. */ thd->m_lip= NULL; + thd->m_tmp_syn= NULL; /* Restore creation context. */ === added file 'sql/sql_signal.h' --- a/sql/sql_signal.h 1970-01-01 00:00:00 +0000 +++ b/sql/sql_signal.h 2008-07-23 00:22:36 +0000 @@ -0,0 +1,147 @@ +/* Copyright (C) 2008 Sun Microsystems, Inc + + 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 */ + +#ifndef SQL_SIGNAL_H +#define SQL_SIGNAL_H + +/** + Abstract_signal represents the common properties of the SIGNAL and RESIGNAL + statements. +*/ +class Abstract_signal : public SQLCOM_statement +{ +protected: + /** + Constructor. + @param lex the LEX structure for this statement. + @param cond the condition signaled if any, or NULL. + @param set collection of signal condition item assignments. + */ + Abstract_signal(LEX *lex, + const sp_cond_type_t *cond, + const Set_signal_information& set) + : SQLCOM_statement(lex), + m_cond(cond), + m_set_signal_information(set) + {} + + virtual ~Abstract_signal() + {} + + /** + Evaluate the condition sqlcode and sqlstate for this statement. + @param thd the current thread. + @param cond the condition to update. + @return 0 on success. + */ + int eval_sqlcode_sqlstate(THD *thd, SQL_condition *cond); + + /** + Evaluate default values for signal condition items for this statement. + @param thd the current thread. + @param cond the condition to update. + @return 0 on success. + */ + int eval_defaults(THD *thd, SQL_condition *cond); + + /** + Evaluate each signal condition items for this statement. + @param thd the current thread. + @param cond the condition to update. + @return 0 on success. + */ + int eval_signal_informations(THD *thd, SQL_condition *cond); + + /** + Raise a SQL condition. + @param thd the current thread. + @param cond the condition to raise. + @return 0 on success. + */ + int raise_condition(THD *thd, SQL_condition *cond); + + /** + The condition to signal or resignal. + This member is optional and can be NULL (RESIGNAL). + */ + const sp_cond_type_t *m_cond; + + /** + Collection of 'SET item = value' assignments in the + SIGNAL/RESIGNAL statement. + */ + Set_signal_information m_set_signal_information; +}; + +/** + SQLCOM_signal represents a SIGNAL statement. +*/ +class SQLCOM_signal : public Abstract_signal +{ +public: + /** + Constructor, used to represent a SIGNAL statement. + @param lex the LEX structure for this statement. + @param cond the SQL condition to signal (required). + @param set the collection of signal informations to signal. + */ + SQLCOM_signal(LEX *lex, + const sp_cond_type_t *cond, + const Set_signal_information& set) + : Abstract_signal(lex, cond, set) + {} + + virtual ~SQLCOM_signal() + {} + + /** + Execute a SIGNAL statement at runtime. + @param thd the current thread. + @return 0 on success. + */ + virtual int execute(THD *thd); +}; + +/** + SQLCOM_resignal represents a RESIGNAL statement. +*/ +class SQLCOM_resignal : public Abstract_signal +{ +public: + /** + Constructor, used to represent a RESIGNAL statement. + @param lex the LEX structure for this statement. + @param cond the SQL condition to resignal (optional, may be NULL). + @param set the collection of signal informations to resignal. + */ + SQLCOM_resignal(LEX *lex, + const sp_cond_type_t *cond, + const Set_signal_information& set) + : Abstract_signal(lex, cond, set) + {} + + virtual ~SQLCOM_resignal() + {} + + /** + Execute a RESIGNAL statement at runtime. + @param thd the current thread. + @return 0 on success. + */ + virtual int execute(THD *thd); +}; + +#endif + === modified file 'sql/sql_yacc.yy' --- a/sql/sql_yacc.yy 2008-07-14 14:56:49 +0000 +++ b/sql/sql_yacc.yy 2008-07-23 00:22:36 +0000 @@ -42,6 +42,7 @@ #include "sp_pcontext.h" #include "sp_rcontext.h" #include "sp.h" +#include "sql_signal.h" #include "event_parse_data.h" #include #include @@ -581,6 +582,7 @@ bool setup_select_in_parentheses(LEX *le enum enum_filetype filetype; enum ha_build_method build_method; enum Foreign_key::fk_option m_fk_option; + Diag_condition_item_name diag_condition_item_name; } %{ @@ -662,6 +664,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token CASCADED /* SQL-2003-R */ %token CASE_SYM /* SQL-2003-R */ %token CAST_SYM /* SQL-2003-R */ +%token CATALOG_NAME_SYM /* SQL-2003-N */ %token CHAIN_SYM /* SQL-2003-N */ %token CHANGE %token CHANGED @@ -670,6 +673,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token CHECKSUM_SYM %token CHECK_SYM /* SQL-2003-R */ %token CIPHER_SYM +%token CLASS_ORIGIN_SYM /* SQL-2003-N */ %token CLIENT_SYM %token CLOSE_SYM /* SQL-2003-R */ %token COALESCE /* SQL-2003-N */ @@ -678,6 +682,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token COLLATION_SYM /* SQL-2003-N */ %token COLUMNS %token COLUMN_SYM /* SQL-2003-R */ +%token COLUMN_NAME_SYM /* SQL-2003-N */ %token COMMENT_SYM %token COMMITTED_SYM /* SQL-2003-N */ %token COMMIT_SYM /* SQL-2003-R */ @@ -687,10 +692,13 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token COMPRESSION_SYM %token COMPRESSION_ALGORITHM_SYM %token CONCURRENT -%token CONDITION_SYM /* SQL-2003-N */ +%token CONDITION_SYM /* SQL-2003-R, SQL-2008-R */ %token CONNECTION_SYM %token CONSISTENT_SYM %token CONSTRAINT /* SQL-2003-R */ +%token CONSTRAINT_CATALOG_SYM /* SQL-2003-N */ +%token CONSTRAINT_NAME_SYM /* SQL-2003-N */ +%token CONSTRAINT_SCHEMA_SYM /* SQL-2003-N */ %token CONTAINS_SYM /* SQL-2003-N */ %token CONTEXT_SYM %token CONTINUE_SYM /* SQL-2003-R */ @@ -704,6 +712,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token CURDATE /* MYSQL-FUNC */ %token CURRENT_USER /* SQL-2003-R */ %token CURSOR_SYM /* SQL-2003-R */ +%token CURSOR_NAME_SYM /* SQL-2003-N */ %token CURTIME /* MYSQL-FUNC */ %token DATABASE %token DATABASES @@ -907,6 +916,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token MEDIUM_SYM %token MEMORY_SYM %token MERGE_SYM /* SQL-2003-R */ +%token MESSAGE_TEXT_SYM /* SQL-2003-N */ %token MICROSECOND_SYM /* MYSQL-FUNC */ %token MIGRATE_SYM %token MINUTE_MICROSECOND_SYM @@ -923,6 +933,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token MULTIPOINT %token MULTIPOLYGON %token MUTEX_SYM +%token MYSQL_ERRNO_SYM %token NAMES_SYM /* SQL-2003-N */ %token NAME_SYM /* SQL-2003-N */ %token NATIONAL_SYM /* SQL-2003-R */ @@ -1027,6 +1038,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token REPLICATION %token REQUIRE_SYM %token RESET_SYM +%token RESIGNAL_SYM /* SQL-2003-R */ %token RESOURCES %token RESTORE_SYM %token RESTRICT @@ -1045,6 +1057,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token RTREE_SYM %token SAVEPOINT_SYM /* SQL-2003-R */ %token SCHEDULE_SYM +%token SCHEMA_NAME_SYM /* SQL-2003-N */ %token SECOND_MICROSECOND_SYM %token SECOND_SYM /* SQL-2003-R */ %token SECURITY_SYM /* SQL-2003-N */ @@ -1063,6 +1076,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token SHIFT_RIGHT /* OPERATOR */ %token SHOW %token SHUTDOWN +%token SIGNAL_SYM /* SQL-2003-R */ %token SIGNED_SYM %token SIMPLE_SYM /* SQL-2003-N */ %token SLAVE @@ -1096,6 +1110,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token STORAGE_SYM %token STRAIGHT_JOIN %token STRING_SYM +%token SUBCLASS_ORIGIN_SYM /* SQL-2003-N */ %token SUBDATE_SYM %token SUBJECT_SYM %token SUBPARTITIONS_SYM @@ -1112,6 +1127,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** %token TABLE_REF_PRIORITY %token TABLE_SYM /* SQL-2003-R */ %token TABLE_CHECKSUM_SYM +%token TABLE_NAME_SYM /* SQL-2003-N */ %token TEMPORARY /* SQL-2003-N */ %token TEMPTABLE_SYM %token TERMINATED @@ -1290,6 +1306,7 @@ bool my_yyoverflow(short **a, YYSTYPE ** function_call_nonkeyword function_call_generic function_call_conflict + signal_allowed_expr %type NUM_literal @@ -1424,7 +1441,7 @@ END_OF_INPUT %type case_stmt_specification simple_case_stmt searched_case_stmt %type sp_decl_idents sp_opt_inout sp_handler_type sp_hcond_list -%type sp_cond sp_hcond +%type sp_cond sp_hcond sqlstate signal_value opt_signal_value %type sp_decls sp_decl %type sp_cursor_stmt %type sp_name @@ -1432,6 +1449,9 @@ END_OF_INPUT %type index_hint_clause %type data_or_xml +%type signal_stmt resignal_stmt +%type signal_condition_information_item_name + %type '-' '+' '*' '/' '%' '(' ')' ',' '!' '{' '}' '&' '|' AND_SYM OR_SYM OR_OR_SYM BETWEEN_SYM CASE_SYM @@ -1552,12 +1572,14 @@ statement: | repair | replace | reset + | resignal_stmt | restore | revoke | rollback | savepoint | select | set + | signal_stmt | show | slave | start @@ -2614,7 +2636,11 @@ sp_cond: $$->type= sp_cond_type_t::number; $$->mysqlerr= $1; } - | SQLSTATE_SYM opt_value TEXT_STRING_literal + | sqlstate + ; + +sqlstate: + SQLSTATE_SYM opt_value TEXT_STRING_literal { /* SQLSTATE */ if (!sp_cond_check(&$3)) { @@ -2623,8 +2649,8 @@ sp_cond: } $$= (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'; + memcpy($$->sqlstate, $3.str, SQLSTATE_LENGTH); + $$->sqlstate[SQLSTATE_LENGTH]= '\0'; } ; @@ -2664,6 +2690,159 @@ sp_hcond: } ; +signal_stmt: + SIGNAL_SYM + signal_value + opt_set_signal_information + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + Tmp_syn *tmp_syn= thd->m_tmp_syn; + + lex->sql_command= SQLCOM_SIGNAL; + lex->m_stmt= new (thd->mem_root) SQLCOM_signal(lex, + $2, + tmp_syn->m_set_signal_info); + } + ; + +signal_value: + ident + { + sp_cond_type_t *cond; + if (Lex->spcont == NULL) + { + /* SIGNAL foo can be used outside of stored programs */ + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + cond= Lex->spcont->find_cond(&$1); + if (cond == NULL) + { + my_error(ER_SP_COND_MISMATCH, MYF(0), $1.str); + MYSQL_YYABORT; + } + if (cond->type != sp_cond_type_t::state) + { + my_error(ER_SIGNAL_BAD_CONDITION_TYPE, MYF(0)); + MYSQL_YYABORT; + } + $$= cond; + } + | sqlstate + { $$= $1; } + ; + +opt_signal_value: + /* empty */ + { $$= NULL; } + | signal_value + { $$= $1; } + ; + +opt_set_signal_information: + /* empty */ + { + YYTHD->m_tmp_syn->m_set_signal_info.clear(); + } + | SET signal_information_item_list + ; + +signal_information_item_list: + signal_condition_information_item_name EQ signal_allowed_expr + { + Set_signal_information *info= & YYTHD->m_tmp_syn->m_set_signal_info; + int index= (int) $1; + info->clear(); + info->m_item[index]= $3; + } + | signal_information_item_list ',' + signal_condition_information_item_name EQ signal_allowed_expr + { + Set_signal_information *info= & YYTHD->m_tmp_syn->m_set_signal_info; + int index= (int) $3; + if (info->m_item[index] != NULL) + { + my_error(ER_DUP_SIGNAL_SET, MYF(0), + Diag_condition_item_names[index].str); + MYSQL_YYABORT; + } + info->m_item[index]= $5; + } + ; + +/* + Only a limited subset of are allowed in SIGNAL/RESIGNAL. +*/ +signal_allowed_expr: + literal + { $$= $1; } + | variable + { + if ($1->type() == Item::FUNC_ITEM) + { + Item_func *item= (Item_func*) $1; + if (item->functype() == Item_func::SUSERVAR_FUNC) + { + /* + Don't allow the following syntax: + SIGNAL/RESIGNAL ... + SET = @foo := expr + */ + my_parse_error(ER(ER_SYNTAX_ERROR)); + MYSQL_YYABORT; + } + } + $$= $1; + } + | simple_ident + { $$= $1; } + ; + +/* conditions that can be set in signal / resignal */ +signal_condition_information_item_name: + CLASS_ORIGIN_SYM + { $$= DIAG_CLASS_ORIGIN; } + | SUBCLASS_ORIGIN_SYM + { $$= DIAG_SUBCLASS_ORIGIN; } + | CONSTRAINT_CATALOG_SYM + { $$= DIAG_CONSTRAINT_CATALOG; } + | CONSTRAINT_SCHEMA_SYM + { $$= DIAG_CONSTRAINT_SCHEMA; } + | CONSTRAINT_NAME_SYM + { $$= DIAG_CONSTRAINT_NAME; } + | CATALOG_NAME_SYM + { $$= DIAG_CATALOG_NAME; } + | SCHEMA_NAME_SYM + { $$= DIAG_SCHEMA_NAME; } + | TABLE_NAME_SYM + { $$= DIAG_TABLE_NAME; } + | COLUMN_NAME_SYM + { $$= DIAG_COLUMN_NAME; } + | CURSOR_NAME_SYM + { $$= DIAG_CURSOR_NAME; } + | MESSAGE_TEXT_SYM + { $$= DIAG_MESSAGE_TEXT; } + | MYSQL_ERRNO_SYM + { $$= DIAG_MYSQL_ERRNO; } + ; + +resignal_stmt: + RESIGNAL_SYM + opt_signal_value + opt_set_signal_information + { + THD *thd= YYTHD; + LEX *lex= thd->lex; + Tmp_syn *tmp_syn= thd->m_tmp_syn; + + lex->sql_command= SQLCOM_RESIGNAL; + lex->m_stmt= new (thd->mem_root) SQLCOM_resignal(lex, + $2, + tmp_syn->m_set_signal_info); + } + ; + sp_decl_idents: ident { @@ -10944,14 +11123,17 @@ keyword_sp: | BOOLEAN_SYM {} | BTREE_SYM {} | CASCADED {} + | CATALOG_NAME_SYM {} | CHAIN_SYM {} | CHANGED {} | CIPHER_SYM {} | CLIENT_SYM {} + | CLASS_ORIGIN_SYM {} | COALESCE {} | CODE_SYM {} | COLLATION_SYM {} | COLUMN_FORMAT_SYM {} + | COLUMN_NAME_SYM {} | COLUMNS {} | COMMITTED_SYM {} | COMPACT_SYM {} @@ -10962,10 +11144,14 @@ keyword_sp: | CONCURRENT {} | CONNECTION_SYM {} | CONSISTENT_SYM {} + | CONSTRAINT_CATALOG_SYM {} + | CONSTRAINT_SCHEMA_SYM {} + | CONSTRAINT_NAME_SYM {} | CONTEXT_SYM {} | CONTRIBUTORS_SYM {} | CPU_SYM {} | CUBE_SYM {} + | CURSOR_NAME_SYM {} | DATA_SYM {} | DATAFILE_SYM {} | DATETIME {} @@ -11057,6 +11243,7 @@ keyword_sp: | MEDIUM_SYM {} | MEMORY_SYM {} | MERGE_SYM {} + | MESSAGE_TEXT_SYM {} | MICROSECOND_SYM {} | MIGRATE_SYM {} | MINUTE_SYM {} @@ -11068,6 +11255,7 @@ keyword_sp: | MULTIPOINT {} | MULTIPOLYGON {} | MUTEX_SYM {} + | MYSQL_ERRNO_SYM {} | NAME_SYM {} | NAMES_SYM {} | NATIONAL_SYM {} @@ -11132,6 +11320,7 @@ keyword_sp: | ROW_SYM {} | RTREE_SYM {} | SCHEDULE_SYM {} + | SCHEMA_NAME_SYM {} | SECOND_SYM {} | SERIAL_SYM {} | SERIALIZABLE_SYM {} @@ -11150,6 +11339,7 @@ keyword_sp: | STATUS_SYM {} | STORAGE_SYM {} | STRING_SYM {} + | SUBCLASS_ORIGIN_SYM {} | SUBDATE_SYM {} | SUBJECT_SYM {} | SUBPARTITION_SYM {} @@ -11158,6 +11348,7 @@ keyword_sp: | SUSPEND_SYM {} | SWAPS_SYM {} | SWITCHES_SYM {} + | TABLE_NAME_SYM {} | TABLES {} | TABLE_CHECKSUM_SYM {} | TABLESPACE {} -- MySQL Code Commits Mailing List For list archives: http://lists.mysql.com/commits To unsubscribe: http://lists.mysql.com/commits?unsub=marc.alff@mysql.com