diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-10-19 20:38:59 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-10-19 20:38:59 +0200 |
commit | e1f681c99b3e5462c033aaafa94ac295e626cde2 (patch) | |
tree | 2da5eff1a0d03831c2d85b32a7bc3df6ec37b522 /client | |
parent | 52c84d144d3b07966d9b3bab8694eb012eef69ce (diff) | |
parent | 807fef40fffbbb8e92564a52b902b504ba8cfcdc (diff) | |
download | mariadb-git-e1f681c99b3e5462c033aaafa94ac295e626cde2.tar.gz |
10.0-base -> 10.0-monty
Diffstat (limited to 'client')
-rw-r--r-- | client/get_password.c | 4 | ||||
-rw-r--r-- | client/mysql.cc | 1 | ||||
-rw-r--r-- | client/mysqladmin.cc | 55 | ||||
-rw-r--r-- | client/mysqlbinlog.cc | 53 | ||||
-rw-r--r-- | client/mysqldump.c | 42 | ||||
-rw-r--r-- | client/mysqltest.cc | 114 |
6 files changed, 220 insertions, 49 deletions
diff --git a/client/get_password.c b/client/get_password.c index c6653183f48..09d307b5553 100644 --- a/client/get_password.c +++ b/client/get_password.c @@ -23,10 +23,6 @@ #include <m_string.h> #include <m_ctype.h> -#if defined(HAVE_BROKEN_GETPASS) && !defined(HAVE_GETPASSPHRASE) -#undef HAVE_GETPASS -#endif - #ifdef HAVE_GETPASS #ifdef HAVE_PWD_H #include <pwd.h> diff --git a/client/mysql.cc b/client/mysql.cc index 5f205791b8e..9bc1d02bb64 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -897,6 +897,7 @@ static COMMANDS commands[] = { { "LAST_INSERT_ID", 0, 0, 0, ""}, { "ISSIMPLE", 0, 0, 0, ""}, { "LAST_DAY", 0, 0, 0, ""}, + { "LAST_VALUE", 0, 0, 0, ""}, { "LCASE", 0, 0, 0, ""}, { "LEAST", 0, 0, 0, ""}, { "LENGTH", 0, 0, 0, ""}, diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index e2c96d35c73..bab566e045c 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -23,7 +23,7 @@ #include <mysql.h> #include <sql_common.h> -#define ADMIN_VERSION "9.0" +#define ADMIN_VERSION "9.1" #define MAX_MYSQL_VAR 512 #define SHUTDOWN_DEF_TIMEOUT 3600 /* Wait for shutdown */ #define MAX_TRUNC_LENGTH 3 @@ -97,6 +97,7 @@ enum commands { ADMIN_FLUSH_HOSTS, ADMIN_FLUSH_TABLES, ADMIN_PASSWORD, ADMIN_PING, ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS, ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE, ADMIN_STOP_SLAVE, + ADMIN_START_ALL_SLAVES, ADMIN_STOP_ALL_SLAVES, ADMIN_FLUSH_THREADS, ADMIN_OLD_PASSWORD, ADMIN_FLUSH_SLOW_LOG, ADMIN_FLUSH_TABLE_STATISTICS, ADMIN_FLUSH_INDEX_STATISTICS, ADMIN_FLUSH_USER_STATISTICS, ADMIN_FLUSH_CLIENT_STATISTICS, @@ -110,6 +111,7 @@ static const char *command_names[]= { "flush-hosts", "flush-tables", "password", "ping", "extended-status", "flush-status", "flush-privileges", "start-slave", "stop-slave", + "start-all-slaves", "stop-all-slaves", "flush-threads", "old-password", "flush-slow-log", "flush-table-statistics", "flush-index-statistics", "flush-user-statistics", "flush-client-statistics", @@ -1117,26 +1119,67 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_START_SLAVE: - if (mysql_query(mysql, "START SLAVE")) + case ADMIN_START_ALL_SLAVES: + { + my_bool many_slaves= 0; + const char *query= "START SLAVE"; + if (command == ADMIN_START_ALL_SLAVES && mariadb_connection(mysql) && + mysql_get_server_version(mysql) >= 100000) + { + query="START ALL SLAVES"; + many_slaves= 1; + } + + if (mysql_query(mysql, query)) { my_printf_error(0, "Error starting slave: %s", error_flags, mysql_error(mysql)); return -1; } + else if (!many_slaves || mysql_warning_count(mysql) > 0) + { + if (!option_silent) + puts("Slave('s) started"); + } else - puts("Slave started"); + { + if (!option_silent) + puts("No slaves to start"); + } break; + } case ADMIN_STOP_SLAVE: - if (mysql_query(mysql, "STOP SLAVE")) + case ADMIN_STOP_ALL_SLAVES: + { + const char *query= "STOP SLAVE"; + my_bool many_slaves= 0; + + if (command == ADMIN_STOP_ALL_SLAVES && mariadb_connection(mysql) && + mysql_get_server_version(mysql) >= 100000) + { + query="STOP ALL SLAVES"; + many_slaves= 1; + } + + if (mysql_query(mysql, query)) { my_printf_error(0, "Error stopping slave: %s", error_flags, mysql_error(mysql)); return -1; } + else if (!many_slaves || mysql_warning_count(mysql) > 0) + { + /* We can't detect if there was any slaves to stop with STOP SLAVE */ + if (many_slaves && !option_silent) + puts("Slave('s) stopped"); + } else - puts("Slave stopped"); + { + if (!option_silent) + puts("All slaves was already stopped"); + } break; - + } case ADMIN_PING: mysql->reconnect=0; /* We want to know of reconnects */ if (!mysql_ping(mysql)) diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 91a2bd2aef3..f604b8bc84f 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2012, Monty Program Ab + Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program 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 @@ -743,7 +743,7 @@ print_use_stmt(PRINT_EVENT_INFO* pinfo, const Query_log_event *ev) return; // In case of rewrite rule print USE statement for db_to - fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter); + my_fprintf(result_file, "use %`s%s\n", db_to, pinfo->delimiter); // Copy the *original* db to pinfo to suppress emiting // of USE stmts by log_event print-functions. @@ -844,6 +844,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, DBUG_ENTER("process_event"); print_event_info->short_form= short_form; Exit_status retval= OK_CONTINUE; + IO_CACHE *const head= &print_event_info->head_cache; /* Format events are not concerned by --offset and such, we always need to @@ -923,6 +924,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, print_skip_replication_statement(print_event_info, ev); ev->print(result_file, print_event_info); } + if (head->error == -1) + goto err; break; } @@ -955,8 +958,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, { print_skip_replication_statement(print_event_info, ev); ce->print(result_file, print_event_info, TRUE); + if (head->error == -1) + goto err; } - // If this binlog is not 3.23 ; why this test?? if (glob_description_event->binlog_version >= 3) { @@ -978,6 +982,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, output of Append_block_log_event::print is only a comment. */ ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; if ((retval= load_processor.process((Append_block_log_event*) ev)) != OK_CONTINUE) goto end; @@ -986,6 +992,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case EXEC_LOAD_EVENT: { ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; Execute_load_log_event *exv= (Execute_load_log_event*)ev; Create_file_log_event *ce= load_processor.grab_event(exv->file_id); /* @@ -1003,6 +1011,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, ce->print(result_file, print_event_info, TRUE); my_free((void*)ce->fname); delete ce; + if (head->error == -1) + goto err; } else warning("Ignoring Execute_load_log_event as there is no " @@ -1015,6 +1025,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, print_event_info->common_header_len= glob_description_event->common_header_len; ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; if (!remote_opt) { ev->free_temp_buf(); // free memory allocated in dump_local_log_entries @@ -1044,6 +1056,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, break; case BEGIN_LOAD_QUERY_EVENT: ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) != OK_CONTINUE) goto end; @@ -1061,6 +1075,12 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, convert_path_to_forward_slashes(fname); print_skip_replication_statement(print_event_info, ev); exlq->print(result_file, print_event_info, fname); + if (head->error == -1) + { + if (fname) + my_free(fname); + goto err; + } } else warning("Ignoring Execute_load_query since there is no " @@ -1191,6 +1211,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, default: print_skip_replication_statement(print_event_info, ev); ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; } } @@ -1354,7 +1376,7 @@ static struct my_option my_options[] = "Stop reading the binlog at position N. Applies to the last binlog " "passed on the command line.", &stop_position, &stop_position, 0, GET_ULL, - REQUIRED_ARG, (ulonglong)(~(my_off_t)0), BIN_LOG_HEADER_SIZE, + REQUIRED_ARG, (longlong)(~(my_off_t)0), BIN_LOG_HEADER_SIZE, (ulonglong)(~(my_off_t)0), 0, 0, 0}, {"to-last-log", 't', "Requires -R. Will not stop at the end of the \ requested binlog but rather continue printing until the end of the last \ @@ -1785,6 +1807,19 @@ static Exit_status check_master_version() "Master returned '%s'", mysql_error(mysql)); goto err; } + + /* + Announce our capabilities to the server, so it will send us all the events + that we know about. + */ + if (mysql_query(mysql, "SET @mariadb_slave_capability=" + STRINGIFY_ARG(MARIA_SLAVE_CAPABILITY_MINE))) + { + error("Could not inform master about capability. Master returned '%s'", + mysql_error(mysql)); + goto err; + } + delete glob_description_event; switch (version) { case 3: @@ -2324,7 +2359,13 @@ err: end: if (fd >= 0) my_close(fd, MYF(MY_WME)); - end_io_cache(file); + /* + Since the end_io_cache() writes to the + file errors may happen. + */ + if (end_io_cache(file)) + retval= ERROR_STOP; + return retval; } diff --git a/client/mysqldump.c b/client/mysqldump.c index a28def57b44..8decdb65582 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2615,6 +2615,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (strcmp(field->name, "View") == 0) { char *scv_buff= NULL; + my_ulonglong n_cols; verbose_msg("-- It's a view, create dummy table for view\n"); @@ -2629,8 +2630,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, the same name in order to satisfy views that depend on this view. The table will be removed when the actual view is created. - The properties of each column, aside from the data type, are not - preserved in this temporary table, because they are not necessary. + The properties of each column, are not preserved in this temporary + table, because they are not necessary. This will not be necessary once we can determine dependencies between views and can simply dump them in the appropriate order. @@ -2657,8 +2658,23 @@ static uint get_table_structure(char *table, char *db, char *table_type, else my_free(scv_buff); - if (mysql_num_rows(result)) + n_cols= mysql_num_rows(result); + if (0 != n_cols) { + + /* + The actual formula is based on the column names and how the .FRM + files are stored and is too volatile to be repeated here. + Thus we simply warn the user if the columns exceed a limit we + know works most of the time. + */ + if (n_cols >= 1000) + fprintf(stderr, + "-- Warning: Creating a stand-in table for view %s may" + " fail when replaying the dump file produced because " + "of the number of columns exceeding 1000. Exercise " + "caution when replaying the produced dump file.\n", + table); if (opt_drop) { /* @@ -2685,14 +2701,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, row= mysql_fetch_row(result); - fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0), - row[1]); + /* + The actual column type doesn't matter anyway, since the table will + be dropped at run time. + We do tinyint to avoid hitting the row size limit. + */ + fprintf(sql_file, " %s tinyint NOT NULL", + quote_name(row[0], name_buff, 0)); while((row= mysql_fetch_row(result))) { /* col name, col type */ - fprintf(sql_file, ",\n %s %s", - quote_name(row[0], name_buff, 0), row[1]); + fprintf(sql_file, ",\n %s tinyint NOT NULL", + quote_name(row[0], name_buff, 0)); } /* @@ -4164,6 +4185,7 @@ static int dump_all_databases() if (dump_all_tables_in_db(row[0])) result=1; } + mysql_free_result(tableres); if (seen_views) { if (mysql_query(mysql, "SHOW DATABASES") || @@ -4186,6 +4208,7 @@ static int dump_all_databases() if (dump_all_views_in_db(row[0])) result=1; } + mysql_free_result(tableres); } return result; } @@ -4314,8 +4337,6 @@ static int init_dumping(char *database, int init_func(char*)) check_io(md_result_file); } } - if (extended_insert) - init_dynamic_string_checked(&extended_row, "", 1024, 1024); return 0; } /* init_dumping */ @@ -5592,6 +5613,9 @@ int main(int argc, char **argv) if (opt_alltspcs) dump_all_tablespaces(); + if (extended_insert) + init_dynamic_string_checked(&extended_row, "", 1024, 1024); + if (opt_alldbs) { if (!opt_alltspcs && !opt_notspcs) diff --git a/client/mysqltest.cc b/client/mysqltest.cc index fe481020574..6ccb1063cd2 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2012 Monty Program Ab. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program 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 @@ -84,6 +84,8 @@ static my_bool non_blocking_api_enabled= 0; #define QUERY_SEND_FLAG 1 #define QUERY_REAP_FLAG 2 +#define QUERY_PRINT_ORIGINAL_FLAG 4 + #ifndef HAVE_SETENV static int setenv(const char *name, const char *value, int overwrite); #endif @@ -253,6 +255,8 @@ static void init_re(void); static int match_re(my_regex_t *, char *); static void free_re(void); +static char *get_string(char **to_ptr, char **from_ptr, + struct st_command *command); static int replace(DYNAMIC_STRING *ds_str, const char *search_str, ulong search_len, const char *replace_str, ulong replace_len); @@ -342,7 +346,8 @@ enum enum_commands { Q_ERROR, Q_SEND, Q_REAP, Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, - Q_PING, Q_EVAL, + Q_PING, Q_EVAL, + Q_EVALP, Q_EVAL_RESULT, Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, @@ -408,6 +413,7 @@ const char *command_names[]= "replace_column", "ping", "eval", + "evalp", "eval_result", /* Enable/disable that the _query_ is logged to result file */ "enable_query_log", @@ -621,6 +627,8 @@ void free_all_replace(){ free_replace_column(); } +void var_set_int(const char* name, int value); + class LogFile { FILE* m_file; @@ -1275,6 +1283,8 @@ void handle_command_error(struct st_command *command, uint error, { DBUG_ENTER("handle_command_error"); DBUG_PRINT("enter", ("error: %d", error)); + var_set_int("$sys_errno",sys_errno); + var_set_int("$errno",error); if (error != 0) { int i; @@ -1285,7 +1295,7 @@ void handle_command_error(struct st_command *command, uint error, "errno: %d", command->first_word_len, command->query, error, my_errno, sys_errno); - return; + DBUG_VOID_RETURN; } i= match_expected_error(command, error, NULL); @@ -4576,7 +4586,8 @@ void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) } -void do_sync_with_master2(struct st_command *command, long offset) +void do_sync_with_master2(struct st_command *command, long offset, + const char *connection_name) { MYSQL_RES *res; MYSQL_ROW row; @@ -4587,8 +4598,9 @@ void do_sync_with_master2(struct st_command *command, long offset) if (!master_pos.file[0]) die("Calling 'sync_with_master' without calling 'save_master_pos'"); - sprintf(query_buf, "select master_pos_wait('%s', %ld, %d)", - master_pos.file, master_pos.pos + offset, timeout); + sprintf(query_buf, "select master_pos_wait('%s', %ld, %d, '%s')", + master_pos.file, master_pos.pos + offset, timeout, + connection_name); if (mysql_query(mysql, query_buf)) die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql), @@ -4648,16 +4660,32 @@ void do_sync_with_master(struct st_command *command) long offset= 0; char *p= command->first_argument; const char *offset_start= p; + char *start, *buff= 0; + start= (char*) ""; + if (*offset_start) { for (; my_isdigit(charset_info, *p); p++) offset = offset * 10 + *p - '0'; - if(*p && !my_isspace(charset_info, *p)) + if (*p && !my_isspace(charset_info, *p) && *p != ',') die("Invalid integer argument \"%s\"", offset_start); + + while (*p && my_isspace(charset_info, *p)) + p++; + if (*p == ',') + { + p++; + while (*p && my_isspace(charset_info, *p)) + p++; + start= buff= (char*)my_malloc(strlen(p)+1,MYF(MY_WME | MY_FAE)); + get_string(&buff, &p, command); + } command->last_argument= p; } - do_sync_with_master2(command, offset); + do_sync_with_master2(command, offset, start); + if (buff) + my_free(start); return; } @@ -5144,7 +5172,7 @@ typedef struct static st_error global_error_names[] = { - { "<No error>", (uint) -1, "" }, + { "<No error>", -1U, "" }, #include <mysqld_ername.h> { 0, 0, 0 } }; @@ -5201,15 +5229,32 @@ const char *get_errname_from_code (uint error_code) void do_get_errcodes(struct st_command *command) { struct st_match_err *to= saved_expected_errors.err; - char *p= command->first_argument; - uint count= 0; - char *next; - DBUG_ENTER("do_get_errcodes"); - if (!*p) + if (!*command->first_argument) die("Missing argument(s) to 'error'"); + /* TODO: Potentially, there is a possibility of variables + being expanded twice, e.g. + + let $errcodes = 1,\$a; + let $a = 1051; + error $errcodes; + DROP TABLE unknown_table; + ... + Got one of the listed errors + + But since it requires manual escaping, it does not seem + particularly dangerous or error-prone. + */ + DYNAMIC_STRING ds; + init_dynamic_string(&ds, 0, command->query_len + 64, 256); + do_eval(&ds, command->first_argument, command->end, !is_windows); + char *p= ds.str; + + uint count= 0; + char *next; + do { char *end; @@ -5265,7 +5310,7 @@ void do_get_errcodes(struct st_command *command) { die("The sqlstate definition must start with an uppercase S"); } - else if (*p == 'E') + else if (*p == 'E' || *p == 'W') { /* Error name string */ @@ -5274,9 +5319,9 @@ void do_get_errcodes(struct st_command *command) to->type= ERR_ERRNO; DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum)); } - else if (*p == 'e') + else if (*p == 'e' || *p == 'w') { - die("The error name definition must start with an uppercase E"); + die("The error name definition must start with an uppercase E or W"); } else { @@ -5319,11 +5364,15 @@ void do_get_errcodes(struct st_command *command) } while (*p); - command->last_argument= p; + command->last_argument= command->first_argument; + while (*command->last_argument) + command->last_argument++; + to->type= ERR_EMPTY; /* End of data */ DBUG_PRINT("info", ("Expected errors: %d", count)); saved_expected_errors.count= count; + dynstr_free(&ds); DBUG_VOID_RETURN; } @@ -5335,8 +5384,8 @@ void do_get_errcodes(struct st_command *command) If string is a '$variable', return the value of the variable. */ -char *get_string(char **to_ptr, char **from_ptr, - struct st_command *command) +static char *get_string(char **to_ptr, char **from_ptr, + struct st_command *command) { char c, sep; char *to= *to_ptr, *from= *from_ptr, *start=to; @@ -7687,6 +7736,8 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, */ if ((counter==0) && do_read_query_result(cn)) { + /* we've failed to collect the result set */ + cn->pending= TRUE; handle_error(command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), ds); goto end; @@ -8271,7 +8322,8 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) /* Evaluate query if this is an eval command */ - if (command->type == Q_EVAL || command->type == Q_SEND_EVAL) + if (command->type == Q_EVAL || command->type == Q_SEND_EVAL || + command->type == Q_EVALP) { init_dynamic_string(&eval_query, "", command->query_len+256, 1024); do_eval(&eval_query, command->query, command->end, FALSE); @@ -8303,10 +8355,20 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) */ if (!disable_query_log && (flags & QUERY_SEND_FLAG)) { - replace_dynstr_append_mem(ds, query, query_len); + char *print_query= query; + int print_len= query_len; + if (flags & QUERY_PRINT_ORIGINAL_FLAG) + { + print_query= command->query; + print_len= command->end - command->query; + } + replace_dynstr_append_mem(ds, print_query, print_len); dynstr_append_mem(ds, delimiter, delimiter_length); dynstr_append_mem(ds, "\n", 1); } + + /* We're done with this flag */ + flags &= ~QUERY_PRINT_ORIGINAL_FLAG; /* Write the command to the result file before we execute the query @@ -9169,6 +9231,7 @@ int main(int argc, char **argv) case Q_EVAL_RESULT: die("'eval_result' command is deprecated"); case Q_EVAL: + case Q_EVALP: case Q_QUERY_VERTICAL: case Q_QUERY_HORIZONTAL: if (command->query == command->query_buf) @@ -9196,6 +9259,9 @@ int main(int argc, char **argv) flags= QUERY_REAP_FLAG; } + if (command->type == Q_EVALP) + flags |= QUERY_PRINT_ORIGINAL_FLAG; + /* Check for special property for this query */ display_result_vertically|= (command->type == Q_QUERY_VERTICAL); @@ -9265,7 +9331,7 @@ int main(int argc, char **argv) select_connection(command); else select_connection_name("slave"); - do_sync_with_master2(command, 0); + do_sync_with_master2(command, 0, ""); break; } case Q_COMMENT: |