From ee1083371067f687eb32bce453f18e9313662819 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 27 Nov 2003 20:51:53 +0300 Subject: [PATCH 01/22] Second attempt: trying to add Statement context to sources. Added classes Statement, Statement_map Merge commit sql/slave.cc: no THD::init_for_queries() as mem_root is statement-local sql/sql_class.cc: added Statement sql/sql_class.h: Statement added sql/sql_parse.cc: no THD::init_for_queries() sql/sql_prepare.cc: current_stmt_id -> statement_id_counter --- sql/slave.cc | 1 - sql/sql_class.cc | 108 +++++++++++++++++++++++++++--------- sql/sql_class.h | 134 ++++++++++++++++++++++++++++++++++++++++----- sql/sql_parse.cc | 8 +-- sql/sql_prepare.cc | 2 +- 5 files changed, 206 insertions(+), 47 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index c531d3cc4f7..a10d0488eed 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3106,7 +3106,6 @@ slave_begin: sql_print_error("Failed during slave thread initialization"); goto err; } - thd->init_for_queries(); rli->sql_thd= thd; thd->temporary_tables = rli->save_temporary_tables; // restore temp tables pthread_mutex_lock(&LOCK_thread_count); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index e2d1069975b..539c864d5ee 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -86,28 +86,28 @@ extern "C" void free_user_var(user_var_entry *entry) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), is_fatal_error(0), +THD::THD():user_time(0), + is_fatal_error(0), last_insert_id_used(0), insert_id_used(0), rand_used(0), in_lock_tables(0), global_read_lock(0), bootstrap(0), spcont(NULL) { - lex= &main_lex; - host=user=priv_user=db=query=ip=0; + host= user= priv_user= db= ip= 0; host_or_ip= "connecting host"; - locked=some_tables_deleted=no_errors=password= - query_start_used=prepare_command=0; + locked=some_tables_deleted=no_errors=password= 0; + query_start_used= 0; count_cuted_fields= CHECK_FIELD_IGNORE; killed= NOT_KILLED; - db_length=query_length=col_access=0; + db_length= col_access=0; query_error= tmp_table_used= 0; next_insert_id=last_insert_id=0; open_tables= temporary_tables= handler_tables= derived_tables= 0; tmp_table=0; lock=locked_tables=0; used_tables=0; - cuted_fields= sent_row_count= current_stmt_id= 0L; + cuted_fields= sent_row_count= 0L; + statement_id_counter= 0UL; // Must be reset to handle error with THD's created for init of mysqld - lex->current_select= 0; start_time=(time_t) 0; current_linfo = 0; slave_thread = 0; @@ -141,7 +141,6 @@ THD::THD():user_time(0), is_fatal_error(0), server_id = ::server_id; slave_net = 0; command=COM_CONNECT; - set_query_id=1; #ifndef NO_EMBEDDED_ACCESS_CHECKS db_access=NO_ACCESS; #endif @@ -149,6 +148,9 @@ THD::THD():user_time(0), is_fatal_error(0), *scramble= '\0'; init(); + init_sql_alloc(&mem_root, // must be after init() + variables.query_alloc_block_size, + variables.query_prealloc_size); /* Initialize sub structures */ bzero((char*) &mem_root,sizeof(mem_root)); init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); @@ -192,7 +194,9 @@ THD::THD():user_time(0), is_fatal_error(0), transaction.trans_log.end_of_file= max_binlog_cache_size; } #endif - + init_sql_alloc(&transaction.mem_root, + variables.trans_alloc_block_size, + variables.trans_prealloc_size); /* We need good random number initialization for new thread Just coping global one will not work @@ -235,22 +239,6 @@ void THD::init(void) } -/* - Init THD for query processing - - This has to be called once before we call mysql_parse() -*/ - -void THD::init_for_queries() -{ - init_sql_alloc(&mem_root, variables.query_alloc_block_size, - variables.query_prealloc_size); - init_sql_alloc(&transaction.mem_root, - variables.trans_alloc_block_size, - variables.trans_prealloc_size); -} - - /* Do what's needed when one invokes change user @@ -351,7 +339,6 @@ THD::~THD() safeFree(user); safeFree(db); safeFree(ip); - free_root(&mem_root,MYF(0)); free_root(&warn_root,MYF(0)); free_root(&transaction.mem_root,MYF(0)); mysys_var=0; // Safety (shouldn't be needed) @@ -1269,3 +1256,70 @@ bool select_dumpvar::send_eof() ::send_ok(thd,row_count); return 0; } + + +/* + Statement functions +*/ + +Statement::Statement(THD *thd) + :id(++thd->statement_id_counter), + query_id(0), /* initialized later */ + set_query_id(1), + allow_sum_func(0), /* initialized later */ + command(COM_SLEEP), /* reset in THD counstructor and mysql_parse */ + lex(&main_lex), + query(0), + query_length(0), + free_list(0) /* reset in THD constructor */ +{ + init_sql_alloc(&mem_root, + thd->variables.query_alloc_block_size, + thd->variables.query_prealloc_size); +} + +/* + This constructor is called when statement is a subobject of THD: + Some variables are initialized in THD::init due to locking problems + This statement object will be used to +*/ + +Statement::Statement() + :id(0), + query_id(0), + set_query_id(1), + allow_sum_func(0), + command(COM_SLEEP), + lex(&main_lex), + query(0), + query_length(0), + free_list(0) +{ + bzero((char *) &mem_root, sizeof(mem_root)); +} + + +Statement::~Statement() +{ + free_root(&mem_root, MYF(0)); +} + +C_MODE_START + +static byte * +get_statement_id_as_hash_key(const byte *record, uint *key_length, + my_bool not_used __attribute__((unused))) +{ + const Statement *statement= (const Statement *) record; + *key_length= sizeof(statement->id); + return (byte *) &((const Statement *) statement)->id; +} + +C_MODE_END + +Statement_map::Statement_map() +{ + enum { START_HASH_SIZE = 16 }; + hash_init(&st_hash, default_charset_info, START_HASH_SIZE, 0, 0, + get_statement_id_as_hash_key, (hash_free_key) 0, MYF(0)); +} diff --git a/sql/sql_class.h b/sql/sql_class.h index f9d74f8b4da..211232e85ea 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -431,12 +431,126 @@ struct system_variables }; void free_tmp_table(THD *thd, TABLE *entry); + + +/* + State of a single command executed against this connection. + One connection can contain a lot of simultaneously running statements, + some of which could be: + - prepared, that is, contain placeholders, + - opened as cursors. We maintain 1 to 1 relationship between + statement and cursor - if user wants to create another cursor for his + query, we create another statement for it. + To perform some action with statement we reset THD part to the state of + that statement, do the action, and then save back modified state from THD + to the statement. It will be changed in near future, and Statement will + be used explicitly. +*/ + +class Statement +{ +public: + /* FIXME: must be private */ + LEX main_lex; +public: + /* + Uniquely identifies each statement object in scope of thread. + Can't be const at the moment because of substitute() method + */ + /* const */ ulong id; + + /* + Id of current query. Statement can be reused to execute several queries + query_id is global in context of the whole MySQL server. + ID is automatically generated from mutex-protected counter. + It's used in handler code for various purposes: to check which columns + from table are necessary for this select, to check if it's necessary to + update auto-updatable fields (like auto_increment and timestamp). + */ + ulong query_id; + /* + - if set_query_id=1, we set field->query_id for all fields. In that case + field list can not contain duplicates. + */ + bool set_query_id; + /* + This variable is used in post-parse stage to declare that sum-functions, + or functions which have sense only if GROUP BY is present, are allowed. + For example in queries + SELECT MIN(i) FROM foo + SELECT GROUP_CONCAT(a, b, MIN(i)) FROM ... GROUP BY ... + MIN(i) have no sense. + Though it's grammar-related issue, it's hard to catch it out during the + parse stage because GROUP BY clause goes in the end of query. This + variable is mainly used in setup_fields/fix_fields. + See item_sum.cc for details. + */ + bool allow_sum_func; + /* + Type of current query: COM_PREPARE, COM_QUERY, etc. Set from + first byte of the packet in do_command() + */ + enum enum_server_command command; + + LEX *lex; // parse tree descriptor + /* + Points to the query associated with this statement. It's const, but + we need to declare it char * because all table handlers are written + in C and need to point to it. + */ + char *query; + uint32 query_length; // current query length + /* + List of items created in the parser for this query. Every item puts + itself to the list on creation (see Item::Item() for details)) + */ + Item *free_list; + MEM_ROOT mem_root; + +protected: + Statement(); +public: + Statement(THD *thd); + virtual ~Statement(); +}; + + +/* + Used to seek all existing statements in the connection + Not responsible for statements memory. +*/ + +class Statement_map +{ +public: + Statement_map(); + + int insert(Statement *statement) + { + return my_hash_insert(&st_hash, (byte *) statement); + } + Statement *seek(ulonglong id) + { + return (Statement *) hash_search(&st_hash, (byte *) &id, sizeof(id)); + } + void erase(Statement *statement) + { + hash_delete(&st_hash, (byte *) statement); + } + + ~Statement_map() { hash_free(&st_hash); } +private: + HASH st_hash; +}; + + /* For each client connection we create a separate thread with THD serving as a thread/connection descriptor */ -class THD :public ilink +class THD :public ilink, + public Statement { public: #ifdef EMBEDDED_LIBRARY @@ -449,9 +563,6 @@ public: ulong extra_length; #endif NET net; // client connection descriptor - LEX main_lex; - LEX *lex; // parse tree descriptor - MEM_ROOT mem_root; // 1 command-life memory pool MEM_ROOT warn_root; // For warnings and errors Protocol *protocol; // Current protocol Protocol_simple protocol_simple; // Normal protocol @@ -464,7 +575,6 @@ public: struct system_variables variables; // Changeable local variables pthread_mutex_t LOCK_delete; // Locked before thd is deleted - char *query; // Points to the current query, /* A pointer to the stack frame of handle_one_connection(), which is called first in the thread for handling a client @@ -513,7 +623,6 @@ public: uint dbug_sentry; // watch out for memory corruption #endif struct st_my_thread_var *mysys_var; - enum enum_server_command command; uint32 server_id; uint32 file_id; // for LOAD DATA INFILE /* @@ -546,7 +655,6 @@ public: free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); } } transaction; - Item *free_list; Field *dupp_field; #ifndef __WIN__ sigset_t signals,block_signals; @@ -580,15 +688,16 @@ public: List warn_list; uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; uint total_warn_count; - ulong query_id, warn_id, version, options, thread_id, col_access; - ulong current_stmt_id; + ulong warn_id, version, options, thread_id, col_access; + + /* Statement id is thread-wide. This counter is used to generate ids */ + ulong statement_id_counter; ulong rand_saved_seed1, rand_saved_seed2; ulong row_count; // Row counter, mainly for errors and warnings long dbug_thread_id; pthread_t real_id; uint current_tablenr,tmp_table; uint server_status,open_options; - uint32 query_length; uint32 db_length; uint select_number; //number of select (used for EXPLAIN) /* variables.transaction_isolation is reset to this after each commit */ @@ -601,9 +710,9 @@ public: char scramble[SCRAMBLE_LENGTH+1]; bool slave_thread; - bool set_query_id,locked,some_tables_deleted; + bool locked, some_tables_deleted; bool last_cuted_field; - bool no_errors, allow_sum_func, password, is_fatal_error; + bool no_errors, password, is_fatal_error; bool query_start_used,last_insert_id_used,insert_id_used,rand_used; bool system_thread,in_lock_tables,global_read_lock; bool query_error, bootstrap, cleanup_done; @@ -647,7 +756,6 @@ public: void init(void); void change_user(void); - void init_for_queries(); void cleanup(void); bool store_globals(); #ifdef SIGNAL_WITH_VIO_CLOSE diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7afc268b270..ea34fdd6ac5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -949,7 +949,6 @@ pthread_handler_decl(handle_one_connection,arg) thd->command=COM_SLEEP; thd->version=refresh_version; thd->set_time(); - thd->init_for_queries(); while (!net->error && net->vio != 0 && !(thd->killed == THD::KILL_CONNECTION)) { if (do_command(thd)) @@ -1029,7 +1028,6 @@ extern "C" pthread_handler_decl(handle_bootstrap,arg) thd->priv_user=thd->user=(char*) my_strdup("boot", MYF(MY_WME)); buff= (char*) thd->net.buff; - thd->init_for_queries(); while (fgets(buff, thd->net.max_packet, file)) { uint length=(uint) strlen(buff); @@ -1202,13 +1200,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd, { NET *net= &thd->net; bool error= 0; + DBUG_ENTER("dispatch_command"); + + thd->command=command; /* Commands which will always take a long time should be marked with this so that they will not get logged to the slow query log */ - DBUG_ENTER("dispatch_command"); - - thd->command=command; thd->slow_command=FALSE; thd->set_time(); VOID(pthread_mutex_lock(&LOCK_thread_count)); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 9721b77e38a..4791dd94bd6 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -904,7 +904,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) bzero((char*) &stmt, sizeof(stmt)); - stmt.stmt_id= ++thd->current_stmt_id; + stmt.stmt_id= ++thd->statement_id_counter; init_sql_alloc(&stmt.mem_root, thd->variables.query_alloc_block_size, thd->variables.query_prealloc_size); From d1a673c8c7349bef45b1acf8a678893be62f0b24 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Dec 2003 15:56:18 +0100 Subject: [PATCH 02/22] - removed INSTALL-WIN-SOURCE from the BK tree as its content has been added to manual.texi - extract it from there instead. BitKeeper/deleted/.del-INSTALL-WIN-SOURCE~8b030042cb95ca9: Delete: INSTALL-WIN-SOURCE Docs/Makefile.am: - Create INSTALL-WIN-SOURCE from mysql.info --- Docs/Makefile.am | 5 +- INSTALL-WIN-SOURCE | 221 --------------------------------------------- 2 files changed, 4 insertions(+), 222 deletions(-) delete mode 100644 INSTALL-WIN-SOURCE diff --git a/Docs/Makefile.am b/Docs/Makefile.am index 606279f967e..19b2efd4cab 100644 --- a/Docs/Makefile.am +++ b/Docs/Makefile.am @@ -26,7 +26,7 @@ EXTRA_DIST = $(noinst_SCRIPTS) $(BUILT_SOURCES) mysqld_error.txt \ all: $(targets) txt_files -txt_files: ../INSTALL-SOURCE ../COPYING \ +txt_files: ../INSTALL-SOURCE ../COPYING ../INSTALL-WIN-SOURCE \ INSTALL-BINARY ../support-files/MacOSX/ReadMe.txt CLEAN_FILES: $(BUILD_SOURCES) @@ -194,6 +194,9 @@ GT = $(srcdir)/Support/generate-text-files.pl ../INSTALL-SOURCE: mysql.info $(GT) perl -w $(GT) mysql.info "Installing" "Tutorial" > $@ +../INSTALL-WIN-SOURCE: mysql.info $(GT) + perl -w $(GT) mysql.info "Windows source build" "Post-installation" > $@ + # We put the description for the binary installation here so that # people who download source wont have to see it. It is moved up to # the toplevel by the script that makes the binary tar files. diff --git a/INSTALL-WIN-SOURCE b/INSTALL-WIN-SOURCE deleted file mode 100644 index 969eb91f5b1..00000000000 --- a/INSTALL-WIN-SOURCE +++ /dev/null @@ -1,221 +0,0 @@ -######################################################### -# # -# HOWTO : INSTALL MySQL FROM SOURCE # -# WINDOWS PORT # -# # -# Copyright (C) MySQL AB 1995-2003 # -######################################################### - -This is a simple 'HOWTO' document describing how to -build MySQL binaries for versions 4.1 and above on -Windows. Instructions are provided for building binaries -from a standard source distribution or from the BitKeeper -tree that contains the latest development source. - ---------------------------------------------------------- -NOTE ---------------------------------------------------------- - -Normally, it is best to use precompiled binary distributions -of MySQL that are built specifically for optimal performance -on Windows by MySQL AB. Binary distributions are available -from: - -http://www.mysql.com/downloads/ - -The instructions in this document are strictly for users -who want to test MySQL on Windows from the latest source or -from the BitKeeper tree, and for internal MySQL developers. - --------------------------------------------------------- -TABLE OF CONTENTS --------------------------------------------------------- -1. REQUIREMENTS -2. OBTAINING A WINDOWS SOURCE DISTRIBUTION -3. CREATING A SOURCE PACKAGE FROM THE 'BitKeeper' TREE -4. BUILDING 'mysql server and clients' FROM VC++ WORKSPACE -5. BUILDING FROM 'nmake' MAKEFILES -6. STARTING THE MYSQL SERVER FOR THE FIRST TIME -7. TESTING THE CONNECTION -8. SPECIAL NOTES AND CONSIDERATIONS - -------------------------------------------------------- -1. REQUIREMENTS -------------------------------------------------------- - -To build MySQL on Windows from source, you need the -following compiler and resources available on your Windows -system: - - - Microsoft Visual C++ 6.0 and above - - ~45 MB disk space - - 64 MB RAM - -You'll also need a MySQL source distribution, which you -can obtain as described in section 2. - -------------------------------------------------------- -2. OBTAINING A WINDOWS SOURCE DISTRIBUTION -------------------------------------------------------- - -There are two ways you can get a Windows source distribution -for MySQL version 4.1 and above: - - I. Obtain a MySQL AB-distributed source distribution for the - particular version of MySQL in which you are interested. - Prepackaged source distributions are available for released - versions of MySQL and can be obtained from: - - http://www.mysql.com/downloads/ - - II. Alternatively, you can package a source distribution - yourself from the latest BitKeeper developer source - tree. If you plan to do this, you must create the - package on a Unix system and then transfer it to your - Windows system. (The reason for this is that some of the - configuration and build steps require tools that work only - on Unix.) The BitKeeper approach thus requires: - - - A system running Unix, or a Unix-like system such as Linux - - BitKeeper 3.0 installed on that system (you can obtain - BitKeeper from http://www.bitkeeper.com) - -If you are using the first option, you can skip the next -section and go directly to "BUILDING 'mysql server & clients' -FROM VC++ WORKSPACE" - -------------------------------------------------------- -3. CREATING A SOURCE PACKAGE FROM THE 'BitKeeper' TREE -------------------------------------------------------- - -To build the latest Windows source package from the current -BitKeeper source tree, use the following instructions. Please -note that this procedure must be performed on a system -running a Unix or Unix-like operating system. (The procedure -is known to work well on Linux, for example.) - -- Clone the BitKeeper source tree for MySQL (version 4.1 - or above, as desired). For more information how to clone - the source tree, see the instructions at: - - http://www.mysql.com/doc/en/Installing_source_tree.html - -- Configure and build the distribution so that you have a - server binary to work with. One way to do this is to run - the following command in the top-level directory of your - source tree: - - ./BUILD/compile-pentium-max - -- After making sure that the build process completed successfully, - run the following utility script from top-level directory - of your source tree: - - ./scripts/make_win_src_distribution - - This script creates a Windows source package, to be used on - your Windows system. You can supply different options to the - script based on your needs. It accepts the following options: - - --debug Debug, without creating the package - --tmp Specify the temporary location - --suffix Suffix name for the package - --dirname Directory name to copy files (intermediate) - --silent Do not list verbosely files processed - --tar Create tar.gz package instead of .zip - --help Show this help message - - By default, make_win_src_distribution creates a zipped - archive with the name mysql-$version-win-src.zip, where - $version represents the version of your MySQL source tree. - - - Copy or upload to your Windows machine the Windows source - package that you have just created. To compile it, use - the instructions in the next section. - ---------------------------------------------------------- -4. BUILDING 'mysql server & clients' FROM VC++ WORKSPACE ---------------------------------------------------------- - -NOTE: MySQL 4.1 and above VC++ workspace files are compatible - with Microsoft Visual Studio 6.0 and above(7.0/.NET) - editions and tested by MySQL folks before each - release. - -Unpack the Windows source zipped archive to a folder and open -mysql.dsw from your top-level directory. - -If you want to build both release and debug versions, then -select 'build' -> 'buildall' option. To build only release -or debug versions, select all appropriate workspaces from -the 'build' -> 'batch build' option. - -The simplest solution to building the basic clients and core -server is to set your current active workspace as 'mysqld' -release or debug version, and just hit 'build' or 'F7', which -creates the necessary client binaries in the 'client_release' -or 'client_debug' directories. The libraries are placed in the -'lib_release' and 'lib_debug' directories for release and -debug versions, respectively. - -Now you have built the distribution. If you get any compiler -errors, please cross check and email the compiler output to -win32@lists.mysql.com for further assistance. - ---------------------------------------------------------- -5. BUILDING FROM 'nmake' MAKEFILES ---------------------------------------------------------- -TODO from MySQL PIEFU team. - ---------------------------------------------------------- -6. STARTING THE MYSQL SERVER FOR THE FIRST TIME ---------------------------------------------------------- - -The server built using the preceding instructions will -expect that the MySQL base directory and data directory -are C:\mysql and C:\mysql\data by default. If you want to -test your server using the source root directory and its -data directory as the base directory and data directory, -you will need to tell the server their pathnames. You can -either do this on the command line with the --basedir -and --data-dir options, or place appropriate options in -an option file (C:\my.cnf or the my.ini file in your -Windows directory). If you have an existing data directory -elsewhere that you want to use, you can specify its pathname -instead. - -Start your server from the 'client_release' or 'client_debug' -directory (depending on which server you want to use). The -general instructions are given here: - -http://www.mysql.com/doc/en/Windows_installation.html - -You'll have to adapt the instructions appropriately if you -want to use a different base directory and/or data directory. - -That's all!!! See, it's as simple to build MySQL on Windows -as on any other platform!!! - ---------------------------------------------------------- -7. TESTING THE CONNECTION ---------------------------------------------------------- - -Once the server is running in standalone fashion or as a -service based on your configuration, try to connect to it -from the 'mysql' command line SQL interactive utility that -exists in your 'client_release' or 'client_debug' directory. - ---------------------------------------------------------- -8. SPECIAL NOTES AND CONSIDERATIONS ---------------------------------------------------------- - -- For production use, MySQL AB does not advise using a MySQL - server built by yourself from source. It is preferable to - stick to using binaries shipped by MySQL AB. - -- If you find something not working as expected, or you have - suggestions about ways to improve the current build process - on Windows, please email to win32@lists.mysql.com. - -Thanks -MySQL Team From c74c90eef6843ec781f7eca0cd632356ee4f65af Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Dec 2003 20:23:13 +0000 Subject: [PATCH 03/22] WorkLog#1280 - Remove fixed table handler from lex/yacc include/mysqld_error.h: New error message: unknown table engine mysql-test/r/create.result: New error message: unknown table engine mysql-test/t/create.test: New error message: unknown table engine sql/lex.h: Remove some keywords: HEAP, ISAM, MERGE, MEMORY, MRG_MYISAM, MYISAM sql/mysql_priv.h: Remove unused symbol sql/set_var.h: New system variable type: sys_var_thd_table_type sql/sql_yacc.yy: Remove tokens and make table_types resolve at run time sql/sql_show.cc: Tidy up sql/sql_table.cc: Tidy up include/sql_state.h: Fix indent sql/mysqld.cc: optimize mysql-test/r/rpl_change_master.result: It wouldn't pass the tests mysql-test/r/variables.result: Fix for changes mysql-test/r/warnings.result: Fix for changes mysql-test/t/variables.test: Fix for changes sql/handler.h: parameter is a const sql/set_var.cc: Code clean up for sys_var_thd_table_type::check() sql/handler.cc: More tidyup sql/share/czech/errmsg.txt: Fixups during review sql/share/danish/errmsg.txt: Fixups during review sql/share/dutch/errmsg.txt: Fixups during review sql/share/english/errmsg.txt: Fixups during review sql/share/estonian/errmsg.txt: Fixups during review sql/share/french/errmsg.txt: Fixups during review sql/share/german/errmsg.txt: Fixups during review sql/share/greek/errmsg.txt: Fixups during review sql/share/hungarian/errmsg.txt: Fixups during review sql/share/italian/errmsg.txt: Fixups during review sql/share/japanese/errmsg.txt: Fixups during review sql/share/korean/errmsg.txt: Fixups during review sql/share/norwegian-ny/errmsg.txt: Fixups during review sql/share/norwegian/errmsg.txt: Fixups during review sql/share/polish/errmsg.txt: Fixups during review sql/share/portuguese/errmsg.txt: Fixups during review sql/share/romanian/errmsg.txt: Fixups during review sql/share/russian/errmsg.txt: Fixups during review sql/share/serbian/errmsg.txt: Fixups during review sql/share/slovak/errmsg.txt: Fixups during review sql/share/spanish/errmsg.txt: Fixups during review sql/share/swedish/errmsg.txt: Fixups during review sql/share/ukrainian/errmsg.txt: Fixups during review BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- BitKeeper/etc/logging_ok | 1 + include/mysqld_error.h | 3 +- include/sql_state.h | 1 + mysql-test/r/create.result | 14 +++-- mysql-test/r/rpl_change_master.result | 4 +- mysql-test/r/variables.result | 4 +- mysql-test/r/warnings.result | 4 +- mysql-test/t/create.test | 4 +- mysql-test/t/variables.test | 2 +- sql/handler.cc | 75 +++++++++++++++++++++++---- sql/handler.h | 12 ++++- sql/lex.h | 6 --- sql/mysql_priv.h | 1 - sql/mysqld.cc | 5 +- sql/set_var.cc | 59 ++++++++++++++++++++- sql/set_var.h | 20 +++++++ sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sql_show.cc | 31 +---------- sql/sql_table.cc | 4 +- sql/sql_yacc.yy | 25 +++------ 42 files changed, 209 insertions(+), 89 deletions(-) diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 9fecdc743db..57b624db888 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -8,6 +8,7 @@ WAX@sergbook.mysql.com administrador@light.hegel.local ahlentz@co3064164-a.rochd1.qld.optusnet.com.au akishkin@work.mysql.com +antony@ltantony.rdg.cyberkinetica.homeunix.net arjen@co3064164-a.bitbike.com arjen@fred.bitbike.com arjen@george.bitbike.com diff --git a/include/mysqld_error.h b/include/mysqld_error.h index a6e23fbff3a..bb5d3ae42f4 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -300,4 +300,5 @@ #define ER_WARN_QC_RESIZE 1281 #define ER_BAD_FT_COLUMN 1282 #define ER_UNKNOWN_KEY_CACHE 1283 -#define ER_ERROR_MESSAGES 284 +#define ER_UNKNOWN_TABLE_ENGINE 1284 +#define ER_ERROR_MESSAGES 285 diff --git a/include/sql_state.h b/include/sql_state.h index a514b1e59fc..ad62ddeb670 100644 --- a/include/sql_state.h +++ b/include/sql_state.h @@ -161,3 +161,4 @@ ER_WARN_DATA_OUT_OF_RANGE, "01000", "", ER_WARN_DATA_TRUNCATED, "01000", "", ER_WRONG_NAME_FOR_INDEX, "42000", "", ER_WRONG_NAME_FOR_CATALOG, "42000", "", +ER_UNKNOWN_TABLE_ENGINE, "42000", "", diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 28f06f0bf47..e71eff44df8 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -200,17 +200,16 @@ t1 CREATE TABLE `t1` ( ) TYPE=HEAP DEFAULT CHARSET=latin1 drop table t1; SET SESSION table_type="gemini"; +ERROR 42000: Unknown table engine 'gemini' SELECT @@table_type; @@table_type -GEMINI +HEAP CREATE TABLE t1 (a int not null); -Warnings: -Warning 1265 Using storage engine MYISAM for table 't1' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0' -) TYPE=MyISAM DEFAULT CHARSET=latin1 +) TYPE=HEAP DEFAULT CHARSET=latin1 SET SESSION table_type=default; drop table t1; create table t1 ( k1 varchar(2), k2 int, primary key(k1,k2)); @@ -349,17 +348,16 @@ t1 CREATE TABLE `t1` ( ) TYPE=HEAP DEFAULT CHARSET=latin1 drop table t1; SET SESSION table_type="gemini"; +ERROR 42000: Unknown table engine 'gemini' SELECT @@table_type; @@table_type -GEMINI +HEAP CREATE TABLE t1 (a int not null); -Warnings: -Warning 1265 Using storage engine MYISAM for table 't1' show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(11) NOT NULL default '0' -) TYPE=MyISAM DEFAULT CHARSET=latin1 +) TYPE=HEAP DEFAULT CHARSET=latin1 SET SESSION table_type=default; drop table t1; create table t1(a int,b int,c int unsigned,d date,e char,f datetime,g time,h blob); diff --git a/mysql-test/r/rpl_change_master.result b/mysql-test/r/rpl_change_master.result index 883cb65171c..a886ad9c304 100644 --- a/mysql-test/r/rpl_change_master.result +++ b/mysql-test/r/rpl_change_master.result @@ -15,11 +15,11 @@ select * from t1; n 1 show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master # 127.0.0.1 root 9306 1 master-bin.000001 273 slave-relay-bin.000002 258 master-bin.000001 No No 0 0 214 317 None 0 No # change master to master_user='root'; show slave status; -Slave_IO_State Master_Host Master_User Master_Port Connect_retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_do_db Replicate_ignore_db Replicate_do_table Replicate_ignore_table Replicate_wild_do_table Replicate_wild_ignore_table Last_errno Last_error Skip_counter Exec_master_log_pos Relay_log_space Until_condition Until_Log_File Until_Log_pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_behind_master +Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master # 127.0.0.1 root 9306 1 master-bin.000001 214 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 214 4 None 0 No # select release_lock("a"); release_lock("a") diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 90654bece2e..8face0ce2b7 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -121,7 +121,7 @@ Variable_name Value table_type HEAP show global variables like 'table_type'; Variable_name Value -table_type INNODB +table_type InnoDB set GLOBAL query_cache_size=100000; set GLOBAL myisam_max_sort_file_size=2000000; show global variables like 'myisam_max_sort_file_size'; @@ -219,7 +219,7 @@ ERROR HY000: Unknown system variable 'unknown_variable' set max_join_size="hello"; ERROR 42000: Wrong argument type to variable 'max_join_size' set table_type=UNKNOWN_TABLE_TYPE; -ERROR 42000: Variable 'table_type' can't be set to the value of 'UNKNOWN_TABLE_TYPE' +ERROR 42000: Unknown table engine 'UNKNOWN_TABLE_TYPE' set table_type=INNODB, big_tables=2; ERROR 42000: Variable 'big_tables' can't be set to the value of '2' show local variables like 'table_type'; diff --git a/mysql-test/r/warnings.result b/mysql-test/r/warnings.result index 26353785733..1942f1a25bb 100644 --- a/mysql-test/r/warnings.result +++ b/mysql-test/r/warnings.result @@ -121,8 +121,8 @@ select @@warning_count; drop table t1; create table t1 (id int) type=isam; Warnings: -Warning 1265 Using storage engine MYISAM for table 't1' +Warning 1265 Using storage engine MyISAM for table 't1' alter table t1 type=isam; Warnings: -Warning 1265 Using storage engine MYISAM for table 't1' +Warning 1265 Using storage engine MyISAM for table 't1' drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 0c1280751bc..d09dd8a8362 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -155,7 +155,7 @@ SELECT @@table_type; CREATE TABLE t1 (a int not null); show create table t1; drop table t1; -# Test what happens when using a non existing table type +--error 1284 SET SESSION table_type="gemini"; SELECT @@table_type; CREATE TABLE t1 (a int not null); @@ -276,7 +276,7 @@ SELECT @@table_type; CREATE TABLE t1 (a int not null); show create table t1; drop table t1; -# Test what happens when using a non existing table type +--error 1284 SET SESSION table_type="gemini"; SELECT @@table_type; CREATE TABLE t1 (a int not null); diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 6365ad77c57..241e0c73931 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -124,7 +124,7 @@ set big_tables="OFFF"; set unknown_variable=1; --error 1232 set max_join_size="hello"; ---error 1231 +--error 1284 set table_type=UNKNOWN_TABLE_TYPE; --error 1231 set table_type=INNODB, big_tables=2; diff --git a/sql/handler.cc b/sql/handler.cc index 5267ddc8986..fe168d12fce 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -50,14 +50,33 @@ ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, ha_commit_count, ha_rollback_count, ha_read_rnd_count, ha_read_rnd_next_count; -const char *ha_table_type[] = { - "", "DIAB_ISAM","HASH","MISAM","PISAM","RMS_ISAM","HEAP", "ISAM", - "MRG_ISAM","MYISAM", "MRG_MYISAM", "BDB", "INNODB", "GEMINI", "?", "?",NullS -}; +static SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES; -TYPELIB ha_table_typelib= +struct show_table_type_st sys_table_types[]= { - array_elements(ha_table_type)-3, "", ha_table_type + {"MyISAM", &have_yes, + "Default type from 3.23 with great performance", DB_TYPE_MYISAM}, + {"HEAP", &have_yes, + "Hash based, stored in memory, useful for temporary tables", DB_TYPE_HEAP}, + {"MEMORY", &have_yes, + "Alias for HEAP", DB_TYPE_HEAP}, + {"MERGE", &have_yes, + "Collection of identical MyISAM tables", DB_TYPE_MRG_MYISAM}, + {"MRG_MYISAM",&have_yes, + "Alias for MERGE", DB_TYPE_MRG_MYISAM}, + {"ISAM", &have_isam, + "Obsolete table type; Is replaced by MyISAM", DB_TYPE_ISAM}, + {"MRG_ISAM", &have_isam, + "Obsolete table type; Is replaced by MRG_MYISAM", DB_TYPE_MRG_ISAM}, + {"InnoDB", &have_innodb, + "Supports transactions, row-level locking and foreign keys", DB_TYPE_INNODB}, + {"INNOBASE", &have_innodb, + "Alias for INNODB", DB_TYPE_INNODB}, + {"BDB", &have_berkeley_db, + "Supports transactions and page-level locking", DB_TYPE_BERKELEY_DB}, + {"BERKELEYDB",&have_berkeley_db, + "Alias for BDB", DB_TYPE_BERKELEY_DB}, + {NullS, NULL, NullS, DB_TYPE_UNKNOWN} }; const char *ha_row_type[] = { @@ -70,6 +89,33 @@ const char *tx_isolation_names[] = TYPELIB tx_isolation_typelib= {array_elements(tx_isolation_names)-1,"", tx_isolation_names}; +enum db_type ha_resolve_by_name(const char *name, uint namelen) +{ + if (!my_strcasecmp(&my_charset_latin1, name, "DEFAULT")) { + return(enum db_type) current_thd->variables.table_type; + } + + show_table_type_st *types; + for (types= sys_table_types; types->type; types++) + { + if (!my_strcasecmp(&my_charset_latin1, name, types->type)) + return(enum db_type)types->db_type; + } + return DB_TYPE_UNKNOWN; +} + +const char *ha_get_table_type(enum db_type db_type) +{ + show_table_type_st *types; + for (types= sys_table_types; types->type; types++) + { + if (db_type == types->db_type) + return types->type; + } + + return "none"; +} + /* Use other database handler if databasehandler is not incompiled */ enum db_type ha_checktype(enum db_type database_type) @@ -77,18 +123,21 @@ enum db_type ha_checktype(enum db_type database_type) switch (database_type) { #ifdef HAVE_BERKELEY_DB case DB_TYPE_BERKELEY_DB: - return(berkeley_skip ? DB_TYPE_MYISAM : database_type); + if (berkeley_skip) break; + return (database_type); #endif #ifdef HAVE_INNOBASE_DB case DB_TYPE_INNODB: - return(innodb_skip ? DB_TYPE_MYISAM : database_type); + if (innodb_skip) break; + return (database_type); #endif #ifndef NO_HASH case DB_TYPE_HASH: #endif #ifdef HAVE_ISAM case DB_TYPE_ISAM: - return (isam_skip ? DB_TYPE_MYISAM : database_type); + if (isam_skip) break; + return (database_type); case DB_TYPE_MRG_ISAM: return (isam_skip ? DB_TYPE_MRG_MYISAM : database_type); #else @@ -102,7 +151,13 @@ enum db_type ha_checktype(enum db_type database_type) default: break; } - return(DB_TYPE_MYISAM); /* Use this as default */ + + return + DB_TYPE_UNKNOWN != (enum db_type) current_thd->variables.table_type ? + (enum db_type) current_thd->variables.table_type : + DB_TYPE_UNKNOWN != (enum db_type) global_system_variables.table_type ? + (enum db_type) global_system_variables.table_type : + DB_TYPE_MYISAM; } /* ha_checktype */ diff --git a/sql/handler.h b/sql/handler.h index 9089db60d77..2183b8fa992 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -131,6 +131,13 @@ enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1, DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, DB_TYPE_GEMINI, DB_TYPE_DEFAULT }; +struct show_table_type_st { + const char *type; + SHOW_COMP_OPTION *value; + const char *comment; + enum db_type db_type; +}; + enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED}; @@ -372,8 +379,9 @@ public: /* Some extern variables used with handlers */ +extern struct show_table_type_st sys_table_types[]; extern const char *ha_row_type[]; -extern TYPELIB ha_table_typelib, tx_isolation_typelib; +extern TYPELIB tx_isolation_typelib; /* Wrapper functions */ #define ha_commit_stmt(thd) (ha_commit_trans((thd), &((thd)->transaction.stmt))) @@ -383,6 +391,8 @@ extern TYPELIB ha_table_typelib, tx_isolation_typelib; #define ha_supports_generate(T) (T != DB_TYPE_INNODB) +enum db_type ha_resolve_by_name(const char *name, uint namelen); +const char *ha_get_table_type(enum db_type db_type); handler *get_new_handler(TABLE *table, enum db_type db_type); my_off_t ha_get_ptr(byte *ptr, uint pack_length); void ha_store_ptr(byte *buff, uint pack_length, my_off_t pos); diff --git a/sql/lex.h b/sql/lex.h index fd13af348d1..9dd3ede7f44 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -186,7 +186,6 @@ static SYMBOL symbols[] = { { "HAVING", SYM(HAVING),0,0}, { "HANDLER", SYM(HANDLER_SYM),0,0}, { "HASH", SYM(HASH_SYM),0,0}, - { "HEAP", SYM(HEAP_SYM),0,0}, { "HELP", SYM(HELP_SYM),0,0}, { "HIGH_PRIORITY", SYM(HIGH_PRIORITY),0,0}, { "HOUR", SYM(HOUR_SYM),0,0}, @@ -219,7 +218,6 @@ static SYMBOL symbols[] = { { "IF", SYM(IF),0,0}, { "IS", SYM(IS),0,0}, { "ISOLATION", SYM(ISOLATION),0,0}, - { "ISAM", SYM(ISAM_SYM),0,0}, { "ISSUER", SYM(ISSUER_SYM),0,0}, { "JOIN", SYM(JOIN_SYM),0,0}, { "KEY", SYM(KEY_SYM),0,0}, @@ -268,9 +266,7 @@ static SYMBOL symbols[] = { { "MEDIUMBLOB", SYM(MEDIUMBLOB),0,0}, { "MEDIUMTEXT", SYM(MEDIUMTEXT),0,0}, { "MEDIUMINT", SYM(MEDIUMINT),0,0}, - { "MERGE", SYM(MERGE_SYM),0,0}, { "MEDIUM", SYM(MEDIUM_SYM),0,0}, - { "MEMORY", SYM(MEMORY_SYM),0,0}, { "MICROSECOND", SYM(MICROSECOND_SYM),0,0}, { "MIDDLEINT", SYM(MEDIUMINT),0,0}, /* For powerbuilder */ { "MIN_ROWS", SYM(MIN_ROWS),0,0}, @@ -284,8 +280,6 @@ static SYMBOL symbols[] = { { "MULTILINESTRING", SYM(MULTILINESTRING),0,0}, { "MULTIPOINT", SYM(MULTIPOINT),0,0}, { "MULTIPOLYGON", SYM(MULTIPOLYGON),0,0}, - { "MRG_MYISAM", SYM(MERGE_SYM),0,0}, - { "MYISAM", SYM(MYISAM_SYM),0,0}, { "NAMES", SYM(NAMES_SYM),0,0}, { "NATURAL", SYM(NATURAL),0,0}, { "NATIONAL", SYM(NATIONAL_SYM),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b9032381c45..981714cb942 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -861,7 +861,6 @@ extern MY_BITMAP temp_pool; extern String my_empty_string; extern String my_null_string; extern SHOW_VAR init_vars[],status_vars[], internal_vars[]; -extern struct show_table_type_st table_type_vars[]; extern SHOW_COMP_OPTION have_isam; extern SHOW_COMP_OPTION have_innodb; extern SHOW_COMP_OPTION have_berkeley_db; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a0b5d910986..153520f4e93 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5417,13 +5417,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), break; case OPT_TABLE_TYPE: { - int type; - if ((type=find_type(argument, &ha_table_typelib, 2)) <= 0) + if ((enum db_type)((global_system_variables.table_type= + ha_resolve_by_name(argument, strlen(argument)))) == DB_TYPE_UNKNOWN) { fprintf(stderr,"Unknown table type: %s\n",argument); exit(1); } - global_system_variables.table_type= type-1; break; } case OPT_SERVER_ID: diff --git a/sql/set_var.cc b/sql/set_var.cc index 9b7be4afacc..4cae3827bf0 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -284,8 +284,8 @@ sys_var_thd_ulong sys_sort_buffer("sort_buffer_size", &SV::sortbuff_size); sys_var_thd_sql_mode sys_sql_mode("sql_mode", &SV::sql_mode); -sys_var_thd_enum sys_table_type("table_type", &SV::table_type, - &ha_table_typelib); +sys_var_thd_table_type sys_table_type("table_type", + &SV::table_type); sys_var_long_ptr sys_table_cache_size("table_cache", &table_cache_size); sys_var_long_ptr sys_thread_cache_size("thread_cache_size", @@ -2403,6 +2403,61 @@ int set_var_password::update(THD *thd) #endif } +/**************************************************************************** + Functions to handle table_type +****************************************************************************/ + +bool sys_var_thd_table_type::check(THD *thd, set_var *var) + /* Based upon sys_var::check_enum() */ +{ + char buff[80]; + const char *value; + String str(buff, sizeof(buff), &my_charset_latin1), *res; + + if (var->value->result_type() == STRING_RESULT) + { + if (!(res=var->value->val_str(&str)) || + !(var->save_result.ulong_value= + (ulong) ha_resolve_by_name(res->ptr(), res->length()))) + { + value= res ? res->c_ptr() : "NULL"; + goto err; + } + return 0; + } + +err: + my_error(ER_UNKNOWN_TABLE_ENGINE, MYF(0), value); + return 1; +} + +byte *sys_var_thd_table_type::value_ptr(THD *thd, enum_var_type type, + LEX_STRING *base) +{ + ulong val; + val= ((type == OPT_GLOBAL) ? global_system_variables.*offset : + thd->variables.*offset); + const char *table_type= ha_get_table_type((enum db_type)val); + return (byte *)table_type; +} + +void sys_var_thd_table_type::set_default(THD *thd, enum_var_type type) +{ + if (type == OPT_GLOBAL) + global_system_variables.*offset= (ulong) DB_TYPE_MYISAM; + else + thd->variables.*offset= (ulong) (global_system_variables.*offset); +} + +bool sys_var_thd_table_type::update(THD *thd, set_var *var) +{ + if (var->type == OPT_GLOBAL) + global_system_variables.*offset= var->save_result.ulong_value; + else + thd->variables.*offset= var->save_result.ulong_value; + return 0; +} + /**************************************************************************** Functions to handle sql_mode ****************************************************************************/ diff --git a/sql/set_var.h b/sql/set_var.h index 58ae53190e0..946341c4559 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -343,6 +343,26 @@ public: }; +class sys_var_thd_table_type :public sys_var_thd +{ +protected: + ulong SV::*offset; +public: + sys_var_thd_table_type(const char *name_arg, ulong SV::*offset_arg) + :sys_var_thd(name_arg), offset(offset_arg) + {} + bool check(THD *thd, set_var *var); +SHOW_TYPE type() { return SHOW_CHAR; } + bool check_update_type(Item_result type) + { + return type != STRING_RESULT; /* Only accept strings */ + } + void set_default(THD *thd, enum_var_type type); + bool update(THD *thd, set_var *var); + byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); +}; + + class sys_var_thd_bit :public sys_var_thd { sys_update_func update_func; diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index c40765ebf94..a29d0f7dbe8 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -296,3 +296,4 @@ character-set=latin2 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 98540e1bd0a..8d3abbc8747 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -290,3 +290,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 44c9399b821..23974c6083a 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -298,3 +298,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index e4f7c27610b..0cf2d21d60b 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -287,3 +287,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index dec488567ff..9b3977eedec 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -292,3 +292,4 @@ character-set=latin7 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index c41c927d539..469d945196a 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -287,3 +287,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 0425a709950..025f3f5172e 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -299,3 +299,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 3cf5bbf592d..2247d3751a7 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -287,3 +287,4 @@ character-set=greek "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index f1b719ba716..5f1f30b6326 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -289,3 +289,4 @@ character-set=latin2 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index ed39950e9f1..c94deae2d77 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -287,3 +287,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 9760cd3f9e8..16cf5816d03 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -289,3 +289,4 @@ character-set=ujis "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 10eed3bb2de..5bcdf2289e2 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -287,3 +287,4 @@ character-set=euckr "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 7149eea8b10..f4b6c073deb 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -289,3 +289,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index dc96d39f8dc..3fc59dc6454 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -289,3 +289,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index b2b2e52ad75..8dbec119d84 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -291,3 +291,4 @@ character-set=latin2 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index c4a150d79bf..6c69b986dbc 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -288,3 +288,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index dce141da20a..8fad1a586dc 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -291,3 +291,4 @@ character-set=latin2 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 27c1b49f4f0..90d2e1afb5c 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -289,3 +289,4 @@ character-set=koi8r "Кеш запросов не может установить размер %lu, новый размер кеша зпросов - %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 5311fa016dc..77b6b60a497 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -282,3 +282,4 @@ character-set=cp1250 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 9355e8fc0c4..49532d7f47a 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -295,3 +295,4 @@ character-set=latin2 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 3cdcc3967d7..2bfb1901d24 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -289,3 +289,4 @@ character-set=latin1 "Query cache failed to set size %lu, new query cache size is %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 17dcdb89ae6..b0c927d46b1 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -287,3 +287,4 @@ character-set=latin1 "Storleken av "Query cache" kunde inte sДttas till %lu, ny storlek Дr %lu", "Kolumn '%-.64s' kan inte vara del av ett FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 99a09afde6c..7e5cc6e94e6 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -292,3 +292,4 @@ character-set=koi8u "Кеш запит╕в неспроможен встановити розм╕р %lu, новий розм╕р кеша запит╕в - %lu", "Column '%-.64s' cannot be part of FULLTEXT index", "Unknown key cache '%-.100s'", +"Unknown table engine '%s'", diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e24102a5094..4181075cb9f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -173,33 +173,6 @@ int mysqld_show_tables(THD *thd,const char *db,const char *wild) ** List all table types supported ***************************************************************************/ -struct show_table_type_st { - const char *type; - SHOW_COMP_OPTION *value; - const char *comment; -}; - - -SHOW_COMP_OPTION have_yes= SHOW_OPTION_YES; - -static struct show_table_type_st sys_table_types[]= -{ - {"MyISAM", &have_yes, - "Default type from 3.23 with great performance"}, - {"HEAP" , &have_yes, - "Hash based, stored in memory, useful for temporary tables"}, - {"MERGE", &have_yes, - "Collection of identical MyISAM tables"}, - {"ISAM", &have_isam, - "Obsolete table type; Is replaced by MyISAM"}, - {"InnoDB", &have_innodb, - "Supports transactions, row-level locking and foreign keys"}, - {"BDB", &have_berkeley_db, - "Supports transactions and page-level locking"}, - {NullS, NULL, NullS} -}; - - int mysqld_show_table_types(THD *thd) { List field_list; @@ -213,8 +186,8 @@ int mysqld_show_table_types(THD *thd) if (protocol->send_fields(&field_list,1)) DBUG_RETURN(1); - const char *default_type_name= - ha_table_typelib.type_names[thd->variables.table_type]; + const char *default_type_name= + ha_get_table_type((enum db_type)thd->variables.table_type); show_table_type_st *types; for (types= sys_table_types; types->type; types++) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8504a408605..dcb657bdce8 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -404,7 +404,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_USING_OTHER_HANDLER, ER(ER_WARN_USING_OTHER_HANDLER), - ha_table_typelib.type_names[new_db_type], + ha_get_table_type(new_db_type), table_name); } db_options=create_info->table_options; @@ -2016,7 +2016,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_USING_OTHER_HANDLER, ER(ER_WARN_USING_OTHER_HANDLER), - ha_table_typelib.type_names[new_db_type], + ha_get_table_type(new_db_type), new_name); } if (create_info->row_type == ROW_TYPE_NOT_USED) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 0dbe14fd2ab..3d5e4e616ab 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -241,7 +241,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token GROUP %token HAVING %token HASH_SYM -%token HEAP_SYM %token HEX_NUM %token HIGH_PRIORITY %token HOSTS_SYM @@ -257,7 +256,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token INTO %token IN_SYM %token ISOLATION -%token ISAM_SYM %token JOIN_SYM %token KEYS %token KEY_SYM @@ -296,10 +294,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token MAX_QUERIES_PER_HOUR %token MAX_UPDATES_PER_HOUR %token MEDIUM_SYM -%token MERGE_SYM -%token MEMORY_SYM %token MIN_ROWS -%token MYISAM_SYM %token NAMES_SYM %token NATIONAL_SYM %token NATURAL @@ -1126,13 +1121,14 @@ create_table_option: | INDEX DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; }; table_types: - ISAM_SYM { $$= DB_TYPE_ISAM; } - | MYISAM_SYM { $$= DB_TYPE_MYISAM; } - | MERGE_SYM { $$= DB_TYPE_MRG_MYISAM; } - | HEAP_SYM { $$= DB_TYPE_HEAP; } - | MEMORY_SYM { $$= DB_TYPE_HEAP; } - | BERKELEY_DB_SYM { $$= DB_TYPE_BERKELEY_DB; } - | INNOBASE_SYM { $$= DB_TYPE_INNODB; }; + ident_or_text + { + $$ = ha_resolve_by_name($1.str,$1.length); + if ($$ == DB_TYPE_UNKNOWN) { + net_printf(YYTHD, ER_UNKNOWN_TABLE_ENGINE, $1.str); + YYABORT; + } + }; row_types: DEFAULT { $$= ROW_TYPE_DEFAULT; } @@ -4633,7 +4629,6 @@ keyword: | GLOBAL_SYM {} | HANDLER_SYM {} | HASH_SYM {} - | HEAP_SYM {} | HELP_SYM {} | HOSTS_SYM {} | HOUR_SYM {} @@ -4641,7 +4636,6 @@ keyword: | IMPORT {} | INDEXES {} | ISOLATION {} - | ISAM_SYM {} | ISSUER_SYM {} | INNOBASE_SYM {} | INSERT_METHOD {} @@ -4672,8 +4666,6 @@ keyword: | MAX_QUERIES_PER_HOUR {} | MAX_UPDATES_PER_HOUR {} | MEDIUM_SYM {} - | MERGE_SYM {} - | MEMORY_SYM {} | MICROSECOND_SYM {} | MINUTE_SYM {} | MIN_ROWS {} @@ -4683,7 +4675,6 @@ keyword: | MULTILINESTRING {} | MULTIPOINT {} | MULTIPOLYGON {} - | MYISAM_SYM {} | NAMES_SYM {} | NATIONAL_SYM {} | NCHAR_SYM {} From c829bceff47182b9b0263b60b63ebde5e1c62a10 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 2 Dec 2003 18:14:56 -0600 Subject: [PATCH 04/22] benchmarks README edits --- sql-bench/README | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) diff --git a/sql-bench/README b/sql-bench/README index 6b6a5fc95c0..a8468b4809b 100755 --- a/sql-bench/README +++ b/sql-bench/README @@ -1,27 +1,29 @@ The MySQL Benchmarks -These tests needs a MySQL version of at least 3.20.28 or 3.21.10. -NOTE: With MySQL 3.20.# you have to use '--skip-in', because MySQL 3.20 -doesn't support the IN operator. +These tests require a MySQL version of at least 3.20.28 or 3.21.10. NOTE: +With MySQL 3.20.x, you must use the --skip-in option, because MySQL 3.20 +does not support the IN() operator. Currently the following servers are supported: MySQL 3.20 and 3.21, PostgreSQL 6.#, mSQL 2.# and Solid Server 2.2 -In this directory are the queries and raw data files used to populate -the MySQL benchmarks. In order to run the benchmarks you should normally -execute a command like the following: +The benchmark directory contains the query files and raw data files used to +populate the MySQL benchmark tables. In order to run the benchmarks, you +should normally execute a command such as the following: run-all-tests --server=mysql --cmp=mysql,pg,solid --user=test --password=test --log -The above means that one wants to run the benchmark with MySQL. The limits -should be taken from all of mysql,PostgreSQL and Solid. Login name and -password is 'test'. The result should be saved as a RUN file in the output +This means that you want to run the benchmarks with MySQL. The +limits should be taken from all of MySQL, PostgreSQL, and Solid. +The login name and password for connecting to the server both are +``test''. The result should be saved as a RUN file in the output directory. -When the above script has run you will have the individual results and the +When run-all-tests has finished, will have the individual results and the the total RUN- file in the output directory. -If you want to look at some old results, try: +If you want to look at some old results, use the compare-results script. +For example: compare-results --dir=Results --cmp=mysql,pg,solid compare-results --dir=Results --cmp=mysql,pg,solid --relative @@ -29,8 +31,9 @@ compare-results --dir=Results --cmp=mysql,pg,solid --relative compare-results --dir=Results --cmp=msql,mysql,pg,solid compare-results --dir=Results --cmp=msql,mysql,pg,solid --relative -compare-results --dir=results --server=mysql --same-server --cmp=mysql,pg,solid +compare-results --dir=Results --server=mysql --same-server --cmp=mysql,pg,solid +Some of the files in the benchmark directory are: File Description @@ -41,15 +44,15 @@ Makefile.am Automake Makefile Overview-paper A paper nicked from the net about database bench- marking. README This file. -test-ATIS.sh Cretation of 29 tables and a lot of selects on them. +test-ATIS.sh Creation of 29 tables and a lot of selects on them. test-connect.sh Test how fast a connection to the server is. test-create.sh Test how fast a table is created. test-insert.sh Test create and fill of a table. test-wisconsin.sh This is a port of the PostgreSQL version of this benchmark. -run-all-test Use this to run all tests. When all test are run, +run-all-tests Use this to run all tests. When all tests are run, use the --log --use-old option to get a RUN-file. -compare-results Makes a compare table from different RUN files. +compare-results Generates a comparison table from different RUN files. server-cfg Contains the limit and functions for all supported SQL servers. If you want to add a new server, this should be the only file that neads to be changed. @@ -65,8 +68,8 @@ Useful options to all test-scripts (and run-all-tests): --host=# Hostname for MySQL server (default: localhost) --db=# Database to use (default: test) --fast Allow use of any non-standard SQL extension to - do the get things done faster. ---skip-in Don't do test with the IN operation (if the SQL server + get things done faster. +--skip-in Don't do test with the IN() operator (if the SQL server hasn't implemented this, for example mSQL and MySQL 3.20). --lock-tables Use table locking to get more speed. @@ -81,13 +84,13 @@ systematically measure and compare the performance of relational database systems with database machines. The benchmark is a single-user and single-factor experiment using a synthetic database and a controlled workload. It measures the query optimization -performance of database systems with 32 query types to exe cise the +performance of database systems with 32 query types to exercise the components of the proposed systems. The query suites include selection, join, projection, aggregate, and simple update queries. The test database consists of four generic relations. The tenk relation is the key table and most used. Two data types of small -integer number and character string are utilized. Data values are +integer numbers and character strings are utilized. Data values are uniformly distributed. The primary metric is the query elapsed time. The main criticisms of the benchmark include the nature of single-user workload, the simplistic database structure, and the From c432c0a03893c400f69a21b6279e8ad1b3896849 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Dec 2003 11:48:34 -0600 Subject: [PATCH 05/22] Delete obsolete references. sql-bench/README: The Overview-paper file has not been present since 3.20.x, either. --- sql-bench/README | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/sql-bench/README b/sql-bench/README index a8468b4809b..b0e1dfac5c1 100755 --- a/sql-bench/README +++ b/sql-bench/README @@ -1,8 +1,6 @@ The MySQL Benchmarks -These tests require a MySQL version of at least 3.20.28 or 3.21.10. NOTE: -With MySQL 3.20.x, you must use the --skip-in option, because MySQL 3.20 -does not support the IN() operator. +These tests require a MySQL version of at least 3.20.28 or 3.21.10. Currently the following servers are supported: MySQL 3.20 and 3.21, PostgreSQL 6.#, mSQL 2.# and Solid Server 2.2 @@ -41,8 +39,6 @@ Data/ATIS Contains data for 29 related tables used in the ATIS tests. Data/Wisconsin Contains data for the Wisconsin benchmark. Results Contains old benchmark results. Makefile.am Automake Makefile -Overview-paper A paper nicked from the net about database bench- - marking. README This file. test-ATIS.sh Creation of 29 tables and a lot of selects on them. test-connect.sh Test how fast a connection to the server is. @@ -69,11 +65,9 @@ Useful options to all test-scripts (and run-all-tests): --db=# Database to use (default: test) --fast Allow use of any non-standard SQL extension to get things done faster. ---skip-in Don't do test with the IN() operator (if the SQL server - hasn't implemented this, for example mSQL and MySQL 3.20). --lock-tables Use table locking to get more speed. -From a text at http://www.mgt.ncu.edu.tw/CSIM/Paper/sixth/11.html +From a text at http://www.mgt.ncu.edu.tw/CSIM/Paper/sixth/11.html: The Wisconsin Benchmark From a7990d0245a15e4b07a53f80dc4079e9f8edfd20 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 3 Dec 2003 21:10:44 -0600 Subject: [PATCH 06/22] README: minor edits sql-bench/README: minor edits --- sql-bench/README | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/sql-bench/README b/sql-bench/README index b0e1dfac5c1..431659a8756 100755 --- a/sql-bench/README +++ b/sql-bench/README @@ -44,17 +44,16 @@ test-ATIS.sh Creation of 29 tables and a lot of selects on them. test-connect.sh Test how fast a connection to the server is. test-create.sh Test how fast a table is created. test-insert.sh Test create and fill of a table. -test-wisconsin.sh This is a port of the PostgreSQL version of this - benchmark. +test-wisconsin.sh A port of the PostgreSQL version of this benchmark. run-all-tests Use this to run all tests. When all tests are run, - use the --log --use-old option to get a RUN-file. + use the --log and --use-old options to get a RUN-file. compare-results Generates a comparison table from different RUN files. -server-cfg Contains the limit and functions for all supported +server-cfg Contains the limits and functions for all supported SQL servers. If you want to add a new server, this should be the only file that neads to be changed. -Most of the test should use portable SQL to make it possible to +Most of the tests should use portable SQL to make it possible to compare different databases. Sometimes SQL extensions can make things a lot faster. In this case the test may use the extensions if the --fast option is used. From 4b994e772e47630ff2e13341cefb34edf32a5c03 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 12:02:18 +0100 Subject: [PATCH 07/22] - Added missing backslash to sql/Makefile.am that prevented the sp_* header files from being included in the source distribution sql/Makefile.am: - Added missing backslash that prevented the sp_* header files from being included in the source distribution --- sql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/Makefile.am b/sql/Makefile.am index 170cd170b96..7353b58df07 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -57,7 +57,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ lex.h lex_symbol.h sql_acl.h sql_crypt.h \ log_event.h sql_repl.h slave.h \ stacktrace.h sql_sort.h sql_cache.h set_var.h \ - spatial.h gstream.h client_settings.h + spatial.h gstream.h client_settings.h \ sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ From 3aaa8ab94e868a81b3e8935a3aca6aa93a818431 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 15:17:55 +0100 Subject: [PATCH 08/22] Fixed BUG#336: Subselects with tables does not work as values for local SP variables and BUG#1654: Stored Procedure Crash if contains subquery and set function Disallowed subselects in RETURN (for FUNCTIONs) and SET of local variables. The latter should work, but turned out to be difficult to fix, so we just disallow it for the time being. include/mysqld_error.h: New error message for unsupported subselect as SP set values (for the time being). include/sql_state.h: New error message for unsupported subselect as SP set values (for the time being). mysql-test/r/sp-error.result: Test cases for BUG#336 and BUG#1654. (Unsupported use of subselect) mysql-test/t/sp-error.test: Test cases for BUG#336 and BUG#1654. (Unsupported use of subselect) sql/item.cc: Made Item_splocal::type() work at compile time, for error checking. sql/item.h: Made Item_splocal::type() work at compile time, for error checking. sql/share/czech/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/danish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/dutch/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/english/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/estonian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/french/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/german/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/greek/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/hungarian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/italian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/japanese/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/korean/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/norwegian-ny/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/norwegian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/polish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/portuguese/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/romanian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/russian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/serbian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/slovak/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/spanish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/swedish/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/share/ukrainian/errmsg.txt: New error message for unsupported subselect as SP set values (for the time being). sql/sp_head.cc: Fixed (bogus) compile error on HP-UX alpha. sql/sql_yacc.yy: Disallowed subselects in RETURN (for FUNCTIONs) and SET of local variables. The latter should work, but turned out to be difficult to fix, so we just disallow it for the time being. --- include/mysqld_error.h | 3 ++- include/sql_state.h | 1 + mysql-test/r/sp-error.result | 10 ++++++++++ mysql-test/t/sp-error.test | 17 +++++++++++++++++ sql/item.cc | 11 +++++++++++ sql/item.h | 5 +---- sql/share/czech/errmsg.txt | 1 + sql/share/danish/errmsg.txt | 1 + sql/share/dutch/errmsg.txt | 1 + sql/share/english/errmsg.txt | 1 + sql/share/estonian/errmsg.txt | 1 + sql/share/french/errmsg.txt | 1 + sql/share/german/errmsg.txt | 1 + sql/share/greek/errmsg.txt | 1 + sql/share/hungarian/errmsg.txt | 1 + sql/share/italian/errmsg.txt | 1 + sql/share/japanese/errmsg.txt | 1 + sql/share/korean/errmsg.txt | 1 + sql/share/norwegian-ny/errmsg.txt | 1 + sql/share/norwegian/errmsg.txt | 1 + sql/share/polish/errmsg.txt | 1 + sql/share/portuguese/errmsg.txt | 1 + sql/share/romanian/errmsg.txt | 1 + sql/share/russian/errmsg.txt | 1 + sql/share/serbian/errmsg.txt | 1 + sql/share/slovak/errmsg.txt | 1 + sql/share/spanish/errmsg.txt | 1 + sql/share/swedish/errmsg.txt | 1 + sql/share/ukrainian/errmsg.txt | 1 + sql/sp_head.cc | 5 +++-- sql/sql_yacc.yy | 16 +++++++++++++--- 31 files changed, 81 insertions(+), 10 deletions(-) diff --git a/include/mysqld_error.h b/include/mysqld_error.h index 6b2e5115a4e..e203c13178e 100644 --- a/include/mysqld_error.h +++ b/include/mysqld_error.h @@ -333,4 +333,5 @@ #define ER_SP_DUP_COND 1314 #define ER_SP_DUP_CURS 1315 #define ER_SP_CANT_ALTER 1316 -#define ER_ERROR_MESSAGES 317 +#define ER_SP_SUBSELECT_NYI 1317 +#define ER_ERROR_MESSAGES 318 diff --git a/include/sql_state.h b/include/sql_state.h index 363632bc167..d206c659b60 100644 --- a/include/sql_state.h +++ b/include/sql_state.h @@ -194,3 +194,4 @@ ER_SP_DUP_VAR, "42000", "", ER_SP_DUP_COND, "42000", "", ER_SP_DUP_CURS, "42000", "", /*ER_SP_CANT_ALTER*/ +ER_SP_SUBSELECT_NYI, "0A000", "", diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index a1ac2a85b6e..37be3454812 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -270,4 +270,14 @@ ERROR 42S22: Unknown column 'valname' in 'order clause' drop procedure bug1965; select 1 into a; ERROR 42000: Undeclared variable: a +create procedure bug336(id char(16)) +begin +declare x int; +set x = (select sum(t.data) from test.t2 t); +end; +ERROR 0A000: Subselect value not supported +create function bug1654() +returns int +return (select sum(t.data) from test.t2 t); +ERROR 0A000: Statements like SELECT, INSERT, UPDATE (and others) are not allowed in a FUNCTION drop table t1; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 50a8b8c8768..32fbac2e92f 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -361,6 +361,23 @@ drop procedure bug1965| --error 1309 select 1 into a| +# +# BUG#336 +# +--error 1317 +create procedure bug336(id char(16)) +begin + declare x int; + set x = (select sum(t.data) from test.t2 t); +end| + +# +# BUG#1654 +# +--error 1296 +create function bug1654() + returns int +return (select sum(t.data) from test.t2 t)| drop table t1| diff --git a/sql/item.cc b/sql/item.cc index 2f089544761..71483bf88d4 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -240,6 +240,17 @@ Item_splocal::this_const_item() const return thd->spcont->get_item(m_offset); } +Item::Type +Item_splocal::type() const +{ + THD *thd= current_thd; + + if (thd->spcont) + return thd->spcont->get_item(m_offset)->type(); + return NULL_ITEM; // Anything but SUBSELECT_ITEM +} + + bool DTCollation::aggregate(DTCollation &dt) { if (!my_charset_same(collation, dt.collation)) diff --git a/sql/item.h b/sql/item.h index a7742f41b56..d8aea6552c3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -260,10 +260,7 @@ public: // Abstract methods inherited from Item. Just defer the call to // the item in the frame - inline enum Type type() const - { - return this_const_item()->type(); - } + enum Type type() const; inline double val() { diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 5cf1dd2a47c..76c936019a0 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -329,3 +329,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 69e14c6acf3..6bacfe53b2c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -323,3 +323,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 386ff34ef59..f45fc31b293 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -331,3 +331,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 2e159d40e40..f68d65467bb 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index e03f60ac040..12e33f48b31 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -325,3 +325,4 @@ character-set=latin7 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index b3591e2f4ab..92c831604d3 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 6a404b2083f..fcd8028863a 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -332,3 +332,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 47cb5125dbb..e5ac5e872ce 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -320,3 +320,4 @@ character-set=greek "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index cbe34d19fe1..ace96dd1420 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 6f7aaaec669..9b4b6f8c601 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index ee9a546cb11..53d39211378 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -322,3 +322,4 @@ character-set=ujis "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 6aa94a4482a..1abf59b2456 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -320,3 +320,4 @@ character-set=euckr "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 65faac4365c..2f14cdcc042 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 26d0bae406f..d086345f97b 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 55e3d9dc1dc..c0333f2b643 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 519434c24b5..1c307d60b25 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -321,3 +321,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 5c6ecd8ddd7..4bb0dd981ae 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -324,3 +324,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 6f0dd2d9ac7..7aab4d23f44 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -322,3 +322,4 @@ character-set=koi8r "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index e9be8102e0e..f32593c6441 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -315,3 +315,4 @@ character-set=cp1250 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index af3eae4f97b..6dccde95e25 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -328,3 +328,4 @@ character-set=latin2 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index b799ce54bec..dcadd07e73e 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -322,3 +322,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 40fc31dfdb3..8189d43fdbb 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -320,3 +320,4 @@ character-set=latin1 "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index e0d42d6264b..c95fd62e104 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -325,3 +325,4 @@ character-set=koi8u "Duplicate condition: %s" "Duplicate cursor: %s" "Failed to ALTER %s %s" +"Subselect value not supported" diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 70810265926..26cf30234d2 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -714,6 +714,7 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) { LEX *olex; // The other lex Item *freelist; + SELECT_LEX *sl; int res; olex= thd->lex; // Save the other lex @@ -726,7 +727,7 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) // Copy WHERE clause pointers to avoid damaging by optimisation // Also clear ref_pointer_arrays. - for (SELECT_LEX *sl= lex->all_selects_list ; + for (sl= lex->all_selects_list ; sl ; sl= sl->next_select_in_list()) { @@ -772,7 +773,7 @@ sp_instr_stmt::exec_stmt(THD *thd, LEX *lex) close_thread_tables(thd); /* Free tables */ } - for (SELECT_LEX *sl= lex->all_selects_list ; + for (sl= lex->all_selects_list ; sl ; sl= sl->next_select_in_list()) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 7e7a8976924..bf346bc24d9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1548,10 +1548,15 @@ sp_proc_stmt: } else { - sp_instr_freturn *i= - new sp_instr_freturn(lex->sphead->instructions(), - $2, lex->sphead->m_returns); + sp_instr_freturn *i; + if ($2->type() == Item::SUBSELECT_ITEM) + { /* QQ For now, just disallow subselects as values */ + send_error(lex->thd, ER_SP_BADSTATEMENT); + YYABORT; + } + i= new sp_instr_freturn(lex->sphead->instructions(), + $2, lex->sphead->m_returns); lex->sphead->add_instr(i); lex->sphead->m_has_return= TRUE; } @@ -5933,6 +5938,11 @@ option_value: } else { /* An SP local variable */ + if ($3 && $3->type() == Item::SUBSELECT_ITEM) + { /* QQ For now, just disallow subselects as values */ + send_error(lex->thd, ER_SP_SUBSELECT_NYI); + YYABORT; + } sp_pvar_t *spv= lex->spcont->find_pvar(&$1.base_name); sp_instr_set *i= new sp_instr_set(lex->sphead->instructions(), spv->offset, $3, spv->type); From 2e939d77dfbfff131a87dbeb30adc5d65393d3bc Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 15:20:44 +0100 Subject: [PATCH 09/22] - Bumped up version number in configure.in 4.1.1-alpha -> 4.1.2-alpha - tagged ChangeSet 1.1641 as "mysql-4.1.1" BitKeeper/etc/ignore: Added INSTALL-WIN-SOURCE to the ignore list configure.in: - Bumped up version number: 4.1.1-alpha -> 4.1.2-alpha --- .bzrignore | 1 + configure.in | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.bzrignore b/.bzrignore index e9de6662cb2..7a3629883af 100644 --- a/.bzrignore +++ b/.bzrignore @@ -640,3 +640,4 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +INSTALL-WIN-SOURCE diff --git a/configure.in b/configure.in index 88622ececab..f46e48eaa1a 100644 --- a/configure.in +++ b/configure.in @@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(sql/mysqld.cc) AC_CANONICAL_SYSTEM # The Docs Makefile.am parses this line! -AM_INIT_AUTOMAKE(mysql, 4.1.1-alpha) +AM_INIT_AUTOMAKE(mysql, 4.1.2-alpha) AM_CONFIG_HEADER(config.h) PROTOCOL_VERSION=10 From 722d19c3d6cb03dcc283ed8a80695dcd9fe101be Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 15:54:37 +0100 Subject: [PATCH 10/22] Fixed another compiler error on HP-UX. --- sql/sp_head.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 26cf30234d2..78829896324 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -537,6 +537,7 @@ sp_head::restore_lex(THD *thd) DBUG_ENTER("sp_head::restore_lex"); LEX *sublex= thd->lex; LEX *oldlex= (LEX *)m_lex.pop(); + SELECT_LEX *sl; if (! oldlex) return; // Nothing to restore @@ -544,7 +545,7 @@ sp_head::restore_lex(THD *thd) // Update some state in the old one first oldlex->ptr= sublex->ptr; oldlex->next_state= sublex->next_state; - for (SELECT_LEX *sl= sublex->all_selects_list ; + for (sl= sublex->all_selects_list ; sl ; sl= sl->next_select_in_list()) { @@ -584,7 +585,7 @@ sp_head::restore_lex(THD *thd) // QQ ...or just open tables in thd->open_tables? // This is not entirerly clear at the moment, but for now, we collect // tables here. - for (SELECT_LEX *sl= sublex.all_selects_list ; + for (sl= sublex.all_selects_list ; sl ; sl= sl->next_select()) { From 270b72ff4f5d59442800347be1db3ab7e3084c95 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 19:12:01 +0300 Subject: [PATCH 11/22] comment to user-level lock added --- sql/sql_class.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sql/sql_class.h b/sql/sql_class.h index beb2de9c0a9..3ffff6f1871 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -505,6 +505,11 @@ public: // TODO: document the variables below MYSQL_LOCK *lock; /* Current locks */ MYSQL_LOCK *locked_tables; /* Tables locked with LOCK */ + /* + One thread can hold up to one named user-level lock. This variable + points to a lock object if the lock is present. See item_func.cc and + chapter 'Miscellaneous functions', for functions GET_LOCK, RELEASE_LOCK. + */ ULL *ull; PREP_STMT *last_prepared_stmt; #ifndef DBUG_OFF From d535144e786ad4761dd6c4a3dcc4f3c50737da75 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 11:54:04 -0500 Subject: [PATCH 12/22] Add charset #defines for Windows platform (as of 4.1.1) include/config-win.h: Add HAVE_CHARSET_* defines for Windows --- include/config-win.h | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/include/config-win.h b/include/config-win.h index 4fdbfbbd02f..86318bddbcb 100644 --- a/include/config-win.h +++ b/include/config-win.h @@ -340,3 +340,38 @@ inline double ulonglong2double(ulonglong value) #define default_shared_memory_base_name "MYSQL" #define MYSQL_DEFAULT_CHARSET_NAME "latin1" #define MYSQL_DEFAULT_COLLATION_NAME "latin1_swedish_ci" + +/* Define charsets you want */ +/* #undef HAVE_CHARSET_armscii8 */ +/* #undef HAVE_CHARSET_ascii */ +#define HAVE_CHARSET_big5 1 +#define HAVE_CHARSET_cp1250 1 +/* #undef HAVE_CHARSET_cp1251 */ +/* #undef HAVE_CHARSET_cp1256 */ +/* #undef HAVE_CHARSET_cp1257 */ +/* #undef HAVE_CHARSET_cp850 */ +/* #undef HAVE_CHARSET_cp852 */ +/* #undef HAVE_CHARSET_cp866 */ +/* #undef HAVE_CHARSET_dec8 */ +#define HAVE_CHARSET_euckr 1 +#define HAVE_CHARSET_gb2312 1 +#define HAVE_CHARSET_gbk 1 +/* #undef HAVE_CHARSET_greek */ +/* #undef HAVE_CHARSET_hebrew */ +/* #undef HAVE_CHARSET_hp8 */ +/* #undef HAVE_CHARSET_keybcs2 */ +/* #undef HAVE_CHARSET_koi8r */ +/* #undef HAVE_CHARSET_koi8u */ +#define HAVE_CHARSET_latin1 1 +#define HAVE_CHARSET_latin2 1 +/* #undef HAVE_CHARSET_latin5 */ +/* #undef HAVE_CHARSET_latin7 */ +/* #undef HAVE_CHARSET_macce */ +/* #undef HAVE_CHARSET_macroman */ +#define HAVE_CHARSET_sjis 1 +/* #undef HAVE_CHARSET_swe7 */ +#define HAVE_CHARSET_tis620 1 +#define HAVE_CHARSET_ucs2 1 +#define HAVE_CHARSET_ujis 1 +#define HAVE_CHARSET_utf8 1 + From 580d754da662f7f9e0abf47f9e738ff737eecf6c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 18:09:36 +0000 Subject: [PATCH 13/22] Fixup error number - Broke during merge mysql-test/t/create.test: Fixup error number mysql-test/t/variables.test: Fixup error number --- mysql-test/t/create.test | 4 ++-- mysql-test/t/variables.test | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 5fc027101aa..5bb7e420e1c 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -157,7 +157,7 @@ SELECT @@table_type; CREATE TABLE t1 (a int not null); show create table t1; drop table t1; ---error 1284 +--error 1285 SET SESSION table_type="gemini"; SELECT @@table_type; CREATE TABLE t1 (a int not null); @@ -277,7 +277,7 @@ SELECT @@table_type; CREATE TABLE t1 (a int not null); show create table t1; drop table t1; ---error 1284 +--error 1285 SET SESSION table_type="gemini"; SELECT @@table_type; CREATE TABLE t1 (a int not null); diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 241e0c73931..b5c402fe962 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -124,7 +124,7 @@ set big_tables="OFFF"; set unknown_variable=1; --error 1232 set max_join_size="hello"; ---error 1284 +--error 1285 set table_type=UNKNOWN_TABLE_TYPE; --error 1231 set table_type=INNODB, big_tables=2; From 3cbe967f34204b39340373f5dd3a4a3c0b7e1d04 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 22:08:26 +0300 Subject: [PATCH 14/22] after-review fixes --- sql/sql_class.cc | 30 +++++++++++++----------------- sql/sql_class.h | 28 +++++++++++++++++++--------- 2 files changed, 32 insertions(+), 26 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 8deae294e36..4251f4f061a 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -86,8 +86,7 @@ extern "C" void free_user_var(user_var_entry *entry) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), - is_fatal_error(0), +THD::THD():user_time(0), is_fatal_error(0), last_insert_id_used(0), insert_id_used(0), rand_used(0), in_lock_tables(0), global_read_lock(0), bootstrap(0), spcont(NULL) @@ -108,6 +107,7 @@ THD::THD():user_time(0), cuted_fields= sent_row_count= 0L; statement_id_counter= 0UL; // Must be reset to handle error with THD's created for init of mysqld + lex->current_select= 0; start_time=(time_t) 0; current_linfo = 0; slave_thread = 0; @@ -339,12 +339,12 @@ THD::~THD() safeFree(user); safeFree(db); safeFree(ip); - free_root(&warn_root,MYF(0)); - free_root(&transaction.mem_root,MYF(0)); - mysys_var=0; // Safety (shouldn't be needed) + free_root(&warn_root, MYF(0)); + free_root(&transaction.mem_root, MYF(0)); + mysys_var= 0; // Safety (shouldn't be needed) pthread_mutex_destroy(&LOCK_delete); #ifndef DBUG_OFF - dbug_sentry = THD_SENTRY_GONE; + dbug_sentry= THD_SENTRY_GONE; #endif DBUG_VOID_RETURN; } @@ -1276,24 +1276,18 @@ Statement::Statement(THD *thd) :id(++thd->statement_id_counter), query_id(0), /* initialized later */ set_query_id(1), - allow_sum_func(0), /* initialized later */ - command(COM_SLEEP), /* reset in THD counstructor and mysql_parse */ + allow_sum_func(0), /* initialized later */ + command(COM_SLEEP), /* initialized later */ lex(&main_lex), - query(0), - query_length(0), - free_list(0) /* reset in THD constructor */ + query(0), /* these two are set */ + query_length(0), /* in alloc_query() */ + free_list(0) { init_sql_alloc(&mem_root, thd->variables.query_alloc_block_size, thd->variables.query_prealloc_size); } -/* - This constructor is called when statement is a subobject of THD: - Some variables are initialized in THD::init due to locking problems - This statement object will be used to hold state of currently active - statement. -*/ Statement::Statement() :id(0), @@ -1329,9 +1323,11 @@ get_statement_id_as_hash_key(const byte *record, uint *key_length, C_MODE_END + Statement_map::Statement_map() { enum { START_HASH_SIZE = 16 }; hash_init(&st_hash, default_charset_info, START_HASH_SIZE, 0, 0, get_statement_id_as_hash_key, (hash_free_key) 0, MYF(0)); } + diff --git a/sql/sql_class.h b/sql/sql_class.h index 0291114177a..019216e0c15 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -454,22 +454,22 @@ public: LEX main_lex; public: /* - Uniquely identifies each statement object in scope of thread. - Can't be const at the moment because of substitute() method + Uniquely identifies each statement object in thread scope; change during + statement lifetime. */ - /* const */ ulong id; + ulong id; /* - Id of current query. Statement can be reused to execute several queries + Id of current query. Statement can be reused to execute several queries. query_id is global in context of the whole MySQL server. - ID is automatically generated from mutex-protected counter. + Id is automatically generated from mutex-protected counter. It's used in handler code for various purposes: to check which columns from table are necessary for this select, to check if it's necessary to update auto-updatable fields (like auto_increment and timestamp). */ ulong query_id; /* - - if set_query_id=1, we set field->query_id for all fields. In that case + - if set_query_id == 1, we set field->query_id for all fields. In that case field list can not contain duplicates. */ bool set_query_id; @@ -487,8 +487,8 @@ public: */ bool allow_sum_func; /* - Type of current query: COM_PREPARE, COM_QUERY, etc. Set from - first byte of the packet in do_command() + Type of current query: COM_PREPARE, COM_QUERY, etc. Set from the + first byte of the incoming packet in do_command() */ enum enum_server_command command; @@ -508,6 +508,10 @@ public: MEM_ROOT mem_root; protected: + /* + This constructor is called when statement is a subobject of THD: + some variables are initialized in THD::init due to locking problems + */ Statement(); public: Statement(THD *thd); @@ -529,7 +533,7 @@ public: { return my_hash_insert(&st_hash, (byte *) statement); } - Statement *seek(ulonglong id) + Statement *seek(ulong id) { return (Statement *) hash_search(&st_hash, (byte *) &id, sizeof(id)); } @@ -685,6 +689,12 @@ public: USER_CONN *user_connect; CHARSET_INFO *db_charset; List temporary_tables_should_be_free; // list of temporary tables + /* + FIXME: this, and some other variables like 'count_cuted_fields' + maybe should be statement/cursor local, that is, moved to Statement + class. With current implementation warnings produced in each prepared + statement/ cursor settle here. + */ List warn_list; uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END]; uint total_warn_count; From b66c016f130934a8ee5a82b572bc46c93ad1f3e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 21:58:28 +0100 Subject: [PATCH 15/22] make a clear distinction between max_word_length in *characters* and in *bytes* --- include/ft_global.h | 4 ++-- myisam/ft_dump.c | 2 +- myisam/ft_static.c | 4 ++-- myisam/ft_update.c | 2 +- myisam/mi_check.c | 6 +++--- myisam/mi_create.c | 4 ++-- myisam/myisamchk.c | 6 +++--- myisam/sort.c | 4 ++-- sql/mysqld.cc | 4 ++-- 9 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/ft_global.h b/include/ft_global.h index df6860109e4..c30b0665216 100644 --- a/include/ft_global.h +++ b/include/ft_global.h @@ -26,8 +26,8 @@ extern "C" { #endif -#define FT_QUERY_MAXLEN 1024 -#define HA_FT_MAXLEN 254 +#define HA_FT_MAXBYTELEN 254 +#define HA_FT_MAXCHARLEN (HA_FT_MAXBYTELEN/3) typedef struct st_ft_info FT_INFO; struct _ft_vft diff --git a/myisam/ft_dump.c b/myisam/ft_dump.c index 8c40878cf00..47134af71d6 100644 --- a/myisam/ft_dump.c +++ b/myisam/ft_dump.c @@ -29,7 +29,7 @@ static my_bool verbose; static char *query=NULL; static uint lengths[256]; -#define MAX_LEN (HA_FT_MAXLEN+10) +#define MAX_LEN (HA_FT_MAXBYTELEN+10) #define HOW_OFTEN_TO_WRITE 10000 static struct my_option my_long_options[] = diff --git a/myisam/ft_static.c b/myisam/ft_static.c index cf4f3d6a02a..0dcea5bec0c 100644 --- a/myisam/ft_static.c +++ b/myisam/ft_static.c @@ -19,7 +19,7 @@ #include "ftdefs.h" ulong ft_min_word_len=4; -ulong ft_max_word_len=HA_FT_MAXLEN; +ulong ft_max_word_len=HA_FT_MAXCHARLEN; ulong ft_query_expansion_limit=5; const char *ft_boolean_syntax="+ -><()~*:\"\"&|"; @@ -29,7 +29,7 @@ const HA_KEYSEG ft_keysegs[FT_SEGS]={ 63, /* language (will be overwritten) */ 0, 0, 0, /* null_bit, bit_start, bit_end */ HA_VAR_LENGTH | HA_PACK_KEY, /* flag */ - HA_FT_MAXLEN, /* length */ + HA_FT_MAXBYTELEN, /* length */ HA_FT_WLEN, /* start */ 0, /* null_pos */ NULL /* charset */ diff --git a/myisam/ft_update.c b/myisam/ft_update.c index b94a174b292..4015abbbeba 100644 --- a/myisam/ft_update.c +++ b/myisam/ft_update.c @@ -279,7 +279,7 @@ int _mi_ft_del(MI_INFO *info, uint keynr, byte *keybuf, const byte *record, uint _ft_make_key(MI_INFO *info, uint keynr, byte *keybuf, FT_WORD *wptr, my_off_t filepos) { - byte buf[HA_FT_MAXLEN+16]; + byte buf[HA_FT_MAXBYTELEN+16]; DBUG_ENTER("_ft_make_key"); #if HA_FT_WTYPE == HA_KEYTYPE_FLOAT diff --git a/myisam/mi_check.c b/myisam/mi_check.c index 6f794ad2ea8..6b2ad9744c4 100644 --- a/myisam/mi_check.c +++ b/myisam/mi_check.c @@ -1979,7 +1979,7 @@ int mi_repair_by_sort(MI_CHECK *param, register MI_INFO *info, sort_param.key_read=sort_ft_key_read; sort_param.key_write=sort_ft_key_write; - sort_param.key_length+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXLEN; + sort_param.key_length+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXBYTELEN; } else { @@ -2375,7 +2375,7 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, total_key_length+=sort_param[i].key_length; if (sort_param[i].keyinfo->flag & HA_FULLTEXT) - sort_param[i].key_length+=FT_MAX_WORD_LEN_FOR_SORT-ft_max_word_len; + sort_param[i].key_length+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXBYTELEN; } sort_info.total_keys=i; sort_param[0].master= 1; @@ -3913,7 +3913,7 @@ static my_bool mi_too_big_key_for_sort(MI_KEYDEF *key, ha_rows rows) { uint key_maxlength=key->maxlength; if (key->flag & HA_FULLTEXT) - key_maxlength+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXLEN; + key_maxlength+=FT_MAX_WORD_LEN_FOR_SORT-HA_FT_MAXBYTELEN; return (key->flag & (HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY | HA_FULLTEXT) && ((ulonglong) rows * key_maxlength > (ulonglong) myisam_max_temp_length)); diff --git a/myisam/mi_create.c b/myisam/mi_create.c index 0982e5bdaf6..9036ced751c 100644 --- a/myisam/mi_create.c +++ b/myisam/mi_create.c @@ -289,9 +289,9 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs, } fulltext_keys++; - key_length+= HA_FT_MAXLEN+HA_FT_WLEN; + key_length+= HA_FT_MAXBYTELEN+HA_FT_WLEN; length++; /* At least one length byte */ - min_key_length_skipp+=HA_FT_MAXLEN; + min_key_length_skipp+=HA_FT_MAXBYTELEN; } else { diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index 61a1736c521..a7528a14353 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -322,11 +322,11 @@ static struct my_option my_long_options[] = { "decode_bits", OPT_DECODE_BITS, "", (gptr*) &decode_bits, (gptr*) &decode_bits, 0, GET_UINT, REQUIRED_ARG, 9L, 4L, 17L, 0L, 1L, 0}, { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "", (gptr*) &ft_min_word_len, - (gptr*) &ft_min_word_len, 0, GET_ULONG, REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, + (gptr*) &ft_min_word_len, 0, GET_ULONG, REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, 0, 1, 0}, { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", (gptr*) &ft_max_word_len, - (gptr*) &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXLEN, 10, - HA_FT_MAXLEN, 0, 1, 0}, + (gptr*) &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, + HA_FT_MAXCHARLEN, 0, 1, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/myisam/sort.c b/myisam/sort.c index 651b2331cd1..e28df1657a7 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -156,7 +156,7 @@ int _create_index_by_sort(MI_SORT_PARAM *info,my_bool no_messages, while ((maxbuffer= (int) (records/(keys-1)+1)) != skr); if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ - HA_FT_MAXLEN, MYF(0)))) + HA_FT_MAXBYTELEN, MYF(0)))) { if (my_init_dynamic_array(&buffpek, sizeof(BUFFPEK), maxbuffer, maxbuffer/2)) @@ -365,7 +365,7 @@ pthread_handler_decl(thr_find_all_keys,arg) } if ((sort_keys=(uchar **)my_malloc(keys*(sort_length+sizeof(char*))+ ((info->keyinfo->flag & HA_FULLTEXT) ? - HA_FT_MAXLEN : 0), MYF(0)))) + HA_FT_MAXBYTELEN : 0), MYF(0)))) { if (my_init_dynamic_array(&info->buffpek, sizeof(BUFFPEK), maxbuffer, maxbuffer/2)) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2a5f639a440..895941503ab 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4223,11 +4223,11 @@ replicating a LOAD DATA INFILE command.", { "ft_min_word_len", OPT_FT_MIN_WORD_LEN, "The minimum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.", (gptr*) &ft_min_word_len, (gptr*) &ft_min_word_len, 0, GET_ULONG, - REQUIRED_ARG, 4, 1, HA_FT_MAXLEN, 0, 1, 0}, + REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, 0, 1, 0}, { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "The maximum length of the word to be included in a FULLTEXT index. Note: FULLTEXT indexes must be rebuilt after changing this variable.", (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_ULONG, - REQUIRED_ARG, HA_FT_MAXLEN, 10, HA_FT_MAXLEN, 0, 1, 0}, + REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0}, { "ft_query_expansion_limit", OPT_FT_QUERY_EXPANSION_LIMIT, "Number of best matches to use for query expansion", (gptr*) &ft_query_expansion_limit, (gptr*) &ft_query_expansion_limit, 0, GET_ULONG, From 7c3be1ba3900042ba97f966858b54589edfc9800 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Dec 2003 00:56:28 +0300 Subject: [PATCH 16/22] cleanup --- sql/sql_class.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4251f4f061a..d1ebcdbd15e 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -152,7 +152,6 @@ THD::THD():user_time(0), is_fatal_error(0), variables.query_alloc_block_size, variables.query_prealloc_size); /* Initialize sub structures */ - bzero((char*) &mem_root,sizeof(mem_root)); init_alloc_root(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE); user_connect=(USER_CONN *)0; hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0, From c135ce0255f66af4354e5b4abb6dfb49207fb7f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 4 Dec 2003 23:18:04 +0100 Subject: [PATCH 17/22] test result fixed --- mysql-test/r/fulltext_var.result | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/r/fulltext_var.result b/mysql-test/r/fulltext_var.result index f45e18a9591..89d477c1a7c 100644 --- a/mysql-test/r/fulltext_var.result +++ b/mysql-test/r/fulltext_var.result @@ -2,6 +2,6 @@ show variables like "ft\_%"; Variable_name Value ft_boolean_syntax + -><()~*:""&| ft_min_word_len 4 -ft_max_word_len 254 +ft_max_word_len 84 ft_query_expansion_limit 20 ft_stopword_file (built-in) From 997c4550f3f80edd3d6f36af45093b957665eede Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Dec 2003 01:55:57 +0300 Subject: [PATCH 18/22] unused variable max_prep_stmt_count removed --- sql/mysqld.cc | 7 +------ sql/set_var.cc | 4 ---- sql/sql_class.h | 1 - sql/unireg.h | 1 - 4 files changed, 1 insertion(+), 12 deletions(-) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 2a5f639a440..926d55313ec 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3597,7 +3597,7 @@ enum options_mysqld OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS, OPT_MAX_LENGTH_FOR_SORT_DATA, OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE, - OPT_MAX_ERROR_COUNT, OPT_MAX_PREP_STMT, + OPT_MAX_ERROR_COUNT, OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE, OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE, OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT, @@ -4386,11 +4386,6 @@ The minimum value for this variable is 4096.", (gptr*) &global_system_variables.max_length_for_sort_data, (gptr*) &max_system_variables.max_length_for_sort_data, 0, GET_ULONG, REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0}, - {"max_prepared_statements", OPT_MAX_PREP_STMT, - "Max number of prepared_statements for a thread.", - (gptr*) &global_system_variables.max_prep_stmt_count, - (gptr*) &max_system_variables.max_prep_stmt_count, 0, GET_ULONG, - REQUIRED_ARG, DEFAULT_PREP_STMT_COUNT, 0, ~0L, 0, 1, 0}, {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE, "If non-zero: relay log will be rotated automatically when the size exceeds this value; if zero (the default): when the size exceeds max_binlog_size. 0 expected, the minimum value for this variable is 4096.", (gptr*) &max_relay_log_size, (gptr*) &max_relay_log_size, 0, GET_ULONG, diff --git a/sql/set_var.cc b/sql/set_var.cc index 5b956cd9c76..e46fe9729d5 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -202,8 +202,6 @@ sys_var_thd_ha_rows sys_sql_max_join_size("sql_max_join_size", &SV::max_join_size, fix_max_join_size); #endif -sys_var_thd_ulong sys_max_prep_stmt_count("max_prepared_statements", - &SV::max_prep_stmt_count); sys_var_long_ptr sys_max_relay_log_size("max_relay_log_size", &max_relay_log_size, fix_max_relay_log_size); @@ -462,7 +460,6 @@ sys_var *sys_variables[]= &sys_max_heap_table_size, &sys_max_join_size, &sys_max_length_for_sort_data, - &sys_max_prep_stmt_count, &sys_max_relay_log_size, &sys_max_seeks_for_key, &sys_max_sort_length, @@ -653,7 +650,6 @@ struct show_var_st init_vars[]= { {sys_max_seeks_for_key.name, (char*) &sys_max_seeks_for_key, SHOW_SYS}, {sys_max_length_for_sort_data.name, (char*) &sys_max_length_for_sort_data, SHOW_SYS}, - {sys_max_prep_stmt_count.name,(char*) &sys_max_prep_stmt_count, SHOW_SYS}, {sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS}, {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS}, {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS}, diff --git a/sql/sql_class.h b/sql/sql_class.h index 3ffff6f1871..1fce0049269 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -373,7 +373,6 @@ struct system_variables ulong max_error_count; ulong max_heap_table_size; ulong max_length_for_sort_data; - ulong max_prep_stmt_count; ulong max_sort_length; ulong max_tmp_tables; ulong myisam_repair_threads; diff --git a/sql/unireg.h b/sql/unireg.h index 2da25edd72a..442809a9e08 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -84,7 +84,6 @@ #define TRANS_MEM_ROOT_PREALLOC 4096 #define DEFAULT_ERROR_COUNT 64 -#define DEFAULT_PREP_STMT_COUNT 64 #define EXTRA_RECORDS 10 /* Extra records in sort */ #define SCROLL_EXTRA 5 /* Extra scroll-rows. */ #define FIELD_NAME_USED ((uint) 32768) /* Bit set if fieldname used */ From b731040383f7f949584f950701e536dbef1f3939 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Dec 2003 14:45:48 +0100 Subject: [PATCH 19/22] Post-merge fixes. --- mysql-test/r/sp-error.result | 4 +- mysql-test/r/variables.result | 2 +- mysql-test/t/sp-error.test | 86 +++++++++++++++++------------------ 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 37be3454812..22f6d37f8de 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -35,7 +35,7 @@ call foo(); ERROR 42000: PROCEDURE foo does not exist drop procedure if exists foo; Warnings: -Warning 1287 PROCEDURE foo does not exist +Warning 1288 PROCEDURE foo does not exist show create procedure foo; ERROR 42000: PROCEDURE foo does not exist create procedure foo() @@ -71,7 +71,7 @@ declare y int; set x = y; end; Warnings: -Warning 1293 Referring to uninitialized variable y +Warning 1294 Referring to uninitialized variable y drop procedure foo; create procedure foo() begin diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 30de6e63598..a5c8be8c819 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -360,7 +360,7 @@ set sql_log_bin=1; set sql_log_off=1; set sql_log_update=1; Warnings: -Note 1297 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. +Note 1298 The update log is deprecated and replaced by the binary log. SET SQL_LOG_UPDATE has been ignored. set sql_low_priority_updates=1; set sql_max_join_size=200; select @@sql_max_join_size,@@max_join_size; diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 32fbac2e92f..042e9baa47f 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -32,18 +32,18 @@ create function func1() returns int return 42| # Can't create recursively ---error 1285 +--error 1286 create procedure foo() create procedure bar() set @x=3| ---error 1285 +--error 1286 create procedure foo() create function bar() returns double return 2.3| # Already exists ---error 1286 +--error 1287 create procedure proc1() set @x = 42| ---error 1286 +--error 1287 create function func1() returns int return 42| @@ -51,39 +51,39 @@ drop procedure proc1| drop function func1| # Does not exist ---error 1287 +--error 1288 alter procedure foo| ---error 1287 +--error 1288 alter function foo| ---error 1287 +--error 1288 drop procedure foo| ---error 1287 +--error 1288 drop function foo| ---error 1287 +--error 1288 call foo()| drop procedure if exists foo| ---error 1287 +--error 1288 show create procedure foo| # LEAVE/ITERATE with no match ---error 1290 +--error 1291 create procedure foo() foo: loop leave bar; end loop| ---error 1290 +--error 1291 create procedure foo() foo: loop iterate bar; end loop| ---error 1290 +--error 1291 create procedure foo() foo: begin iterate foo; end| # Redefining label ---error 1291 +--error 1292 create procedure foo() foo: loop foo: loop @@ -92,7 +92,7 @@ foo: loop end loop foo| # End label mismatch ---error 1292 +--error 1293 create procedure foo() foo: loop set @x=2; @@ -113,17 +113,17 @@ begin select name from mysql.proc; select type from mysql.proc; end| ---error 1294 +--error 1295 call foo()| drop procedure foo| # RETURN in FUNCTION only ---error 1295 +--error 1296 create procedure foo() return 42| # Doesn't allow queries in FUNCTIONs (for now :-( ) ---error 1296 +--error 1297 create function foo() returns int begin declare x int; @@ -137,19 +137,19 @@ create procedure p(x int) create function f(x int) returns int return x+42| ---error 1300 +--error 1301 call p()| ---error 1300 +--error 1301 call p(1, 2)| ---error 1300 +--error 1301 select f()| ---error 1300 +--error 1301 select f(1, 2)| drop procedure p| drop function f| ---error 1301 +--error 1302 create procedure p(val int, out res int) begin declare x int default 0; @@ -163,7 +163,7 @@ begin end if; end| ---error 1301 +--error 1302 create procedure p(val int, out res int) begin declare x int default 0; @@ -178,7 +178,7 @@ begin end if; end| ---error 1302 +--error 1303 create function f(val int) returns int begin declare x int; @@ -196,12 +196,12 @@ begin end if; end| ---error 1303 +--error 1304 select f(10)| drop function f| ---error 1304 +--error 1305 create procedure p() begin declare c cursor for insert into test.t1 values ("foo", 42); @@ -210,7 +210,7 @@ begin close c; end| ---error 1305 +--error 1306 create procedure p() begin declare x int; @@ -220,7 +220,7 @@ begin close c; end| ---error 1306 +--error 1307 create procedure p() begin declare c cursor for select * from test.t; @@ -242,7 +242,7 @@ begin open c; close c; end| ---error 1307 +--error 1308 call p()| drop procedure p| @@ -254,11 +254,11 @@ begin close c; close c; end| ---error 1308 +--error 1309 call p()| drop procedure p| ---error 1287 +--error 1288 alter procedure bar3 sql security invoker| --error 1059 alter procedure bar3 name @@ -272,7 +272,7 @@ drop table if exists t1| create table t1 (val int, x float)| insert into t1 values (42, 3.1), (19, 1.2)| ---error 1309 +--error 1310 create procedure p() begin declare c cursor for select * from t1; @@ -292,7 +292,7 @@ begin fetch c into x; close c; end| ---error 1310 +--error 1311 call p()| drop procedure p| @@ -307,34 +307,34 @@ begin fetch c into x, y, z; close c; end| ---error 1310 +--error 1311 call p()| drop procedure p| ---error 1312 +--error 1313 create procedure p(in x int, x char(10)) begin end| ---error 1312 +--error 1313 create function p(x int, x char(10)) begin end| ---error 1313 +--error 1314 create procedure p() begin declare x float; declare x int; end| ---error 1314 +--error 1315 create procedure p() begin declare c condition for 1064; declare c condition for 1065; end| ---error 1315 +--error 1316 create procedure p() begin declare c cursor for select * from t1; @@ -358,13 +358,13 @@ drop procedure bug1965| # # BUG#1966 # ---error 1309 +--error 1310 select 1 into a| # # BUG#336 # ---error 1317 +--error 1318 create procedure bug336(id char(16)) begin declare x int; @@ -374,7 +374,7 @@ end| # # BUG#1654 # ---error 1296 +--error 1297 create function bug1654() returns int return (select sum(t.data) from test.t2 t)| From 7f9ba01f9918d43742fc7de6fb4550d34e8f3541 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 5 Dec 2003 18:52:33 +0100 Subject: [PATCH 20/22] New test cases for BUG#1653 (recalling a procedure after replacing a faulty table definition crashed), and recursive calls. mysql-test/r/sp.result: New test cases for BUG#1653 and recursive calls. mysql-test/t/sp.test: New test cases for BUG#1653 and recursive calls. --- mysql-test/r/sp.result | 56 +++++++++++++++++++++++++++++++++++ mysql-test/t/sp.test | 67 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 121 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index a419f4a0565..b8581674e5a 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -801,6 +801,17 @@ avg 0 4.4 delete from t1; delete from t2; drop procedure bug1874; +drop table if exists table_1; +create table t3 (column_1_0 int); +create procedure bug1653() +update t3 set column_1 = 0; +call bug1653(); +ERROR 42S22: Unknown column 'column_1' in 'field list' +drop table t3; +create table t3 (column_1 int); +call bug1653(); +drop procedure bug1653; +drop table t3; drop table if exists fac; create table fac (n int unsigned not null primary key, f bigint unsigned); create procedure ifac(n int unsigned) @@ -948,6 +959,51 @@ drop procedure opp; drop procedure ip; show procedure status like '%p%'; Name Type Creator Modified Created Suid Comment +drop table if exists fib; +create table fib ( f bigint unsigned not null ); +insert into fib values (1), (1); +create procedure fib(n int unsigned) +begin +if n > 0 then +begin +declare x, y bigint unsigned; +declare c cursor for select f from fib order by f desc limit 2; +open c; +fetch c into y; +fetch c into x; +close c; +insert into fib values (x+y); +call fib(n-1); +end; +end if; +end; +call fib(20); +select * from fib order by f asc; +f +1 +1 +2 +3 +5 +8 +13 +21 +34 +55 +89 +144 +233 +377 +610 +987 +1597 +2584 +4181 +6765 +10946 +17711 +drop table fib; +drop procedure fib; create procedure bar(x char(16), y int) comment "111111111111" sql security invoker insert into test.t1 values (x, y); diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 25657bd79e2..3c4c850ba79 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -815,6 +815,11 @@ delete from t2| drop table t3| drop procedure cur2| + +# +# Test cases for old bugs +# + # # BUG#822 # @@ -898,7 +903,6 @@ select @1, @2| drop table t70| drop procedure bug1656| - # # BUG#1862 # @@ -920,7 +924,6 @@ select * from t3| drop table t3| drop procedure bug1862| - # # BUG#1874 # @@ -945,6 +948,26 @@ delete from t1| delete from t2| drop procedure bug1874| +# +# BUG#1653 +# +--disable_warnings +drop table if exists table_1| +--enable_warnings +create table t3 (column_1_0 int)| + +create procedure bug1653() + update t3 set column_1 = 0| + +--error 1054 +call bug1653()| +drop table t3| +create table t3 (column_1 int)| +call bug1653()| + +drop procedure bug1653| +drop table t3| + # # Some "real" examples @@ -1071,7 +1094,47 @@ drop procedure ip| --replace_column 4 '0000-00-00 00:00:00' 5 '0000-00-00 00:00:00' show procedure status like '%p%'| + +# Fibonacci, for recursion test. (Yet Another Numerical series :) + +--disable_warnings +drop table if exists fib| +--enable_warnings +create table fib ( f bigint unsigned not null )| + +insert into fib values (1), (1)| + +# We deliberately do it the awkward way, fetching the last two +# values from the table, in order to exercise various statements +# and table accesses at each turn. +create procedure fib(n int unsigned) +begin + if n > 0 then + begin + declare x, y bigint unsigned; + declare c cursor for select f from fib order by f desc limit 2; + + open c; + fetch c into y; + fetch c into x; + close c; + insert into fib values (x+y); + call fib(n-1); + end; + end if; +end| + +call fib(20)| + +select * from fib order by f asc| +drop table fib| +drop procedure fib| + + +# # Comment & suid +# + create procedure bar(x char(16), y int) comment "111111111111" sql security invoker insert into test.t1 values (x, y)| From 417354eaa127934f5aadcc9b245561a1519ba998 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Dec 2003 14:41:41 +0400 Subject: [PATCH 21/22] WL#530&531: TIMESTAMPADD, TIMESTAMPDIFF functions Syntax for TIMESTAMPADD: TIMESTAMPADD(interval, integer_expression, datetime_expression) interval:= FRAC_SECOND | SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR Supported SQL_TSI_ prefix (like SQL_TSI_SECOND) Syntax for TIMESTAMPDIFF: TIMESTAMPDIFF(interval, datetime_expression1, datetime_expression2) interval:= FRAC_SECOND | SECOND | MINUTE | HOUR | DAY | WEEK | MONTH | QUARTER | YEAR Supported SQL_TSI_ prefix (like SQL_TSI_SECOND) mysql-test/r/func_sapdb.result: Additional tests for timediff mysql-test/r/func_time.result: Tests for timestampadd, timestampdiff functions mysql-test/r/keywords.result: Test for new keywords mysql-test/t/func_sapdb.test: Additional tests for timediff mysql-test/t/func_time.test: Tests for timestampadd, timestampdiff functions mysql-test/t/keywords.test: Test for new keywords sql/item_create.cc: WL#530&531: TIMESTAMPADD, TIMESTAMPDIFF functions sql/item_create.h: WL#530&531: TIMESTAMPADD, TIMESTAMPDIFF functions sql/item_timefunc.cc: WL#530&531: TIMESTAMPADD, TIMESTAMPDIFF functions sql/item_timefunc.h: WL#530&531: TIMESTAMPADD, TIMESTAMPDIFF functions sql/lex.h: WL#530&531: TIMESTAMPADD, TIMESTAMPDIFF functions sql/sql_yacc.yy: WL#530&531: TIMESTAMPADD, TIMESTAMPDIFF functions --- mysql-test/r/func_sapdb.result | 19 ++- mysql-test/r/func_time.result | 57 +++++++ mysql-test/r/keywords.result | 16 +- mysql-test/t/func_sapdb.test | 3 +- mysql-test/t/func_time.test | 24 +++ mysql-test/t/keywords.test | 8 +- sql/item_create.cc | 5 - sql/item_create.h | 1 - sql/item_timefunc.cc | 293 +++++++++++++++++++++++++++++---- sql/item_timefunc.h | 28 +++- sql/lex.h | 16 +- sql/sql_yacc.yy | 34 +++- 12 files changed, 434 insertions(+), 70 deletions(-) diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index e330c73727b..6bd4c6f46a2 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -188,13 +188,14 @@ ttt qqq NULL NULL NULL NULL 2001-01-01 02:02:02 26:02:02 -SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test; -ttt qqq --744:00:00 NULL -26305:01:02 22:58:58 --26305:01:02 -22:58:58 -NULL 26:02:02 -NULL NULL -NULL NULL -00:00:00 -24:00:00 +SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq, +TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test; +ttt qqq eee rrr +-744:00:00 NULL NULL NULL +26305:01:02 22:58:58 -22:58:58 NULL +-26305:01:02 -22:58:58 22:58:58 NULL +NULL 26:02:02 26:02:02 NULL +NULL NULL NULL NULL +NULL NULL NULL NULL +00:00:00 -24:00:00 24:00:00 NULL drop table t1, test; diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index b8709487c6d..0bad2c4d636 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -464,6 +464,63 @@ date_add(date,INTERVAL "1 1:1" DAY_MINUTE) select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1; date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) 2003-01-03 01:01:01 +select date_add(date,INTERVAL "1" WEEK) from t1; +date_add(date,INTERVAL "1" WEEK) +2003-01-09 00:00:00 +select date_add(date,INTERVAL "1" QUARTER) from t1; +date_add(date,INTERVAL "1" QUARTER) +2003-04-02 +select timestampadd(MINUTE, 1, date) from t1; +timestampadd(MINUTE, 1, date) +2003-01-02 00:01:00 +select timestampadd(WEEK, 1, date) from t1; +timestampadd(WEEK, 1, date) +2003-01-09 00:00:00 +select timestampadd(SQL_TSI_SECOND, 1, date) from t1; +timestampadd(SQL_TSI_SECOND, 1, date) +2003-01-02 00:00:01 +select timestampadd(SQL_TSI_FRAC_SECOND, 1, date) from t1; +timestampadd(SQL_TSI_FRAC_SECOND, 1, date) +2003-01-02 00:00:00.000001 +select timestampdiff(MONTH, '2001-02-01', '2001-05-01') as a; +a +3 +select timestampdiff(YEAR, '2002-05-01', '2001-01-01') as a; +a +-1 +select timestampdiff(QUARTER, '2002-05-01', '2001-01-01') as a; +a +-5 +select timestampdiff(MONTH, '2000-03-28', '2000-02-29') as a; +a +0 +select timestampdiff(MONTH, '1991-03-28', '2000-02-29') as a; +a +107 +select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a; +a +12 +select timestampdiff(SQL_TSI_HOUR, '2001-02-01', '2001-05-01') as a; +a +2136 +select timestampdiff(SQL_TSI_DAY, '2001-02-01', '2001-05-01') as a; +a +89 +select timestampdiff(SQL_TSI_MINUTE, '2001-02-01 12:59:59', '2001-05-01 12:58:59') as a; +a +128159 +select timestampdiff(SQL_TSI_SECOND, '2001-02-01 12:59:59', '2001-05-01 12:58:58') as a; +a +7689539 +select timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a; +a +7689538999999 +select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1, +timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2, +timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3, +timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4; +a1 a2 a3 a4 +28 28 29 29 select date_add(time,INTERVAL 1 SECOND) from t1; date_add(time,INTERVAL 1 SECOND) 2006-07-08 00:00:01 diff --git a/mysql-test/r/keywords.result b/mysql-test/r/keywords.result index c218379110f..88a0ab8abd5 100644 --- a/mysql-test/r/keywords.result +++ b/mysql-test/r/keywords.result @@ -1,12 +1,14 @@ drop table if exists t1; -create table t1 (time time, date date, timestamp timestamp); -insert into t1 values ("12:22:22","97:02:03","1997-01-02"); +create table t1 (time time, date date, timestamp timestamp, +quarter int, week int, year int, timestampadd int, timestampdiff int); +insert into t1 values ("12:22:22","97:02:03","1997-01-02",1,2,3,4,5); select * from t1; -time date timestamp -12:22:22 1997-02-03 1997-01-02 00:00:00 -select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1; -t1.time+0 t1.date+0 t1.timestamp+0 concat(date," ",time) -122222 19970203 19970102000000 1997-02-03 12:22:22 +time date timestamp quarter week year timestampadd timestampdiff +12:22:22 1997-02-03 1997-01-02 00:00:00 1 2 3 4 5 +select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time), +t1.quarter+t1.week, t1.year+timestampadd, timestampdiff from t1; +t1.time+0 t1.date+0 t1.timestamp+0 concat(date," ",time) t1.quarter+t1.week t1.year+timestampadd timestampdiff +122222 19970203 19970102000000 1997-02-03 12:22:22 3 7 5 drop table t1; create table events(binlog int); insert into events values(1); diff --git a/mysql-test/t/func_sapdb.test b/mysql-test/t/func_sapdb.test index afd84fe9630..ba64e13873d 100644 --- a/mysql-test/t/func_sapdb.test +++ b/mysql-test/t/func_sapdb.test @@ -94,6 +94,7 @@ insert into test values ('2001-01-01 01:01:01', '01:01:01', '1 01:01:01', '2001-01-01 01:01:01'); SELECT ADDTIME(t1,t2) As ttt, ADDTIME(t2, t3) As qqq from test; -SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test; +SELECT TIMEDIFF(t1, t4) As ttt, TIMEDIFF(t2, t3) As qqq, + TIMEDIFF(t3, t2) As eee, TIMEDIFF(t2, t4) As rrr from test; drop table t1, test; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 30d616915ab..35a532f330e 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -219,6 +219,30 @@ select date_add(date,INTERVAL "1:1:1" HOUR_SECOND) from t1; select date_add(date,INTERVAL "1 1:1" DAY_MINUTE) from t1; select date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) from t1; +select date_add(date,INTERVAL "1" WEEK) from t1; +select date_add(date,INTERVAL "1" QUARTER) from t1; +select timestampadd(MINUTE, 1, date) from t1; +select timestampadd(WEEK, 1, date) from t1; +select timestampadd(SQL_TSI_SECOND, 1, date) from t1; +select timestampadd(SQL_TSI_FRAC_SECOND, 1, date) from t1; + +select timestampdiff(MONTH, '2001-02-01', '2001-05-01') as a; +select timestampdiff(YEAR, '2002-05-01', '2001-01-01') as a; +select timestampdiff(QUARTER, '2002-05-01', '2001-01-01') as a; +select timestampdiff(MONTH, '2000-03-28', '2000-02-29') as a; +select timestampdiff(MONTH, '1991-03-28', '2000-02-29') as a; +select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a; +select timestampdiff(SQL_TSI_HOUR, '2001-02-01', '2001-05-01') as a; +select timestampdiff(SQL_TSI_DAY, '2001-02-01', '2001-05-01') as a; +select timestampdiff(SQL_TSI_MINUTE, '2001-02-01 12:59:59', '2001-05-01 12:58:59') as a; +select timestampdiff(SQL_TSI_SECOND, '2001-02-01 12:59:59', '2001-05-01 12:58:58') as a; +select timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a; + +select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1, + timestampdiff(SQL_TSI_DAY, '1900-02-01', '1900-03-01') as a2, + timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3, + timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4; + # The following is not as one would expect... select date_add(time,INTERVAL 1 SECOND) from t1; drop table t1; diff --git a/mysql-test/t/keywords.test b/mysql-test/t/keywords.test index e7ec63afe54..3392bfa1b3b 100644 --- a/mysql-test/t/keywords.test +++ b/mysql-test/t/keywords.test @@ -6,10 +6,12 @@ drop table if exists t1; --enable_warnings -create table t1 (time time, date date, timestamp timestamp); -insert into t1 values ("12:22:22","97:02:03","1997-01-02"); +create table t1 (time time, date date, timestamp timestamp, +quarter int, week int, year int, timestampadd int, timestampdiff int); +insert into t1 values ("12:22:22","97:02:03","1997-01-02",1,2,3,4,5); select * from t1; -select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time) from t1; +select t1.time+0,t1.date+0,t1.timestamp+0,concat(date," ",time), + t1.quarter+t1.week, t1.year+timestampadd, timestampdiff from t1; drop table t1; create table events(binlog int); insert into events values(1); diff --git a/sql/item_create.cc b/sql/item_create.cc index 4a000ebc556..baf9fcb9470 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -312,11 +312,6 @@ Item *create_func_current_user() system_charset_info); } -Item *create_func_quarter(Item* a) -{ - return new Item_func_quarter(a); -} - Item *create_func_radians(Item *a) { return new Item_func_units((char*) "radians",a,M_PI/180,0.0); diff --git a/sql/item_create.h b/sql/item_create.h index c75f4404bad..1f8c3d1fe51 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -72,7 +72,6 @@ Item *create_func_period_diff(Item* a, Item *b); Item *create_func_pi(void); Item *create_func_pow(Item* a, Item *b); Item *create_func_current_user(void); -Item *create_func_quarter(Item* a); Item *create_func_radians(Item *a); Item *create_func_release_lock(Item* a); Item *create_func_repeat(Item* a, Item *b); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 31ce2ad9cdc..f61466fbce1 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -421,9 +421,15 @@ static bool get_interval_value(Item *args,interval_type int_type, case INTERVAL_YEAR: t->year=value; break; + case INTERVAL_QUARTER: + t->month=value*3; + break; case INTERVAL_MONTH: t->month=value; break; + case INTERVAL_WEEK: + t->day=value*7; + break; case INTERVAL_DAY: t->day=value; break; @@ -1286,6 +1292,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) goto null_date; break; case INTERVAL_DAY: + case INTERVAL_WEEK: period= calc_daynr(ltime->year,ltime->month,ltime->day) + sign*interval.day; if (period < 0 || period >= MAX_DAY_NUMBER) // Daynumber from year 0 to 9999-12-31 @@ -1301,6 +1308,7 @@ bool Item_date_add_interval::get_date(TIME *ltime, bool fuzzy_date) ltime->day=28; // Was leap-year break; case INTERVAL_YEAR_MONTH: + case INTERVAL_QUARTER: case INTERVAL_MONTH: period= (ltime->year*12 + sign*interval.year*12 + ltime->month-1 + sign*interval.month); @@ -1367,7 +1375,9 @@ void Item_extract::fix_length_and_dec() switch (int_type) { case INTERVAL_YEAR: max_length=4; date_value=1; break; case INTERVAL_YEAR_MONTH: max_length=6; date_value=1; break; + case INTERVAL_QUARTER: max_length=2; date_value=1; break; case INTERVAL_MONTH: max_length=2; date_value=1; break; + case INTERVAL_WEEK: max_length=2; date_value=1; break; case INTERVAL_DAY: max_length=2; date_value=1; break; case INTERVAL_DAY_HOUR: max_length=9; date_value=0; break; case INTERVAL_DAY_MINUTE: max_length=11; date_value=0; break; @@ -1390,6 +1400,8 @@ void Item_extract::fix_length_and_dec() longlong Item_extract::val_int() { TIME ltime; + uint year; + ulong week_format; long neg; if (date_value) { @@ -1412,7 +1424,16 @@ longlong Item_extract::val_int() switch (int_type) { case INTERVAL_YEAR: return ltime.year; case INTERVAL_YEAR_MONTH: return ltime.year*100L+ltime.month; + case INTERVAL_QUARTER: return ltime.month/3 + 1; case INTERVAL_MONTH: return ltime.month; + case INTERVAL_WEEK: + { + week_format= current_thd->variables.default_week_format; + return calc_week(<ime, + (week_format & 2) != 0, + (week_format & 1) == 0, + &year); + } case INTERVAL_DAY: return ltime.day; case INTERVAL_DAY_HOUR: return (long) (ltime.day*100L+ltime.hour)*neg; case INTERVAL_DAY_MINUTE: return (long) (ltime.day*10000L+ @@ -1740,6 +1761,79 @@ null_date: return 0; } +/* + SYNOPSIS + calc_time_diff() + l_time1 TIME/DATE/DATETIME value + l_time2 TIME/DATE/DATETIME value + l_sign Can be 1 (operation of addition) + or -1 (substraction) + seconds_out Returns count of seconds bitween + l_time1 and l_time2 + microseconds_out Returns count of microseconds bitween + l_time1 and l_time2. + + DESCRIPTION + Calculates difference in seconds(seconds_out) + and microseconds(microseconds_out) + bitween two TIME/DATE/DATETIME values. + + RETURN VALUES + Rertuns sign of difference. + 1 means negative result + 0 means positive result + +*/ + +bool calc_time_diff(TIME *l_time1,TIME *l_time2, int l_sign, + longlong *seconds_out, long *microseconds_out) +{ + long days; + bool neg; + longlong seconds= *seconds_out; + long microseconds= *microseconds_out; + + /* + We suppose that if first argument is TIMESTAMP_TIME + the second argument should be TIMESTAMP_TIME also. + We should check it before calc_time_diff call. + */ + if (l_time1->time_type == TIMESTAMP_TIME) // Time value + days= l_time1->day - l_sign*l_time2->day; + else // DateTime value + days= (calc_daynr((uint) l_time1->year, + (uint) l_time1->month, + (uint) l_time1->day) - + l_sign*calc_daynr((uint) l_time2->year, + (uint) l_time2->month, + (uint) l_time2->day)); + + microseconds= l_time1->second_part - l_sign*l_time2->second_part; + seconds= ((longlong) days*86400L + l_time1->hour*3600L + + l_time1->minute*60L + l_time1->second + microseconds/1000000L - + (longlong)l_sign*(l_time2->hour*3600L+l_time2->minute*60L+l_time2->second)); + + neg= 0; + if (seconds < 0) + { + seconds= -seconds; + neg= 1; + } + else if (seconds == 0 && microseconds < 0) + { + microseconds= -microseconds; + neg= 1; + } + if (microseconds < 0) + { + microseconds+= 1000000L; + seconds--; + } + *seconds_out= seconds; + *microseconds_out= microseconds; + return neg; +} + /* TIMEDIFF(t,s) is a time function that calculates the time value between a start and end time. @@ -1765,39 +1859,16 @@ String *Item_func_timediff::val_str(String *str) if (l_time1.neg != l_time2.neg) l_sign= -l_sign; - if (l_time1.time_type == TIMESTAMP_TIME) // Time value - days= l_time1.day - l_sign*l_time2.day; - else // DateTime value - days= (calc_daynr((uint) l_time1.year, - (uint) l_time1.month, - (uint) l_time1.day) - - l_sign*calc_daynr((uint) l_time2.year, - (uint) l_time2.month, - (uint) l_time2.day)); + l_time3.neg= calc_time_diff(&l_time1,&l_time2, l_sign, + &seconds, µseconds); - microseconds= l_time1.second_part - l_sign*l_time2.second_part; - seconds= ((longlong) days*86400L + l_time1.hour*3600L + - l_time1.minute*60L + l_time1.second + microseconds/1000000L - - (longlong)l_sign*(l_time2.hour*3600L+l_time2.minute*60L+l_time2.second)); - - l_time3.neg= 0; - if (seconds < 0) - { - seconds= -seconds; - l_time3.neg= 1; - } - else if (seconds == 0 && microseconds < 0) - { - microseconds= -microseconds; - l_time3.neg= 1; - } - if (microseconds < 0) - { - microseconds+= 1000000L; - seconds--; - } + /* + For TIMESTAMP_TIME only: + If both argumets are negative values and diff between them + is negative we need to swap sign as result should be positive. + */ if ((l_time2.neg == l_time1.neg) && l_time1.neg) - l_time3.neg= l_time3.neg ? 0 : 1; + l_time3.neg= 1-l_time3.neg; // Swap sign of result calc_time_from_sec(&l_time3, seconds, microseconds); if (make_datetime(str, &l_time3, @@ -1860,3 +1931,163 @@ longlong Item_func_microsecond::val_int() return ltime.second_part; return 0; } + + +longlong Item_func_timestamp_diff::val_int() +{ + TIME ltime1, ltime2; + longlong seconds; + long microseconds; + long months= 0; + int neg= 1; + + null_value= 0; + if (args[0]->get_date(<ime1, 0) || + args[1]->get_date(<ime2, 0)) + goto null_date; + + if (calc_time_diff(<ime2,<ime1, 1, + &seconds, µseconds)) + neg= -1; + + if (int_type == INTERVAL_YEAR || + int_type == INTERVAL_QUARTER || + int_type == INTERVAL_MONTH) + { + uint year, year_tmp; + uint year_beg, year_end, month_beg, month_end; + uint diff_days= seconds/86400L; + uint diff_months= 0; + uint diff_years= 0; + if (neg == -1) + { + year_beg= ltime2.year; + year_end= ltime1.year; + month_beg= ltime2.month; + month_end= ltime1.month; + } + else + { + year_beg= ltime1.year; + year_end= ltime2.year; + month_beg= ltime1.month; + month_end= ltime2.month; + } + /* calc years*/ + for (year= year_beg;year < year_end; year++) + { + uint days=calc_days_in_year(year); + if (days > diff_days) + break; + diff_days-= days; + diff_years++; + } + + /* calc months; Current year is in the 'year' variable */ + month_beg--; /* Change months to be 0-11 for easier calculation */ + month_end--; + + months= 12*diff_years; + while (month_beg != month_end) + { + uint m_days= (uint) days_in_month[month_beg]; + if (month_beg == 1) + { + /* This is only calculated once so there is no reason to cache it*/ + uint leap= (uint) ((year & 3) == 0 && (year%100 || + (year%400 == 0 && year))); + m_days+= leap; + } + if (m_days > diff_days) + break; + diff_days-= m_days; + months++; + if (month_beg++ == 11) /* if we wrap to next year */ + { + month_beg= 0; + year++; + } + } + if (neg == -1) + months= -months; + } + + switch (int_type) { + case INTERVAL_YEAR: + return months/12; + case INTERVAL_QUARTER: + return months/3; + case INTERVAL_MONTH: + return months; + case INTERVAL_WEEK: + return seconds/86400L/7L*neg; + case INTERVAL_DAY: + return seconds/86400L*neg; + case INTERVAL_HOUR: + return seconds/3600L*neg; + case INTERVAL_MINUTE: + return seconds/60L*neg; + case INTERVAL_SECOND: + return seconds*neg; + case INTERVAL_MICROSECOND: + { + longlong max_sec= LONGLONG_MAX/1000000; + if (max_sec > seconds || + max_sec == seconds && LONGLONG_MAX%1000000 >= microseconds) + return (longlong) (seconds*1000000L+microseconds)*neg; + goto null_date; + } + default: + break; + } + +null_date: + null_value=1; + return 0; +} + + +void Item_func_timestamp_diff::print(String *str) +{ + str->append(func_name()); + str->append('('); + + switch (int_type) { + case INTERVAL_YEAR: + str->append("YEAR"); + break; + case INTERVAL_QUARTER: + str->append("QUARTER"); + break; + case INTERVAL_MONTH: + str->append("MONTH"); + break; + case INTERVAL_WEEK: + str->append("WEEK"); + break; + case INTERVAL_DAY: + str->append("DAY"); + break; + case INTERVAL_HOUR: + str->append("HOUR"); + break; + case INTERVAL_MINUTE: + str->append("MINUTE"); + break; + case INTERVAL_SECOND: + str->append("SECOND"); + break; + case INTERVAL_MICROSECOND: + str->append("SECOND_FRAC"); + break; + default: + break; + } + + for (uint i=0 ; i < 2 ; i++) + { + str->append(','); + args[i]->print(str); + } + str->append(')'); +} diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 6dcf7d00ce1..d0c6c501d85 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -543,11 +543,12 @@ public: enum interval_type { - INTERVAL_YEAR, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE, - INTERVAL_SECOND, INTERVAL_MICROSECOND ,INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, - INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, - INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, - INTERVAL_HOUR_MICROSECOND, INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND + INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, + INTERVAL_MINUTE, INTERVAL_WEEK, INTERVAL_SECOND, INTERVAL_MICROSECOND , + INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, + INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND, + INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND, INTERVAL_MINUTE_MICROSECOND, + INTERVAL_SECOND_MICROSECOND }; @@ -763,3 +764,20 @@ public: maybe_null=1; } }; + + +class Item_func_timestamp_diff :public Item_int_func +{ + const interval_type int_type; +public: + Item_func_timestamp_diff(Item *a,Item *b,interval_type type_arg) + :Item_int_func(a,b), int_type(type_arg) {} + const char *func_name() const { return "timestamp_diff"; } + longlong val_int(); + void fix_length_and_dec() + { + decimals=0; + maybe_null=1; + } + void print(String *str); +}; diff --git a/sql/lex.h b/sql/lex.h index a5830ac8620..87f3b582276 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -176,6 +176,7 @@ static SYMBOL symbols[] = { { "FOREIGN", SYM(FOREIGN),0,0}, { "FORCE", SYM(FORCE_SYM),0,0}, { "FOUND", SYM(FOUND_SYM),0,0}, + { "FRAC_SECOND", SYM(FRAC_SECOND_SYM),0,0}, { "RAID_TYPE", SYM(RAID_TYPE),0,0}, { "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0}, { "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0}, @@ -335,6 +336,7 @@ static SYMBOL symbols[] = { { "PROCESS" , SYM(PROCESS),0,0}, { "PROCESSLIST", SYM(PROCESSLIST_SYM),0,0}, { "PRIVILEGES", SYM(PRIVILEGES),0,0}, + { "QUARTER", SYM(QUARTER_SYM),0,0}, { "QUERY", SYM(QUERY_SYM),0,0}, { "QUICK", SYM(QUICK),0,0}, { "RAID0", SYM(RAID_0_SYM),0,0}, @@ -397,6 +399,15 @@ static SYMBOL symbols[] = { { "SQL_NO_CACHE", SYM(SQL_NO_CACHE_SYM), 0, 0}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, { "SQL_THREAD", SYM(SQL_THREAD),0,0}, + { "SQL_TSI_FRAC_SECOND", SYM(FRAC_SECOND_SYM),0,0}, + { "SQL_TSI_SECOND", SYM(SECOND_SYM),0,0}, + { "SQL_TSI_MINUTE", SYM(MINUTE_SYM),0,0}, + { "SQL_TSI_HOUR", SYM(HOUR_SYM),0,0}, + { "SQL_TSI_DAY", SYM(DAY_SYM),0,0}, + { "SQL_TSI_WEEK", SYM(WEEK_SYM),0,0}, + { "SQL_TSI_MONTH", SYM(MONTH_SYM),0,0}, + { "SQL_TSI_QUARTER", SYM(QUARTER_SYM),0,0}, + { "SQL_TSI_YEAR", SYM(YEAR_SYM),0,0}, { "SOUNDS", SYM(SOUNDS_SYM),0,0}, { "SSL", SYM(SSL_SYM),0,0}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0}, @@ -416,6 +427,8 @@ static SYMBOL symbols[] = { { "THEN", SYM(THEN_SYM),0,0}, { "TIME", SYM(TIME_SYM),0,0}, { "TIMESTAMP", SYM(TIMESTAMP),0,0}, + { "TIMESTAMPADD", SYM(TIMESTAMP_ADD),0,0}, + { "TIMESTAMPDIFF", SYM(TIMESTAMP_DIFF),0,0}, { "TINYBLOB", SYM(TINYBLOB),0,0}, { "TINYTEXT", SYM(TINYTEXT),0,0}, { "TINYINT", SYM(TINYINT),0,0}, @@ -451,6 +464,7 @@ static SYMBOL symbols[] = { { "VARYING", SYM(VARYING),0,0}, { "VARBINARY", SYM(VARBINARY),0,0}, { "WARNINGS", SYM(WARNINGS),0,0}, + { "WEEK", SYM(WEEK_SYM),0,0}, { "WITH", SYM(WITH),0,0}, { "WORK", SYM(WORK_SYM),0,0}, { "WRITE", SYM(WRITE_SYM),0,0}, @@ -637,7 +651,6 @@ static SYMBOL sql_functions[] = { { "POSITION", SYM(POSITION_SYM),0,0}, { "POW", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, { "POWER", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_pow)}, - { "QUARTER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quarter)}, { "QUOTE", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_quote)}, { "RADIANS", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_radians)}, { "RAND", SYM(RAND),0,0}, @@ -683,7 +696,6 @@ static SYMBOL sql_functions[] = { { "UPPER", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_ucase)}, { "VARIANCE", SYM(VARIANCE_SYM),0,0}, { "VERSION", SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_version)}, - { "WEEK", SYM(WEEK_SYM),0,0}, { "WEEKDAY", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekday)}, { "WEEKOFYEAR", SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_weekofyear)}, { "WITHIN", SYM(FUNC_ARG2),0,CREATE_FUNC(create_func_within)}, diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index c9fb5e0db41..14f73b6c95e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -82,7 +82,7 @@ inline Item *or_or_concat(THD *thd, Item* A, Item* B) enum Item_udftype udf_type; CHARSET_INFO *charset; thr_lock_type lock_type; - interval_type interval; + interval_type interval, interval_time_st; st_select_lex *select_lex; chooser_compare_func_creator boolfunc2creator; struct sp_cond_type *spcondtype; @@ -452,6 +452,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token STRING_SYM %token TEXT_SYM %token TIMESTAMP +%token TIMESTAMP_ADD +%token TIMESTAMP_DIFF %token TIME_SYM %token TINYBLOB %token TINYINT @@ -494,6 +496,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token FIELD_FUNC %token FORMAT_SYM %token FOR_SYM +%token FRAC_SECOND_SYM %token FROM_UNIXTIME %token GEOMCOLLFROMTEXT %token GEOMFROMTEXT @@ -538,6 +541,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token POLYGON %token POSITION_SYM %token PROCEDURE +%token QUARTER_SYM %token RAND %token REPLACE %token RIGHT @@ -679,6 +683,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %type interval +%type interval_time_st + %type table_types %type row_types @@ -3453,6 +3459,8 @@ simple_expr: Geometry::wkbPolygon, Geometry::wkbLineString); } | POSITION_SYM '(' no_in_expr IN_SYM expr ')' { $$ = new Item_func_locate($5,$3); } + | QUARTER_SYM '(' expr ')' + { $$ = new Item_func_quarter($3); } | RAND '(' expr ')' { $$= new Item_func_rand($3); Lex->uncacheable();} | RAND '(' ')' @@ -3486,6 +3494,10 @@ simple_expr: { $$= new Item_datetime_typecast($3); } | TIMESTAMP '(' expr ',' expr ')' { $$= new Item_func_add_time($3, $5, 1, 0); } + | TIMESTAMP_ADD '(' interval_time_st ',' expr ',' expr ')' + { $$= new Item_date_add_interval($7,$5,$3,0); } + | TIMESTAMP_DIFF '(' interval_time_st ',' expr ',' expr ')' + { $$= new Item_func_timestamp_diff($5,$7,$3); } | TRIM '(' expr ')' { $$= new Item_func_trim($3); } | TRIM '(' LEADING expr FROM expr ')' @@ -3926,23 +3938,29 @@ using_list: }; interval: - DAY_HOUR_SYM { $$=INTERVAL_DAY_HOUR; } + 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; } - | DAY_SYM { $$=INTERVAL_DAY; } | HOUR_MICROSECOND_SYM { $$=INTERVAL_HOUR_MICROSECOND; } | HOUR_MINUTE_SYM { $$=INTERVAL_HOUR_MINUTE; } | HOUR_SECOND_SYM { $$=INTERVAL_HOUR_SECOND; } - | HOUR_SYM { $$=INTERVAL_HOUR; } | 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; } - | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; } + | QUARTER_SYM { $$=INTERVAL_QUARTER; } | SECOND_SYM { $$=INTERVAL_SECOND; } - | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } | YEAR_SYM { $$=INTERVAL_YEAR; }; table_alias: @@ -5414,6 +5432,7 @@ keyword: | PREV_SYM {} | PROCESS {} | PROCESSLIST_SYM {} + | QUARTER_SYM {} | QUERY_SYM {} | QUICK {} | RAID_0_SYM {} @@ -5463,6 +5482,8 @@ keyword: | TRANSACTION_SYM {} | TRUNCATE_SYM {} | TIMESTAMP {} + | TIMESTAMP_ADD {} + | TIMESTAMP_DIFF {} | TIME_SYM {} | TYPE_SYM {} | FUNCTION_SYM {} @@ -5474,6 +5495,7 @@ keyword: | VARIABLES {} | VALUE_SYM {} | WARNINGS {} + | WEEK_SYM {} | WORK_SYM {} | X509_SYM {} | YEAR_SYM {} From 8b915a43166e8aa914698a61a9079d3667452d65 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 8 Dec 2003 17:44:56 +0400 Subject: [PATCH 22/22] post-merge fixes --- mysql-test/r/func_time.result | 6 ++++++ mysql-test/t/func_time.test | 3 +++ sql/item_timefunc.cc | 13 +++++++------ 3 files changed, 16 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index e4804790ed0..f7cad44ecc9 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -565,3 +565,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select high_priority no_cache period_add(_latin1'9602',-(12)) AS `period_add("9602",-12)`,period_diff(199505,_latin1'9404') AS `period_diff(199505,"9404")`,from_days(to_days(_latin1'960101')) AS `from_days(to_days("960101"))`,dayofmonth(_latin1'1997-01-02') AS `dayofmonth("1997-01-02")`,month(_latin1'1997-01-02') AS `month("1997-01-02")`,monthname(_latin1'1972-03-04') AS `monthname("1972-03-04")`,dayofyear(_latin1'0000-00-00') AS `dayofyear("0000-00-00")`,hour(_latin1'1997-03-03 23:03:22') AS `HOUR("1997-03-03 23:03:22")`,minute(_latin1'23:03:22') AS `MINUTE("23:03:22")`,second(230322) AS `SECOND(230322)`,quarter(980303) AS `QUARTER(980303)`,week(_latin1'1998-03-03',0) AS `WEEK("1998-03-03")`,yearweek(_latin1'2000-01-01',1) AS `yearweek("2000-01-01",1)`,week(19950101,1) AS `week(19950101,1)`,year(_latin1'98-02-03') AS `year("98-02-03")`,(weekday(to_days(curdate())) - weekday(to_days(now()))) AS `weekday(curdate())-weekday(now())`,dayname(to_days(_latin1'1962-03-03')) AS `dayname("1962-03-03")`,unix_timestamp() AS `unix_timestamp()`,sec_to_time((time_to_sec(_latin1'0:30:47') / 6.21)) AS `sec_to_time(time_to_sec("0:30:47")/6.21)`,curtime() AS `curtime()`,utc_time() AS `utc_time()`,curdate() AS `curdate()`,utc_date() AS `utc_date()`,utc_timestamp() AS `utc_timestamp()`,date_format(_latin1'1997-01-02 03:04:05',_latin1'%M %W %D %Y %y %m %d %h %i %s %w') AS `date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w")`,from_unixtime(unix_timestamp(_latin1'1994-03-02 10:11:12')) AS `from_unixtime(unix_timestamp("1994-03-02 10:11:12"))`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `"1997-12-31 23:59:59" + INTERVAL 1 SECOND`,(_latin1'1998-01-01 00:00:00' - interval 1 second) AS `"1998-01-01 00:00:00" - INTERVAL 1 SECOND`,(_latin1'1997-12-31' + interval 1 day) AS `INTERVAL 1 DAY + "1997-12-31"`,extract(year from _latin1'1999-01-02 10:11:12') AS `extract(YEAR FROM "1999-01-02 10:11:12")`,(_latin1'1997-12-31 23:59:59' + interval 1 second) AS `date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND)` +explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, +timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +Warnings: +Note 1003 select high_priority timestamp_diff(WEEK,_latin1'2001-02-01',_latin1'2001-05-01') AS `a1`,timestamp_diff(SECOND_FRAC,_latin1'2001-02-01 12:59:59.120000',_latin1'2001-05-01 12:58:58.119999') AS `a2` diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 955b0358ae3..cfc8a635f0e 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -271,3 +271,6 @@ select strcmp(date_format(utc_timestamp(),"%Y-%m-%d"), utc_date())=0; select strcmp(concat(utc_date(),' ',utc_time()),utc_timestamp())=0; explain extended select period_add("9602",-12),period_diff(199505,"9404"),from_days(to_days("960101")),dayofmonth("1997-01-02"), month("1997-01-02"), monthname("1972-03-04"),dayofyear("0000-00-00"),HOUR("1997-03-03 23:03:22"),MINUTE("23:03:22"),SECOND(230322),QUARTER(980303),WEEK("1998-03-03"),yearweek("2000-01-01",1),week(19950101,1),year("98-02-03"),weekday(curdate())-weekday(now()),dayname("1962-03-03"),unix_timestamp(),sec_to_time(time_to_sec("0:30:47")/6.21),curtime(),utc_time(),curdate(),utc_date(),utc_timestamp(),date_format("1997-01-02 03:04:05", "%M %W %D %Y %y %m %d %h %i %s %w"),from_unixtime(unix_timestamp("1994-03-02 10:11:12")),"1997-12-31 23:59:59" + INTERVAL 1 SECOND,"1998-01-01 00:00:00" - INTERVAL 1 SECOND,INTERVAL 1 DAY + "1997-12-31", extract(YEAR FROM "1999-01-02 10:11:12"),date_add("1997-12-31 23:59:59",INTERVAL 1 SECOND); + +explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, + timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 66190371575..7936006acc4 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1631,12 +1631,13 @@ longlong Item_date_add_interval::val_int() static const char *interval_names[]= { - "year", "month", "day", "hour", "minute", - "second", "microsecond", "year_month", - "day_hour", "day_minute", "day_second", - "hour_minute", "hour_second", "minute_second", - "day_microsecond", "hour_microsecond", - "minute_microsecond", "second_microsecond" + "year", "quarter", "month", "day", "hour", + "minute", "week", "second", "microsecond", + "year_month", "day_hour", "day_minute", + "day_second", "hour_minute", "hour_second", + "minute_second", "day_microsecond", + "hour_microsecond", "minute_microsecond", + "second_microsecond" }; void Item_date_add_interval::print(String *str)