From 3e9f47d6b01e7943a79a9c6f76e1f271489d84e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 11 Jun 2004 13:49:22 +0200 Subject: Fix handler w.r.t scan ndb/include/ndbapi/NdbApi.hpp: Removed SchemaOp, SchemaCon ndb/src/ndbapi/NdbRecAttr.cpp: merge error ndb/tools/select_count.cpp: clean up sql/ha_ndbcluster.cc: Fixed handler w.r.t scan sql/ha_ndbcluster.h: Fixed handler w.r.t scan --- sql/ha_ndbcluster.cc | 30 +++++++++++++++--------------- sql/ha_ndbcluster.h | 4 +++- 2 files changed, 18 insertions(+), 16 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index c76534943b8..e3a63eacd22 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -462,10 +462,10 @@ void ha_ndbcluster::release_metadata() DBUG_VOID_RETURN; } -NdbCursorOperation::LockMode get_ndb_lock_type(enum thr_lock_type type) +NdbScanOperation::LockMode get_ndb_lock_type(enum thr_lock_type type) { return (type == TL_WRITE_ALLOW_WRITE) ? - NdbCursorOperation::LM_Exclusive : NdbCursorOperation::LM_Read; + NdbScanOperation::LM_Exclusive : NdbScanOperation::LM_Read; } static const ulong index_type_flags[]= @@ -795,7 +795,7 @@ inline int ha_ndbcluster::next_result(byte *buf) Set bounds for a ordered index scan, use key_range */ -int ha_ndbcluster::set_bounds(NdbOperation *op, +int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, const key_range *key, int bound) { @@ -843,7 +843,7 @@ int ha_ndbcluster::set_bounds(NdbOperation *op, so if this bound was not EQ, bail out and make a best effort attempt */ - if (bound != NdbOperation::BoundEQ) + if (bound != NdbIndexScanOperation::BoundEQ) break; } @@ -861,7 +861,7 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, { NdbConnection *trans= m_active_trans; NdbResultSet *cursor; - NdbScanOperation *op; + NdbIndexScanOperation *op; const char *index_name; DBUG_ENTER("ordered_index_scan"); @@ -869,19 +869,19 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, DBUG_PRINT("enter", ("Starting new ordered scan on %s", m_tabname)); index_name= get_index_name(active_index); - if (!(op= trans->getNdbScanOperation(index_name, m_tabname))) + if (!(op= trans->getNdbIndexScanOperation(index_name, m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(parallelism, get_ndb_lock_type(m_lock.type)))) + if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0,parallelism))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; if (start_key && set_bounds(op, start_key, (start_key->flag == HA_READ_KEY_EXACT) ? - NdbOperation::BoundEQ : + NdbIndexScanOperation::BoundEQ : (start_key->flag == HA_READ_AFTER_KEY) ? - NdbOperation::BoundLT : - NdbOperation::BoundLE)) + NdbIndexScanOperation::BoundLT : + NdbIndexScanOperation::BoundLE)) DBUG_RETURN(1); if (end_key) @@ -892,8 +892,8 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, } else if (set_bounds(op, end_key, (end_key->flag == HA_READ_AFTER_KEY) ? - NdbOperation::BoundGE : - NdbOperation::BoundGT)) + NdbIndexScanOperation::BoundGE : + NdbIndexScanOperation::BoundGT)) DBUG_RETURN(1); } DBUG_RETURN(define_read_attrs(buf, op)); @@ -931,10 +931,10 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len, if (!(op= trans->getNdbScanOperation(m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(parallelism, get_ndb_lock_type(m_lock.type)))) + if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0,parallelism))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; - + { // Start scan filter NdbScanFilter sf(op); @@ -1000,7 +1000,7 @@ int ha_ndbcluster::full_table_scan(byte *buf) if (!(op=trans->getNdbScanOperation(m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(parallelism, get_ndb_lock_type(m_lock.type)))) + if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0,parallelism))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; DBUG_RETURN(define_read_attrs(buf, op)); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index df296648272..9c01f839b1f 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -33,6 +33,8 @@ class NdbOperation; // Forward declaration class NdbConnection; // Forward declaration class NdbRecAttr; // Forward declaration class NdbResultSet; // Forward declaration +class NdbScanOperation; +class NdbIndexScanOperation; typedef enum ndb_index_type { UNDEFINED_INDEX = 0, @@ -182,7 +184,7 @@ class ha_ndbcluster: public handler int set_primary_key(NdbOperation *op, const byte *key); int set_primary_key(NdbOperation *op); int set_primary_key_from_old_data(NdbOperation *op, const byte *old_data); - int set_bounds(NdbOperation *ndb_op, const key_range *key, + int set_bounds(NdbIndexScanOperation *ndb_op, const key_range *key, int bound); int key_cmp(uint keynr, const byte * old_row, const byte * new_row); void print_results(); -- cgit v1.2.1 From ab773d3582b12759916331dd4c338e9a24d01df9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Jun 2004 09:54:00 +0200 Subject: Added static print error function to be used by handler in ndbcluster_commit and ndbcluster_rollback --- sql/ha_ndbcluster.cc | 21 +++++++++++++++++++++ sql/ha_ndbcluster.h | 1 + 2 files changed, 22 insertions(+) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index c76534943b8..cfa71a0a886 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -63,6 +63,9 @@ typedef NdbDictionary::Dictionary NDBDICT; bool ndbcluster_inited= false; +TABLE *g_tab_dummy; +static ha_ndbcluster* g_ha_error= NULL; + static Ndb* g_ndb= NULL; // Handler synchronization @@ -2689,6 +2692,15 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked) DBUG_PRINT("enter", ("name: %s mode: %d test_if_locked: %d", name, mode, test_if_locked)); + // Create error handler needed for error msg handling in static + // handler functions (ha_commit_trans and ha_rollback_trans) + if (!g_ha_error) + { + g_tab_dummy = new TABLE(); + g_tab_dummy->table_name = NULL; + g_ha_error= new ha_ndbcluster(g_tab_dummy); + } + // Setup ref_length to make room for the whole // primary key to be written in the ref variable @@ -2928,6 +2940,11 @@ bool ndbcluster_init() bool ndbcluster_end() { DBUG_ENTER("ndbcluster_end"); + if (g_ha_error) + { + delete g_tab_dummy; + delete g_ha_error; + } delete g_ndb; g_ndb= NULL; if (!ndbcluster_inited) @@ -2941,6 +2958,10 @@ bool ndbcluster_end() DBUG_RETURN(0); } +void ndbcluster_print_error(int error) +{ + g_ha_error->print_error(error, MYF(0)); +} /* Set m_tabname from full pathname to table file diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index df296648272..bd22abdf264 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -227,6 +227,7 @@ int ndbcluster_discover(const char* dbname, const char* name, const void** frmblob, uint* frmlen); int ndbcluster_drop_database(const char* path); +void ndbcluster_print_error(int error); -- cgit v1.2.1 From c5e9441294cb56bcca34e7931644b07a0484ff8d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 22 Jun 2004 14:24:51 +0200 Subject: Added static print error function to be used by handler in ndbcluster_commit and ndbcluster_rollback --- sql/ha_ndbcluster.cc | 26 +++++++++++++++++--------- sql/handler.cc | 4 ++-- 2 files changed, 19 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index d8fb742e54d..8bf2948563f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -63,8 +63,10 @@ typedef NdbDictionary::Dictionary NDBDICT; bool ndbcluster_inited= false; +// Error handler for printing out ndbcluster error messages TABLE *g_tab_dummy; static ha_ndbcluster* g_ha_error= NULL; +static bool g_error_handler = FALSE; static Ndb* g_ndb= NULL; @@ -2657,6 +2659,17 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_unique_index_name[i]= NULL; } + // Create error handler needed for error msg handling in static + // handler functions (ha_commit_trans and ha_rollback_trans) + if (!g_error_handler) + { + DBUG_PRINT("info", ("Setting up error printing handler object")); + g_tab_dummy = new TABLE(); + g_tab_dummy->table_name = NULL; + g_error_handler = TRUE; + g_ha_error= new ha_ndbcluster(g_tab_dummy); + } + DBUG_VOID_RETURN; } @@ -2692,15 +2705,6 @@ int ha_ndbcluster::open(const char *name, int mode, uint test_if_locked) DBUG_PRINT("enter", ("name: %s mode: %d test_if_locked: %d", name, mode, test_if_locked)); - // Create error handler needed for error msg handling in static - // handler functions (ha_commit_trans and ha_rollback_trans) - if (!g_ha_error) - { - g_tab_dummy = new TABLE(); - g_tab_dummy->table_name = NULL; - g_ha_error= new ha_ndbcluster(g_tab_dummy); - } - // Setup ref_length to make room for the whole // primary key to be written in the ref variable @@ -2942,8 +2946,12 @@ bool ndbcluster_end() DBUG_ENTER("ndbcluster_end"); if (g_ha_error) { + DBUG_PRINT("info", ("deallocating error printing handler object")); delete g_tab_dummy; + g_tab_dummy= NULL; delete g_ha_error; + g_ha_error= NULL; + g_ha_error = FALSE; } delete g_ndb; g_ndb= NULL; diff --git a/sql/handler.cc b/sql/handler.cc index 717b2ee0ce8..c729b80d0ce 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -478,7 +478,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) { if ((error=ndbcluster_commit(thd,trans->ndb_tid))) { - my_error(ER_ERROR_DURING_COMMIT, MYF(0), error); + ndbcluster_print_error(error); error=1; } if (trans == &thd->transaction.all) @@ -544,7 +544,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) { if ((error=ndbcluster_rollback(thd, trans->ndb_tid))) { - my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error); + ndbcluster_print_error(error); error=1; } trans->ndb_tid = 0; -- cgit v1.2.1 From 82f8a71df47f68c188b412c725ebb9d0411c701f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 23 Jun 2004 15:34:45 +0200 Subject: Modified ndbcluster_print_error to stack allocate table and handler, NOT for review, will make patch instead --- sql/ha_ndbcluster.cc | 37 +++++++++++-------------------------- 1 file changed, 11 insertions(+), 26 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 8bf2948563f..1b7c504aff3 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -63,11 +63,6 @@ typedef NdbDictionary::Dictionary NDBDICT; bool ndbcluster_inited= false; -// Error handler for printing out ndbcluster error messages -TABLE *g_tab_dummy; -static ha_ndbcluster* g_ha_error= NULL; -static bool g_error_handler = FALSE; - static Ndb* g_ndb= NULL; // Handler synchronization @@ -2659,17 +2654,6 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_unique_index_name[i]= NULL; } - // Create error handler needed for error msg handling in static - // handler functions (ha_commit_trans and ha_rollback_trans) - if (!g_error_handler) - { - DBUG_PRINT("info", ("Setting up error printing handler object")); - g_tab_dummy = new TABLE(); - g_tab_dummy->table_name = NULL; - g_error_handler = TRUE; - g_ha_error= new ha_ndbcluster(g_tab_dummy); - } - DBUG_VOID_RETURN; } @@ -2944,15 +2928,7 @@ bool ndbcluster_init() bool ndbcluster_end() { DBUG_ENTER("ndbcluster_end"); - if (g_ha_error) - { - DBUG_PRINT("info", ("deallocating error printing handler object")); - delete g_tab_dummy; - g_tab_dummy= NULL; - delete g_ha_error; - g_ha_error= NULL; - g_ha_error = FALSE; - } + delete g_ndb; g_ndb= NULL; if (!ndbcluster_inited) @@ -2966,9 +2942,18 @@ bool ndbcluster_end() DBUG_RETURN(0); } +/* + Static error print function called from + static handler method ndbcluster_commit + and ndbcluster_rollback +*/ void ndbcluster_print_error(int error) { - g_ha_error->print_error(error, MYF(0)); + DBUG_ENTER("ndbcluster_print_error"); + TABLE tab; + tab.table_name = NULL; + ha_ndbcluster error_handler(&tab); + error_handler.print_error(error, MYF(0)); } /* -- cgit v1.2.1 From 8ad0e2a2b5998dde6b8b518334aa0e850c41d507 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 2 Jul 2004 11:50:28 +0200 Subject: Added support for update of pk --- sql/ha_ndbcluster.cc | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 09a94e51068..3517883cdc1 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -866,7 +866,8 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, index_name= get_index_name(active_index); if (!(op= trans->getNdbIndexScanOperation(index_name, m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0,parallelism))) + if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0, + parallelism))) //, sorted))) // Bug ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; @@ -1173,8 +1174,30 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) /* Check for update of primary key and return error */ if ((table->primary_key != MAX_KEY) && (key_cmp(table->primary_key, old_data, new_data))) - DBUG_RETURN(HA_ERR_UNSUPPORTED); - + { + DBUG_PRINT("info", ("primary key update, doing insert + delete")); + int insert_res = write_row(new_data); + if (!insert_res) + { + DBUG_PRINT("info", ("delete succeded")); + int delete_res = delete_row(old_data); + if (!delete_res) + { + DBUG_PRINT("info", ("insert + delete succeeded")); + DBUG_RETURN(0); + } + else + { + DBUG_PRINT("info", ("delete failed")); + DBUG_RETURN(delete_row(new_data)); + } + } + else + { + DBUG_PRINT("info", ("insert failed")); + DBUG_RETURN(insert_res); + } + } if (cursor) { /* @@ -2600,10 +2623,12 @@ int ndbcluster_drop_database(const char *path) longlong ha_ndbcluster::get_auto_increment() { + DBUG_ENTER("get_auto_increment"); + DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); int cache_size = rows_to_insert ? rows_to_insert : 32; Uint64 auto_value= m_ndb->getAutoIncrementValue(m_tabname, cache_size); - return (longlong)auto_value; + DBUG_RETURN((longlong)auto_value); } -- cgit v1.2.1 From ef389ca0b26ef5f8fcae0ef8016cdd08effeb6b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 2 Jul 2004 16:14:08 +0200 Subject: Fixed ndbcluster_print_error to use table name from failed NdbOperation --- sql/ha_ndbcluster.cc | 16 +++++++++++++--- sql/ha_ndbcluster.h | 2 +- sql/handler.cc | 8 ++------ 3 files changed, 16 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 3517883cdc1..dc4d20db74b 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1179,7 +1179,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) int insert_res = write_row(new_data); if (!insert_res) { - DBUG_PRINT("info", ("delete succeded")); + DBUG_PRINT("info", ("insert succeded")); int delete_res = delete_row(old_data); if (!delete_res) { @@ -2211,8 +2211,11 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction) if (trans->execute(Commit) != 0) { const NdbError err= trans->getNdbError(); + const NdbOperation *error_op= trans->getNdbErrorOperation(); ERR_PRINT(err); res= ndb_to_mysql_error(&err); + if (res != -1) + ndbcluster_print_error(res, error_op); } ndb->closeTransaction(trans); DBUG_RETURN(res); @@ -2238,8 +2241,11 @@ int ndbcluster_rollback(THD *thd, void *ndb_transaction) if (trans->execute(Rollback) != 0) { const NdbError err= trans->getNdbError(); + const NdbOperation *error_op= trans->getNdbErrorOperation(); ERR_PRINT(err); res= ndb_to_mysql_error(&err); + if (res != -1) + ndbcluster_print_error(res, error_op); } ndb->closeTransaction(trans); DBUG_RETURN(0); @@ -2964,13 +2970,17 @@ bool ndbcluster_end() static handler method ndbcluster_commit and ndbcluster_rollback */ -void ndbcluster_print_error(int error) + +void ndbcluster_print_error(int error, const NdbOperation *error_op) { DBUG_ENTER("ndbcluster_print_error"); TABLE tab; - tab.table_name = NULL; + const char *tab_name= (error_op) ? error_op->getTableName() : ""; + tab.table_name= (char *) tab_name; ha_ndbcluster error_handler(&tab); + tab.file= &error_handler; error_handler.print_error(error, MYF(0)); + DBUG_VOID_RETURN } /* diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index a60432ca5e6..bc906bf198d 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -230,7 +230,7 @@ int ndbcluster_discover(const char* dbname, const char* name, const void** frmblob, uint* frmlen); int ndbcluster_drop_database(const char* path); -void ndbcluster_print_error(int error); +void ndbcluster_print_error(int error, const NdbOperation *error_op); diff --git a/sql/handler.cc b/sql/handler.cc index 017b9d9d4c8..97c8b8d6778 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -495,9 +495,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if ((error=ndbcluster_commit(thd,trans->ndb_tid))) { if (error == -1) - my_error(ER_ERROR_DURING_COMMIT, MYF(0), error); - else - ndbcluster_print_error(error); + my_error(ER_ERROR_DURING_COMMIT, MYF(0)); error=1; } if (trans == &thd->transaction.all) @@ -564,9 +562,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) if ((error=ndbcluster_rollback(thd, trans->ndb_tid))) { if (error == -1) - my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), error); - else - ndbcluster_print_error(error); + my_error(ER_ERROR_DURING_ROLLBACK, MYF(0)); error=1; } trans->ndb_tid = 0; -- cgit v1.2.1 From 3f3ea3037a5575a4f2121592ddc40c3441962c15 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 5 Jul 2004 20:41:06 +0200 Subject: Fixed bugs in ordered scan discovered by mysql-test-run Enabled ordered scan in handler ndb/include/ndbapi/NdbIndexScanOperation.hpp: Moved saveBound to NdbIndexScanOperation ndb/include/ndbapi/NdbScanOperation.hpp: Moved saveBound to NdbIndexScanOperation ndb/src/ndbapi/NdbDictionaryImpl.cpp: Introduced map for index attributes (keys) -> real attr id (and back) ndb/src/ndbapi/NdbDictionaryImpl.hpp: Introduced map for index attributes (keys) -> real attr id (and back) ndb/src/ndbapi/NdbOperationDefine.cpp: Moved saveBound to NdbIndexScanOperation ndb/src/ndbapi/NdbOperationInt.cpp: Moved saveBound to NdbIndexScanOperation ndb/src/ndbapi/NdbScanOperation.cpp: Moved saveBound to NdbIndexScanOperation Fixed bugs in handling of setBounds w.r.t getValues and index keys (use new reverse map) Fixed bugs in next_result_ordered sql/ha_ndbcluster.cc: Use sorted scan when requested --- sql/ha_ndbcluster.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index e3a63eacd22..403306c786e 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -871,7 +871,8 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, index_name= get_index_name(active_index); if (!(op= trans->getNdbIndexScanOperation(index_name, m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0,parallelism))) + if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0, + parallelism, sorted))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; -- cgit v1.2.1 From 3e73b86d7fa6a1732496d3c4617c582b7b14aaa5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 6 Jul 2004 08:43:57 +0200 Subject: missing ; --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index dc4d20db74b..88d11813a0e 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2980,7 +2980,7 @@ void ndbcluster_print_error(int error, const NdbOperation *error_op) ha_ndbcluster error_handler(&tab); tab.file= &error_handler; error_handler.print_error(error, MYF(0)); - DBUG_VOID_RETURN + DBUG_VOID_RETURN; } /* -- cgit v1.2.1 From 1cbbbcf70e1c285193c97dd2354c255241c105a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 9 Jul 2004 13:18:56 +0200 Subject: Fixed bug #4106 and removed buggy pk update --- sql/ha_ndbcluster.cc | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index e88cbc0c4b3..5c5256cc622 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1174,30 +1174,8 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) /* Check for update of primary key and return error */ if ((table->primary_key != MAX_KEY) && (key_cmp(table->primary_key, old_data, new_data))) - { - DBUG_PRINT("info", ("primary key update, doing insert + delete")); - int insert_res = write_row(new_data); - if (!insert_res) - { - DBUG_PRINT("info", ("insert succeded")); - int delete_res = delete_row(old_data); - if (!delete_res) - { - DBUG_PRINT("info", ("insert + delete succeeded")); - DBUG_RETURN(0); - } - else - { - DBUG_PRINT("info", ("delete failed")); - DBUG_RETURN(delete_row(new_data)); - } - } - else - { - DBUG_PRINT("info", ("insert failed")); - DBUG_RETURN(insert_res); - } - } + DBUG_RETURN(HA_ERR_UNSUPPORTED); + if (cursor) { /* @@ -1650,8 +1628,10 @@ int ha_ndbcluster::rnd_init(bool scan) NdbResultSet *cursor= m_active_cursor; DBUG_ENTER("rnd_init"); DBUG_PRINT("enter", ("scan: %d", scan)); - // Check that cursor is not defined - if (cursor) + // Check if scan is to be restarted + if (cursor && scan) + cursor->restart(); + else DBUG_RETURN(1); index_init(table->primary_key); DBUG_RETURN(0); -- cgit v1.2.1 From e5c416e4f19f72cb6c1c5462cf5aa39dba0c35d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 19 Jul 2004 17:28:07 +0200 Subject: Fix for bug#4595 --- sql/ha_ndbcluster.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b57735b9de6..1fea8752c86 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -624,11 +624,12 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) return res; } - // Read non-key field(s) + // Read non-key field(s) unless HA_EXTRA_RETRIEVE_ALL_COLS for (i= 0; i < no_fields; i++) { Field *field= table->field[i]; - if (thd->query_id == field->query_id) + if ((thd->query_id == field->query_id) || + retrieve_all_fields) { if (get_ndb_value(op, i, field->ptr)) goto err; -- cgit v1.2.1 From 238b226f2626573021103872b85d54a79c5743ea Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 20 Jul 2004 14:15:38 +0300 Subject: Added innodb_locks_unsafe_for_binlog option. This option turns off Innodb next-key locking. Using this option the locks InnoDB sets on index records do not affect the ``gap'' before that index record. Thus, this option allows phantom problem. innobase/include/srv0srv.h: Added srv_locks_unsafe_for_binlog for innodb_locks_unsafe_for_binlog option. innobase/row/row0sel.c: If innodb_locks_unsafe_for_binlog option is used, we lock only the record, i.e. next-key locking is not used. Therefore, setting lock to the index record do not affect the ``gap'' before that index record. Thus, this option allows phantom problem, because concurrent insert operations are allowed inside the select range. innobase/srv/srv0srv.c: Added srv_locks_unsafe_for_binlog for innodb_locks_unsafe_for_binlog option. sql/ha_innodb.cc: Added innobase_locks_unsafe_for_binlog and srv_locks_unsafe_for_binlog for innodb_locks_unsafe_for_binlog option. sql/ha_innodb.h: Added innobase_locks_unsafe_for_binlog for innodb_locks_unsafe_for_binlog option. sql/mysqld.cc: Added OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, innobase_locks_unsafe_for_binlog for innodb_locks_unsafe_for_binlog option. sql/set_var.cc: Added innodb_locks_unsafe_for_binlog and innobase_locks_unsafe_for_binlog for innodb_locks_unsafe_for_binlog option. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/ha_innodb.cc | 2 ++ sql/ha_innodb.h | 2 +- sql/mysqld.cc | 5 +++++ sql/set_var.cc | 1 + 4 files changed, 9 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 6eae315e443..a7dce3a6ab8 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -117,6 +117,7 @@ my_bool innobase_log_archive = FALSE;/* unused */ my_bool innobase_use_native_aio = FALSE; my_bool innobase_fast_shutdown = TRUE; my_bool innobase_file_per_table = FALSE; +my_bool innobase_locks_unsafe_for_binlog = FALSE; static char *internal_innobase_data_file_path = NULL; @@ -908,6 +909,7 @@ innobase_init(void) srv_fast_shutdown = (ibool) innobase_fast_shutdown; srv_file_per_table = (ibool) innobase_file_per_table; + srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog; srv_max_n_open_files = (ulint) innobase_open_files; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index e09697f7ce6..6815bdd632d 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -189,7 +189,7 @@ extern char *innobase_unix_file_flush_method; /* The following variables have to be my_bool for SHOW VARIABLES to work */ extern my_bool innobase_log_archive, innobase_use_native_aio, innobase_fast_shutdown, - innobase_file_per_table; + innobase_file_per_table, innobase_locks_unsafe_for_binlog; extern "C" { extern ulong srv_max_buf_pool_modified_pct; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4fd13d33bab..869048cee93 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3880,6 +3880,7 @@ enum options_mysqld OPT_INNODB_FLUSH_METHOD, OPT_INNODB_FAST_SHUTDOWN, OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB, + OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, OPT_INNODB, OPT_ISAM, OPT_NDBCLUSTER, OPT_SKIP_SAFEMALLOC, OPT_TEMP_POOL, OPT_TX_ISOLATION, @@ -4156,6 +4157,10 @@ Disable with --skip-bdb (will save memory).", "Stores each InnoDB table to an .ibd file in the database dir.", (gptr*) &innobase_file_per_table, (gptr*) &innobase_file_per_table, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, + "Force Innodb not to use next-key locking. Instead use only row-level locking", + (gptr*) &innobase_locks_unsafe_for_binlog, + (gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif /* End HAVE_INNOBASE_DB */ {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection", (gptr*) &opt_init_connect, (gptr*) &opt_init_connect, 0, GET_STR_ALLOC, diff --git a/sql/set_var.cc b/sql/set_var.cc index e1cfb77d297..fb9ff285859 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -673,6 +673,7 @@ struct show_var_st init_vars[]= { {"innodb_fast_shutdown", (char*) &innobase_fast_shutdown, SHOW_MY_BOOL}, {"innodb_file_io_threads", (char*) &innobase_file_io_threads, SHOW_LONG }, {"innodb_file_per_table", (char*) &innobase_file_per_table, SHOW_MY_BOOL}, + {"innodb_locks_unsafe_for_binlog", (char*) &innobase_locks_unsafe_for_binlog, SHOW_MY_BOOL}, {"innodb_flush_log_at_trx_commit", (char*) &innobase_flush_log_at_trx_commit, SHOW_INT}, {"innodb_flush_method", (char*) &innobase_unix_file_flush_method, SHOW_CHAR_PTR}, {"innodb_force_recovery", (char*) &innobase_force_recovery, SHOW_LONG }, -- cgit v1.2.1 From 2d74872cf8c9dd11244f7d1b9248be51d91dc147 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 21 Jul 2004 11:46:14 +0200 Subject: Fix for bug#4669, Scans do not ignore uncommitted inserts (instead hang on lock) --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1fea8752c86..66c01bb2231 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -465,7 +465,7 @@ void ha_ndbcluster::release_metadata() NdbScanOperation::LockMode get_ndb_lock_type(enum thr_lock_type type) { return (type == TL_WRITE_ALLOW_WRITE) ? - NdbScanOperation::LM_Exclusive : NdbScanOperation::LM_Read; + NdbScanOperation::LM_Exclusive : NdbScanOperation::LM_CommittedRead; } static const ulong index_type_flags[]= -- cgit v1.2.1 From d1e7ef7927ede0c1754676324c9be407beb6f4f4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jul 2004 12:38:09 +0200 Subject: ha_ndb blobs 2 --- sql/ha_ndbcluster.cc | 677 ++++++++++++++++++++++++++++++++++++--------------- sql/ha_ndbcluster.h | 23 +- 2 files changed, 495 insertions(+), 205 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b57735b9de6..e46857bc6f6 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -181,6 +181,21 @@ bool ha_ndbcluster::get_error_message(int error, } +/* + Check if type is supported by NDB. +*/ + +static inline bool ndb_supported_type(enum_field_types type) +{ + switch (type) { + case MYSQL_TYPE_NULL: + case MYSQL_TYPE_GEOMETRY: + return false; + } + return true; +} + + /* Instruct NDB to set the value of the hidden primary key */ @@ -208,40 +223,15 @@ int ha_ndbcluster::set_ndb_key(NdbOperation *ndb_op, Field *field, pack_len)); DBUG_DUMP("key", (char*)field_ptr, pack_len); - switch (field->type()) { - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_NEWDATE: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - // Common implementation for most field types - DBUG_RETURN(ndb_op->equal(fieldnr, (char*) field_ptr, pack_len) != 0); - - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_NULL: - case MYSQL_TYPE_GEOMETRY: - default: - // Unhandled field types - DBUG_PRINT("error", ("Field type %d not supported", field->type())); - DBUG_RETURN(2); + if (ndb_supported_type(field->type())) + { + if (! (field->flags & BLOB_FLAG)) + // Common implementation for most field types + DBUG_RETURN(ndb_op->equal(fieldnr, (char*) field_ptr, pack_len) != 0); } - DBUG_RETURN(3); + // Unhandled field types + DBUG_PRINT("error", ("Field type %d not supported", field->type())); + DBUG_RETURN(2); } @@ -259,63 +249,197 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, fieldnr, field->field_name, field->type(), pack_len, field->is_null()?"Y":"N")); DBUG_DUMP("value", (char*) field_ptr, pack_len); - - if (field->is_null()) + + if (ndb_supported_type(field->type())) { - // Set value to NULL - DBUG_RETURN((ndb_op->setValue(fieldnr, (char*)NULL, pack_len) != 0)); - } - - switch (field->type()) { - case MYSQL_TYPE_DECIMAL: - case MYSQL_TYPE_TINY: - case MYSQL_TYPE_SHORT: - case MYSQL_TYPE_LONG: - case MYSQL_TYPE_FLOAT: - case MYSQL_TYPE_DOUBLE: - case MYSQL_TYPE_TIMESTAMP: - case MYSQL_TYPE_LONGLONG: - case MYSQL_TYPE_INT24: - case MYSQL_TYPE_DATE: - case MYSQL_TYPE_TIME: - case MYSQL_TYPE_DATETIME: - case MYSQL_TYPE_YEAR: - case MYSQL_TYPE_NEWDATE: - case MYSQL_TYPE_ENUM: - case MYSQL_TYPE_SET: - case MYSQL_TYPE_VAR_STRING: - case MYSQL_TYPE_STRING: - // Common implementation for most field types - DBUG_RETURN(ndb_op->setValue(fieldnr, (char*)field_ptr, pack_len) != 0); - - case MYSQL_TYPE_TINY_BLOB: - case MYSQL_TYPE_MEDIUM_BLOB: - case MYSQL_TYPE_LONG_BLOB: - case MYSQL_TYPE_BLOB: - case MYSQL_TYPE_NULL: - case MYSQL_TYPE_GEOMETRY: - default: - // Unhandled field types - DBUG_PRINT("error", ("Field type %d not supported", field->type())); - DBUG_RETURN(2); + if (! (field->flags & BLOB_FLAG)) + { + if (field->is_null()) + // Set value to NULL + DBUG_RETURN((ndb_op->setValue(fieldnr, (char*)NULL, pack_len) != 0)); + // Common implementation for most field types + DBUG_RETURN(ndb_op->setValue(fieldnr, (char*)field_ptr, pack_len) != 0); + } + + // Blob type + NdbBlob *ndb_blob = ndb_op->getBlobHandle(fieldnr); + if (ndb_blob != NULL) + { + if (field->is_null()) + DBUG_RETURN(ndb_blob->setNull() != 0); + + Field_blob *field_blob= (Field_blob*)field; + + // Get length and pointer to data + uint32 blob_len= field_blob->get_length(field_ptr); + char* blob_ptr= NULL; + field_blob->get_ptr(&blob_ptr); + + // Looks like NULL blob can also be signaled in this way + if (blob_ptr == NULL) + DBUG_RETURN(ndb_blob->setNull() != 0); + + DBUG_PRINT("value", ("set blob ptr=%x len=%u", + (unsigned)blob_ptr, blob_len)); + DBUG_DUMP("value", (char*)blob_ptr, min(blob_len, 26)); + + // No callback needed to write value + DBUG_RETURN(ndb_blob->setValue(blob_ptr, blob_len) != 0); + } + DBUG_RETURN(1); + } + // Unhandled field types + DBUG_PRINT("error", ("Field type %d not supported", field->type())); + DBUG_RETURN(2); +} + + +/* + Callback to read all blob values. + - not done in unpack_record because unpack_record is valid + after execute(Commit) but reading blobs is not + - may only generate read operations; they have to be executed + somewhere before the data is available + - due to single buffer for all blobs, we let the last blob + process all blobs (last so that all are active) + - null bit is still set in unpack_record + - TODO allocate blob part aligned buffers +*/ + +NdbBlob::ActiveHook get_ndb_blobs_value; + +int get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg) +{ + DBUG_ENTER("get_ndb_blobs_value [callback]"); + if (ndb_blob->blobsNextBlob() != NULL) + DBUG_RETURN(0); + ha_ndbcluster *ha= (ha_ndbcluster *)arg; + DBUG_RETURN(ha->get_ndb_blobs_value(ndb_blob)); +} + +int ha_ndbcluster::get_ndb_blobs_value(NdbBlob *last_ndb_blob) +{ + DBUG_ENTER("get_ndb_blobs_value"); + + // Field has no field number so cannot use TABLE blob_field + // Loop twice, first only counting total buffer size + for (int loop= 0; loop <= 1; loop++) + { + uint32 offset= 0; + for (uint i= 0; i < table->fields; i++) + { + Field *field= table->field[i]; + NdbValue value= m_value[i]; + if (value.ptr != NULL && (field->flags & BLOB_FLAG)) + { + Field_blob *field_blob= (Field_blob *)field; + NdbBlob *ndb_blob= value.blob; + Uint64 blob_len= 0; + if (ndb_blob->getLength(blob_len) != 0) + DBUG_RETURN(-1); + // Align to Uint64 + uint32 blob_size= blob_len; + if (blob_size % 8 != 0) + blob_size+= 8 - blob_size % 8; + if (loop == 1) + { + char *buf= blobs_buffer + offset; + uint32 len= 0xffffffff; // Max uint32 + DBUG_PRINT("value", ("read blob ptr=%x len=%u", + (uint)buf, (uint)blob_len)); + if (ndb_blob->readData(buf, len) != 0) + DBUG_RETURN(-1); + DBUG_ASSERT(len == blob_len); + field_blob->set_ptr(len, buf); + } + offset+= blob_size; + } + } + if (loop == 0 && offset > blobs_buffer_size) + { + my_free(blobs_buffer, MYF(MY_ALLOW_ZERO_PTR)); + blobs_buffer_size= 0; + DBUG_PRINT("value", ("allocate blobs buffer size %u", offset)); + blobs_buffer= my_malloc(offset, MYF(MY_WME)); + if (blobs_buffer == NULL) + DBUG_RETURN(-1); + blobs_buffer_size= offset; + } } - DBUG_RETURN(3); + DBUG_RETURN(0); } /* Instruct NDB to fetch one field - - data is read directly into buffer provided by field_ptr - if it's NULL, data is read into memory provided by NDBAPI + - data is read directly into buffer provided by field + if field is NULL, data is read into memory provided by NDBAPI */ -int ha_ndbcluster::get_ndb_value(NdbOperation *op, - uint field_no, byte *field_ptr) +int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field, + uint fieldnr) { DBUG_ENTER("get_ndb_value"); - DBUG_PRINT("enter", ("field_no: %d", field_no)); - m_value[field_no]= op->getValue(field_no, field_ptr); - DBUG_RETURN(m_value == NULL); + DBUG_PRINT("enter", ("fieldnr: %d flags: %o", fieldnr, + (int)(field != NULL ? field->flags : 0))); + + if (field != NULL) + { + if (ndb_supported_type(field->type())) + { + DBUG_ASSERT(field->ptr != NULL); + if (! (field->flags & BLOB_FLAG)) + { + m_value[fieldnr].rec= ndb_op->getValue(fieldnr, field->ptr); + DBUG_RETURN(m_value[fieldnr].rec == NULL); + } + + // Blob type + NdbBlob *ndb_blob= ndb_op->getBlobHandle(fieldnr); + m_value[fieldnr].blob= ndb_blob; + if (ndb_blob != NULL) + { + // Set callback + void *arg= (void *)this; + DBUG_RETURN(ndb_blob->setActiveHook(::get_ndb_blobs_value, arg) != 0); + } + DBUG_RETURN(1); + } + // Unhandled field types + DBUG_PRINT("error", ("Field type %d not supported", field->type())); + DBUG_RETURN(2); + } + + // Used for hidden key only + m_value[fieldnr].rec= ndb_op->getValue(fieldnr, NULL); + DBUG_RETURN(m_value[fieldnr].rec == NULL); +} + + +/* + Check if any set or get of blob value in current query. +*/ +bool ha_ndbcluster::uses_blob_value(bool all_fields) +{ + if (table->blob_fields == 0) + return false; + if (all_fields) + return true; + { + uint no_fields= table->fields; + int i; + THD *thd= current_thd; + // They always put blobs at the end.. + for (i= no_fields - 1; i >= 0; i--) + { + Field *field= table->field[i]; + if (thd->query_id == field->query_id) + { + return true; + } + } + } + return false; } @@ -462,10 +586,19 @@ void ha_ndbcluster::release_metadata() DBUG_VOID_RETURN; } -NdbScanOperation::LockMode get_ndb_lock_type(enum thr_lock_type type) +int ha_ndbcluster::get_ndb_lock_type(enum thr_lock_type type) { - return (type == TL_WRITE_ALLOW_WRITE) ? - NdbScanOperation::LM_Exclusive : NdbScanOperation::LM_Read; + int lm; + if (type == TL_WRITE_ALLOW_WRITE) + lm = NdbScanOperation::LM_Exclusive; + else if (uses_blob_value(retrieve_all_fields)) + /* + TODO use a new scan mode to read + lock + keyinfo + */ + lm = NdbScanOperation::LM_Exclusive; + else + lm = NdbScanOperation::LM_Read; + return lm; } static const ulong index_type_flags[]= @@ -614,7 +747,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) if (set_hidden_key(op, no_fields, key)) goto err; // Read key at the same time, for future reference - if (get_ndb_value(op, no_fields, NULL)) + if (get_ndb_value(op, NULL, no_fields)) goto err; } else @@ -630,13 +763,13 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) Field *field= table->field[i]; if (thd->query_id == field->query_id) { - if (get_ndb_value(op, i, field->ptr)) + if (get_ndb_value(op, field, i)) goto err; } else { // Attribute was not to be read - m_value[i]= NULL; + m_value[i].ptr= NULL; } } @@ -700,13 +833,13 @@ int ha_ndbcluster::unique_index_read(const byte *key, if ((thd->query_id == field->query_id) || (field->flags & PRI_KEY_FLAG)) { - if (get_ndb_value(op, i, field->ptr)) + if (get_ndb_value(op, field, i)) ERR_RETURN(op->getNdbError()); } else { // Attribute was not to be read - m_value[i]= NULL; + m_value[i].ptr= NULL; } } @@ -749,11 +882,22 @@ inline int ha_ndbcluster::next_result(byte *buf) bool contact_ndb = m_lock.type != TL_WRITE_ALLOW_WRITE; do { DBUG_PRINT("info", ("Call nextResult, contact_ndb: %d", contact_ndb)); + /* + We can only handle one tuple with blobs at a time. + */ + if (ops_pending && blobs_pending) + { + if (trans->execute(NoCommit) != 0) + DBUG_RETURN(ndb_err(trans)); + ops_pending= 0; + blobs_pending= false; + } check= cursor->nextResult(contact_ndb); if (check == 0) { // One more record found DBUG_PRINT("info", ("One more record found")); + unpack_record(buf); table->status= 0; DBUG_RETURN(0); @@ -867,8 +1011,10 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, index_name= get_index_name(active_index); if (!(op= trans->getNdbIndexScanOperation(index_name, m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0, - parallelism, sorted))) + + NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) + get_ndb_lock_type(m_lock.type); + if (!(cursor= op->readTuples(lm, 0, parallelism, sorted))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; @@ -928,7 +1074,9 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len, if (!(op= trans->getNdbScanOperation(m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0,parallelism))) + NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) + get_ndb_lock_type(m_lock.type); + if (!(cursor= op->readTuples(lm, 0, parallelism))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; @@ -997,7 +1145,9 @@ int ha_ndbcluster::full_table_scan(byte *buf) if (!(op=trans->getNdbScanOperation(m_tabname))) ERR_RETURN(trans->getNdbError()); - if (!(cursor= op->readTuples(get_ndb_lock_type(m_lock.type), 0,parallelism))) + NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) + get_ndb_lock_type(m_lock.type); + if (!(cursor= op->readTuples(lm, 0, parallelism))) ERR_RETURN(trans->getNdbError()); m_active_cursor= cursor; DBUG_RETURN(define_read_attrs(buf, op)); @@ -1021,12 +1171,12 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) (field->flags & PRI_KEY_FLAG) || retrieve_all_fields) { - if (get_ndb_value(op, i, field->ptr)) + if (get_ndb_value(op, field, i)) ERR_RETURN(op->getNdbError()); } else { - m_value[i]= NULL; + m_value[i].ptr= NULL; } } @@ -1040,7 +1190,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) if (!tab->getColumn(hidden_no)) DBUG_RETURN(1); #endif - if (get_ndb_value(op, hidden_no, NULL)) + if (get_ndb_value(op, NULL, hidden_no)) ERR_RETURN(op->getNdbError()); } @@ -1108,12 +1258,13 @@ int ha_ndbcluster::write_row(byte *record) */ rows_inserted++; if ((rows_inserted == rows_to_insert) || - ((rows_inserted % bulk_insert_rows) == 0)) + ((rows_inserted % bulk_insert_rows) == 0) || + uses_blob_value(false) != 0) { // Send rows to NDB DBUG_PRINT("info", ("Sending inserts to NDB, "\ "rows_inserted:%d, bulk_insert_rows: %d", - rows_inserted, bulk_insert_rows)); + (int)rows_inserted, (int)bulk_insert_rows)); if (trans->execute(NoCommit) != 0) DBUG_RETURN(ndb_err(trans)); } @@ -1190,6 +1341,8 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) if (!(op= cursor->updateTuple())) ERR_RETURN(trans->getNdbError()); ops_pending++; + if (uses_blob_value(false)) + blobs_pending= true; } else { @@ -1205,7 +1358,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) // Require that the PK for this record has previously been // read into m_value uint no_fields= table->fields; - NdbRecAttr* rec= m_value[no_fields]; + NdbRecAttr* rec= m_value[no_fields].rec; DBUG_ASSERT(rec); DBUG_DUMP("key", (char*)rec->aRef(), NDB_HIDDEN_PRIMARY_KEY_LENGTH); @@ -1280,7 +1433,7 @@ int ha_ndbcluster::delete_row(const byte *record) // This table has no primary key, use "hidden" primary key DBUG_PRINT("info", ("Using hidden key")); uint no_fields= table->fields; - NdbRecAttr* rec= m_value[no_fields]; + NdbRecAttr* rec= m_value[no_fields].rec; DBUG_ASSERT(rec != NULL); if (set_hidden_key(op, no_fields, rec->aRef())) @@ -1318,7 +1471,7 @@ void ha_ndbcluster::unpack_record(byte* buf) { uint row_offset= (uint) (buf - table->record[0]); Field **field, **end; - NdbRecAttr **value= m_value; + NdbValue *value= m_value; DBUG_ENTER("unpack_record"); // Set null flag(s) @@ -1327,8 +1480,23 @@ void ha_ndbcluster::unpack_record(byte* buf) field < end; field++, value++) { - if (*value && (*value)->isNULL()) - (*field)->set_null(row_offset); + if ((*value).ptr) + { + if (! ((*field)->flags & BLOB_FLAG)) + { + if ((*value).rec->isNULL()) + (*field)->set_null(row_offset); + } + else + { + NdbBlob* ndb_blob= (*value).blob; + bool isNull= true; + int ret= ndb_blob->getNull(isNull); + DBUG_ASSERT(ret == 0); + if (isNull) + (*field)->set_null(row_offset); + } + } } #ifndef DBUG_OFF @@ -1339,7 +1507,7 @@ void ha_ndbcluster::unpack_record(byte* buf) int hidden_no= table->fields; const NDBTAB *tab= (NDBTAB *) m_table; const NDBCOL *hidden_col= tab->getColumn(hidden_no); - NdbRecAttr* rec= m_value[hidden_no]; + NdbRecAttr* rec= m_value[hidden_no].rec; DBUG_ASSERT(rec); DBUG_PRINT("hidden", ("%d: %s \"%llu\"", hidden_no, hidden_col->getName(), rec->u_64_value())); @@ -1367,9 +1535,9 @@ void ha_ndbcluster::print_results() { Field *field; const NDBCOL *col; - NdbRecAttr *value; + NdbValue value; - if (!(value= m_value[f])) + if (!(value= m_value[f]).ptr) { fprintf(DBUG_FILE, "Field %d was not read\n", f); continue; @@ -1378,19 +1546,28 @@ void ha_ndbcluster::print_results() DBUG_DUMP("field->ptr", (char*)field->ptr, field->pack_length()); col= tab->getColumn(f); fprintf(DBUG_FILE, "%d: %s\t", f, col->getName()); - - if (value->isNULL()) + + NdbBlob *ndb_blob= NULL; + if (! (field->flags & BLOB_FLAG)) { - fprintf(DBUG_FILE, "NULL\n"); - continue; + if (value.rec->isNULL()) + { + fprintf(DBUG_FILE, "NULL\n"); + continue; + } + } + else + { + ndb_blob= value.blob; + bool isNull= true; + ndb_blob->getNull(isNull); + if (isNull) { + fprintf(DBUG_FILE, "NULL\n"); + continue; + } } switch (col->getType()) { - case NdbDictionary::Column::Blob: - case NdbDictionary::Column::Clob: - case NdbDictionary::Column::Undefined: - fprintf(DBUG_FILE, "Unknown type: %d", col->getType()); - break; case NdbDictionary::Column::Tinyint: { char value= *field->ptr; fprintf(DBUG_FILE, "Tinyint\t%d", value); @@ -1482,6 +1659,21 @@ void ha_ndbcluster::print_results() fprintf(DBUG_FILE, "Timespec\t%llu", value); break; } + case NdbDictionary::Column::Blob: { + Uint64 len= 0; + ndb_blob->getLength(len); + fprintf(DBUG_FILE, "Blob\t[len=%u]", (unsigned)len); + break; + } + case NdbDictionary::Column::Text: { + Uint64 len= 0; + ndb_blob->getLength(len); + fprintf(DBUG_FILE, "Text\t[len=%u]", (unsigned)len); + break; + } + case NdbDictionary::Column::Undefined: + fprintf(DBUG_FILE, "Unknown type: %d", col->getType()); + break; } fprintf(DBUG_FILE, "\n"); @@ -1727,7 +1919,7 @@ void ha_ndbcluster::position(const byte *record) // No primary key, get hidden key DBUG_PRINT("info", ("Getting hidden key")); int hidden_no= table->fields; - NdbRecAttr* rec= m_value[hidden_no]; + NdbRecAttr* rec= m_value[hidden_no].rec; const NDBTAB *tab= (NDBTAB *) m_table; const NDBCOL *hidden_col= tab->getColumn(hidden_no); DBUG_ASSERT(hidden_col->getPrimaryKey() && @@ -1901,7 +2093,7 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows) const NDBTAB *tab= (NDBTAB *) m_table; DBUG_ENTER("start_bulk_insert"); - DBUG_PRINT("enter", ("rows: %d", rows)); + DBUG_PRINT("enter", ("rows: %d", (int)rows)); rows_inserted= 0; rows_to_insert= rows; @@ -1936,7 +2128,7 @@ int ha_ndbcluster::end_bulk_insert() int ha_ndbcluster::extra_opt(enum ha_extra_function operation, ulong cache_size) { DBUG_ENTER("extra_opt"); - DBUG_PRINT("enter", ("cache_size: %d", cache_size)); + DBUG_PRINT("enter", ("cache_size: %lu", cache_size)); DBUG_RETURN(extra(operation)); } @@ -2157,7 +2349,7 @@ int ha_ndbcluster::start_stmt(THD *thd) NdbConnection *tablock_trans= (NdbConnection*)thd->transaction.all.ndb_tid; - DBUG_PRINT("info", ("tablock_trans: %x", tablock_trans)); + DBUG_PRINT("info", ("tablock_trans: %x", (uint)tablock_trans)); DBUG_ASSERT(tablock_trans); trans= m_ndb->hupp(tablock_trans); if (trans == NULL) ERR_RETURN(m_ndb->getNdbError()); @@ -2234,71 +2426,184 @@ int ndbcluster_rollback(THD *thd, void *ndb_transaction) /* - Map MySQL type to the corresponding NDB type + Define NDB column based on Field. + Returns 0 or mysql error code. + Not member of ha_ndbcluster because NDBCOL cannot be declared. */ -inline NdbDictionary::Column::Type -mysql_to_ndb_type(enum enum_field_types mysql_type, bool unsigned_flg) +static int create_ndb_column(NDBCOL &col, + Field *field, + HA_CREATE_INFO *info) { - switch(mysql_type) { + // Set name + col.setName(field->field_name); + // Set type and sizes + const enum enum_field_types mysql_type= field->real_type(); + switch (mysql_type) { + // Numeric types case MYSQL_TYPE_DECIMAL: - return NdbDictionary::Column::Char; + col.setType(NDBCOL::Char); + col.setLength(field->pack_length()); + break; case MYSQL_TYPE_TINY: - return (unsigned_flg) ? - NdbDictionary::Column::Tinyunsigned : - NdbDictionary::Column::Tinyint; + if (field->flags & UNSIGNED_FLAG) + col.setType(NDBCOL::Tinyunsigned); + else + col.setType(NDBCOL::Tinyint); + col.setLength(1); + break; case MYSQL_TYPE_SHORT: - return (unsigned_flg) ? - NdbDictionary::Column::Smallunsigned : - NdbDictionary::Column::Smallint; + if (field->flags & UNSIGNED_FLAG) + col.setType(NDBCOL::Smallunsigned); + else + col.setType(NDBCOL::Smallint); + col.setLength(1); + break; case MYSQL_TYPE_LONG: - return (unsigned_flg) ? - NdbDictionary::Column::Unsigned : - NdbDictionary::Column::Int; - case MYSQL_TYPE_TIMESTAMP: - return NdbDictionary::Column::Unsigned; - case MYSQL_TYPE_LONGLONG: - return (unsigned_flg) ? - NdbDictionary::Column::Bigunsigned : - NdbDictionary::Column::Bigint; + if (field->flags & UNSIGNED_FLAG) + col.setType(NDBCOL::Unsigned); + else + col.setType(NDBCOL::Int); + col.setLength(1); + break; case MYSQL_TYPE_INT24: - return (unsigned_flg) ? - NdbDictionary::Column::Mediumunsigned : - NdbDictionary::Column::Mediumint; + if (field->flags & UNSIGNED_FLAG) + col.setType(NDBCOL::Mediumunsigned); + else + col.setType(NDBCOL::Mediumint); + col.setLength(1); + break; + case MYSQL_TYPE_LONGLONG: + if (field->flags & UNSIGNED_FLAG) + col.setType(NDBCOL::Bigunsigned); + else + col.setType(NDBCOL::Bigint); + col.setLength(1); break; case MYSQL_TYPE_FLOAT: - return NdbDictionary::Column::Float; + col.setType(NDBCOL::Float); + col.setLength(1); + break; case MYSQL_TYPE_DOUBLE: - return NdbDictionary::Column::Double; - case MYSQL_TYPE_DATETIME : - return NdbDictionary::Column::Datetime; - case MYSQL_TYPE_DATE : - case MYSQL_TYPE_NEWDATE : - case MYSQL_TYPE_TIME : - case MYSQL_TYPE_YEAR : - // Missing NDB data types, mapped to char - return NdbDictionary::Column::Char; - case MYSQL_TYPE_ENUM : - return NdbDictionary::Column::Char; - case MYSQL_TYPE_SET : - return NdbDictionary::Column::Char; - case MYSQL_TYPE_TINY_BLOB : - case MYSQL_TYPE_MEDIUM_BLOB : - case MYSQL_TYPE_LONG_BLOB : - case MYSQL_TYPE_BLOB : - return NdbDictionary::Column::Blob; - case MYSQL_TYPE_VAR_STRING : - return NdbDictionary::Column::Varchar; - case MYSQL_TYPE_STRING : - return NdbDictionary::Column::Char; - case MYSQL_TYPE_NULL : - case MYSQL_TYPE_GEOMETRY : - return NdbDictionary::Column::Undefined; - } - return NdbDictionary::Column::Undefined; + col.setType(NDBCOL::Double); + col.setLength(1); + break; + // Date types + case MYSQL_TYPE_TIMESTAMP: + col.setType(NDBCOL::Unsigned); + col.setLength(1); + break; + case MYSQL_TYPE_DATETIME: + col.setType(NDBCOL::Datetime); + col.setLength(1); + break; + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_YEAR: + col.setType(NDBCOL::Char); + col.setLength(field->pack_length()); + break; + // Char types + case MYSQL_TYPE_STRING: + if (field->flags & BINARY_FLAG) + col.setType(NDBCOL::Binary); + else + col.setType(NDBCOL::Char); + col.setLength(field->pack_length()); + break; + case MYSQL_TYPE_VAR_STRING: + if (field->flags & BINARY_FLAG) + col.setType(NDBCOL::Varbinary); + else + col.setType(NDBCOL::Varchar); + col.setLength(field->pack_length()); + break; + // Blob types (all come in as MYSQL_TYPE_BLOB) + mysql_type_tiny_blob: + case MYSQL_TYPE_TINY_BLOB: + if (field->flags & BINARY_FLAG) + col.setType(NDBCOL::Blob); + else + col.setType(NDBCOL::Text); + col.setInlineSize(256); + // No parts + col.setPartSize(0); + col.setStripeSize(0); + break; + mysql_type_blob: + case MYSQL_TYPE_BLOB: + if (field->flags & BINARY_FLAG) + col.setType(NDBCOL::Blob); + else + col.setType(NDBCOL::Text); + // Use "<=" even if "<" is the exact condition + if (field->max_length() <= (1 << 8)) + goto mysql_type_tiny_blob; + else if (field->max_length() <= (1 << 16)) + { + col.setInlineSize(256); + col.setPartSize(2000); + col.setStripeSize(16); + } + else if (field->max_length() <= (1 << 24)) + goto mysql_type_medium_blob; + else + goto mysql_type_long_blob; + break; + mysql_type_medium_blob: + case MYSQL_TYPE_MEDIUM_BLOB: + if (field->flags & BINARY_FLAG) + col.setType(NDBCOL::Blob); + else + col.setType(NDBCOL::Text); + col.setInlineSize(256); + col.setPartSize(4000); + col.setStripeSize(8); + break; + mysql_type_long_blob: + case MYSQL_TYPE_LONG_BLOB: + if (field->flags & BINARY_FLAG) + col.setType(NDBCOL::Blob); + else + col.setType(NDBCOL::Text); + col.setInlineSize(256); + col.setPartSize(8000); + col.setStripeSize(4); + break; + // Other types + case MYSQL_TYPE_ENUM: + col.setType(NDBCOL::Char); + col.setLength(field->pack_length()); + break; + case MYSQL_TYPE_SET: + col.setType(NDBCOL::Char); + col.setLength(field->pack_length()); + break; + case MYSQL_TYPE_NULL: + case MYSQL_TYPE_GEOMETRY: + goto mysql_type_unsupported; + mysql_type_unsupported: + default: + return HA_ERR_UNSUPPORTED; + } + // Set nullable and pk + col.setNullable(field->maybe_null()); + col.setPrimaryKey(field->flags & PRI_KEY_FLAG); + // Set autoincrement + if (field->flags & AUTO_INCREMENT_FLAG) + { + col.setAutoIncrement(TRUE); + ulonglong value= info->auto_increment_value ? + info->auto_increment_value -1 : (ulonglong) 0; + DBUG_PRINT("info", ("Autoincrement key, initial: %llu", value)); + col.setAutoIncrementInitialValue(value); + } + else + col.setAutoIncrement(false); + return 0; } - /* Create a table in NDB Cluster */ @@ -2308,7 +2613,6 @@ int ha_ndbcluster::create(const char *name, HA_CREATE_INFO *info) { NDBTAB tab; - NdbDictionary::Column::Type ndb_type; NDBCOL col; uint pack_length, length, i; const void *data, *pack_data; @@ -2339,31 +2643,11 @@ int ha_ndbcluster::create(const char *name, for (i= 0; i < form->fields; i++) { Field *field= form->field[i]; - ndb_type= mysql_to_ndb_type(field->real_type(), - field->flags & UNSIGNED_FLAG); DBUG_PRINT("info", ("name: %s, type: %u, pack_length: %d", field->field_name, field->real_type(), field->pack_length())); - col.setName(field->field_name); - col.setType(ndb_type); - if ((ndb_type == NdbDictionary::Column::Char) || - (ndb_type == NdbDictionary::Column::Varchar)) - col.setLength(field->pack_length()); - else - col.setLength(1); - col.setNullable(field->maybe_null()); - col.setPrimaryKey(field->flags & PRI_KEY_FLAG); - if (field->flags & AUTO_INCREMENT_FLAG) - { - col.setAutoIncrement(TRUE); - ulonglong value= info->auto_increment_value ? - info->auto_increment_value -1 : (ulonglong) 0; - DBUG_PRINT("info", ("Autoincrement key, initial: %d", value)); - col.setAutoIncrementInitialValue(value); - } - else - col.setAutoIncrement(false); - + if (my_errno= create_ndb_column(col, field, info)) + DBUG_RETURN(my_errno); tab.addColumn(col); } @@ -2631,14 +2915,15 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_table(NULL), m_table_flags(HA_REC_NOT_IN_SEQ | HA_NOT_EXACT_COUNT | - HA_NO_PREFIX_CHAR_KEYS | - HA_NO_BLOBS), + HA_NO_PREFIX_CHAR_KEYS), m_use_write(false), retrieve_all_fields(FALSE), rows_to_insert(0), rows_inserted(0), bulk_insert_rows(1024), - ops_pending(0) + ops_pending(0), + blobs_buffer(0), + blobs_buffer_size(0) { int i; @@ -2671,6 +2956,8 @@ ha_ndbcluster::~ha_ndbcluster() DBUG_ENTER("~ha_ndbcluster"); release_metadata(); + my_free(blobs_buffer, MYF(MY_ALLOW_ZERO_PTR)); + blobs_buffer= 0; // Check for open cursor/transaction DBUG_ASSERT(m_active_cursor == NULL); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index fc0d607abaa..e08b409059c 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -35,6 +35,7 @@ class NdbRecAttr; // Forward declaration class NdbResultSet; // Forward declaration class NdbScanOperation; class NdbIndexScanOperation; +class NdbBlob; typedef enum ndb_index_type { UNDEFINED_INDEX = 0, @@ -171,6 +172,7 @@ class ha_ndbcluster: public handler enum ha_rkey_function find_flag); int close_scan(); void unpack_record(byte *buf); + int get_ndb_lock_type(enum thr_lock_type type); void set_dbname(const char *pathname); void set_tabname(const char *pathname); @@ -181,7 +183,9 @@ class ha_ndbcluster: public handler int set_ndb_key(NdbOperation*, Field *field, uint fieldnr, const byte* field_ptr); int set_ndb_value(NdbOperation*, Field *field, uint fieldnr); - int get_ndb_value(NdbOperation*, uint fieldnr, byte *field_ptr); + int get_ndb_value(NdbOperation*, Field *field, uint fieldnr); + friend int ::get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg); + int get_ndb_blobs_value(NdbBlob *last_ndb_blob); int set_primary_key(NdbOperation *op, const byte *key); int set_primary_key(NdbOperation *op); int set_primary_key_from_old_data(NdbOperation *op, const byte *old_data); @@ -191,8 +195,8 @@ class ha_ndbcluster: public handler void print_results(); longlong get_auto_increment(); - int ndb_err(NdbConnection*); + bool uses_blob_value(bool all_fields); private: int check_ndb_connection(); @@ -209,13 +213,19 @@ class ha_ndbcluster: public handler NDB_SHARE *m_share; NDB_INDEX_TYPE m_indextype[MAX_KEY]; const char* m_unique_index_name[MAX_KEY]; - NdbRecAttr *m_value[NDB_MAX_ATTRIBUTES_IN_TABLE]; + // NdbRecAttr has no reference to blob + typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue; + NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE]; bool m_use_write; bool retrieve_all_fields; ha_rows rows_to_insert; ha_rows rows_inserted; ha_rows bulk_insert_rows; ha_rows ops_pending; + bool blobs_pending; + // memory for blobs in one tuple + char *blobs_buffer; + uint32 blobs_buffer_size; }; bool ndbcluster_init(void); @@ -231,10 +241,3 @@ int ndbcluster_discover(const char* dbname, const char* name, int ndbcluster_drop_database(const char* path); void ndbcluster_print_error(int error, const NdbOperation *error_op); - - - - - - - -- cgit v1.2.1 From 2cd7e4cdefec2bd529a5de78e0d8c8adb636b036 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jul 2004 20:54:25 +0500 Subject: Fixes for bugs in embedded library: #4700 (Unsigned value returned as signed) just no appropriate checking #4701 (Errors returned earlier than expected) all errors returned from send_command() #4702 (Result isn't freed properly if there's no retrieval) flush_use_result has only 'client' version and should be made 'virtual' include/mysql.h: flush_use_result 'virtual' method added to MYSQL (#4701) include/sql_common.h: no flush_use_result() now (#4702) libmysql/libmysql.c: call of the flush_use_result changed (#4702) libmysqld/lib_sql.cc: now errors returned from emb_advanced_command() or from emb_read_rows() depending on if number of returned fields is not 0 (#4701) emb_flush_use_result() implementation (#4702) sql-common/client.c: cli_flush_use_result() implementation (#4702) sql/sql_prepare.cc: unsigned flag now checked (#4700) --- sql/sql_prepare.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 4305bee42a2..47cc461fac0 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -696,6 +696,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query) else { uchar *buff= (uchar*) client_param->buffer; + param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, client_param->length ? *client_param->length : -- cgit v1.2.1 From cf4cfab2163048d789ad75b85b29f5b10cbafabe Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jul 2004 18:35:51 +0200 Subject: WL#1791 Handler: support update of primary key --- sql/ha_ndbcluster.cc | 100 +++++++++++++++++++++++++++++++++++++++++++++++---- sql/ha_ndbcluster.h | 4 +-- 2 files changed, 96 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 66c01bb2231..553358e37e6 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -593,7 +593,7 @@ int ha_ndbcluster::set_primary_key(NdbOperation *op) Read one record from NDB using primary key */ -int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) +int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) { uint no_fields= table->fields, i; NdbConnection *trans= m_active_trans; @@ -624,11 +624,11 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) return res; } - // Read non-key field(s) unless HA_EXTRA_RETRIEVE_ALL_COLS + // Read all wanted non-key field(s) unless HA_EXTRA_RETRIEVE_ALL_COLS for (i= 0; i < no_fields; i++) { Field *field= table->field[i]; - if ((thd->query_id == field->query_id) || + if ((thd->query_id == field->query_id) || retrieve_all_fields) { if (get_ndb_value(op, i, field->ptr)) @@ -657,6 +657,62 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) } +/* + Read one complementing record from NDB using primary key from old_data +*/ + +int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) +{ + uint no_fields= table->fields, i; + NdbConnection *trans= m_active_trans; + NdbOperation *op; + THD *thd= current_thd; + DBUG_ENTER("complemented_pk_read"); + + if (retrieve_all_fields) + // We have allready retrieved all fields, nothing to complement + DBUG_RETURN(0); + + if (!(op= trans->getNdbOperation(m_tabname)) || op->readTuple() != 0) + goto err; + + int res; + if (res= set_primary_key_from_old_data(op, old_data)) + return res; + + // Read all unreferenced non-key field(s) + for (i= 0; i < no_fields; i++) + { + Field *field= table->field[i]; + if (!(field->flags & PRI_KEY_FLAG) && + (thd->query_id != field->query_id)) + { + if (get_ndb_value(op, i, field->ptr)) + goto err; + } + else + { + // Attribute was not to be read + m_value[i]= NULL; + } + } + + if (trans->execute(NoCommit, IgnoreError) != 0) + { + table->status= STATUS_NOT_FOUND; + DBUG_RETURN(ndb_err(trans)); + } + + // The value have now been fetched from NDB + unpack_record(new_data); + table->status= 0; + DBUG_RETURN(0); + + err: + ERR_RETURN(trans->getNdbError()); +} + + /* Read one record from NDB using unique secondary index */ @@ -1173,10 +1229,43 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) if (table->timestamp_on_update_now) update_timestamp(new_data+table->timestamp_on_update_now-1); - /* Check for update of primary key and return error */ + /* Check for update of primary key for special handling */ if ((table->primary_key != MAX_KEY) && (key_cmp(table->primary_key, old_data, new_data))) - DBUG_RETURN(HA_ERR_UNSUPPORTED); + { + DBUG_PRINT("info", ("primary key update, doing pk read+insert+delete")); + + // Get all old fields, since we optimize away fields not in query + int read_res = complemented_pk_read(old_data, new_data); + if (read_res) + { + DBUG_PRINT("info", ("pk read failed")); + DBUG_RETURN(read_res); + } + // Insert new row + int insert_res = write_row(new_data); + if (!insert_res) + { + // Delete old row + DBUG_PRINT("info", ("insert succeded")); + int delete_res = delete_row(old_data); + if (!delete_res) + { + DBUG_PRINT("info", ("insert+delete succeeded")); + DBUG_RETURN(0); + } + else + { + DBUG_PRINT("info", ("delete failed")); + DBUG_RETURN(delete_row(new_data)); + } + } + else + { + DBUG_PRINT("info", ("insert failed")); + DBUG_RETURN(insert_res); + } + } if (cursor) { @@ -1350,7 +1439,6 @@ void ha_ndbcluster::unpack_record(byte* buf) DBUG_VOID_RETURN; } - /* Utility function to print/dump the fetched field */ diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index fc0d607abaa..a1cb1698067 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -156,8 +156,8 @@ class ha_ndbcluster: public handler NDB_INDEX_TYPE get_index_type(uint idx_no) const; NDB_INDEX_TYPE get_index_type_from_table(uint index_no) const; - int pk_read(const byte *key, uint key_len, - byte *buf); + int pk_read(const byte *key, uint key_len, byte *buf); + int complemented_pk_read(const byte *old_data, byte *new_data); int unique_index_read(const byte *key, uint key_len, byte *buf); int ordered_index_scan(const key_range *start_key, -- cgit v1.2.1 From 25a54005ae4c5566519d72eb8bc74226d0a7758f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jul 2004 19:14:05 +0200 Subject: Cosmetic fix --- sql/ha_ndbcluster.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 553358e37e6..372168b0bb2 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1236,19 +1236,19 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) DBUG_PRINT("info", ("primary key update, doing pk read+insert+delete")); // Get all old fields, since we optimize away fields not in query - int read_res = complemented_pk_read(old_data, new_data); + int read_res= complemented_pk_read(old_data, new_data); if (read_res) { DBUG_PRINT("info", ("pk read failed")); DBUG_RETURN(read_res); } // Insert new row - int insert_res = write_row(new_data); + int insert_res= write_row(new_data); if (!insert_res) { // Delete old row DBUG_PRINT("info", ("insert succeded")); - int delete_res = delete_row(old_data); + int delete_res= delete_row(old_data); if (!delete_res) { DBUG_PRINT("info", ("insert+delete succeeded")); -- cgit v1.2.1 From 473eec23285c0338fa0cf45787c111686d8abd47 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 22 Jul 2004 19:28:11 +0200 Subject: distclean: rm -f lex_hash.h BUG#4583 --- sql/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index f3751eabd25..0a664a120a5 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -125,8 +125,8 @@ sql_lex.o: lex_hash.h udf_example.so: udf_example.cc $(CXXCOMPILE) -shared -o $@ $< -#distclean: -# rm -f lex_hash.h +distclean: + rm -f lex_hash.h # Don't update the files from bitkeeper %::SCCS/s.% -- cgit v1.2.1 From 205703ff06f4f90d3542fe593294c3c54b06a5ec Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jul 2004 00:00:50 +0500 Subject: Several fixes to make tests working for embedded library libmysqld/lib_sql.cc: max_allowed_packet - don't send client one to global thread initialization fixed "std" to "def" in catalog name sql/mysqld.cc: added initialization of global_system_variables.max_allowed_packet sql/set_var.cc: don't do this in embedded library --- sql/mysqld.cc | 2 ++ sql/set_var.cc | 2 ++ 2 files changed, 4 insertions(+) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4fd13d33bab..27e9c5127f8 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5583,9 +5583,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), #ifdef EMBEDDED_LIBRARY case OPT_MAX_ALLOWED_PACKET: max_allowed_packet= atoi(argument); + global_system_variables.max_allowed_packet= max_allowed_packet; break; case OPT_NET_BUFFER_LENGTH: net_buffer_length= atoi(argument); + global_system_variables.net_buffer_length= net_buffer_length; break; #endif #include diff --git a/sql/set_var.cc b/sql/set_var.cc index e1cfb77d297..1bd45cccda3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -1129,8 +1129,10 @@ static int check_max_delayed_threads(THD *thd, set_var *var) static void fix_max_connections(THD *thd, enum_var_type type) { +#ifndef EMBEDDED_LIBRARY resize_thr_alarm(max_connections + global_system_variables.max_insert_delayed_threads + 10); +#endif } -- cgit v1.2.1 From 564b2736a4b63dc17237380bd4403ecd2d70072d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jul 2004 10:33:51 +0200 Subject: Fixes after code review of WL#1791 Handler: support update of primary key --- sql/ha_ndbcluster.cc | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 372168b0bb2..82445f175e7 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -604,7 +604,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) DBUG_DUMP("key", (char*)key, key_len); if (!(op= trans->getNdbOperation(m_tabname)) || op->readTuple() != 0) - goto err; + ERR_RETURN(trans->getNdbError()); if (table->primary_key == MAX_KEY) { @@ -612,10 +612,11 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) DBUG_PRINT("info", ("Using hidden key")); DBUG_DUMP("key", (char*)key, 8); if (set_hidden_key(op, no_fields, key)) - goto err; + ERR_RETURN(trans->getNdbError()); + // Read key at the same time, for future reference if (get_ndb_value(op, no_fields, NULL)) - goto err; + ERR_RETURN(trans->getNdbError()); } else { @@ -632,7 +633,7 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) retrieve_all_fields) { if (get_ndb_value(op, i, field->ptr)) - goto err; + ERR_RETURN(trans->getNdbError()); } else { @@ -651,9 +652,6 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) unpack_record(buf); table->status= 0; DBUG_RETURN(0); - - err: - ERR_RETURN(trans->getNdbError()); } @@ -674,11 +672,11 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) DBUG_RETURN(0); if (!(op= trans->getNdbOperation(m_tabname)) || op->readTuple() != 0) - goto err; + ERR_RETURN(trans->getNdbError()); int res; if (res= set_primary_key_from_old_data(op, old_data)) - return res; + ERR_RETURN(trans->getNdbError()); // Read all unreferenced non-key field(s) for (i= 0; i < no_fields; i++) @@ -688,16 +686,11 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) (thd->query_id != field->query_id)) { if (get_ndb_value(op, i, field->ptr)) - goto err; - } - else - { - // Attribute was not to be read - m_value[i]= NULL; + ERR_RETURN(trans->getNdbError()); } } - if (trans->execute(NoCommit, IgnoreError) != 0) + if (trans->execute(NoCommit) != 0) { table->status= STATUS_NOT_FOUND; DBUG_RETURN(ndb_err(trans)); @@ -707,9 +700,6 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) unpack_record(new_data); table->status= 0; DBUG_RETURN(0); - - err: - ERR_RETURN(trans->getNdbError()); } @@ -1243,6 +1233,8 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) DBUG_RETURN(read_res); } // Insert new row + rows_inserted= 0; + rows_to_insert= 1; int insert_res= write_row(new_data); if (!insert_res) { @@ -1344,9 +1336,9 @@ int ha_ndbcluster::delete_row(const byte *record) if (cursor) { /* - We are scanning records and want to update the record + We are scanning records and want to delete the record that was just found, call deleteTuple on the cursor - to take over the lock to a new update operation + to take over the lock to a new updatedelete operation And thus setting the primary key of the record from the active record in cursor */ -- cgit v1.2.1 From 206cc88b6933ecf2ee752afa466824c6ed3feb99 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jul 2004 13:13:50 +0200 Subject: Changed bulk insert to only be statement wise --- sql/ha_ndbcluster.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 82445f175e7..ce452222fb9 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1233,8 +1233,6 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) DBUG_RETURN(read_res); } // Insert new row - rows_inserted= 0; - rows_to_insert= 1; int insert_res= write_row(new_data); if (!insert_res) { @@ -1338,7 +1336,7 @@ int ha_ndbcluster::delete_row(const byte *record) /* We are scanning records and want to delete the record that was just found, call deleteTuple on the cursor - to take over the lock to a new updatedelete operation + to take over the lock to a new delete operation And thus setting the primary key of the record from the active record in cursor */ @@ -2010,6 +2008,8 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows) int ha_ndbcluster::end_bulk_insert() { DBUG_ENTER("end_bulk_insert"); + rows_inserted= 0; + rows_to_insert= 1; DBUG_RETURN(0); } @@ -2716,7 +2716,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): HA_NO_BLOBS), m_use_write(false), retrieve_all_fields(FALSE), - rows_to_insert(0), + rows_to_insert(1), rows_inserted(0), bulk_insert_rows(1024), ops_pending(0) -- cgit v1.2.1 From a3b71309d76cb126adb8ab7458595d3cd3c3822b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jul 2004 13:21:39 +0200 Subject: ha_ndbcluster.cc: ndb_supported_type, include all types in switch sql/ha_ndbcluster.cc: ndb_supported_type, include all types in switch --- sql/ha_ndbcluster.cc | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index e46857bc6f6..d98be25ee56 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -183,16 +183,40 @@ bool ha_ndbcluster::get_error_message(int error, /* Check if type is supported by NDB. + TODO Use this once, not in every operation */ static inline bool ndb_supported_type(enum_field_types type) { switch (type) { + case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + case MYSQL_TYPE_TIMESTAMP: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_STRING: + case MYSQL_TYPE_VAR_STRING: + case MYSQL_TYPE_TINY_BLOB: + case MYSQL_TYPE_BLOB: + case MYSQL_TYPE_MEDIUM_BLOB: + case MYSQL_TYPE_LONG_BLOB: + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + return true; case MYSQL_TYPE_NULL: case MYSQL_TYPE_GEOMETRY: - return false; + break; } - return true; + return false; } -- cgit v1.2.1 From 9628ff1a8e6c2ffd7faf281224c80062f73a7586 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jul 2004 13:41:38 +0200 Subject: ha_ndbcluster.cc: merge sql/ha_ndbcluster.cc: merge --- sql/ha_ndbcluster.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 312bcbe5c2a..442dc2f840e 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -614,14 +614,14 @@ int ha_ndbcluster::get_ndb_lock_type(enum thr_lock_type type) { int lm; if (type == TL_WRITE_ALLOW_WRITE) - lm = NdbScanOperation::LM_Exclusive; + lm= NdbScanOperation::LM_Exclusive; else if (uses_blob_value(retrieve_all_fields)) /* TODO use a new scan mode to read + lock + keyinfo */ - lm = NdbScanOperation::LM_Exclusive; + lm= NdbScanOperation::LM_Exclusive; else - lm = NdbScanOperation::LM_CommittedRead; + lm= NdbScanOperation::LM_CommittedRead; return lm; } @@ -842,7 +842,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) if (!(field->flags & PRI_KEY_FLAG) && (thd->query_id != field->query_id)) { - if (get_ndb_value(op, i, field->ptr)) + if (get_ndb_value(op, field, i)) ERR_RETURN(trans->getNdbError()); } } -- cgit v1.2.1 From 410c7b332304e4da64de11bdd32235d2276dada3 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 23 Jul 2004 15:46:56 +0200 Subject: Fixed merge problems, optimized bulk insert --- sql/ha_ndbcluster.cc | 110 ++++++++++++++++++++++++++++++--------------------- sql/ha_ndbcluster.h | 1 + 2 files changed, 66 insertions(+), 45 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 442dc2f840e..ec8bd035c83 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -41,7 +41,10 @@ static const int parallelism= 240; // Default value for max number of transactions // createable against NDB from this handler -static const int max_transactions = 256; +static const int max_transactions= 256; + +// Default value for prefetch of autoincrement values +static const ha_rows autoincrement_prefetch= 32; #define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8 @@ -286,7 +289,7 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, } // Blob type - NdbBlob *ndb_blob = ndb_op->getBlobHandle(fieldnr); + NdbBlob *ndb_blob= ndb_op->getBlobHandle(fieldnr); if (ndb_blob != NULL) { if (field->is_null()) @@ -832,7 +835,7 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) ERR_RETURN(trans->getNdbError()); int res; - if (res= set_primary_key_from_old_data(op, old_data)) + if ((res= set_primary_key_from_old_data(op, old_data))) ERR_RETURN(trans->getNdbError()); // Read all unreferenced non-key field(s) @@ -950,7 +953,7 @@ inline int ha_ndbcluster::next_result(byte *buf) If this an update or delete, call nextResult with false to process any records already cached in NdbApi */ - bool contact_ndb = m_lock.type != TL_WRITE_ALLOW_WRITE; + bool contact_ndb= m_lock.type != TL_WRITE_ALLOW_WRITE; do { DBUG_PRINT("info", ("Call nextResult, contact_ndb: %d", contact_ndb)); /* @@ -1328,7 +1331,8 @@ int ha_ndbcluster::write_row(byte *record) Find out how this is detected! */ rows_inserted++; - if ((rows_inserted == rows_to_insert) || + bulk_insert_not_flushed= true; + if ((rows_to_insert == 1) || ((rows_inserted % bulk_insert_rows) == 0) || uses_blob_value(false) != 0) { @@ -1336,6 +1340,7 @@ int ha_ndbcluster::write_row(byte *record) DBUG_PRINT("info", ("Sending inserts to NDB, "\ "rows_inserted:%d, bulk_insert_rows: %d", (int)rows_inserted, (int)bulk_insert_rows)); + bulk_insert_not_flushed= false; if (trans->execute(NoCommit) != 0) DBUG_RETURN(ndb_err(trans)); } @@ -1398,38 +1403,34 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) if ((table->primary_key != MAX_KEY) && (key_cmp(table->primary_key, old_data, new_data))) { - DBUG_PRINT("info", ("primary key update, doing pk read+insert+delete")); + int read_res, insert_res, delete_res; + DBUG_PRINT("info", ("primary key update, doing pk read+insert+delete")); // Get all old fields, since we optimize away fields not in query - int read_res= complemented_pk_read(old_data, new_data); + read_res= complemented_pk_read(old_data, new_data); if (read_res) { DBUG_PRINT("info", ("pk read failed")); DBUG_RETURN(read_res); } // Insert new row - int insert_res= write_row(new_data); - if (!insert_res) - { - // Delete old row - DBUG_PRINT("info", ("insert succeded")); - int delete_res= delete_row(old_data); - if (!delete_res) - { - DBUG_PRINT("info", ("insert+delete succeeded")); - DBUG_RETURN(0); - } - else - { - DBUG_PRINT("info", ("delete failed")); - DBUG_RETURN(delete_row(new_data)); - } - } - else + insert_res= write_row(new_data); + if (insert_res) { DBUG_PRINT("info", ("insert failed")); DBUG_RETURN(insert_res); } + // Delete old row + DBUG_PRINT("info", ("insert succeded")); + delete_res= delete_row(old_data); + if (delete_res) + { + DBUG_PRINT("info", ("delete failed")); + // Undo write_row(new_data) + DBUG_RETURN(delete_row(new_data)); + } + DBUG_PRINT("info", ("insert+delete succeeded")); + DBUG_RETURN(0); } if (cursor) @@ -1833,7 +1834,7 @@ int ha_ndbcluster::index_next(byte *buf) { DBUG_ENTER("index_next"); - int error = 1; + int error= 1; statistic_increment(ha_read_next_count,&LOCK_status); DBUG_RETURN(next_result(buf)); } @@ -2208,7 +2209,7 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows) degrade if too many bytes are inserted, thus it's limited by this calculation. */ - const int bytesperbatch = 8192; + const int bytesperbatch= 8192; bytes= 12 + tab->getRowSizeInBytes() + 4 * tab->getNoOfColumns(); batch= bytesperbatch/bytes; batch= batch == 0 ? 1 : batch; @@ -2223,10 +2224,25 @@ void ha_ndbcluster::start_bulk_insert(ha_rows rows) */ int ha_ndbcluster::end_bulk_insert() { + int error= 0; + DBUG_ENTER("end_bulk_insert"); + // Check if last inserts need to be flushed + if (bulk_insert_not_flushed) + { + NdbConnection *trans= m_active_trans; + // Send rows to NDB + DBUG_PRINT("info", ("Sending inserts to NDB, "\ + "rows_inserted:%d, bulk_insert_rows: %d", + rows_inserted, bulk_insert_rows)); + bulk_insert_not_flushed= false; + if (trans->execute(NoCommit) != 0) + error= ndb_err(trans); + } + rows_inserted= 0; rows_to_insert= 1; - DBUG_RETURN(0); + DBUG_RETURN(error); } @@ -2247,7 +2263,7 @@ int ha_ndbcluster::reset() const char **ha_ndbcluster::bas_ext() const -{ static const char *ext[1] = { NullS }; return ext; } +{ static const char *ext[1]= { NullS }; return ext; } /* @@ -2751,7 +2767,7 @@ int ha_ndbcluster::create(const char *name, DBUG_PRINT("info", ("name: %s, type: %u, pack_length: %d", field->field_name, field->real_type(), field->pack_length())); - if (my_errno= create_ndb_column(col, field, info)) + if ((my_errno= create_ndb_column(col, field, info))) DBUG_RETURN(my_errno); tab.addColumn(col); } @@ -3001,7 +3017,10 @@ longlong ha_ndbcluster::get_auto_increment() { DBUG_ENTER("get_auto_increment"); DBUG_PRINT("enter", ("m_tabname: %s", m_tabname)); - int cache_size = rows_to_insert ? rows_to_insert : 32; + int cache_size= + (rows_to_insert > autoincrement_prefetch) ? + rows_to_insert + : autoincrement_prefetch; Uint64 auto_value= m_ndb->getAutoIncrementValue(m_tabname, cache_size); DBUG_RETURN((longlong)auto_value); @@ -3026,6 +3045,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): rows_to_insert(1), rows_inserted(0), bulk_insert_rows(1024), + bulk_insert_not_flushed(false), ops_pending(0), blobs_buffer(0), blobs_buffer_size(0) @@ -3378,7 +3398,7 @@ void ha_ndbcluster::set_tabname(const char *path_name) ptr= m_tabname; while (*ptr != '\0') { - *ptr = tolower(*ptr); + *ptr= tolower(*ptr); ptr++; } #endif @@ -3394,17 +3414,17 @@ ha_ndbcluster::set_tabname(const char *path_name, char * tabname) char *end, *ptr; /* Scan name from the end */ - end = strend(path_name)-1; - ptr = end; + end= strend(path_name)-1; + ptr= end; while (ptr >= path_name && *ptr != '\\' && *ptr != '/') { ptr--; } - uint name_len = end - ptr; + uint name_len= end - ptr; memcpy(tabname, ptr + 1, end - ptr); - tabname[name_len] = '\0'; + tabname[name_len]= '\0'; #ifdef __WIN__ /* Put to lower case */ - ptr = tabname; + ptr= tabname; while (*ptr != '\0') { *ptr= tolower(*ptr); @@ -3567,7 +3587,7 @@ static int packfrm(const void *data, uint len, DBUG_PRINT("enter", ("data: %x, len: %d", data, len)); error= 1; - org_len = len; + org_len= len; if (my_compress((byte*)data, &org_len, &comp_len)) goto err; @@ -3587,9 +3607,9 @@ static int packfrm(const void *data, uint len, // Copy frm data into blob, already in machine independent format memcpy(blob->data, data, org_len); - *pack_data = blob; - *pack_len = blob_len; - error = 0; + *pack_data= blob; + *pack_len= blob_len; + error= 0; DBUG_PRINT("exit", ("pack_data: %x, pack_len: %d", *pack_data, *pack_len)); err: @@ -3601,7 +3621,7 @@ err: static int unpackfrm(const void **unpack_data, uint *unpack_len, const void *pack_data) { - const frm_blob_struct *blob = (frm_blob_struct*)pack_data; + const frm_blob_struct *blob= (frm_blob_struct*)pack_data; byte *data; ulong complen, orglen, ver; DBUG_ENTER("unpackfrm"); @@ -3617,7 +3637,7 @@ static int unpackfrm(const void **unpack_data, uint *unpack_len, if (ver != 1) DBUG_RETURN(1); - if (!(data = my_malloc(max(orglen, complen), MYF(MY_WME)))) + if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME)))) DBUG_RETURN(2); memcpy(data, blob->data, complen); @@ -3627,8 +3647,8 @@ static int unpackfrm(const void **unpack_data, uint *unpack_len, DBUG_RETURN(3); } - *unpack_data = data; - *unpack_len = complen; + *unpack_data= data; + *unpack_len= complen; DBUG_PRINT("exit", ("frmdata: %x, len: %d", *unpack_data, *unpack_len)); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 661eb582786..bd8d78ec00b 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -221,6 +221,7 @@ class ha_ndbcluster: public handler ha_rows rows_to_insert; ha_rows rows_inserted; ha_rows bulk_insert_rows; + bool bulk_insert_not_flushed; ha_rows ops_pending; bool blobs_pending; // memory for blobs in one tuple -- cgit v1.2.1 From 108864ed3b523fdb377ebc1ac176000652cad33f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 24 Jul 2004 03:30:11 -0700 Subject: WL#1518, "make bundled zlib usable for unix builds": required autotools macro written and deployed in all apropriate Makefile.ams. Use cases checked: - linux, standard location of zlib, no ndb - linux, standard locatoin of zlib, with ndb - linux, non-standard location of zlib, no ndb - hpux11, use of bundled zlib, no ndb The only non-checked case is non-standard location of zlib (or use of bundled zlib) + ndb. I wasn't able to check it as ndb/ just won't compile on beasts like AIX52 or HPUX11, where such a check is possible. It didn't compile there before as these systems dont't have installed zlib, so nothing got broken ;) Makefile.am: WL#1518 "make bundled zlib usable for unix builds", part 2: - zlib dir should be built only if there is no system zlib available; with introducing of DIST_SUBDIRS goal, os2, BUILD and SSH now only entered if make dist acinclude.m4: WL#1518, "make bundled zlib usable for unix builds": - actual implementation of the check for various zlib usage options configure.in: WL#1518, "make bundled zlib usable for unix builds": - MYSQL_CHECK_ZLIB_WITH_COMPRESS deployed libmysql/Makefile.am: WL#1518, "make bundled zlib usable for unix builds": - support for non-standard zlib include dir added libmysql_r/Makefile.am: WL#1518, "make bundled zlib usable for unix builds": - support for non-standard zlib include dir added libmysqld/Makefile.am: WL#1518, "make bundled zlib usable for unix builds": - support for non-standard zlib include dir added myisam/Makefile.am: WL#1518, "make bundled zlib usable for unix builds": - support for non-standard zlib binary dir added mysys/Makefile.am: WL#1518, "make bundled zlib usable for unix builds": - support for non-standard zlib include dir added sql/Makefile.am: WL#1518, "make bundled zlib usable for unix builds": - support for non-standard zlib include dir and library dir added tools/Makefile.am: WL#1518, "make bundled zlib usable for unix builds": - support for non-standard zlib include dir added - copyright added --- sql/Makefile.am | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index 007239f2e8c..9859f1ef841 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -19,7 +19,7 @@ MYSQLDATAdir = $(localstatedir) MYSQLSHAREdir = $(pkgdatadir) MYSQLBASEdir= $(prefix) -INCLUDES = @MT_INCLUDES@ \ +INCLUDES = @MT_INCLUDES@ @ZLIB_INCLUDES@ \ @bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \ -I$(top_srcdir)/include -I$(top_srcdir)/regex \ -I$(srcdir) $(openssl_includes) @@ -30,14 +30,15 @@ noinst_PROGRAMS = gen_lex_hash bin_PROGRAMS = mysql_tzinfo_to_sql gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ LDADD = @isam_libs@ \ - ../myisam/libmyisam.a \ - ../myisammrg/libmyisammrg.a \ - ../heap/libheap.a \ - ../vio/libvio.a \ - ../mysys/libmysys.a \ - ../dbug/libdbug.a \ - ../regex/libregex.a \ - ../strings/libmystrings.a + @ZLIB_LIBS@ \ + $(top_builddir)/myisam/libmyisam.a \ + $(top_builddir)/myisammrg/libmyisammrg.a \ + $(top_builddir)/heap/libheap.a \ + $(top_builddir)/vio/libvio.a \ + $(top_builddir)/mysys/libmysys.a \ + $(top_builddir)/dbug/libdbug.a \ + $(top_builddir)/regex/libregex.a \ + $(top_builddir)/strings/libmystrings.a mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @bdb_libs@ @innodb_libs@ @pstack_libs@ \ -- cgit v1.2.1 From 65ba6aa2934e465fa31ed6185dcd22c714bc1403 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Jul 2004 10:52:40 +0200 Subject: BUG#4717 - check for valid table names in ALTER TABLE ... RENAME --- sql/sql_yacc.yy | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a50e37e54f5..2199a0c8be5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1316,10 +1316,16 @@ alter_list_item: lex->simple_alter=0; } | RENAME opt_to table_ident - { + { LEX *lex=Lex; lex->select->db=$3->db.str; lex->name= $3->table.str; + if (check_table_name($3->table.str,$3->table.length) || + $3->db.str && check_db_name($3->db.str)) + { + net_printf(&lex->thd->net,ER_WRONG_TABLE_NAME,$3->table.str); + YYABORT; + } } | create_table_options { Lex->simple_alter=0; } | order_clause { Lex->simple_alter=0; }; -- cgit v1.2.1 From d2aaa0f817f6e673931adb7299fbe3c19e6b1ed0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Jul 2004 17:41:52 +0300 Subject: Added info about new --log-warnings option. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4fd13d33bab..83eb8bb864b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4523,7 +4523,7 @@ replicating a LOAD DATA INFILE command.", 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"log-warnings", 'W', "Log some not critical warnings to the log file.", + {"log-warnings", 'W', "Log some not critical warnings to the log file. Use this option twice, or --log-warnings=2 if you want 'Aborted connections' warning to be logged in the error log file.", (gptr*) &global_system_variables.log_warnings, (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, 0, 0, 0}, -- cgit v1.2.1 From b66a13eeb8f4a9bef7bda5a9d035328860fb7718 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 26 Jul 2004 21:33:42 +0200 Subject: safemalloc always resets the free'd memory, not only when PEDANTIC_SAFEMALLOC --- sql/field.h | 2 +- sql/sql_list.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/field.h b/sql/field.h index 24faee9d314..7f35b006c03 100644 --- a/sql/field.h +++ b/sql/field.h @@ -38,7 +38,7 @@ class Field public: static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } static void operator delete(void *ptr_arg, size_t size) { -#ifdef PEDANTIC_SAFEMALLOC +#ifdef SAFEMALLOC bfill(ptr_arg, size, 0x8F); #endif } diff --git a/sql/sql_list.h b/sql/sql_list.h index 22e9ed37386..c3b9c7f87ea 100644 --- a/sql/sql_list.h +++ b/sql/sql_list.h @@ -19,9 +19,9 @@ #pragma interface /* gcc class implementation */ #endif -/* mysql standard class memoryallocator */ +/* mysql standard class memory allocator */ -#ifdef PEDANTIC_SAFEMALLOC +#ifdef SAFEMALLOC #define TRASH(XX,YY) bfill((XX), (YY), 0x8F) #else #define TRASH(XX,YY) /* no-op */ -- cgit v1.2.1 From ac43db9c7d948c543fa7b6b6b48348c7b458f4cd Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 27 Jul 2004 18:43:40 +0500 Subject: A small fix to understand 4.1.0 format. --- sql/sql_db.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/sql_db.cc b/sql/sql_db.cc index ef180b58ee0..82fef3f7c7b 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -320,10 +320,17 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) { if (!strncmp(buf,"default-character-set", (pos-buf))) { + /* + Try character set name, and if it fails + try collation name, probably it's an old + 4.1.0 db.opt file, which didn't have + separate default-character-set and + default-collation commands. + */ if (!(create->default_table_charset= - get_charset_by_csname(pos+1, - MY_CS_PRIMARY, - MYF(0)))) + get_charset_by_csname(pos+1, MY_CS_PRIMARY, MYF(0))) && + !(create->default_table_charset= + get_charset_by_name(pos+1, MYF(0)))) { sql_print_error("Error while loading database options: '%s':",path); sql_print_error(ER(ER_UNKNOWN_CHARACTER_SET),pos+1); -- cgit v1.2.1 From a5e453e6085f441a014d7fdbb4878be4487ee708 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jul 2004 10:49:21 +0400 Subject: Fix for bug #4492. TIMESTAMP columns should be unsigned to preserve compatibility with 4.0 (Or else InnoDB will return different internal TIMESTAMP values when user upgrades to 4.1). Altough this fix will introduce problems with early 4.1 -> 4.1 upgrades (tables with TIMESTAMP field should be reloaded using mysqldump) it will allow easy 4.0 -> 4.1 upgrade (which is more important since 4.1 is still beta). mysql-test/r/metadata.result: TIMESTAMP should be UNSIGNED as in 4.0. mysql-test/r/ps_2myisam.result: TIMESTAMP should be UNSIGNED as in 4.0. mysql-test/r/ps_3innodb.result: TIMESTAMP should be UNSIGNED as in 4.0. mysql-test/r/ps_4heap.result: TIMESTAMP should be UNSIGNED as in 4.0. mysql-test/r/ps_5merge.result: TIMESTAMP should be UNSIGNED as in 4.0. sql/field.cc: TIMESTAMP should be UNSIGNED to preserve compatiblity with 4.0. (Or else InnoDB will return different internal TIMESTAMP values when user upgrades to 4.1). --- sql/field.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index c96a5a6d809..8fba132738c 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2877,7 +2877,8 @@ Field_timestamp::Field_timestamp(char *ptr_arg, uint32 len_arg, :Field_str(ptr_arg, 19, (uchar*) 0,0, unireg_check_arg, field_name_arg, table_arg, cs) { - flags|=ZEROFILL_FLAG; /* 4.0 MYD compatibility */ + /* For 4.0 MYD and 4.0 InnoDB compatibility */ + flags|= ZEROFILL_FLAG | UNSIGNED_FLAG; if (table && !table->timestamp_field && unireg_check != NONE) { -- cgit v1.2.1 From a58f826acf8d075c5b442853bad55afcf8468563 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 28 Jul 2004 14:52:04 -0500 Subject: Fix some variable misorderings. --- sql/mysqld.cc | 18 +++++++++--------- sql/set_var.cc | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 83eb8bb864b..4018294a61b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5056,6 +5056,8 @@ struct show_var_st status_vars[]= { {"Com_create_function", (char*) (com_stat+(uint) SQLCOM_CREATE_FUNCTION),SHOW_LONG}, {"Com_create_index", (char*) (com_stat+(uint) SQLCOM_CREATE_INDEX),SHOW_LONG}, {"Com_create_table", (char*) (com_stat+(uint) SQLCOM_CREATE_TABLE),SHOW_LONG}, + {"Com_dealloc_sql", (char*) (com_stat+(uint) + SQLCOM_DEALLOCATE_PREPARE), SHOW_LONG}, {"Com_delete", (char*) (com_stat+(uint) SQLCOM_DELETE),SHOW_LONG}, {"Com_delete_multi", (char*) (com_stat+(uint) SQLCOM_DELETE_MULTI),SHOW_LONG}, {"Com_do", (char*) (com_stat+(uint) SQLCOM_DO),SHOW_LONG}, @@ -5064,6 +5066,8 @@ struct show_var_st status_vars[]= { {"Com_drop_index", (char*) (com_stat+(uint) SQLCOM_DROP_INDEX),SHOW_LONG}, {"Com_drop_table", (char*) (com_stat+(uint) SQLCOM_DROP_TABLE),SHOW_LONG}, {"Com_drop_user", (char*) (com_stat+(uint) SQLCOM_DROP_USER),SHOW_LONG}, + {"Com_execute_sql", (char*) (com_stat+(uint) SQLCOM_EXECUTE), + SHOW_LONG}, {"Com_flush", (char*) (com_stat+(uint) SQLCOM_FLUSH),SHOW_LONG}, {"Com_grant", (char*) (com_stat+(uint) SQLCOM_GRANT),SHOW_LONG}, {"Com_ha_close", (char*) (com_stat+(uint) SQLCOM_HA_CLOSE),SHOW_LONG}, @@ -5079,6 +5083,8 @@ struct show_var_st status_vars[]= { {"Com_lock_tables", (char*) (com_stat+(uint) SQLCOM_LOCK_TABLES),SHOW_LONG}, {"Com_optimize", (char*) (com_stat+(uint) SQLCOM_OPTIMIZE),SHOW_LONG}, {"Com_preload_keys", (char*) (com_stat+(uint) SQLCOM_PRELOAD_KEYS),SHOW_LONG}, + {"Com_prepare_sql", (char*) (com_stat+(uint) SQLCOM_PREPARE), + SHOW_LONG}, {"Com_purge", (char*) (com_stat+(uint) SQLCOM_PURGE),SHOW_LONG}, {"Com_purge_before_date", (char*) (com_stat+(uint) SQLCOM_PURGE_BEFORE),SHOW_LONG}, {"Com_rename_table", (char*) (com_stat+(uint) SQLCOM_RENAME_TABLE),SHOW_LONG}, @@ -5125,12 +5131,6 @@ struct show_var_st status_vars[]= { {"Com_unlock_tables", (char*) (com_stat+(uint) SQLCOM_UNLOCK_TABLES),SHOW_LONG}, {"Com_update", (char*) (com_stat+(uint) SQLCOM_UPDATE),SHOW_LONG}, {"Com_update_multi", (char*) (com_stat+(uint) SQLCOM_UPDATE_MULTI),SHOW_LONG}, - {"Com_prepare_sql", (char*) (com_stat+(uint) SQLCOM_PREPARE), - SHOW_LONG}, - {"Com_execute_sql", (char*) (com_stat+(uint) SQLCOM_EXECUTE), - SHOW_LONG}, - {"Com_dealloc_sql", (char*) (com_stat+(uint) - SQLCOM_DEALLOCATE_PREPARE), SHOW_LONG}, {"Connections", (char*) &thread_id, SHOW_LONG_CONST}, {"Created_tmp_disk_tables", (char*) &created_tmp_disk_tables,SHOW_LONG}, {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG}, @@ -5141,6 +5141,7 @@ struct show_var_st status_vars[]= { {"Flush_commands", (char*) &refresh_version, SHOW_LONG_CONST}, {"Handler_commit", (char*) &ha_commit_count, SHOW_LONG}, {"Handler_delete", (char*) &ha_delete_count, SHOW_LONG}, + {"Handler_discover", (char*) &ha_discover_count, SHOW_LONG}, {"Handler_read_first", (char*) &ha_read_first_count, SHOW_LONG}, {"Handler_read_key", (char*) &ha_read_key_count, SHOW_LONG}, {"Handler_read_next", (char*) &ha_read_next_count, SHOW_LONG}, @@ -5150,13 +5151,12 @@ struct show_var_st status_vars[]= { {"Handler_rollback", (char*) &ha_rollback_count, SHOW_LONG}, {"Handler_update", (char*) &ha_update_count, SHOW_LONG}, {"Handler_write", (char*) &ha_write_count, SHOW_LONG}, - {"Handler_discover", (char*) &ha_discover_count, SHOW_LONG}, {"Key_blocks_not_flushed", (char*) &dflt_key_cache_var.global_blocks_changed, SHOW_KEY_CACHE_LONG}, - {"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used, - SHOW_KEY_CACHE_CONST_LONG}, {"Key_blocks_unused", (char*) &dflt_key_cache_var.blocks_unused, SHOW_KEY_CACHE_CONST_LONG}, + {"Key_blocks_used", (char*) &dflt_key_cache_var.blocks_used, + SHOW_KEY_CACHE_CONST_LONG}, {"Key_read_requests", (char*) &dflt_key_cache_var.global_cache_r_requests, SHOW_KEY_CACHE_LONG}, {"Key_reads", (char*) &dflt_key_cache_var.global_cache_read, diff --git a/sql/set_var.cc b/sql/set_var.cc index e1cfb77d297..47d9973495a 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -611,8 +611,8 @@ struct show_var_st init_vars[]= { #ifdef HAVE_BERKELEY_DB {"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG}, {"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR}, - {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR}, {"bdb_log_buffer_size", (char*) &berkeley_log_buffer_size, SHOW_LONG}, + {"bdb_logdir", (char*) &berkeley_logdir, SHOW_CHAR_PTR}, {"bdb_max_lock", (char*) &berkeley_max_lock, SHOW_LONG}, {"bdb_shared_data", (char*) &berkeley_shared_data, SHOW_BOOL}, {"bdb_tmpdir", (char*) &berkeley_tmpdir, SHOW_CHAR_PTR}, @@ -652,9 +652,9 @@ struct show_var_st init_vars[]= { {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE}, {"have_compress", (char*) &have_compress, SHOW_HAVE}, {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, + {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, {"have_innodb", (char*) &have_innodb, SHOW_HAVE}, {"have_isam", (char*) &have_isam, SHOW_HAVE}, - {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, {"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE}, {"have_openssl", (char*) &have_openssl, SHOW_HAVE}, {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE}, -- cgit v1.2.1 From 96d0e46bcb6bddac6235d7083153eaf1980b5cc2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2004 10:33:33 +0200 Subject: Fixed a copy-and-paste error: mysql_create_frm() should have its own enter string. --- sql/unireg.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/unireg.cc b/sql/unireg.cc index b5f6c3546a4..c82fcc4abef 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -75,7 +75,7 @@ bool mysql_create_frm(THD *thd, my_string file_name, uchar fileinfo[64],forminfo[288],*keybuff; TYPELIB formnames; uchar *screen_buff; - DBUG_ENTER("rea_create_table"); + DBUG_ENTER("mysql_create_frm"); formnames.type_names=0; if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0))) -- cgit v1.2.1 From 9778a2c98d7a99310dbe5c52cb924b9e1718c76d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2004 10:44:53 +0200 Subject: ha_ndbcluster.h, ha_ndbcluster.cc: compile fix for gcc-2.95 sql/ha_ndbcluster.cc: compile fix for gcc-2.95 sql/ha_ndbcluster.h: compile fix for gcc-2.95 --- sql/ha_ndbcluster.cc | 8 ++++---- sql/ha_ndbcluster.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index ec8bd035c83..2c966aab73a 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -333,11 +333,11 @@ int ha_ndbcluster::set_ndb_value(NdbOperation *ndb_op, Field *field, - TODO allocate blob part aligned buffers */ -NdbBlob::ActiveHook get_ndb_blobs_value; +NdbBlob::ActiveHook g_get_ndb_blobs_value; -int get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg) +int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg) { - DBUG_ENTER("get_ndb_blobs_value [callback]"); + DBUG_ENTER("g_get_ndb_blobs_value"); if (ndb_blob->blobsNextBlob() != NULL) DBUG_RETURN(0); ha_ndbcluster *ha= (ha_ndbcluster *)arg; @@ -428,7 +428,7 @@ int ha_ndbcluster::get_ndb_value(NdbOperation *ndb_op, Field *field, { // Set callback void *arg= (void *)this; - DBUG_RETURN(ndb_blob->setActiveHook(::get_ndb_blobs_value, arg) != 0); + DBUG_RETURN(ndb_blob->setActiveHook(g_get_ndb_blobs_value, arg) != 0); } DBUG_RETURN(1); } diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index bd8d78ec00b..31dd9a52331 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -184,7 +184,7 @@ class ha_ndbcluster: public handler uint fieldnr, const byte* field_ptr); int set_ndb_value(NdbOperation*, Field *field, uint fieldnr); int get_ndb_value(NdbOperation*, Field *field, uint fieldnr); - friend int ::get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg); + friend int g_get_ndb_blobs_value(NdbBlob *ndb_blob, void *arg); int get_ndb_blobs_value(NdbBlob *last_ndb_blob); int set_primary_key(NdbOperation *op, const byte *key); int set_primary_key(NdbOperation *op); -- cgit v1.2.1 From 66e46aeb568f5cdd7cc442f4421f97d64582a194 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2004 11:35:38 +0200 Subject: Fix for bug#3912 Auto increment not correctly initialised when table is altered, completes WL#1911 Extended AUTO_INCREMENT support in NDB --- sql/ha_ndbcluster.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index ec8bd035c83..a996b921536 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1281,6 +1281,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) int ha_ndbcluster::write_row(byte *record) { + bool has_auto_increment; uint i; NdbConnection *trans= m_active_trans; NdbOperation *op; @@ -1290,7 +1291,8 @@ int ha_ndbcluster::write_row(byte *record) statistic_increment(ha_write_count,&LOCK_status); if (table->timestamp_default_now) update_timestamp(record+table->timestamp_default_now-1); - if (table->next_number_field && record == table->record[0]) + has_auto_increment= (table->next_number_field && record == table->record[0]); + if (has_auto_increment) update_auto_increment(); if (!(op= trans->getNdbOperation(m_tabname))) @@ -1344,6 +1346,13 @@ int ha_ndbcluster::write_row(byte *record) if (trans->execute(NoCommit) != 0) DBUG_RETURN(ndb_err(trans)); } + if ( (has_auto_increment) && (!auto_increment_column_changed) ) + { + Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1; + DBUG_PRINT("info", ("Setting next auto increment value to %u", next_val)); + m_ndb->setAutoIncrementValue(m_tabname, next_val, true); + } + DBUG_RETURN(0); } -- cgit v1.2.1 From 88e3aead85b7136fab3d8cfcfa19174c4c2e2662 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 29 Jul 2004 23:25:58 +0200 Subject: WL#1580: --start-datetime, --stop-datetime, --start-position (alias for --position) and --stop-position options for mysqlbinlog, with a test file. This enables user to say "recover my database to how it was this morning at 10:30" (mysqlbinlog "--stop-datetime=2003-07-29 10:30:00"). Using time functions into client/ made me move them out of sql/ into sql-common/. + (small) fix for BUG#4507 "mysqlbinlog --read-from-remote-server sometimes cannot accept 2 binlogs" (that is, on command line). client/client_priv.h: new options for mysqlbinlog client/mysqlbinlog.cc: WL#1580: --start-datetime, --stop-datetime, --start-position (alias for --position) and --stop-position. (small) fix for BUG#4507 "mysqlbinlog --read-from-remote-server sometimes cannot accept 2 binlogs". include/my_time.h: importing time functions so that client/ files can use them. include/mysql_time.h: importing time types so that client/ files can use them. sql-common/my_time.c: importing time functions so that client/ files can use them. sql/mysql_priv.h: moving time functions out of sql/ into sql-common/ sql/time.cc: moving time functions out of sql/ into sql-common/ sql/tztime.h: moving time functions out of sql/ into sql-common/ --- sql/mysql_priv.h | 5 +- sql/time.cc | 157 ------------------------------------------------------- sql/tztime.h | 9 +--- 3 files changed, 3 insertions(+), 168 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 72ac3af70ff..f68d0951ea1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -823,7 +823,7 @@ extern Gt_creator gt_creator; extern Lt_creator lt_creator; extern Ge_creator ge_creator; extern Le_creator le_creator; -extern uchar *days_in_month; +extern uchar days_in_month[]; extern char language[LIBLEN],reg_ext[FN_EXTLEN]; extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN]; extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file; @@ -989,12 +989,9 @@ void free_blobs(TABLE *table); int set_zone(int nr,int min_zone,int max_zone); ulong convert_period_to_month(ulong period); ulong convert_month_to_period(ulong month); -long calc_daynr(uint year,uint month,uint day); uint calc_days_in_year(uint year); void get_date_from_daynr(long daynr,uint *year, uint *month, uint *day); -void init_time(void); -my_time_t my_system_gmt_sec(const TIME *, long *current_timezone, bool *not_exist); my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *not_exist); bool str_to_time_with_warn(const char *str,uint length,TIME *l_time); timestamp_type str_to_datetime_with_warn(const char *str, uint length, diff --git a/sql/time.cc b/sql/time.cc index 132612e53c5..4421b6aa00f 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -20,166 +20,9 @@ #include "mysql_priv.h" #include -static ulong const days_at_timestart=719528; /* daynr at 1970.01.01 */ -uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037"; - - -/* - Offset of system time zone from UTC in seconds used to speed up - work of my_system_gmt_sec() function. -*/ -static long my_time_zone=0; - - -/* - Prepare offset of system time zone from UTC for my_system_gmt_sec() func. - - SYNOPSIS - init_time() -*/ -void init_time(void) -{ - time_t seconds; - struct tm *l_time,tm_tmp;; - TIME my_time; - bool not_used; - - seconds= (time_t) time((time_t*) 0); - localtime_r(&seconds,&tm_tmp); - l_time= &tm_tmp; - my_time_zone= 3600; /* Comp. for -3600 in my_gmt_sec */ - my_time.year= (uint) l_time->tm_year+1900; - my_time.month= (uint) l_time->tm_mon+1; - my_time.day= (uint) l_time->tm_mday; - my_time.hour= (uint) l_time->tm_hour; - my_time.minute= (uint) l_time->tm_min; - my_time.second= (uint) l_time->tm_sec; - my_system_gmt_sec(&my_time, &my_time_zone, ¬_used); /* Init my_time_zone */ -} - - -/* - Convert time in TIME representation in system time zone to its - my_time_t form (number of seconds in UTC since begginning of Unix Epoch). - - SYNOPSIS - my_system_gmt_sec() - t - time value to be converted - my_timezone - pointer to long where offset of system time zone - from UTC will be stored for caching - in_dst_time_gap - set to true if time falls into spring time-gap - - NOTES - The idea is to cache the time zone offset from UTC (including daylight - saving time) for the next call to make things faster. But currently we - just calculate this offset during startup (by calling init_time() - function) and use it all the time. - Time value provided should be legal time value (e.g. '2003-01-01 25:00:00' - is not allowed). - - RETURN VALUE - Time in UTC seconds since Unix Epoch representation. -*/ -my_time_t -my_system_gmt_sec(const TIME *t, long *my_timezone, bool *in_dst_time_gap) -{ - uint loop; - time_t tmp; - struct tm *l_time,tm_tmp; - long diff, current_timezone; - - /* - Calculate the gmt time based on current time and timezone - The -1 on the end is to ensure that if have a date that exists twice - (like 2002-10-27 02:00:0 MET), we will find the initial date. - - By doing -3600 we will have to call localtime_r() several times, but - I couldn't come up with a better way to get a repeatable result :( - - We can't use mktime() as it's buggy on many platforms and not thread safe. - */ - tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) - - (long) days_at_timestart)*86400L + (long) t->hour*3600L + - (long) (t->minute*60 + t->second)) + (time_t) my_time_zone - - 3600); - current_timezone= my_time_zone; - - localtime_r(&tmp,&tm_tmp); - l_time=&tm_tmp; - for (loop=0; - loop < 2 && - (t->hour != (uint) l_time->tm_hour || - t->minute != (uint) l_time->tm_min); - loop++) - { /* One check should be enough ? */ - /* Get difference in days */ - int days= t->day - l_time->tm_mday; - if (days < -1) - days= 1; // Month has wrapped - else if (days > 1) - days= -1; - diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) + - (long) (60*((int) t->minute - (int) l_time->tm_min))); - current_timezone+= diff+3600; // Compensate for -3600 above - tmp+= (time_t) diff; - localtime_r(&tmp,&tm_tmp); - l_time=&tm_tmp; - } - /* - Fix that if we are in the not existing daylight saving time hour - we move the start of the next real hour - */ - if (loop == 2 && t->hour != (uint) l_time->tm_hour) - { - int days= t->day - l_time->tm_mday; - if (days < -1) - days=1; // Month has wrapped - else if (days > 1) - days= -1; - diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour))+ - (long) (60*((int) t->minute - (int) l_time->tm_min))); - if (diff == 3600) - tmp+=3600 - t->minute*60 - t->second; // Move to next hour - else if (diff == -3600) - tmp-=t->minute*60 + t->second; // Move to previous hour - - *in_dst_time_gap= 1; - } - *my_timezone= current_timezone; - - return (my_time_t) tmp; -} /* my_system_gmt_sec */ - /* Some functions to calculate dates */ - /* Calculate nr of day since year 0 in new date-system (from 1615) */ - -long calc_daynr(uint year,uint month,uint day) -{ - long delsum; - int temp; - DBUG_ENTER("calc_daynr"); - - if (year == 0 && month == 0 && day == 0) - DBUG_RETURN(0); /* Skip errors */ - if (year < 200) - { - if ((year=year+1900) < 1900+YY_PART_YEAR) - year+=100; - } - delsum= (long) (365L * year+ 31*(month-1) +day); - if (month <= 2) - year--; - else - delsum-= (long) (month*4+23)/10; - temp=(int) ((year/100+1)*3)/4; - DBUG_PRINT("exit",("year: %d month: %d day: %d -> daynr: %ld", - year+(month <= 2),month,day,delsum+year/4-temp)); - DBUG_RETURN(delsum+(int) year/4-temp); -} /* calc_daynr */ - - #ifndef TESTTIME /* Calc weekday from daynr */ /* Returns 0 for monday, 1 for tuesday .... */ diff --git a/sql/tztime.h b/sql/tztime.h index 334b14f4fc4..9df5f965f34 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -19,15 +19,10 @@ #pragma interface /* gcc class interface */ #endif -/* - Portable time_t replacement. - Should be signed and hold seconds for 1902-2038 range. -*/ -typedef long my_time_t; -#define MY_TIME_T_MAX LONG_MAX -#define MY_TIME_T_MIN LONG_MIN +#include #if !defined(TESTTIME) && !defined(TZINFO2SQL) + /* This class represents abstract time zone and provides basic interface for TIME <-> my_time_t conversion. -- cgit v1.2.1 From d475643da872a78a8b9a4f806b768803959bbb69 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 00:53:25 +0200 Subject: Avoiding a theoretically possible crash (pthread_mutex_lock(0)) which could (at least in POSIX Threads books) happen on SMP machines, when a thread is going to wait on a condition and it is KILLed at the same time. Cleaning code a bit by adding a test in enter_cond() that we have the mutex (was already the case in all places where it's called except one which is fixed here). sql/log.cc: safe_mutex_assert_owner() is now in THD::enter_cond() sql/slave.cc: lock mutex before waiting on condition. sql/sql_class.cc: THD::awake(): before locking the mutex, let's test it's not zero; in theory indeed, the killer thread may see current_cond non-zero and current_mutex zero (order of assignments is not guaranteed by POSIX). A comment noting that there is still a small chance a KILL does not work and needs being re-issued. sql/sql_class.h: Assert in enter_cond() that we have the mutex. It is already the case in all places where we call enter_cond(), so better ensure it there. --- sql/log.cc | 1 - sql/slave.cc | 1 + sql/sql_class.cc | 12 +++++++++++- sql/sql_class.h | 1 + 4 files changed, 13 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index 559d30f28ba..a0e2196cc59 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1544,7 +1544,6 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, void MYSQL_LOG:: wait_for_update(THD* thd, bool master_or_slave) { - safe_mutex_assert_owner(&LOCK_log); const char* old_msg = thd->enter_cond(&update_cond, &LOCK_log, master_or_slave ? "Has read all relay log; waiting for \ diff --git a/sql/slave.cc b/sql/slave.cc index 2269fc8d8cf..9e9e3045ad2 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -588,6 +588,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock, while (start_id == *slave_run_id) { DBUG_PRINT("sleep",("Waiting for slave thread to start")); + pthread_mutex_lock(cond_lock); const char* old_msg = thd->enter_cond(start_cond,cond_lock, "Waiting for slave thread to start"); pthread_cond_wait(start_cond,cond_lock); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 44faa3d6963..eb6e74a58c4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -299,8 +299,18 @@ void THD::awake(bool prepare_to_die) exits the cond in the time between read and broadcast, but that is ok since all we want to do is to make the victim thread get out of waiting on current_cond. + If we see a non-zero current_cond: it cannot be an old value (because + then exit_cond() should have run and it can't because we have mutex); so + it is the true value but maybe current_mutex is not yet non-zero (we're + in the middle of enter_cond() and there is a "memory order + inversion"). So we test the mutex too to not lock 0. + Note that there is a small chance we fail to kill. If victim has locked + current_mutex, and hasn't entered enter_cond(), then we don't know it's + going to wait on cond. Then victim goes into its cond "forever" (until + we issue a second KILL). True we have set its thd->killed but it may not + see it immediately and so may have time to reach the cond_wait(). */ - if (mysys_var->current_cond) + if (mysys_var->current_cond && mysys_var->current_mutex) { pthread_mutex_lock(mysys_var->current_mutex); pthread_cond_broadcast(mysys_var->current_cond); diff --git a/sql/sql_class.h b/sql/sql_class.h index 484a442af20..e045c70517e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -539,6 +539,7 @@ public: const char* msg) { const char* old_msg = proc_info; + safe_mutex_assert_owner(mutex); mysys_var->current_mutex = mutex; mysys_var->current_cond = cond; proc_info = msg; -- cgit v1.2.1 From 1adf793ddfd6a4eab32e6d28c7a7152ae5422766 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 01:00:52 +0200 Subject: Reverting a line I had just added to slave.cc (mutex is already locked when we come at this place). sql/slave.cc: stupid me; this line is a mistake --- sql/slave.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql') diff --git a/sql/slave.cc b/sql/slave.cc index 9e9e3045ad2..2269fc8d8cf 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -588,7 +588,6 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock, while (start_id == *slave_run_id) { DBUG_PRINT("sleep",("Waiting for slave thread to start")); - pthread_mutex_lock(cond_lock); const char* old_msg = thd->enter_cond(start_cond,cond_lock, "Waiting for slave thread to start"); pthread_cond_wait(start_cond,cond_lock); -- cgit v1.2.1 From e4525483524b701cf669b0adb75b392123870bf5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 09:47:56 +0200 Subject: auto_value_on_zero bug test mysql-test/r/auto_increment.result: bug test mysql-test/t/auto_increment.test: bug test sql/sql_base.cc: cleanup --- sql/sql_base.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b6d14092885..1a923b2410a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2587,7 +2587,7 @@ fill_record(List &fields,List &values, bool ignore_errors) Field *rfield= field->field; TABLE *table= rfield->table; if (rfield == table->next_number_field) - table->auto_increment_field_not_null= true; + table->auto_increment_field_not_null= TRUE; if ((value->save_in_field(rfield, 0) < 0) && !ignore_errors) DBUG_RETURN(1); } @@ -2608,7 +2608,7 @@ fill_record(Field **ptr,List &values, bool ignore_errors) value=v++; TABLE *table= field->table; if (field == table->next_number_field) - table->auto_increment_field_not_null= true; + table->auto_increment_field_not_null= TRUE; if ((value->save_in_field(field, 0) < 0) && !ignore_errors) DBUG_RETURN(1); } -- cgit v1.2.1 From d249218105081335be1c562acedcdff6e1f39a00 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 13:52:44 +0200 Subject: - added the MYSQL_EXTRA_LDFLAGS to the mysql_tzinfo_to_sql link flags to enable static linking (to avoid having a shared lib dependency in the Linux RPMs) - Disabled OpenSSL in the Max RPM sql/Makefile.am: - added the MYSQL_EXTRA_LDFLAGS to the mysql_tzinfo_to_sql link flags to enable static linking (to avoid having a shared lib dependency in the Linux Server RPMs) support-files/mysql.spec.sh: - Disable OpenSSL in the Max RPM --- sql/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index 9859f1ef841..4eaf6d5377e 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -96,7 +96,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) mysql_tzinfo_to_sql_SOURCES = mysql_tzinfo_to_sql.cc -mysql_tzinfo_to_sql_LDADD = $(LDADD) $(CXXLDFLAGS) +mysql_tzinfo_to_sql_LDADD = @MYSQLD_EXTRA_LDFLAGS@ $(LDADD) $(CXXLDFLAGS) DEFS = -DMYSQL_SERVER \ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \ -- cgit v1.2.1 From 864405db7d9bd1c627ca787324e9db81ea9e19bf Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 14:17:12 +0200 Subject: no_auto_value_on_zero + alter table bug --- sql/sql_table.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8d82ca44951..7afbe6d0b87 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3271,13 +3271,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, ha_rows *deleted) { int error; - Copy_field *copy,*copy_end; + Copy_field *copy,*copy_end, *next_field; ulong found_count,delete_count; THD *thd= current_thd; uint length; SORT_FIELD *sortorder; READ_RECORD info; - Field *next_field; TABLE_LIST tables; List fields; List all_fields; @@ -3298,7 +3297,12 @@ copy_data_between_tables(TABLE *from,TABLE *to, { def=it++; if (def->field) + { + if (*ptr == to->next_number_field) + next_field= copy_end; (copy_end++)->set(*ptr,def->field,0); + } + } found_count=delete_count=0; @@ -3334,7 +3338,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, error= 1; goto err; } - + /* Handler must be told explicitly to retrieve all columns, because this function does not set field->query_id in the columns to the current query id */ @@ -3343,7 +3347,6 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (handle_duplicates == DUP_IGNORE || handle_duplicates == DUP_REPLACE) to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); - next_field=to->next_number_field; thd->row_count= 0; while (!(error=info.read_record(&info))) { @@ -3354,10 +3357,14 @@ copy_data_between_tables(TABLE *from,TABLE *to, break; } thd->row_count++; - if (next_field) - next_field->reset(); + if (to->next_number_field) + to->next_number_field->reset(); for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++) + { + if (copy_ptr == next_field) + to->auto_increment_field_not_null= TRUE; copy_ptr->do_copy(copy_ptr); + } if ((error=to->file->write_row((byte*) to->record[0]))) { if ((handle_duplicates != DUP_IGNORE && -- cgit v1.2.1 From 979126224b4a04a548e7663c72e4212de6121f20 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 16:08:19 +0300 Subject: ha_innodb.cc: ha_innobase::create(): pass the query string as UTF-8 to row_table_add_foreign_constraints() (Bug #4649) sql/ha_innodb.cc: ha_innobase::create(): pass the query string as UTF-8 to row_table_add_foreign_constraints() (Bug #4649) --- sql/ha_innodb.cc | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index c06448647d5..a8309d4f32c 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -3642,11 +3642,19 @@ ha_innobase::create( } if (current_thd->query != NULL) { - - error = row_table_add_foreign_constraints(trx, - current_thd->query, norm_name); - error = convert_error_code_to_mysql(error, NULL); + LEX_STRING q; + if (thd->convert_string(&q, system_charset_info, + current_thd->query, + current_thd->query_length, + current_thd->charset())) { + error = HA_ERR_OUT_OF_MEM; + } else { + error = row_table_add_foreign_constraints(trx, + q.str, norm_name); + + error = convert_error_code_to_mysql(error, NULL); + } if (error) { innobase_commit_low(trx); -- cgit v1.2.1 From 95da1ff0fcc75b5cacdfebb529611ebf62aeb08f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 30 Jul 2004 22:05:08 +0200 Subject: apply in SET PASSWORD same checks as in GRANT, to let only valid hashes through --- sql/set_var.cc | 9 +++++---- sql/sql_acl.cc | 20 +++++++++++++++----- sql/sql_acl.h | 3 ++- 3 files changed, 22 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/set_var.cc b/sql/set_var.cc index e70fdaedb29..bcebb62ae4d 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2851,8 +2851,9 @@ int set_var_password::check(THD *thd) if (!user->host.str) user->host.str= (char*) thd->host_or_ip; /* Returns 1 as the function sends error to client */ - return check_change_password(thd, user->host.str, user->user.str) ? 1 : 0; -#else + return check_change_password(thd, user->host.str, user->user.str, password) ? + 1 : 0; +#else return 0; #endif } @@ -2861,8 +2862,8 @@ int set_var_password::update(THD *thd) { #ifndef NO_EMBEDDED_ACCESS_CHECKS /* Returns 1 as the function sends error to client */ - return (change_password(thd, user->host.str, user->user.str, password) ? - 1 : 0); + return change_password(thd, user->host.str, user->user.str, password) ? + 1 : 0; #else return 0; #endif diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fddd5b70a2f..f316bca4876 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1127,13 +1127,14 @@ bool acl_check_host(const char *host, const char *ip) 1 ERROR ; In this case the error is sent to the client. */ -bool check_change_password(THD *thd, const char *host, const char *user) +bool check_change_password(THD *thd, const char *host, const char *user, + char *new_password) { if (!initialized) { net_printf(thd,ER_OPTION_PREVENTS_STATEMENT, - "--skip-grant-tables"); /* purecov: inspected */ - return(1); /* purecov: inspected */ + "--skip-grant-tables"); + return(1); } if (!thd->slave_thread && (strcmp(thd->user,user) || @@ -1147,6 +1148,15 @@ bool check_change_password(THD *thd, const char *host, const char *user) send_error(thd, ER_PASSWORD_ANONYMOUS_USER); return(1); } + uint len=strlen(new_password); + if (len != SCRAMBLED_PASSWORD_CHAR_LENGTH && + len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) + { + net_printf(thd, 0, + "Password hash should be a %d-digit hexadecimal number", + SCRAMBLED_PASSWORD_CHAR_LENGTH); + return -1; + } return(0); } @@ -1174,7 +1184,7 @@ bool change_password(THD *thd, const char *host, const char *user, host,user,new_password)); DBUG_ASSERT(host != 0); // Ensured by parent - if (check_change_password(thd, host, user)) + if (check_change_password(thd, host, user, new_password)) DBUG_RETURN(1); VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -1433,7 +1443,7 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, if (combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH && combo.password.length != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { - my_printf_error(ER_PASSWORD_NO_MATCH, + my_printf_error(ER_UNKNOWN_ERROR, "Password hash should be a %d-digit hexadecimal number", MYF(0), SCRAMBLED_PASSWORD_CHAR_LENGTH); DBUG_RETURN(-1); diff --git a/sql/sql_acl.h b/sql/sql_acl.h index a237b45e29c..68cb1476eb5 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -142,7 +142,8 @@ ulong acl_get(const char *host, const char *ip, int acl_getroot(THD *thd, USER_RESOURCES *mqh, const char *passwd, uint passwd_len); bool acl_check_host(const char *host, const char *ip); -bool check_change_password(THD *thd, const char *host, const char *user); +bool check_change_password(THD *thd, const char *host, const char *user, + char *password); bool change_password(THD *thd, const char *host, const char *user, char *password); int mysql_grant(THD *thd, const char *db, List &user_list, -- cgit v1.2.1 From 6ce5da27a7b714e6f2a4d2968488a0bd84803ce2 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Jul 2004 09:49:32 +0200 Subject: removing assertion (will be moved to 4.1) for non-debug to compile sql/sql_class.h: removing the assertion as I don't want to include assert.h (inclusion of assert.h has already been reworked in 4.1, so I'll move the assertion to 4.1). Assertion makes compilation fail if non-debug. --- sql/sql_class.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index e045c70517e..df246b42337 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -535,11 +535,19 @@ public: void close_active_vio(); #endif void awake(bool prepare_to_die); + /* + For enter_cond() / exit_cond() to work the mutex must be got before + enter_cond() but released before exit_cond() (in 4.1, assertions will soon + ensure this). Use must be: + lock mutex; enter_cond(); ...; unlock mutex; exit_cond(). + If you don't do it this way, you will get a deadlock if another thread is + doing a THD::awake() on you. + + */ inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg) { const char* old_msg = proc_info; - safe_mutex_assert_owner(mutex); mysys_var->current_mutex = mutex; mysys_var->current_cond = cond; proc_info = msg; -- cgit v1.2.1 From 00e7ec42795c08da55a22cc76d1e988c2a114098 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Jul 2004 22:33:20 +0200 Subject: Fix for: Bug #4810 "deadlock with KILL when the victim was in a wait state" (I included mutex unlock into exit_cond() for future safety) and BUG#4827 "KILL while START SLAVE may lead to replication slave crash" sql/lock.cc: we did exit_cond() before unlock(LOCK_open), which led to deadlocks with THD::awake(). Fixing this. sql/log.cc: mutex unlock is now included in exit_cond() sql/repl_failsafe.cc: we did exit_cond() before unlock(LOCK_rpl_status), which led to deadlocks with THD::awake(). Fixing this. sql/slave.cc: we did exit_cond() before unlock(cond_lock), which led to deadlocks with THD::awake(). Fixing this. Fixing also that if killed while waiting for slave thread to start, we don't release the mutex (that caused a double release of the mutex => crash). sql/sql_class.h: comments about exit_cond()/enter_cond(). Mutex unlock is now included in exit_cond() so that it's always done in the good order. sql/sql_table.cc: unlock is now included in exit_cond(). --- sql/lock.cc | 16 +++++++++------- sql/log.cc | 9 ++------- sql/repl_failsafe.cc | 9 +++++---- sql/slave.cc | 18 +++++++----------- sql/sql_class.h | 16 ++++++++++------ sql/sql_table.cc | 1 - 6 files changed, 33 insertions(+), 36 deletions(-) (limited to 'sql') diff --git a/sql/lock.cc b/sql/lock.cc index 5010d115a6c..9ea1ce96175 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -692,15 +692,14 @@ bool lock_global_read_lock(THD *thd) while (protect_against_global_read_lock && !thd->killed) pthread_cond_wait(&COND_refresh, &LOCK_open); waiting_for_read_lock--; - thd->exit_cond(old_message); if (thd->killed) { - (void) pthread_mutex_unlock(&LOCK_open); + thd->exit_cond(old_message); DBUG_RETURN(1); } thd->global_read_lock=1; global_read_lock++; - (void) pthread_mutex_unlock(&LOCK_open); + thd->exit_cond(old_message); } DBUG_RETURN(0); } @@ -721,11 +720,12 @@ void unlock_global_read_lock(THD *thd) bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) { const char *old_message; - bool result=0; + bool result= 0, need_exit_cond; DBUG_ENTER("wait_if_global_read_lock"); + LINT_INIT(old_message); (void) pthread_mutex_lock(&LOCK_open); - if (global_read_lock) + if (need_exit_cond= (bool)global_read_lock) { if (thd->global_read_lock) // This thread had the read locks { @@ -740,11 +740,13 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) (void) pthread_cond_wait(&COND_refresh,&LOCK_open); if (thd->killed) result=1; - thd->exit_cond(old_message); } if (!abort_on_refresh && !result) protect_against_global_read_lock++; - pthread_mutex_unlock(&LOCK_open); + if (unlikely(need_exit_cond)) // global read locks are rare + thd->exit_cond(old_message); + else + pthread_mutex_unlock(&LOCK_open); DBUG_RETURN(result); } diff --git a/sql/log.cc b/sql/log.cc index a0e2196cc59..e031656cc6e 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1533,12 +1533,8 @@ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length, NOTES One must have a lock on LOCK_log before calling this function. - This lock will be freed before return! - - The reason for the above is that for enter_cond() / exit_cond() to - work the mutex must be got before enter_cond() but releases before - exit_cond(). - If you don't do it this way, you will get a deadlock in THD::awake() + This lock will be freed before return! That's required by + THD::enter_cond() (see NOTES in sql_class.h). */ @@ -1551,7 +1547,6 @@ the I/O slave thread to update it" : "Has sent all binlog to slave; \ waiting for binlog to be updated"); pthread_cond_wait(&update_cond, &LOCK_log); - pthread_mutex_unlock(&LOCK_log); // See NOTES thd->exit_cond(old_msg); } diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc index 1edf452d5f6..604938a8ed0 100644 --- a/sql/repl_failsafe.cc +++ b/sql/repl_failsafe.cc @@ -584,6 +584,8 @@ pthread_handler_decl(handle_failsafe_rpl,arg) THD *thd = new THD; thd->thread_stack = (char*)&thd; MYSQL* recovery_captain = 0; + const char* msg; + pthread_detach_this_thread(); if (init_failsafe_rpl_thread(thd) || !(recovery_captain=mc_mysql_init(0))) { @@ -591,11 +593,11 @@ pthread_handler_decl(handle_failsafe_rpl,arg) goto err; } pthread_mutex_lock(&LOCK_rpl_status); + msg= thd->enter_cond(&COND_rpl_status, + &LOCK_rpl_status, "Waiting for request"); while (!thd->killed && !abort_loop) { bool break_req_chain = 0; - const char* msg = thd->enter_cond(&COND_rpl_status, - &LOCK_rpl_status, "Waiting for request"); pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status); thd->proc_info="Processing request"; while (!break_req_chain) @@ -613,9 +615,8 @@ pthread_handler_decl(handle_failsafe_rpl,arg) break; } } - thd->exit_cond(msg); } - pthread_mutex_unlock(&LOCK_rpl_status); + thd->exit_cond(msg); err: if (recovery_captain) mc_mysql_close(recovery_captain); diff --git a/sql/slave.cc b/sql/slave.cc index 2269fc8d8cf..4416a2544ef 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -582,7 +582,7 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock, pthread_mutex_unlock(start_lock); DBUG_RETURN(ER_SLAVE_THREAD); } - if (start_cond && cond_lock) + if (start_cond && cond_lock) // caller has cond_lock { THD* thd = current_thd; while (start_id == *slave_run_id) @@ -592,11 +592,9 @@ int start_slave_thread(pthread_handler h_func, pthread_mutex_t *start_lock, "Waiting for slave thread to start"); pthread_cond_wait(start_cond,cond_lock); thd->exit_cond(old_msg); + pthread_mutex_lock(cond_lock); // re-acquire it as exit_cond() released if (thd->killed) - { - pthread_mutex_unlock(cond_lock); DBUG_RETURN(ER_SERVER_SHUTDOWN); - } } } if (start_lock) @@ -1561,7 +1559,6 @@ thread to free enough relay log space"); !rli->ignore_log_space_limit) pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock); thd->exit_cond(save_proc_info); - pthread_mutex_unlock(&rli->log_space_lock); DBUG_RETURN(slave_killed); } @@ -1965,6 +1962,9 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, (long) timeout)); pthread_mutex_lock(&data_lock); + const char *msg= thd->enter_cond(&data_cond, &data_lock, + "Waiting for the SQL slave thread to " + "advance position"); /* This function will abort when it notices that some CHANGE MASTER or RESET MASTER has changed the master info. @@ -2063,9 +2063,6 @@ int st_relay_log_info::wait_for_pos(THD* thd, String* log_name, //wait for master update, with optional timeout. DBUG_PRINT("info",("Waiting for master update")); - const char* msg = thd->enter_cond(&data_cond, &data_lock, - "Waiting for the SQL slave thread to \ -advance position"); /* We are going to pthread_cond_(timed)wait(); if the SQL thread stops it will wake us up. @@ -2087,8 +2084,7 @@ advance position"); } else pthread_cond_wait(&data_cond, &data_lock); - DBUG_PRINT("info",("Got signal of master update")); - thd->exit_cond(msg); + DBUG_PRINT("info",("Got signal of master update or timed out")); if (error == ETIMEDOUT || error == ETIME) { error= -1; @@ -2100,7 +2096,7 @@ advance position"); } err: - pthread_mutex_unlock(&data_lock); + thd->exit_cond(msg); DBUG_PRINT("exit",("killed: %d abort: %d slave_running: %d \ improper_arguments: %d timed_out: %d", (int) thd->killed, diff --git a/sql/sql_class.h b/sql/sql_class.h index df246b42337..e646d33fe5d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -537,12 +537,9 @@ public: void awake(bool prepare_to_die); /* For enter_cond() / exit_cond() to work the mutex must be got before - enter_cond() but released before exit_cond() (in 4.1, assertions will soon - ensure this). Use must be: - lock mutex; enter_cond(); ...; unlock mutex; exit_cond(). - If you don't do it this way, you will get a deadlock if another thread is - doing a THD::awake() on you. - + enter_cond() (in 4.1 an assertion will soon ensure this); this mutex is + then released by exit_cond(). Use must be: + lock mutex; enter_cond(); your code; exit_cond(). */ inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, const char* msg) @@ -555,6 +552,13 @@ public: } inline void exit_cond(const char* old_msg) { + /* + Putting the mutex unlock in exit_cond() ensures that + mysys_var->current_mutex is always unlocked _before_ mysys_var->mutex is + locked (if that would not be the case, you'll get a deadlock if someone + does a THD::awake() on you). + */ + pthread_mutex_unlock(mysys_var->current_mutex); pthread_mutex_lock(&mysys_var->mutex); mysys_var->current_mutex = 0; mysys_var->current_cond = 0; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9ab4859bc13..7f4a8583b78 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1301,7 +1301,6 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables, dropping_tables--; } thd->exit_cond(old_message); - pthread_mutex_unlock(&LOCK_open); if (thd->killed) goto err; open_for_modify=0; -- cgit v1.2.1 From 9ca47d047e5164515eac6fcae05ae9450cb94213 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 31 Jul 2004 22:39:10 +0200 Subject: BUG#4393, BUG#4356 - incorrect decimals in fix_length_and_dec() in some functions mysql-test/mysql-test-run.sh: report failed test name mysql-test/r/func_math.result: test results fixed --- sql/item_func.cc | 4 ++-- sql/item_func.h | 2 +- sql/item_sum.h | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index 368c14cc8df..237db890abb 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -684,7 +684,7 @@ void Item_func_round::fix_length_and_dec() if (tmp < 0) decimals=0; else - decimals=tmp; + decimals=min(tmp,NOT_FIXED_DEC); } } @@ -1286,7 +1286,7 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func, func->max_length=min(initid.max_length,MAX_BLOB_WIDTH); func->maybe_null=initid.maybe_null; const_item_cache=initid.const_item; - func->decimals=min(initid.decimals,31); + func->decimals=min(initid.decimals,NOT_FIXED_DEC); } initialized=1; if (error) diff --git a/sql/item_func.h b/sql/item_func.h index 4d171cda490..8a013f42c05 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -295,7 +295,7 @@ class Item_dec_func :public Item_real_func Item_dec_func(Item *a,Item *b) :Item_real_func(a,b) {} void fix_length_and_dec() { - decimals=6; max_length=float_length(decimals); + decimals=NOT_FIXED_DEC; max_length=float_length(decimals); maybe_null=1; } inline double fix_result(double value) diff --git a/sql/item_sum.h b/sql/item_sum.h index 6835b1e8fae..802e3f1ba45 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -234,7 +234,11 @@ public: class Item_sum_avg :public Item_sum_num { - void fix_length_and_dec() { decimals+=4; maybe_null=1; } + void fix_length_and_dec() + { + decimals=min(decimals+4, NOT_FIXED_DEC); + maybe_null=1; + } double sum; ulonglong count; @@ -276,7 +280,11 @@ class Item_sum_std :public Item_sum_num double sum; double sum_sqr; ulonglong count; - void fix_length_and_dec() { decimals+=4; maybe_null=1; } + void fix_length_and_dec() + { + decimals=min(decimals+4, NOT_FIXED_DEC); + maybe_null=1; + } public: Item_sum_std(Item *item_par) :Item_sum_num(item_par),count(0) {} -- cgit v1.2.1 From 3c1327021a837257b3b75a75ae2bc92acae6d719 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 1 Aug 2004 17:21:55 +0200 Subject: followup to SET PASSWORD fix --- sql/sql_acl.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f316bca4876..44fd5e9e94f 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1149,7 +1149,7 @@ bool check_change_password(THD *thd, const char *host, const char *user, return(1); } uint len=strlen(new_password); - if (len != SCRAMBLED_PASSWORD_CHAR_LENGTH && + if (len && len != SCRAMBLED_PASSWORD_CHAR_LENGTH && len != SCRAMBLED_PASSWORD_CHAR_LENGTH_323) { net_printf(thd, 0, -- cgit v1.2.1 From ea8ac8ab9845e039e5770821c5dbfc4604390299 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Aug 2004 11:12:11 +0200 Subject: hang in dummy natural join (no common columns) Bug #4807 --- sql/sql_base.cc | 47 +++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 22 deletions(-) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 1a923b2410a..dd8283e057a 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2522,29 +2522,32 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) // to prevent natural join processing during PS re-execution table->natural_join= 0; - if (!table->outer_join) // Not left join + if (cond_and->list.elements) { - *conds= and_conds(*conds, cond_and); - // fix_fields() should be made with temporary memory pool - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); - if (*conds && !(*conds)->fixed) - { - if ((*conds)->fix_fields(thd, tables, conds)) - DBUG_RETURN(1); - } - } - else - { - table->on_expr= and_conds(table->on_expr, cond_and); - // fix_fields() should be made with temporary memory pool - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); - if (table->on_expr && !table->on_expr->fixed) - { - if (table->on_expr->fix_fields(thd, tables, &table->on_expr)) - DBUG_RETURN(1); - } + if (!table->outer_join) // Not left join + { + *conds= and_conds(*conds, cond_and); + // fix_fields() should be made with temporary memory pool + if (stmt) + thd->restore_backup_item_arena(stmt, &backup); + if (*conds && !(*conds)->fixed) + { + if ((*conds)->fix_fields(thd, tables, conds)) + DBUG_RETURN(1); + } + } + else + { + table->on_expr= and_conds(table->on_expr, cond_and); + // fix_fields() should be made with temporary memory pool + if (stmt) + thd->restore_backup_item_arena(stmt, &backup); + if (table->on_expr && !table->on_expr->fixed) + { + if (table->on_expr->fix_fields(thd, tables, &table->on_expr)) + DBUG_RETURN(1); + } + } } } } -- cgit v1.2.1 From 4e2137fabfdb4aba3e3647c43548afbf8a529719 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Aug 2004 13:54:55 +0200 Subject: Fix duplicate declaration in NDB cluster handler sql/ha_ndbcluster.cc: Fix duplicate declaration --- sql/ha_ndbcluster.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 5b36d6d2b55..8f23a0f3919 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -403,7 +403,7 @@ int ha_ndbcluster::build_index_list() DBUG_ENTER("build_index_list"); // Save information about all known indexes - for (uint i= 0; i < table->keys; i++) + for (i= 0; i < table->keys; i++) { NDB_INDEX_TYPE idx_type= get_index_type_from_table(i); m_indextype[i]= idx_type; -- cgit v1.2.1 From 92498f81dbc94cd9327b431f4456e17fc8dddb8f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Aug 2004 10:54:42 +0200 Subject: BUG#4818 DELETE FROM tab LIMIT Check if there are any operations pending that needs to be taken over to the updating/deleting transaction before closing the scan sql/ha_ndbcluster.cc: Check ops_pending if there are operations to take over before closing the scan --- sql/ha_ndbcluster.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 2c966aab73a..f9dca1b36bb 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1937,11 +1937,25 @@ int ha_ndbcluster::rnd_init(bool scan) int ha_ndbcluster::close_scan() { NdbResultSet *cursor= m_active_cursor; + NdbConnection *trans= m_active_trans; DBUG_ENTER("close_scan"); if (!cursor) DBUG_RETURN(1); + + if (ops_pending) + { + /* + Take over any pending transactions to the + deleteing/updating transaction before closing the scan + */ + DBUG_PRINT("info", ("ops_pending: %d", ops_pending)); + if (trans->execute(NoCommit) != 0) + DBUG_RETURN(ndb_err(trans)); + ops_pending= 0; + } + cursor->close(); m_active_cursor= NULL; DBUG_RETURN(0); -- cgit v1.2.1 From 94a1e48232184a25837e49fc01120228e5ff7860 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Aug 2004 11:28:36 +0200 Subject: BUG#4892 TRUNCATE TABLE returns error 156 Added NDBCLUSTER to table types which does not support generate. Added test case for truncate. sql/handler.h: Add NDBCLUSTER to table types that does not support generate. --- sql/handler.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/handler.h b/sql/handler.h index 28b0b8df6e2..3dd89a0c5d0 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -516,7 +516,8 @@ extern TYPELIB tx_isolation_typelib; #define ha_rollback(thd) (ha_rollback_trans((thd), &((thd)->transaction.all))) #define ha_supports_generate(T) (T != DB_TYPE_INNODB && \ - T != DB_TYPE_BERKELEY_DB) + T != DB_TYPE_BERKELEY_DB && \ + T != DB_TYPE_NDBCLUSTER) bool ha_caching_allowed(THD* thd, char* table_key, uint key_length, uint8 cache_type); -- cgit v1.2.1 From 03daa16a9501626dcddb2ea3fb7c310153c2d3f5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Aug 2004 10:12:57 -0600 Subject: Print MYSQL_COMPILATION_COMMENT after ER_READY on server startup sql/share/czech/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/danish/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/dutch/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/english/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/estonian/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/french/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/german/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/greek/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/hungarian/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/japanese/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/korean/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/norwegian-ny/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/norwegian/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/polish/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/portuguese/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/romanian/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/russian/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/slovak/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/spanish/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/swedish/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) sql/share/ukrainian/errmsg.txt: Remove trailing \n from ER_READY (it is now printed in mysqld.cc) --- sql/mysqld.cc | 3 +++ sql/share/czech/errmsg.txt | 2 +- sql/share/danish/errmsg.txt | 2 +- sql/share/dutch/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 2 +- sql/share/estonian/errmsg.txt | 2 +- sql/share/french/errmsg.txt | 2 +- sql/share/german/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/errmsg.txt | 2 +- sql/share/japanese/errmsg.txt | 2 +- sql/share/korean/errmsg.txt | 2 +- sql/share/norwegian-ny/errmsg.txt | 2 +- sql/share/norwegian/errmsg.txt | 2 +- sql/share/polish/errmsg.txt | 2 +- sql/share/portuguese/errmsg.txt | 2 +- sql/share/romanian/errmsg.txt | 2 +- sql/share/russian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- sql/share/spanish/errmsg.txt | 2 +- sql/share/swedish/errmsg.txt | 2 +- sql/share/ukrainian/errmsg.txt | 2 +- 22 files changed, 24 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 80e9292a873..55f58e9970e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2614,6 +2614,9 @@ server."); printf(ER(ER_READY),my_progname,server_version, ((unix_sock == INVALID_SOCKET) ? (char*) "" : mysql_unix_port), mysql_port); + if (MYSQL_COMPILATION_COMMENT[0] != '\0') + fputs(" " MYSQL_COMPILATION_COMMENT, stdout); + putchar('\n'); fflush(stdout); #ifdef __NT__ diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index e36475d7803..b6737df91e1 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -86,7 +86,7 @@ "Blob sloupec '%-.64s' nem-Bù¾e být pou¾it jako klíè", "P-Bøíli¹ velká délka sloupce '%-.64s' (nejvíce %d). Pou¾ijte BLOB", "M-Bù¾ete mít pouze jedno AUTO pole a to musí být definováno jako klíè", -"%s: p-Bøipraven na spojení\n", +"%s: p-Bøipraven na spojení", "%s: norm-Bální ukonèení\n", "%s: p-Bøijat signal %d, konèím\n", "%s: ukon-Bèení práce hotovo\n", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 4e612c599ec..ba50c78e92c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -80,7 +80,7 @@ "BLOB feltet '%-.64s' kan ikke bruges ved specifikation af indeks", "For stor feltlængde for kolonne '%-.64s' (maks = %d). Brug BLOB i stedet", "Der kan kun specificeres eet AUTO_INCREMENT-felt, og det skal være indekseret", -"%s: klar til tilslutninger\n", +"%s: klar til tilslutninger", "%s: Normal nedlukning\n", "%s: Fangede signal %d. Afslutter!!\n", "%s: Server lukket\n", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 4aafa51e856..1b9c1025e69 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -88,7 +88,7 @@ "BLOB kolom '%-.64s' kan niet gebruikt worden bij zoeksleutel specificatie", "Te grote kolomlengte voor '%-.64s' (max = %d). Maak hiervoor gebruik van het type BLOB", "Er kan slechts 1 autofield zijn en deze moet als zoeksleutel worden gedefinieerd.", -"%s: klaar voor verbindingen\n", +"%s: klaar voor verbindingen", "%s: Normaal afgesloten \n", "%s: Signaal %d. Systeem breekt af!\n", "%s: Afsluiten afgerond\n", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index dca9311b277..edbf2357ff8 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -77,7 +77,7 @@ "BLOB column '%-.64s' can't be used in key specification with the used table type", "Too big column length for column '%-.64s' (max = %d). Use BLOB instead", "Incorrect table definition; There can only be one auto column and it must be defined as a key", -"%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d\n", +"%s: ready for connections.\nVersion: '%s' socket: '%s' port: %d", "%s: Normal shutdown\n", "%s: Got signal %d. Aborting!\n", "%s: Shutdown Complete\n", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index f583568193f..8ec5d4b29f0 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -82,7 +82,7 @@ "BLOB-tüüpi tulpa '%-.64s' ei saa kasutada võtmena", "Tulba '%-.64s' pikkus on liiga pikk (maksimaalne pikkus: %d). Kasuta BLOB väljatüüpi", "Vigane tabelikirjeldus; Tabelis tohib olla üks auto_increment tüüpi tulp ning see peab olema defineeritud võtmena", -"%s: ootab ühendusi\n", +"%s: ootab ühendusi", "%s: MySQL lõpetas\n", "%s: sain signaali %d. Lõpetan!\n", "%s: Lõpp\n", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index cabb22a6494..3c5c827aa62 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -77,7 +77,7 @@ "Champ BLOB '%-.64s' ne peut être utilisé dans une clé", "Champ '%-.64s' trop long (max = %d). Utilisez un BLOB", "Un seul champ automatique est permis et il doit être indexé", -"%s: Prêt pour des connections\n", +"%s: Prêt pour des connections", "%s: Arrêt normal du serveur\n", "%s: Reçu le signal %d. Abandonne!\n", "%s: Arrêt du serveur terminé\n", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 518cb507466..3960dcc2122 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -80,7 +80,7 @@ "BLOB-Feld '%-.64s' kann nicht als Schlüssel verwendet werden.", "Feldlänge für Feld '%-.64s' zu groß (max = %d). BLOB-Feld verwenden!", "Nur ein Auto-Feld möglich, welches als Schlüssel definiert werden muß.", -"%-.64s: Warten auf Verbindungen.\n", +"%-.64s: Warten auf Verbindungen", "%-.64s: Normal beendet.\n", "%-.64s: Signal %d erhalten. Abbruch!\n", "%-.64s: Shutdown ausgeführt.\n", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index d993d80dcc1..3e9a68f2b4b 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -77,7 +77,7 @@ "Ðåäßï ôýðïõ Blob '%-.64s' äåí ìðïñåß íá ÷ñçóéìïðïéçèåß óôïí ïñéóìü åíüò êëåéäéïý (key specification)", "Ðïëý ìåãÜëï ìÞêïò ãéá ôï ðåäßï '%-.64s' (max = %d). Ðáñáêáëþ ÷ñçóéìïðïéåßóôå ôïí ôýðï BLOB", "Ìðïñåß íá õðÜñ÷åé ìüíï Ýíá auto field êáé ðñÝðåé íá Ý÷åé ïñéóèåß óáí key", -"%s: óå áíáìïíÞ óõíäÝóåùí\n", +"%s: óå áíáìïíÞ óõíäÝóåùí", "%s: ÖõóéïëïãéêÞ äéáäéêáóßá shutdown\n", "%s: ÅëÞöèç ôï ìÞíõìá %d. Ç äéáäéêáóßá åãêáôáëåßðåôáé!\n", "%s: Ç äéáäéêáóßá Shutdown ïëïêëçñþèçêå\n", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 4a65e735ef9..9da878981b0 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -79,7 +79,7 @@ "Blob objektum '%-.64s' nem hasznalhato kulcskent", "A(z) '%-.64s' oszlop tul hosszu. (maximum = %d). Hasznaljon BLOB tipust inkabb.", "Csak egy auto mezo lehetseges, es azt kulcskent kell definialni.", -"%s: kapcsolatra kesz\n", +"%s: kapcsolatra kesz", "%s: Normal leallitas\n", "%s: %d jelzes. Megszakitva!\n", "%s: A leallitas kesz\n", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index c384c4bded4..7e267261a2e 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -79,7 +79,7 @@ "BLOB column '%-.64s' can't be used in key specification with the used table type", "column '%-.64s' ¤Ï,³ÎÊݤ¹¤ë column ¤ÎÂ礭¤µ¤¬Â¿¤¹¤®¤Þ¤¹. (ºÇÂç %d ¤Þ¤Ç). BLOB ¤ò¤«¤ï¤ê¤Ë»ÈÍѤ·¤Æ¤¯¤À¤µ¤¤.", "¥Æ¡¼¥Ö¥ë¤ÎÄêµÁ¤¬°ã¤¤¤Þ¤¹; There can only be one auto column and it must be defined as a key", -"%s: ½àÈ÷´°Î»\n", +"%s: ½àÈ÷´°Î»", "%s: Normal shutdown\n", "%s: Got signal %d. ÃæÃÇ!\n", "%s: Shutdown ´°Î»\n", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index b706069b495..1ad5432f4db 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -77,7 +77,7 @@ "BLOB Ä®·³ '%-.64s'´Â Å° Á¤ÀÇ¿¡¼­ »ç¿ëµÉ ¼ö ¾ø½À´Ï´Ù.", "Ä®·³ '%-.64s'ÀÇ Ä®·³ ±æÀÌ°¡ ³Ê¹« ±é´Ï´Ù (ÃÖ´ë = %d). ´ë½Å¿¡ BLOB¸¦ »ç¿ëÇϼ¼¿ä.", "ºÎÁ¤È®ÇÑ Å×À̺í Á¤ÀÇ; Å×À̺íÀº ÇϳªÀÇ auto Ä®·³ÀÌ Á¸ÀçÇÏ°í Å°·Î Á¤ÀǵǾîÁ®¾ß ÇÕ´Ï´Ù.", -"%s: ¿¬°á ÁغñÁßÀÔ´Ï´Ù.\n", +"%s: ¿¬°á ÁغñÁßÀÔ´Ï´Ù", "%s: Á¤»óÀûÀÎ shutdown\n", "%s: %d ½ÅÈ£°¡ µé¾î¿ÔÀ½. ÁßÁö!\n", "%s: Shutdown ÀÌ ¿Ï·áµÊ!\n", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 2c1deead312..234a53b53fb 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -79,7 +79,7 @@ "Blob kolonne '%-.64s' kan ikkje brukast ved spesifikasjon av nyklar", "For stor nykkellengde for felt '%-.64s' (maks = %d). Bruk BLOB istadenfor", "Bare eitt auto felt kan være definert som nøkkel.", -"%s: klar for tilkoblingar\n", +"%s: klar for tilkoblingar", "%s: Normal nedkopling\n", "%s: Oppdaga signal %d. Avsluttar!\n", "%s: Nedkopling komplett\n", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 42b35c18cfc..e582786dc6e 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -79,7 +79,7 @@ "Blob felt '%-.64s' kan ikke brukes ved spesifikasjon av nøkler", "For stor nøkkellengde for kolonne '%-.64s' (maks = %d). Bruk BLOB istedenfor", "Bare ett auto felt kan være definert som nøkkel.", -"%s: klar for tilkoblinger\n", +"%s: klar for tilkoblinger", "%s: Normal avslutning\n", "%s: Oppdaget signal %d. Avslutter!\n", "%s: Avslutning komplett\n", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index d8e84b08a9a..a4d11046ea4 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -81,7 +81,7 @@ "Kolumna typu Blob '%-.64s' nie mo¿e byæ u¿yta w specyfikacji klucza", "Zbyt du¿a d³ugo?æ kolumny '%-.64s' (maks. = %d). W zamian u¿yj typu BLOB", "W tabeli mo¿e byæ tylko jedno pole auto i musi ono byæ zdefiniowane jako klucz", -"%s: gotowe do po³?czenia\n", +"%s: gotowe do po³?czenia", "%s: Standardowe zakoñczenie dzia³ania\n", "%s: Otrzymano sygna³ %d. Koñczenie dzia³ania!\n", "%s: Zakoñczenie dzia³ania wykonane\n", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index a1b5e87a52d..14c14270dc0 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -77,7 +77,7 @@ "Coluna BLOB '%-.64s' não pode ser utilizada na especificação de chave para o tipo de tabela usado", "Comprimento da coluna '%-.64s' grande demais (max = %d). Use BLOB em seu lugar", "Definição incorreta de tabela. Somente é permitido um único campo auto-incrementado e ele tem que ser definido como chave", -"%s: Pronto para conexões\n", +"%s: Pronto para conexões", "%s: 'Shutdown' normal\n", "%s: Obteve sinal %d. Abortando!\n", "%s: 'Shutdown' completo\n", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 44e8b9fa8de..8d2decdf23f 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -81,7 +81,7 @@ "Coloana de tip BLOB '%-.64s' nu poate fi folosita in specificarea cheii cu tipul de tabla folosit", "Lungimea coloanei '%-.64s' este prea lunga (maximum = %d). Foloseste BLOB mai bine", "Definitia tabelei este incorecta; Nu pot fi mai mult de o singura coloana de tip auto si aceasta trebuie definita ca cheie", -"%s: sint gata pentru conectii\n", +"%s: sint gata pentru conectii", "%s: Terminare normala\n", "%s: Semnal %d obtinut. Aborting!\n", "%s: Terminare completa\n", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 472031c6300..42845b57d76 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -79,7 +79,7 @@ "óÔÏÌÂÅà ÔÉÐÁ BLOB '%-.64s' ÎÅ ÍÏÖÅÔ ÂÙÔØ ÉÓÐÏÌØÚÏ×ÁÎ ËÁË ÚÎÁÞÅÎÉÅ ËÌÀÞÁ × ÔÁÂÌÉÃÅ ÔÁËÏÇÏ ÔÉÐÁ", "óÌÉÛËÏÍ ÂÏÌØÛÁÑ ÄÌÉÎÁ ÓÔÏÌÂÃÁ '%-.64s' (ÍÁËÓÉÍÕÍ = %d). éÓÐÏÌØÚÕÊÔÅ ÔÉÐ BLOB ×ÍÅÓÔÏ ÔÅËÕÝÅÇÏ", "îÅËÏÒÒÅËÔÎÏÅ ÏÐÒÅÄÅÌÅÎÉÅ ÔÁÂÌÉÃÙ: ÍÏÖÅÔ ÓÕÝÅÓÔ×Ï×ÁÔØ ÔÏÌØËÏ ÏÄÉÎ Á×ÔÏÉÎËÒÅÍÅÎÔÎÙÊ ÓÔÏÌÂÅÃ, É ÏÎ ÄÏÌÖÅÎ ÂÙÔØ ÏÐÒÅÄÅÌÅÎ ËÁË ËÌÀÞ", -"%s: çÏÔÏ× ÐÒÉÎÉÍÁÔØ ÓÏÅÄÉÎÅÎÉÑ.\n÷ÅÒÓÉÑ: '%s' ÓÏËÅÔ: '%s' ÐÏÒÔ: %d\n", +"%s: çÏÔÏ× ÐÒÉÎÉÍÁÔØ ÓÏÅÄÉÎÅÎÉÑ.\n÷ÅÒÓÉÑ: '%s' ÓÏËÅÔ: '%s' ÐÏÒÔ: %d", "%s: ëÏÒÒÅËÔÎÁÑ ÏÓÔÁÎÏ×ËÁ\n", "%s: ðÏÌÕÞÅÎ ÓÉÇÎÁÌ %d. ðÒÅËÒÁÝÁÅÍ!\n", "%s: ïÓÔÁÎÏ×ËÁ ÚÁ×ÅÒÛÅÎÁ\n", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 411f93b97da..52ed69a238d 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -85,7 +85,7 @@ "Blob pole '%-.64s' nemô¾e by» pou¾ité ako kµúè", "Príli¹ veµká då¾ka pre pole '%-.64s' (maximum = %d). Pou¾ite BLOB", "Mô¾ete ma» iba jedno AUTO pole a to musí by» definované ako kµúè", -"%s: pripravený na spojenie\n", +"%s: pripravený na spojenie", "%s: normálne ukonèenie\n", "%s: prijatý signál %d, ukonèenie (Abort)!\n", "%s: práca ukonèená\n", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 0010769aa4f..2ed3c19b68e 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -78,7 +78,7 @@ "La columna Blob '%-.64s' no puede ser usada en una declaracion de clave", "Longitud de columna demasiado grande para la columna '%-.64s' (maximo = %d).Usar BLOB en su lugar", "Puede ser solamente un campo automatico y este debe ser definido como una clave", -"%s: preparado para conexiones\n", +"%s: preparado para conexiones", "%s: Apagado normal\n", "%s: Recibiendo signal %d. Abortando!\n", "%s: Apagado completado\n", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 508737dde2f..4fd05875b43 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -77,7 +77,7 @@ "En BLOB '%-.64s' kan inte vara nyckel med den använda tabelltypen", "För stor kolumnlängd angiven för '%-.64s' (max= %d). Använd en BLOB instället", "Det får finnas endast ett AUTO_INCREMENT-fält och detta måste vara en nyckel", -"%s: klar att ta emot klienter\n", +"%s: klar att ta emot klienter", "%s: Normal avslutning\n", "%s: Fick signal %d. Avslutar!\n", "%s: Avslutning klar\n", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 372cfa78dff..6036f4be2d5 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -82,7 +82,7 @@ "BLOB ÓÔÏ×ÂÅÃØ '%-.64s' ÎÅ ÍÏÖÅ ÂÕÔÉ ×ÉËÏÒÉÓÔÁÎÉÊ Õ ×ÉÚÎÁÞÅÎΦ ËÌÀÞÁ × ÃØÏÍÕ ÔÉЦ ÔÁÂÌÉæ", "úÁÄÏ×ÇÁ ÄÏ×ÖÉÎÁ ÓÔÏ×ÂÃÑ '%-.64s' (max = %d). ÷ÉËÏÒÉÓÔÁÊÔÅ ÔÉÐ BLOB", "îÅצÒÎÅ ×ÉÚÎÁÞÅÎÎÑ ÔÁÂÌÉæ; íÏÖÅ ÂÕÔÉ ÌÉÛÅ ÏÄÉÎ Á×ÔÏÍÁÔÉÞÎÉÊ ÓÔÏ×ÂÅÃØ, ÝÏ ÐÏ×ÉÎÅÎ ÂÕÔÉ ×ÉÚÎÁÞÅÎÉÊ ÑË ËÌÀÞ", -"%s: çÏÔÏ×ÉÊ ÄÌÑ Ú'¤ÄÎÁÎØ!\n", +"%s: çÏÔÏ×ÉÊ ÄÌÑ Ú'¤ÄÎÁÎØ!", "%s: îÏÒÍÁÌØÎÅ ÚÁ×ÅÒÛÅÎÎÑ\n", "%s: ïÔÒÉÍÁÎÏ ÓÉÇÎÁÌ %d. ðÅÒÅÒÉ×ÁÀÓØ!\n", "%s: òÏÂÏÔÕ ÚÁ×ÅÒÛÅÎÏ\n", -- cgit v1.2.1 From c0cc90c2e5574307e41d84426f2c0cbf0325fe2a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Aug 2004 17:05:21 +0200 Subject: mysqld.cc, mysql_test_run.c: Changed URL in error message, page has moved netware/mysql_test_run.c: Changed URL in error message, page has moved sql/mysqld.cc: Changed URL in error message, page has moved BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 78e1268f363..998b5501724 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1788,7 +1788,7 @@ bytes of memory\n", ((ulong) sql_key_cache->key_cache_mem_size + You seem to be running 32-bit Linux and have %d concurrent connections.\n\ If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\ yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\ -the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n", +the thread stack. Please read http://www.mysql.com/doc/en/Linux.html\n\n", thread_count); } #endif /* HAVE_LINUXTHREADS */ -- cgit v1.2.1 From 9919574acfe36f2841dae33c729367658cc84078 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Aug 2004 14:16:43 -0700 Subject: Cleanup in mysql_time.h/my_time.h headers. The first is used in mysql.h, the second is for the rest of time declarations in mysys. include/my_time.h: New declarations moved from mysql_time.h include/mysql_time.h: New declarations moved to my_time.h. sql/tztime.cc: Enforcing Monty's approach to header files. sql/tztime.h: Enforcing Monty's approach to header files: everything is included in one place. --- sql/tztime.cc | 1 + sql/tztime.h | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/tztime.cc b/sql/tztime.cc index aab0d36b61e..2ed55f2fa4e 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -32,6 +32,7 @@ #include "mysql_priv.h" #else #include +#include #include "tztime.h" #include #endif diff --git a/sql/tztime.h b/sql/tztime.h index 9df5f965f34..69ff176326e 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -19,8 +19,6 @@ #pragma interface /* gcc class interface */ #endif -#include - #if !defined(TESTTIME) && !defined(TZINFO2SQL) /* -- cgit v1.2.1 From 1b0f0b0afc6cf33db2b39bf2653bf6f6ddef015b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Aug 2004 10:01:29 +0400 Subject: Fix for bug #4756 "STR_TO_DATE() returning bad results with AM/PM". Added support of converion specifiers mentioned in manual but missing in code. mysql-test/r/date_formats.result: Added tests of str_to_date() with new %T, %r and %V, %v conversion specifiers, and also some other specifiers for which tests were missing previously. mysql-test/t/date_formats.test: Added tests of str_to_date() and new %T, %r and %V, %v conversion specifiers, and also some other specifiers for which tests were missing previously. sql/item_timefunc.cc: Added support for %T, %r, %V, %v, %X, %x conversion specifiers to extract_date_time() function. Also simplified a bit calculation of dates from week number. --- sql/item_timefunc.cc | 140 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 110 insertions(+), 30 deletions(-) (limited to 'sql') diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 786bcf434ed..cc320addd47 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -113,6 +113,12 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, } +/* Date formats corresponding to compound %r and %T conversion specifiers */ +static DATE_TIME_FORMAT time_ampm_format= {{}, '\0', 0, + {(char *)"%I:%i:%S %p", 11}}; +static DATE_TIME_FORMAT time_24hrs_format= {{}, '\0', 0, + {(char *)"%H:%i:%S", 8}}; + /* Extract datetime value to TIME struct from string value according to format string. @@ -126,6 +132,17 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, cached_timestamp_type It uses to get an appropriate warning in the case when the value is truncated. + sub_pattern_end if non-zero then we are parsing string which + should correspond compound specifier (like %T or + %r) and this parameter is pointer to place where + pointer to end of string matching this specifier + should be stored. + NOTE + Possibility to parse strings matching to patterns equivalent to compound + specifiers is mainly intended for use from inside of this function in + order to understand %T and %r conversion specifiers, so number of + conversion specifiers that can be used in such sub-patterns is limited. + Also most of checks are skipped in this case. RETURN 0 ok @@ -134,14 +151,18 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, static bool extract_date_time(DATE_TIME_FORMAT *format, const char *val, uint length, TIME *l_time, - timestamp_type cached_timestamp_type) + timestamp_type cached_timestamp_type, + const char **sub_pattern_end) { int weekday= 0, yearday= 0, daypart= 0; int week_number= -1; CHARSET_INFO *cs= &my_charset_bin; int error= 0; bool usa_time= 0; - bool sunday_first= 0; + bool sunday_first_n_first_week_non_iso; + bool strict_week_number; + int strict_week_number_year= -1; + bool strict_week_number_year_type; int frac_part; const char *val_begin= val; const char *val_end= val + length; @@ -149,7 +170,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, const char *end= ptr + format->format.length; DBUG_ENTER("extract_date_time"); - bzero((char*) l_time, sizeof(*l_time)); + LINT_INIT(sunday_first_n_first_week_non_iso); + LINT_INIT(strict_week_number); + LINT_INIT(strict_week_number_year_type); + + if (!sub_pattern_end) + bzero((char*) l_time, sizeof(*l_time)); for (; ptr != end && val != val_end; ptr++) { @@ -160,7 +186,7 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, char *tmp; /* Skip pre-space between each argument */ - while (my_isspace(cs, *val) && val != val_end) + while (val != val_end && my_isspace(cs, *val)) val++; val_len= (uint) (val_end - val); @@ -268,9 +294,12 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, break; case 'w': tmp= (char*) val + 1; - if ((weekday= (int) my_strtoll10(val, &tmp, &error)) <= 0 || + if ((weekday= (int) my_strtoll10(val, &tmp, &error)) < 0 || weekday >= 7) goto err; + /* We should use the same 1 - 7 scale for %w as for %W */ + if (!weekday) + weekday= 7; val= tmp; break; case 'j': @@ -279,15 +308,45 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, val= tmp; break; + /* Week numbers */ + case 'V': case 'U': - sunday_first= 1; - /* Fall through */ + case 'v': case 'u': + sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V'); + strict_week_number= (*ptr=='V' || *ptr=='v'); tmp= (char*) val + min(val_len, 2); - week_number= (int) my_strtoll10(val, &tmp, &error); + if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 || + strict_week_number && !week_number || + week_number > 53) + goto err; val= tmp; break; + /* Year used with 'strict' %V and %v week numbers */ + case 'X': + case 'x': + strict_week_number_year_type= (*ptr=='X'); + tmp= (char*) val + min(4, val_len); + strict_week_number_year= (int) my_strtoll10(val, &tmp, &error); + val= tmp; + break; + + /* Time in AM/PM notation */ + case 'r': + error= extract_date_time(&time_ampm_format, val, + (uint)(val_end - val), l_time, + cached_timestamp_type, &val); + break; + + /* Time in 24-hour notation */ + case 'T': + error= extract_date_time(&time_24hrs_format, val, + (uint)(val_end - val), l_time, + cached_timestamp_type, &val); + break; + + /* Conversion specifiers that match classes of characters */ case '.': while (my_ispunct(cs, *val) && val != val_end) val++; @@ -320,6 +379,16 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, l_time->hour= l_time->hour%12+daypart; } + /* + If we are recursively called for parsing string matching compound + specifiers we are already done. + */ + if (sub_pattern_end) + { + *sub_pattern_end= val; + DBUG_RETURN(0); + } + if (yearday > 0) { uint days= calc_daynr(l_time->year,1,1) + yearday - 1; @@ -330,34 +399,45 @@ static bool extract_date_time(DATE_TIME_FORMAT *format, if (week_number >= 0 && weekday) { - int days= calc_daynr(l_time->year,1,1); + int days; uint weekday_b; - - if (weekday > 7 || weekday < 0) - goto err; - if (sunday_first) - weekday = weekday%7; - if (week_number == 53) - { - days+= (week_number - 1)*7; - weekday_b= calc_weekday(days, sunday_first); - weekday = weekday - weekday_b - !sunday_first; - days+= weekday; - } - else if (week_number == 0) + /* + %V,%v require %X,%x resprectively, + %U,%u should be used with %Y and not %X or %x + */ + if (strict_week_number && + (strict_week_number_year < 0 || + strict_week_number_year_type != sunday_first_n_first_week_non_iso) || + !strict_week_number && strict_week_number_year >= 0) + goto err; + + /* Number of days since year 0 till 1st Jan of this year */ + days= calc_daynr((strict_week_number ? strict_week_number_year : + l_time->year), + 1, 1); + /* Which day of week is 1st Jan of this year */ + weekday_b= calc_weekday(days, sunday_first_n_first_week_non_iso); + + /* + Below we are going to sum: + 1) number of days since year 0 till 1st day of 1st week of this year + 2) number of days between 1st week and our week + 3) and position of our day in the week + */ + if (sunday_first_n_first_week_non_iso) { - weekday_b= calc_weekday(days, sunday_first); - weekday = weekday - weekday_b - !sunday_first; - days+= weekday; + days+= ((weekday_b == 0) ? 0 : 7) - weekday_b + + (week_number - 1) * 7 + + weekday % 7; } else { - days+= (week_number - !sunday_first)*7; - weekday_b= calc_weekday(days, sunday_first); - weekday =weekday - weekday_b - !sunday_first; - days+= weekday; + days+= ((weekday_b <= 3) ? 0 : 7) - weekday_b + + (week_number - 1) * 7 + + (weekday - 1); } + if (days <= 0 || days >= MAX_DAY_NUMBER) goto err; get_date_from_daynr(days,&l_time->year,&l_time->month,&l_time->day); @@ -2599,7 +2679,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) date_time_format.format.str= (char*) format->ptr(); date_time_format.format.length= format->length(); if (extract_date_time(&date_time_format, val->ptr(), val->length(), - ltime, cached_timestamp_type)) + ltime, cached_timestamp_type, 0)) goto null_date; if (cached_timestamp_type == MYSQL_TIMESTAMP_TIME && ltime->day) { -- cgit v1.2.1 From 3a00469e4a5a2da31e82f15b1ebcaf546737c9a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Aug 2004 12:15:40 +0400 Subject: Fix for bug #4491 "timestamp(19) doesn't work". We should allow 19 as length of newly created TIMESTAMP fields. mysql-test/r/type_timestamp.result: Added test of TIMESTAMP(19) support. mysql-test/t/type_timestamp.test: Added test of TIMESTAMP(19) support. sql/sql_parse.cc: add_field_to_list(): TIMESTAMP columns should also support 19 as length since it is length of 4.1 compatible representation. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/sql_parse.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1f0af05a460..39c1a78b081 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3231,8 +3231,12 @@ bool add_field_to_list(char *field_name, enum_field_types type, case FIELD_TYPE_TIMESTAMP: if (!length) new_field->length= 14; // Full date YYYYMMDDHHMMSS - else + else if (new_field->length != 19) { + /* + We support only even TIMESTAMP lengths less or equal than 14 + and 19 as length of 4.1 compatible representation. + */ new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */ new_field->length= min(new_field->length,14); /* purecov: inspected */ } -- cgit v1.2.1 From fc4364e3509f9fa625e65f9e124b8133aa103f76 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Aug 2004 15:55:50 +0300 Subject: InnoDB: Add option for disabling innodb_status. files. InnoDB: Implement tmpfile() differently on Windows (Bug #3998) innobase/dict/dict0dict.c: Check the return value of os_file_create_tmpfile(), as it can now return NULL innobase/include/os0file.h: Note that os_file_create_tmpfile() can now return NULL innobase/include/srv0srv.h: Add a new server flag (srv_innodb_status) to disable the creation of innodb_status. files innobase/lock/lock0lock.c: Check the return value of os_file_create_tmpfile(), as it can now return NULL innobase/os/os0file.c: os_file_create_tmpfile(): separate implementation for Win32; errors will be reported but will not cause assertion failure innobase/srv/srv0srv.c: Add a new server flag (srv_innodb_status) to disable the creation of innodb_status. files innobase/srv/srv0start.c: innobase_start_or_create_for_mysql(): create srv_monitor_file with tmpfile() or with a visible name "innodb_status.", depending on the setting of the flag srv_innodb_status. sql/ha_innodb.cc: innobase_init(): initialize srv_innodb_status update_table_comment(), get_foreign_key_create_info(): replace tmpfile() with os_file_create_tmpfile() sql/ha_innodb.h: Add new Boolean flag, innobase_create_status_file. sql/mysqld.cc: Add new Boolean flag, innodb_status_file --- sql/ha_innodb.cc | 6 ++++-- sql/ha_innodb.h | 3 ++- sql/mysqld.cc | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 21dd7f748c2..6319c1494d3 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -103,6 +103,7 @@ uint innobase_flush_log_at_trx_commit = 1; my_bool innobase_log_archive = FALSE; my_bool innobase_use_native_aio = FALSE; my_bool innobase_fast_shutdown = TRUE; +my_bool innobase_create_status_file = FALSE; static char *internal_innobase_data_file_path = NULL; @@ -861,6 +862,7 @@ innobase_init(void) srv_force_recovery = (ulint) innobase_force_recovery; srv_fast_shutdown = (ibool) innobase_fast_shutdown; + srv_innodb_status = (ibool) innobase_create_status_file; srv_print_verbose_log = mysql_embedded ? 0 : 1; @@ -4270,7 +4272,7 @@ ha_innobase::update_table_comment( trx_search_latch_release_if_reserved(prebuilt->trx); str = NULL; - if (FILE* file = tmpfile()) { + if (FILE* file = os_file_create_tmpfile()) { long flen; /* output the data to a temporary file */ @@ -4330,7 +4332,7 @@ ha_innobase::get_foreign_key_create_info(void) update_thd(current_thd); - if (FILE* file = tmpfile()) { + if (FILE* file = os_file_create_tmpfile()) { long flen; prebuilt->trx->op_info = (char*)"getting info on foreign keys"; diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index 384b3dec949..5736f70c65c 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -203,7 +203,8 @@ extern char *innobase_log_group_home_dir, *innobase_log_arch_dir; extern char *innobase_unix_file_flush_method; /* The following variables have to be my_bool for SHOW VARIABLES to work */ extern my_bool innobase_log_archive, - innobase_use_native_aio, innobase_fast_shutdown; + innobase_use_native_aio, innobase_fast_shutdown, + innobase_create_status_file; extern "C" { extern ulong srv_max_buf_pool_modified_pct; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 55f58e9970e..3f7c187ccdd 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3458,6 +3458,7 @@ enum options_mysqld { OPT_INNODB_LOCK_WAIT_TIMEOUT, OPT_INNODB_THREAD_CONCURRENCY, OPT_INNODB_FORCE_RECOVERY, + OPT_INNODB_STATUS_FILE, OPT_INNODB_MAX_DIRTY_PAGES_PCT, OPT_BDB_CACHE_SIZE, OPT_BDB_LOG_BUFFER_SIZE, @@ -3625,6 +3626,10 @@ struct my_option my_long_options[] = {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN, "Speeds up server shutdown process", (gptr*) &innobase_fast_shutdown, (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"innodb_status_file", OPT_INNODB_STATUS_FILE, + "Enable SHOW INNODB STATUS output in the innodb_status. file", + (gptr*) &innobase_create_status_file, (gptr*) &innobase_create_status_file, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT, "Percentage of dirty pages allowed in bufferpool", (gptr*) &srv_max_buf_pool_modified_pct, (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, -- cgit v1.2.1 From 978e1ba084f97863efe4b2bd52beeba4e6f8ecb1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Aug 2004 18:26:59 +0200 Subject: bug#4881 - crash in ALTER .. RENAME if rename fails sql/sql_select.cc: typos in comments harmless (hopefully) bug in optimizer fixed --- sql/sql_select.cc | 16 +++++++--------- sql/sql_table.cc | 2 +- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 487caeb62db..3b02735edc3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -854,7 +854,7 @@ JOIN::optimize() as in other cases the join is done before the sort. */ if (const_tables != tables && - (order || group_list) && + (order || group_list) && join_tab[const_tables].type != JT_ALL && join_tab[const_tables].type != JT_FT && join_tab[const_tables].type != JT_REF_OR_NULL && @@ -868,9 +868,7 @@ JOIN::optimize() ((group_list && const_tables != tables && (!simple_group || !test_if_skip_sort_order(&join_tab[const_tables], group_list, - unit->select_limit_cnt, - 0))) || - select_distinct) && + HA_POS_ERROR, 0))) || select_distinct) && tmp_table_param.quick_group && !procedure) { need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort @@ -2069,7 +2067,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, } else if (old->eq_func && new_fields->eq_func && old->val->eq(new_fields->val, old->field->binary())) - + { old->level= and_level; old->optimize= ((old->optimize & new_fields->optimize & @@ -2128,7 +2126,7 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end, field Field used in comparision eq_func True if we used =, <=> or IS NULL value Value used for comparison with field - Is NULL for BETWEEN and IN + Is NULL for BETWEEN and IN usable_tables Tables which can be used for key optimization NOTES @@ -2207,7 +2205,7 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond, (*value)->result_type() != STRING_RESULT && field->cmp_type() != (*value)->result_type()) return; - + /* We can't use indexes if the effective collation of the operation differ from the field collation. @@ -2320,7 +2318,7 @@ add_key_fields(JOIN_TAB *stat,KEY_FIELD **key_fields,uint *and_level, !(cond_func->used_tables() & OUTER_REF_TABLE_BIT)) { Item *tmp=new Item_null; - if (!tmp) // Should never be true + if (unlikely(!tmp)) // Should never be true return; add_key_field(key_fields,*and_level,cond_func, ((Item_field*) (cond_func->arguments()[0])->real_item()) @@ -2731,7 +2729,7 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, rec= keyuse->ref_table_rows; /* If there is one 'key_column IS NULL' expression, we can - use this ref_or_null optimsation of this field + use this ref_or_null optimisation of this field */ found_ref_or_null|= (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7afbe6d0b87..37e959d38a1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2691,7 +2691,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (do_send_ok) send_ok(thd); } - else + else if (error > 0) { table->file->print_error(error, MYF(0)); error= -1; -- cgit v1.2.1 From 91f20a16b8322e50ef79461239de06d402055372 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Aug 2004 23:18:13 +0200 Subject: cleanup mysql-test/r/select_found.result: explain added mysql-test/t/select_found.test: cleanup. 5000-char long line removed :) sql/sql_select.cc: reverted --- sql/item_cmpfunc.cc | 4 ++-- sql/sql_select.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 60f80249e94..14c0d996360 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -268,8 +268,8 @@ void Item_bool_func2::fix_length_and_dec() int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) { owner= item; - func= comparator_matrix[type][(owner->functype() == Item_func::EQUAL_FUNC)? - 1:0]; + func= comparator_matrix[type] + [test(owner->functype() == Item_func::EQUAL_FUNC)]; if (type == ROW_RESULT) { uint n= (*a)->cols(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3b02735edc3..3b3d8303210 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -868,7 +868,7 @@ JOIN::optimize() ((group_list && const_tables != tables && (!simple_group || !test_if_skip_sort_order(&join_tab[const_tables], group_list, - HA_POS_ERROR, 0))) || select_distinct) && + unit->select_limit_cnt, 0))) || select_distinct) && tmp_table_param.quick_group && !procedure) { need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort -- cgit v1.2.1 From 82d9b4a8a080f07a4779138e2ab9d966e90f4a39 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Aug 2004 15:46:57 +0200 Subject: mysqld.cc: get_options() did an exit(0) after reporting "Too many arguments" sql/mysqld.cc: get_options() did a exit(0) when reporting "Too many arguments" --- sql/mysqld.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 998b5501724..669c8f91c4c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6078,12 +6078,13 @@ static void get_options(int argc,char **argv) my_getopt_register_get_addr(mysql_getopt_value); strmake(def_ft_boolean_syntax, ft_boolean_syntax, sizeof(ft_boolean_syntax)-1); - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option)) != 0) exit(ho_error); if (argc > 0) { fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv); - exit(ho_error); + /* FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code? */ + exit(1); } if (opt_help) -- cgit v1.2.1 From caaa692ca681e1e94734e38efd224b3ce08fe6b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Aug 2004 21:23:03 -0500 Subject: mysqld.cc: Put --help first, reorder other options so that they are alphabetical. (shouldn't have to use grep to find an option.) Move group_concat_max_len to variable part of list. Rename character_set_server, collation_server, shared_memory_base_name to character-set-server, collation-server, shared-memory-base-name. Make default-collation message refer to collation-server rather than character-set-server. sql/mysqld.cc: Put --help first, reorder other options so that they are alphabetical. (shouldn't have to use grep to find an option.) Move group_concat_max_len to variable part of list. Rename character_set_server, collation_server, shared_memory_base_name to character-set-server, collation-server, shared-memory-base-name. Make default-collation message refer to collation-server rather than character-set-server. --- sql/mysqld.cc | 416 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 213 insertions(+), 203 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 669c8f91c4c..98e8183d2d5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3973,12 +3973,25 @@ enum options_mysqld struct my_option my_long_options[] = { + {"help", '?', "Display this help and exit.", + (gptr*) &opt_help, (gptr*) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, +#ifdef HAVE_REPLICATION + {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT, + "Option used by mysql-test for debugging and testing of replication.", + (gptr*) &abort_slave_event_count, (gptr*) &abort_slave_event_count, + 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif /* HAVE_REPLICATION */ {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"basedir", 'b', "Path to installation directory. All paths are usually resolved relative to this.", (gptr*) &mysql_home_ptr, (gptr*) &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"bdb", OPT_BDB, "Enable Berkeley DB (if this version of MySQL supports it). \ +Disable with --skip-bdb (will save memory).", + (gptr*) &opt_bdb, (gptr*) &opt_bdb, 0, GET_BOOL, NO_ARG, 1, 0, 0, + 0, 0, 0}, #ifdef HAVE_BERKELEY_DB {"bdb-home", OPT_BDB_HOME, "Berkeley home directory.", (gptr*) &berkeley_home, (gptr*) &berkeley_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -3995,10 +4008,6 @@ struct my_option my_long_options[] = "Disable synchronously flushing logs. This option is deprecated, use --skip-sync-bdb-logs or sync-bdb-logs=0 instead", // (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"sync-bdb-logs", OPT_BDB_SYNC, - "Synchronously flush logs. Enabled by default", - (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL, - NO_ARG, 1, 0, 0, 0, 0, 0}, {"bdb-shared-data", OPT_BDB_SHARED, "Start Berkeley DB in multi-process mode.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -4006,70 +4015,51 @@ struct my_option my_long_options[] = (gptr*) &berkeley_tmpdir, (gptr*) &berkeley_tmpdir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif /* HAVE_BERKELEY_DB */ - {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default", - (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, - 0, 0, 0, 0}, - {"bdb", OPT_BDB, "Enable Berkeley DB (if this version of MySQL supports it). \ -Disable with --skip-bdb (will save memory).", - (gptr*) &opt_bdb, (gptr*) &opt_bdb, 0, GET_BOOL, NO_ARG, 1, 0, 0, - 0, 0, 0}, {"big-tables", OPT_BIG_TABLES, "Allow big result sets by saving all temporary sets on file (Solves most 'table full' errors).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.", + (gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"binlog-do-db", OPT_BINLOG_DO_DB, "Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB, "Tells the master that updates to the given database should not be logged tothe binary log.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.", - (gptr*) &my_bind_addr_str, (gptr*) &my_bind_addr_str, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"character_set_server", 'C', "Set the default character set.", + {"character-set-server", 'C', "Set the default character set.", (gptr*) &default_character_set_name, (gptr*) &default_character_set_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - {"collation_server", OPT_DEFAULT_COLLATION, "Set the default collation.", + {"character-sets-dir", OPT_CHARSETS_DIR, + "Directory where character sets are.", (gptr*) &charsets_dir, + (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"chroot", 'r', "Chroot mysqld daemon during startup.", + (gptr*) &mysqld_chroot, (gptr*) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, + {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.", (gptr*) &default_collation_name, (gptr*) &default_collation_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + {"concurrent-insert", OPT_CONCURRENT_INSERT, + "Use concurrent insert with MyISAM. Disable with --skip-concurrent-insert.", + (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert, + 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"console", OPT_CONSOLE, "Write error output on screen; Don't remove the console window on windows.", (gptr*) &opt_console, (gptr*) &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef __WIN__ - {"standalone", OPT_STANDALONE, - "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG, - NO_ARG, 0, 0, 0, 0, 0, 0}, -#endif {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"chroot", 'r', "Chroot mysqld daemon during startup.", - (gptr*) &mysqld_chroot, (gptr*) &mysqld_chroot, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, - {"character-sets-dir", OPT_CHARSETS_DIR, - "Directory where character sets are.", (gptr*) &charsets_dir, - (gptr*) &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"datadir", 'h', "Path to the database root.", (gptr*) &mysql_data_home, (gptr*) &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifndef DBUG_OFF {"debug", '#', "Debug log.", (gptr*) &default_dbug_option, (gptr*) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef SAFEMALLOC - {"skip-safemalloc", OPT_SKIP_SAFEMALLOC, - "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, - 0, 0, 0, 0, 0, 0}, -#endif #endif -#ifdef HAVE_OPENSSL - {"des-key-file", OPT_DES_KEY_FILE, - "Load keys for des_encrypt() and des_encrypt from given file.", - (gptr*) &des_key_file, (gptr*) &des_key_file, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, -#endif /* HAVE_OPENSSL */ - {"default-character-set", 'C', "Set the default character set (Deprecated option, use character_set_server instead).", + {"default-character-set", 'C', "Set the default character set (deprecated option, use --character-set-server instead).", (gptr*) &default_character_set_name, (gptr*) &default_character_set_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, - {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (Deprecated option, use character_set_server instead).", + {"default-collation", OPT_DEFAULT_COLLATION, "Set the default collation (deprecated option, use --collation-server instead).", (gptr*) &default_collation_name, (gptr*) &default_collation_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, {"default-storage-engine", OPT_STORAGE_ENGINE, @@ -4086,6 +4076,19 @@ Disable with --skip-bdb (will save memory).", {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL, "Don't flush key buffers between writes for any MyISAM table (Deprecated option, use --delay-key-write=all instead).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef HAVE_OPENSSL + {"des-key-file", OPT_DES_KEY_FILE, + "Load keys for des_encrypt() and des_encrypt from given file.", + (gptr*) &des_key_file, (gptr*) &des_key_file, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, +#endif /* HAVE_OPENSSL */ +#ifdef HAVE_REPLICATION + {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT, + "Option used by mysql-test for debugging and testing of replication.", + (gptr*) &disconnect_slave_event_count, + (gptr*) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, + 0, 0, 0}, +#endif /* HAVE_REPLICATION */ {"enable-locking", OPT_ENABLE_LOCK, "Deprecated option, use --external-locking instead.", (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, @@ -4098,46 +4101,49 @@ Disable with --skip-bdb (will save memory).", {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure.", (gptr*) &opt_do_pstack, (gptr*) &opt_do_pstack, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifdef HAVE_SMEM - {"shared-memory", OPT_ENABLE_SHARED_MEMORY, - "Enable the shared memory.",(gptr*) &opt_enable_shared_memory, (gptr*) &opt_enable_shared_memory, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#endif {"exit-info", 'T', "Used for debugging; Use at your own risk!", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running.", + (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN, - "The maximum length of the result of function group_concat.", - (gptr*) &global_system_variables.group_concat_max_len, - (gptr*) &max_system_variables.group_concat_max_len, 0, GET_ULONG, - REQUIRED_ARG, 1024, 4, (long) ~0, 0, 1, 0}, /* We must always support the next option to make scripts like mysqltest easier to do */ {"gdb", OPT_DEBUGGING, "Set up signals usable for debugging", (gptr*) &opt_debugging, (gptr*) &opt_debugging, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection", + (gptr*) &opt_init_connect, (gptr*) &opt_init_connect, 0, GET_STR_ALLOC, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.", + (gptr*) &opt_init_file, (gptr*) &opt_init_file, 0, GET_STR, REQUIRED_ARG, + 0, 0, 0, 0, 0, 0}, {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master", + (gptr*) &opt_init_slave, (gptr*) &opt_init_slave, 0, GET_STR_ALLOC, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb", OPT_INNODB, "Enable InnoDB (if this version of MySQL supports it). \ +Disable with --skip-innodb (will save memory).", + (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, 1, 0, 0, + 0, 0, 0}, {"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH, "Path to individual files and their sizes.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_INNOBASE_DB {"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR, - "The common part for Innodb table spaces.", (gptr*) &innobase_data_home_dir, + "The common part for InnoDB table spaces.", (gptr*) &innobase_data_home_dir, (gptr*) &innobase_data_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR, - "Path to innodb log files.", (gptr*) &innobase_log_group_home_dir, - (gptr*) &innobase_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, - 0, 0}, - {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR, - "Where full logs should be archived.", (gptr*) &innobase_log_arch_dir, - (gptr*) &innobase_log_arch_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"innodb_log_archive", OPT_INNODB_LOG_ARCHIVE, - "Set to 1 if you want to have logs archived.", 0, 0, 0, GET_LONG, OPT_ARG, - 0, 0, 0, 0, 0, 0}, + {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN, + "Speeds up server shutdown process.", (gptr*) &innobase_fast_shutdown, + (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"innodb_file_per_table", OPT_INNODB_FILE_PER_TABLE, + "Stores each InnoDB table to an .ibd file in the database dir.", + (gptr*) &innobase_file_per_table, + (gptr*) &innobase_file_per_table, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_flush_log_at_trx_commit", OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT, "Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second).", (gptr*) &innobase_flush_log_at_trx_commit, @@ -4147,38 +4153,28 @@ Disable with --skip-bdb (will save memory).", "With which method to flush data.", (gptr*) &innobase_unix_file_flush_method, (gptr*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"innodb_fast_shutdown", OPT_INNODB_FAST_SHUTDOWN, - "Speeds up server shutdown process.", (gptr*) &innobase_fast_shutdown, - (gptr*) &innobase_fast_shutdown, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, - {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT, - "Percentage of dirty pages allowed in bufferpool.", (gptr*) &srv_max_buf_pool_modified_pct, - (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, - {"innodb_file_per_table", OPT_INNODB_FILE_PER_TABLE, - "Stores each InnoDB table to an .ibd file in the database dir.", - (gptr*) &innobase_file_per_table, - (gptr*) &innobase_file_per_table, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"innodb_locks_unsafe_for_binlog", OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, - "Force Innodb not to use next-key locking. Instead use only row-level locking", + "Force InnoDB not to use next-key locking. Instead use only row-level locking", (gptr*) &innobase_locks_unsafe_for_binlog, (gptr*) &innobase_locks_unsafe_for_binlog, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, -#endif /* End HAVE_INNOBASE_DB */ - {"init-connect", OPT_INIT_CONNECT, "Command(s) that are executed for each new connection", - (gptr*) &opt_init_connect, (gptr*) &opt_init_connect, 0, GET_STR_ALLOC, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed when a slave connects to this master", - (gptr*) &opt_init_slave, (gptr*) &opt_init_slave, 0, GET_STR_ALLOC, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', "Display this help and exit.", - (gptr*) &opt_help, (gptr*) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"verbose", 'v', "Used with --help option for detailed help", - (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, - 0, 0}, - {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.", - (gptr*) &opt_init_file, (gptr*) &opt_init_file, 0, GET_STR, REQUIRED_ARG, + {"innodb_log_arch_dir", OPT_INNODB_LOG_ARCH_DIR, + "Where full logs should be archived.", (gptr*) &innobase_log_arch_dir, + (gptr*) &innobase_log_arch_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb_log_archive", OPT_INNODB_LOG_ARCHIVE, + "Set to 1 if you want to have logs archived.", 0, 0, 0, GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"log", 'l', "Log connections and queries to file.", (gptr*) &opt_logname, - (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR, + "Path to InnoDB log files.", (gptr*) &innobase_log_group_home_dir, + (gptr*) &innobase_log_group_home_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, + 0, 0}, + {"innodb_max_dirty_pages_pct", OPT_INNODB_MAX_DIRTY_PAGES_PCT, + "Percentage of dirty pages allowed in bufferpool.", (gptr*) &srv_max_buf_pool_modified_pct, + (gptr*) &srv_max_buf_pool_modified_pct, 0, GET_ULONG, REQUIRED_ARG, 90, 0, 100, 0, 0, 0}, +#endif /* End HAVE_INNOBASE_DB */ + {"isam", OPT_ISAM, "Enable ISAM (if this version of MySQL supports it). \ +Disable with --skip-isam.", + (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 1, 0, 0, + 0, 0, 0}, {"language", 'L', "Client error messages in given language. May be given as a full path.", (gptr*) &language_ptr, (gptr*) &language_ptr, 0, GET_STR, REQUIRED_ARG, @@ -4188,6 +4184,8 @@ Disable with --skip-bdb (will save memory).", (gptr*) &opt_local_infile, (gptr*) &opt_local_infile, 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + {"log", 'l', "Log connections and queries to file.", (gptr*) &opt_logname, + (gptr*) &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-bin", OPT_BIN_LOG, "Log update queries in binary format.", (gptr*) &opt_bin_logname, (gptr*) &opt_bin_logname, 0, GET_STR_ALLOC, @@ -4196,45 +4194,57 @@ Disable with --skip-bdb (will save memory).", "File that holds the names for last binary log files.", (gptr*) &opt_binlog_index_name, (gptr*) &opt_binlog_index_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"log-error", OPT_ERROR_LOG_FILE, "Log error file.", + (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR, + OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.", (gptr*) &myisam_log_filename, (gptr*) &myisam_log_filename, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"log-update", OPT_UPDATE_LOG, - "Log updates to file.# where # is a unique number if not given.", - (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR, - OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"log-slow-queries", OPT_SLOW_QUERY_LOG, - "Log slow queries to this log file. Defaults logging to hostname-slow.log file.", - (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG, - 0, 0, 0, 0, 0, 0}, {"log-long-format", '0', "Log some extra information to update log. Please note that this option is deprecated; see --log-short-format option.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"log-short-format", OPT_SHORT_LOG_FORMAT, - "Don't log extra information to update and slow-query logs.", - (gptr*) &opt_short_log_format, (gptr*) &opt_short_log_format, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES, "Log queries that are executed without benefit of any index.", (gptr*) &opt_log_queries_not_using_indexes, (gptr*) &opt_log_queries_not_using_indexes, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"log-short-format", OPT_SHORT_LOG_FORMAT, + "Don't log extra information to update and slow-query logs.", + (gptr*) &opt_short_log_format, (gptr*) &opt_short_log_format, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"log-slave-updates", OPT_LOG_SLAVE_UPDATES, "Tells the slave to log the updates from the slave thread to the binary log. You will need to turn it on if you plan to daisy-chain the slaves.", (gptr*) &opt_log_slave_updates, (gptr*) &opt_log_slave_updates, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"log-slow-queries", OPT_SLOW_QUERY_LOG, + "Log slow queries to this log file. Defaults logging to hostname-slow.log file.", + (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG, + 0, 0, 0, 0, 0, 0}, + {"log-update", OPT_UPDATE_LOG, + "Log updates to file.# where # is a unique number if not given.", + (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR, + OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"log-warnings", 'W', "Log some not critical warnings to the log file. Use this option twice, or --log-warnings=2 if you want 'Aborted connections' warning to be logged in the error log file.", + (gptr*) &global_system_variables.log_warnings, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + 0, 0, 0}, {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES, "INSERT/DELETE/UPDATE has lower priority than selects.", (gptr*) &global_system_variables.low_priority_updates, (gptr*) &max_system_variables.low_priority_updates, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"master-connect-retry", OPT_MASTER_CONNECT_RETRY, + "The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is lost.", + (gptr*) &master_connect_retry, (gptr*) &master_connect_retry, 0, GET_UINT, + REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, {"master-host", OPT_MASTER_HOST, "Master hostname or IP address for replication. If not set, the slave thread will not be started. Note that the setting of master-host will be ignored if there exists a valid master.info file.", (gptr*) &master_host, (gptr*) &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"master-user", OPT_MASTER_USER, - "The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read.", - (gptr*) &master_user, (gptr*) &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0, - 0, 0, 0, 0}, + {"master-info-file", OPT_MASTER_INFO_FILE, + "The location and name of the file that remembers the master and where the I/O replication \ +thread is in the master's binlogs.", + (gptr*) &master_info_file, (gptr*) &master_info_file, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"master-password", OPT_MASTER_PASSWORD, "The password the slave thread will authenticate with when connecting to the master. If not set, an empty password is assumed.The value in master.info will take precedence if it can be read.", (gptr*)&master_password, (gptr*)&master_password, 0, @@ -4243,32 +4253,14 @@ Disable with --skip-bdb (will save memory).", "The port the master is listening on. If not set, the compiled setting of MYSQL_PORT is assumed. If you have not tinkered with configure options, this should be 3306. The value in master.info will take precedence if it can be read.", (gptr*) &master_port, (gptr*) &master_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, - {"master-connect-retry", OPT_MASTER_CONNECT_RETRY, - "The number of seconds the slave thread will sleep before retrying to connect to the master in case the master goes down or the connection is lost.", - (gptr*) &master_connect_retry, (gptr*) &master_connect_retry, 0, GET_UINT, - REQUIRED_ARG, 60, 0, 0, 0, 0, 0}, {"master-retry-count", OPT_MASTER_RETRY_COUNT, "The number of tries the slave will make to connect to the master before giving up.", (gptr*) &master_retry_count, (gptr*) &master_retry_count, 0, GET_ULONG, REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0}, - {"master-info-file", OPT_MASTER_INFO_FILE, - "The location and name of the file that remembers the master and where the I/O replication \ -thread is in the master's binlogs.", - (gptr*) &master_info_file, (gptr*) &master_info_file, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"master-ssl", OPT_MASTER_SSL, "Enable the slave to connect to the master using SSL.", (gptr*) &master_ssl, (gptr*) &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"master-ssl-key", OPT_MASTER_SSL_KEY, - "Master SSL keyfile name. Only applies if you have enabled master-ssl.", - (gptr*) &master_ssl_key, (gptr*) &master_ssl_key, 0, GET_STR, OPT_ARG, - 0, 0, 0, 0, 0, 0}, - {"master-ssl-cert", OPT_MASTER_SSL_CERT, - "Master SSL certificate file name. Only applies if you have enabled \ -master-ssl", - (gptr*) &master_ssl_cert, (gptr*) &master_ssl_cert, 0, GET_STR, OPT_ARG, - 0, 0, 0, 0, 0, 0}, {"master-ssl-ca", OPT_MASTER_SSL_CA, "Master SSL CA file. Only applies if you have enabled master-ssl.", (gptr*) &master_ssl_ca, (gptr*) &master_ssl_ca, 0, GET_STR, OPT_ARG, @@ -4277,39 +4269,39 @@ master-ssl", "Master SSL CA path. Only applies if you have enabled master-ssl.", (gptr*) &master_ssl_capath, (gptr*) &master_ssl_capath, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"master-ssl-cert", OPT_MASTER_SSL_CERT, + "Master SSL certificate file name. Only applies if you have enabled \ +master-ssl", + (gptr*) &master_ssl_cert, (gptr*) &master_ssl_cert, 0, GET_STR, OPT_ARG, + 0, 0, 0, 0, 0, 0}, {"master-ssl-cipher", OPT_MASTER_SSL_CIPHER, "Master SSL cipher. Only applies if you have enabled master-ssl.", (gptr*) &master_ssl_cipher, (gptr*) &master_ssl_capath, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"myisam-recover", OPT_MYISAM_RECOVER, - "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.", - (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0, - GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (gptr*) &locked_in_memory, - (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"master-ssl-key", OPT_MASTER_SSL_KEY, + "Master SSL keyfile name. Only applies if you have enabled master-ssl.", + (gptr*) &master_ssl_key, (gptr*) &master_ssl_key, 0, GET_STR, OPT_ARG, + 0, 0, 0, 0, 0, 0}, + {"master-user", OPT_MASTER_USER, + "The username the slave thread will use for authentication when connecting to the master. The user must have FILE privilege. If the master user is not set, user test is assumed. The value in master.info will take precedence if it can be read.", + (gptr*) &master_user, (gptr*) &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0, + 0, 0, 0, 0}, #ifdef HAVE_REPLICATION - {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT, - "Option used by mysql-test for debugging and testing of replication.", - (gptr*) &disconnect_slave_event_count, - (gptr*) &disconnect_slave_event_count, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, - 0, 0, 0}, - {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT, - "Option used by mysql-test for debugging and testing of replication.", - (gptr*) &abort_slave_event_count, (gptr*) &abort_slave_event_count, - 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS, "Option used by mysql-test for debugging and testing of replication.", (gptr*) &max_binlog_dump_events, (gptr*) &max_binlog_dump_events, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL, - "Option used by mysql-test for debugging and testing of replication.", - (gptr*) &opt_sporadic_binlog_dump_fail, - (gptr*) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, - 0}, #endif /* HAVE_REPLICATION */ - {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT, - "Simulate memory shortage when compiled with the --with-debug=full option.", - 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", (gptr*) &locked_in_memory, + (gptr*) &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"myisam-recover", OPT_MYISAM_RECOVER, + "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.", + (gptr*) &myisam_recover_options_str, (gptr*) &myisam_recover_options_str, 0, + GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"ndbcluster", OPT_NDBCLUSTER, "Enable NDB Cluster (if this version of MySQL supports it). \ +Disable with --skip-ndbcluster (will save memory).", + (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 1, 0, 0, + 0, 0, 0}, {"new", 'n', "Use very new possible 'unsafe' functions.", (gptr*) &global_system_variables.new_mode, (gptr*) &max_system_variables.new_mode, @@ -4331,32 +4323,43 @@ master-ssl", {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.", (gptr*) &pidfile_name_ptr, (gptr*) &pidfile_name_ptr, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"log-error", OPT_ERROR_LOG_FILE, "Log error file.", - (gptr*) &log_error_file_ptr, (gptr*) &log_error_file_ptr, 0, GET_STR, - OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection.", (gptr*) &mysqld_port, (gptr*) &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"relay-log", OPT_RELAY_LOG, + "The location and name to use for relay logs.", + (gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0, + GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"relay-log-index", OPT_RELAY_LOG_INDEX, + "The location and name to use for the file that keeps a list of the last \ +relay logs.", + (gptr*) &opt_relaylog_index_name, (gptr*) &opt_relaylog_index_name, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, + "The location and name of the file that remembers where the SQL replication \ +thread is in the relay logs.", + (gptr*) &relay_log_info_file, (gptr*) &relay_log_info_file, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-do-db", OPT_REPLICATE_DO_DB, "Tells the slave thread to restrict replication to the specified database. To specify more than one database, use the directive multiple times, once for each database. Note that this will only work if you do not use cross-database queries such as UPDATE some_db.some_table SET foo='bar' while having selected a different or no database. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-do-table=db_name.%.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-do-table", OPT_REPLICATE_DO_TABLE, "Tells the slave thread to restrict replication to the specified table. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates, in contrast to replicate-do-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE, - "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB, "Tells the slave thread to not replicate to the specified database. To specify more than one database to ignore, use the directive multiple times, once for each database. This option will not work if you use cross database updates. If you need cross database updates to work, make sure you have 3.23.28 or later, and use replicate-wild-ignore-table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE, "Tells the slave thread to not replicate to the specified table. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-datbase updates, in contrast to replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE, - "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB, "Updates to a database with a different name than the original. Example: replicate-rewrite-db=master_db_name->slave_db_name.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE, + "Tells the slave thread to restrict replication to the tables that match the specified wildcard pattern. To specify more than one table, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-do-table=foo%.bar% will replicate only updates to tables in all databases that start with foo and whose table names start with bar.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE, + "Tells the slave thread to not replicate to the tables that match the given wildcard pattern. To specify more than one table to ignore, use the directive multiple times, once for each table. This will work for cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% will not do updates to tables in databases that start with foo and whose table names start with bar.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_REPLICATION {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID, "In replication, if set to 1, do not skip events having our server id. \ @@ -4371,8 +4374,6 @@ Can't be set to 1 if --log-slave-updates is used.", "Hostname or IP of the slave to be reported to to the master during slave registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset if you do not want the slave to register itself with the master. Note that it is not sufficient for the master to simply read the IP of the slave off the socket once the slave connects. Due to NAT and other routing issues, that IP may not be valid for connecting to the slave from the master or other hosts.", (gptr*) &report_host, (gptr*) &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"report-user", OPT_REPORT_USER, "Undocumented.", (gptr*) &report_user, - (gptr*) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"report-password", OPT_REPORT_PASSWORD, "Undocumented.", (gptr*) &report_password, (gptr*) &report_password, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -4380,29 +4381,25 @@ Can't be set to 1 if --log-slave-updates is used.", "Port for connecting to slave reported to the master during slave registration. Set it only if the slave is listening on a non-default port or if you have a special tunnel from the master or other clients to the slave. If not sure, leave this option unset.", (gptr*) &report_port, (gptr*) &report_port, 0, GET_UINT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, + {"report-user", OPT_REPORT_USER, "Undocumented.", (gptr*) &report_user, + (gptr*) &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented.", (gptr*) &rpl_recovery_rank, (gptr*) &rpl_recovery_rank, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"relay-log", OPT_RELAY_LOG, - "The location and name to use for relay logs.", - (gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0, - GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"relay-log-index", OPT_RELAY_LOG_INDEX, - "The location and name to use for the file that keeps a list of the last \ -relay logs.", - (gptr*) &opt_relaylog_index_name, (gptr*) &opt_relaylog_index_name, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifndef TO_BE_DELETED {"safe-show-database", OPT_SAFE_SHOW_DB, - "Deprecated option; One should use GRANT SHOW DATABASES instead...", + "Deprecated option; use GRANT SHOW DATABASES instead...", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, #endif {"safe-user-create", OPT_SAFE_USER_CREATE, "Don't allow new user creation by the user who has no write privileges to the mysql.user table.", (gptr*) &opt_safe_user_create, (gptr*) &opt_safe_user_create, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT, + "Simulate memory shortage when compiled with the --with-debug=full option.", + 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.", (gptr*) &opt_secure_auth, (gptr*) &opt_secure_auth, 0, GET_BOOL, NO_ARG, my_bool(0), 0, 0, 0, 0, 0}, @@ -4414,7 +4411,12 @@ relay logs.", "Change the value of a variable. Please note that this option is deprecated;you can set variables directly with --variable-name=value.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_SMEM - {"shared_memory_base_name",OPT_SHARED_MEMORY_BASE_NAME, + {"shared-memory", OPT_ENABLE_SHARED_MEMORY, + "Enable the shared memory.",(gptr*) &opt_enable_shared_memory, (gptr*) &opt_enable_shared_memory, + 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif +#ifdef HAVE_SMEM + {"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME, "Base name of shared memory.", (gptr*) &shared_memory_base_name, (gptr*) &shared_memory_base_name, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #endif @@ -4422,31 +4424,15 @@ relay logs.", "Show user and password in SHOW SLAVE HOSTS on this master", (gptr*) &opt_show_slave_auth_info, (gptr*) &opt_show_slave_auth_info, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"concurrent-insert", OPT_CONCURRENT_INSERT, - "Use concurrent insert with MyISAM. Disable with --skip-concurrent-insert.", - (gptr*) &myisam_concurrent_insert, (gptr*) &myisam_concurrent_insert, - 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"skip-grant-tables", OPT_SKIP_GRANT, "Start without grant tables. This gives all users FULL ACCESS to all tables!", (gptr*) &opt_noacl, (gptr*) &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"innodb", OPT_INNODB, "Enable InnoDB (if this version of MySQL supports it). \ -Disable with --skip-innodb (will save memory).", - (gptr*) &opt_innodb, (gptr*) &opt_innodb, 0, GET_BOOL, NO_ARG, 1, 0, 0, - 0, 0, 0}, - {"isam", OPT_ISAM, "Enable isam (if this version of MySQL supports it). \ -Disable with --skip-isam.", - (gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 1, 0, 0, - 0, 0, 0}, - {"ndbcluster", OPT_NDBCLUSTER, "Enable NDB Cluster (if this version of MySQL supports it). \ -Disable with --skip-ndbcluster (will save memory).", - (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 1, 0, 0, - 0, 0, 0}, + {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0, + GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-locking", OPT_SKIP_LOCK, "Deprecated option, use --skip-external-locking instead.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0, - GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"skip-name-resolve", OPT_SKIP_RESOLVE, "Don't resolve hostnames. All hostnames are IP's or 'localhost'.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -4455,6 +4441,13 @@ Disable with --skip-ndbcluster (will save memory).", 0, 0, 0}, {"skip-new", OPT_SKIP_NEW, "Don't use new, possible wrong routines.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DBUG_OFF +#ifdef SAFEMALLOC + {"skip-safemalloc", OPT_SKIP_SAFEMALLOC, + "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, +#endif +#endif {"skip-show-database", OPT_SKIP_SHOW_DB, "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -4469,11 +4462,6 @@ Disable with --skip-ndbcluster (will save memory).", {"skip-thread-priority", OPT_SKIP_PRIOR, "Don't give threads different priorities.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE, - "The location and name of the file that remembers where the SQL replication \ -thread is in the relay logs.", - (gptr*) &relay_log_info_file, (gptr*) &relay_log_info_file, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, #ifdef HAVE_REPLICATION {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR, "The location where the slave should put its temporary files when \ @@ -4487,6 +4475,13 @@ replicating a LOAD DATA INFILE command.", {"socket", OPT_SOCKET, "Socket file to use for connection.", (gptr*) &mysqld_unix_port, (gptr*) &mysqld_unix_port, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef HAVE_REPLICATION + {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL, + "Option used by mysql-test for debugging and testing of replication.", + (gptr*) &opt_sporadic_binlog_dump_fail, + (gptr*) &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, + 0}, +#endif /* HAVE_REPLICATION */ {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME, "If set, setting SQL_LOG_BIN to a value will automatically set SQL_LOG_UPDATE to the same value and vice versa.", (gptr*) &opt_sql_bin_update, (gptr*) &opt_sql_bin_update, 0, GET_BOOL, @@ -4498,6 +4493,14 @@ replicating a LOAD DATA INFILE command.", #ifdef HAVE_OPENSSL #include "sslopt-longopts.h" #endif +#ifdef __WIN__ + {"standalone", OPT_STANDALONE, + "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG, + NO_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"symbolic-links", 's', "Enable symbolic link support.", + (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, + IF_PURIFY(0,1), 0, 0, 0, 0, 0}, {"temp-pool", OPT_TEMP_POOL, "Using this option will cause most temporary files created to use a small set of names, rather than a unique name for each new file.", (gptr*) &use_temp_pool, (gptr*) &use_temp_pool, 0, GET_BOOL, NO_ARG, 1, @@ -4515,24 +4518,17 @@ replicating a LOAD DATA INFILE command.", {"transaction-isolation", OPT_TX_ISOLATION, "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"external-locking", OPT_USE_LOCKING, "Use system (external) locking. With this option enabled you can run myisamchk to test (not repair) tables while the MySQL server is running.", - (gptr*) &opt_external_locking, (gptr*) &opt_external_locking, - 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; Use --symbolic-links instead.", - (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, - IF_PURIFY(0,1), 0, 0, 0, 0, 0}, - {"symbolic-links", 's', "Enable symbolic link support.", + {"use-symbolic-links", 's', "Enable symbolic link support. Deprecated option; use --symbolic-links instead.", (gptr*) &my_use_symdir, (gptr*) &my_use_symdir, 0, GET_BOOL, NO_ARG, IF_PURIFY(0,1), 0, 0, 0, 0, 0}, {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"verbose", 'v', "Used with --help option for detailed help", + (gptr*) &opt_verbose, (gptr*) &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, + 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"log-warnings", 'W', "Log some not critical warnings to the log file. Use this option twice, or --log-warnings=2 if you want 'Aborted connections' warning to be logged in the error log file.", - (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, - 0, 0, 0}, - {"warnings", 'W', "Deprecated ; Use --log-warnings instead.", + {"warnings", 'W', "Deprecated; use --log-warnings instead.", (gptr*) &global_system_variables.log_warnings, (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, 0, 0, 0}, @@ -4608,6 +4604,11 @@ replicating a LOAD DATA INFILE command.", "Use stopwords from this file instead of built-in list.", (gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN, + "The maximum length of the result of function group_concat.", + (gptr*) &global_system_variables.group_concat_max_len, + (gptr*) &max_system_variables.group_concat_max_len, 0, GET_ULONG, + REQUIRED_ARG, 1024, 4, (long) ~0, 0, 1, 0}, #ifdef HAVE_INNOBASE_DB {"innodb_mirrored_log_groups", OPT_INNODB_MIRRORED_LOG_GROUPS, "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.", @@ -4967,12 +4968,21 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG, MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD, 1, 0}, +#ifdef HAVE_BERKELEY_DB + {"sync-bdb-logs", OPT_BDB_SYNC, + "Synchronously flush logs. Enabled by default", + (gptr*) &opt_sync_bdb_logs, (gptr*) &opt_sync_bdb_logs, 0, GET_BOOL, + NO_ARG, 1, 0, 0, 0, 0, 0}, +#endif /* HAVE_BERKELEY_DB */ {"sync-binlog", OPT_SYNC_BINLOG, "Sync the binlog to disk after every #th event. \ #=0 (the default) does no sync. Syncing slows MySQL down", (gptr*) &sync_binlog_period, (gptr*) &sync_binlog_period, 0, GET_ULONG, REQUIRED_ARG, 0, 0, ~0L, 0, 1, 0}, + {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default", + (gptr*) &opt_sync_frm, (gptr*) &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0, + 0, 0, 0, 0}, {"table_cache", OPT_TABLE_CACHE, "The number of open tables for all threads.", (gptr*) &table_cache_size, (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L, -- cgit v1.2.1 From 9694a1f9dd1ddbc667c40fc88b0d30e8c69985c6 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Aug 2004 11:02:09 +0200 Subject: bug#4369 - MySQL 4.1 regression in Alter table/tmp table from hash. Solved performance problems by fixing a typo, which prevented enabling of write buffer. sql/ha_myisam.cc: bug#4369 - MySQL 4.1 regression in Alter table/tmp table from hash. Solved performance problems by fixing a typo, which prevented enabling of write buffer. Supplied no test case, as it required too much data to see the performance regression. --- sql/ha_myisam.cc | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 51c8521c376..3d2d25b3e7d 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -957,15 +957,21 @@ int ha_myisam::indexes_are_disabled(void) start_bulk_insert(rows) rows Rows to be inserted 0 if we don't know + + NOTICE + Do not forget to call end_bulk_insert() later! */ void ha_myisam::start_bulk_insert(ha_rows rows) { + DBUG_ENTER("ha_myisam::start_bulk_insert"); THD *thd=current_thd; ulong size= min(thd->variables.read_buff_size, table->avg_row_length*rows); + DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu", + (ulong) rows, size)); /* don't enable row cache if too few rows */ - if (!rows && rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE) + if (! rows || (rows > MI_MIN_ROWS_TO_USE_WRITE_CACHE)) mi_extra(file, HA_EXTRA_WRITE_CACHE, (void*) &size); can_enable_indexes= (file->s->state.key_map == @@ -989,8 +995,22 @@ void ha_myisam::start_bulk_insert(ha_rows rows) mi_init_bulk_insert(file, thd->variables.bulk_insert_buff_size, rows); } } + DBUG_VOID_RETURN; } +/* + end special bulk-insert optimizations, + which have been activated by start_bulk_insert(). + + SYNOPSIS + end_bulk_insert() + no arguments + + RETURN + 0 OK + != 0 Error +*/ + int ha_myisam::end_bulk_insert() { mi_end_bulk_insert(file); -- cgit v1.2.1 From 63ae5d0b4d87e25eb3fa773bb4b22b94b2d1fe52 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Aug 2004 11:39:26 +0200 Subject: bug#4497 - Serious regression if disk based TMP table is used. Solved performance problems by enabling write buffer. sql/sql_select.cc: bug#4497 - Serious regression if disk based TMP table is used. Solved performance problems by enabling write buffer. Supplied no test case, as it required too much data to see the performance regression. --- sql/sql_select.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 096b73c482f..7b688041acc 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4533,6 +4533,20 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, new_table.no_rows=1; } +#ifdef TO_BE_DONE_LATER_IN_4_1 + /* + To use start_bulk_insert() (which is new in 4.1) we need to find + all places where a corresponding end_bulk_insert() should be put. + */ + table->file->info(HA_STATUS_VARIABLE); /* update table->file->records */ + new_table.file->start_bulk_insert(table->file->records); +#else + /* + HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it explicitly. + */ + new_table.file->extra(HA_EXTRA_WRITE_CACHE); +#endif + /* copy all old rows */ while (!table->file->rnd_next(new_table.record[1])) { -- cgit v1.2.1 From 17f95c28da681733690e2a8de4f5e2e2f367a2fb Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Aug 2004 10:34:36 -0500 Subject: mysqld.cc: minor option description change. sql/mysqld.cc: minor option description change. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 98e8183d2d5..c81a888d2e9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4066,7 +4066,7 @@ Disable with --skip-bdb (will save memory).", "Set the default storage engine (table tyoe) for tables.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-table-type", OPT_STORAGE_ENGINE, - "(deprecated) Use default-storage-engine.", 0, 0, + "(deprecated) Use --default-storage-engine.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.", (gptr*) &default_tz_name, (gptr*) &default_tz_name, -- cgit v1.2.1 From 68d7b266988abb4c24a10282a338c305f3395882 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Aug 2004 12:42:31 +0400 Subject: Fix for bug #4508 "CONVERT_TZ() function with new time zone as param crashes server". Instead of trying to open time zone tables during calculation of CONVERT_TZ() function or setting of @@time_zone variable we should open and lock them with the rest of statement's table (so we should add them to global table list) and after that use such pre-opened tables for loading info about time zones. mysql-test/r/timezone2.result: Added test for bug #4508 mysql-test/t/timezone2.test: Added test for bug #4508 scripts/mysql_create_system_tables.sh: Added one more test time zone to time zone tables which is needed for test for bug #4508. sql/item_create.cc: CONVERT_TZ() now is treated as special function. sql/item_create.h: CONVERT_TZ() now is treated as special function. sql/item_timefunc.cc: Item_func_convert_tz now uses list of pre-opened time zone tables instead of trying to open them ad-hoc. Also it avoid calling of current_thd. sql/item_timefunc.h: Added comment describing special nature of CONVERT_TZ() function. Optimization: Added own fix_fields() method and tz_tables member for caching pointer to list of open time zone tables to Item_func_convert_tz class. sql/lex.h: CONVERT_TZ() now is treated as special function. sql/mysql_priv.h: Removed function which is no longer used. sql/set_var.cc: Now my_tz_find() accepts list of pre-opened time zone tables as last argument and no longer needs pointer to current THD. sql/set_var.h: Exported sys_time_zone, which is now used in sql_yacc.yy for quick finding out if we are setting @@time_zone variable. sql/sql_base.cc: Moved propagation of pointers to open tables from global list to local select lists to open_and_lock_tables(), also added implicit usage of time zone tables as condition for such propagation. sql/sql_lex.cc: Added fake_time_zone_tables_list which is used to indicate that time zone tables are implicitly used in statement. st_select_lex_unit::create_total_list(): if time zone tables are implicitly used in statement add them to global tables list. sql/sql_lex.h: Added LEX::time_zone_tables_used member which is used to indicate that time zone tables are implicitly used in this statement (by pointing to fake_time_zone_table_list) and for holding pointer to those tables after they've been opened. sql/sql_parse.cc: We should also create global table list if statement uses time zone tables implicitly. Added initialization of LEX::time_zone_tables_used to mysql_query_init(). sql/sql_prepare.cc: We should also create global table list if statement uses time zone tables implicitly. sql/sql_select.cc: Removed functions which are no longer used. sql/sql_yacc.yy: CONVERT_TZ() and @@time_zone variable are handled in special way since they implicitly use time zone tables. sql/tztime.cc: Fix for bug #4508 "CONVERT_TZ() function with new time zone as param crashes server". If statement uses CONVERT_TZ() function or @@time_zone variable is set then it implicitly uses time zone tables. We need to open and lock such tables with all other tables of such statement. All code responsible for opening table was removed from tz_load_from_db() and function was renamed to tz_load_from_open_tables() (which uses list of pre-opened tables). We also have new functions for construction and initialization of table list of time zone tables. my_tz_find() now always require list of pre-opened time zone tables and no longer needs current THD. So we have to pre-open them in my_tz_init(). Also now we try to open time zone tables only if they were found during startup. sql/tztime.h: New function for construction of table list of time zone tables my_tz_get_table_list(). Now my_tz_find() requires list of pre-pened time zone tables instead of current thread. --- sql/item_create.cc | 5 - sql/item_create.h | 1 - sql/item_timefunc.cc | 28 +++-- sql/item_timefunc.h | 16 ++- sql/lex.h | 2 +- sql/mysql_priv.h | 1 - sql/set_var.cc | 8 +- sql/set_var.h | 1 + sql/sql_base.cc | 17 ++- sql/sql_lex.cc | 37 ++++++- sql/sql_lex.h | 7 ++ sql/sql_parse.cc | 4 +- sql/sql_prepare.cc | 3 +- sql/sql_select.cc | 33 ------ sql/sql_yacc.yy | 12 ++ sql/tztime.cc | 306 ++++++++++++++++++++++++++++----------------------- sql/tztime.h | 3 +- 17 files changed, 289 insertions(+), 195 deletions(-) (limited to 'sql') diff --git a/sql/item_create.cc b/sql/item_create.cc index 4290a25e348..c98c7892c26 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -89,11 +89,6 @@ Item *create_func_conv(Item* a, Item *b, Item *c) return new Item_func_conv(a,b,c); } -Item *create_func_convert_tz(Item* a, Item *b, Item *c) -{ - return new Item_func_convert_tz(a,b,c); -} - Item *create_func_cos(Item* a) { return new Item_func_cos(a); diff --git a/sql/item_create.h b/sql/item_create.h index 19f0c9133f2..7577627ef04 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -31,7 +31,6 @@ Item *create_func_char_length(Item* a); Item *create_func_cast(Item *a, Cast_target cast_type, int len, CHARSET_INFO *cs); Item *create_func_connection_id(void); Item *create_func_conv(Item* a, Item *b, Item *c); -Item *create_func_convert_tz(Item* a, Item *b, Item *c); Item *create_func_cos(Item* a); Item *create_func_cot(Item* a); Item *create_func_crc32(Item* a); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cc320addd47..73aec7e8bdd 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1648,19 +1648,29 @@ bool Item_func_from_unixtime::get_date(TIME *ltime, void Item_func_convert_tz::fix_length_and_dec() -{ - String str; - - thd= current_thd; +{ collation.set(&my_charset_bin); decimals= 0; max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; +} + + +bool +Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **ref) +{ + String str; + if (Item_date_func::fix_fields(thd_arg, tables_arg, ref)) + return 1; + + tz_tables= thd_arg->lex->time_zone_tables_used; if (args[1]->const_item()) - from_tz= my_tz_find(thd, args[1]->val_str(&str)); - + from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); + if (args[2]->const_item()) - to_tz= my_tz_find(thd, args[2]->val_str(&str)); + to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); + + return 0; } @@ -1701,10 +1711,10 @@ bool Item_func_convert_tz::get_date(TIME *ltime, String str; if (!args[1]->const_item()) - from_tz= my_tz_find(thd, args[1]->val_str(&str)); + from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); if (!args[2]->const_item()) - to_tz= my_tz_find(thd, args[2]->val_str(&str)); + to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, 0)) { diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index a7ff2924786..2254fc830c9 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -531,9 +531,22 @@ class Item_func_from_unixtime :public Item_date_func */ class Time_zone; +/* + This class represents CONVERT_TZ() function. + The important fact about this function that it is handled in special way. + When such function is met in expression time_zone system tables are added + to global list of tables to open, so later those already opened and locked + tables can be used during this function calculation for loading time zone + descriptions. +*/ class Item_func_convert_tz :public Item_date_func { - THD *thd; + /* Cached pointer to list of pre-opened time zone tables. */ + TABLE_LIST *tz_tables; + /* + If time zone parameters are constants we are caching objects that + represent them. + */ Time_zone *from_tz, *to_tz; public: Item_func_convert_tz(Item *a, Item *b, Item *c): @@ -542,6 +555,7 @@ class Item_func_convert_tz :public Item_date_func double val() { return (double) val_int(); } String *val_str(String *str); const char *func_name() const { return "convert_tz"; } + bool fix_fields(THD *, struct st_table_list *, Item **); void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); }; diff --git a/sql/lex.h b/sql/lex.h index 218a1762a5c..c64a7069c32 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -499,7 +499,7 @@ static SYMBOL sql_functions[] = { { "CONNECTION_ID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, { "CONTAINS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)}, { "CONV", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, - { "CONVERT_TZ", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_convert_tz)}, + { "CONVERT_TZ", SYM(CONVERT_TZ_SYM)}, { "COUNT", SYM(COUNT_SYM)}, { "COS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, { "COT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2f0e2085430..b3b79c16787 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -500,7 +500,6 @@ int mysql_select(THD *thd, Item ***rref_pointer_array, select_result *result, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); void free_underlaid_joins(THD *thd, SELECT_LEX *select); -void fix_tables_pointers(SELECT_LEX *select_lex); int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result); int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, diff --git a/sql/set_var.cc b/sql/set_var.cc index bcebb62ae4d..fc1332695d6 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2372,8 +2372,9 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) return 1; } #endif - - if (!(var->save_result.time_zone= my_tz_find(thd, res))) + + if (!(var->save_result.time_zone= + my_tz_find(res, thd->lex->time_zone_tables_used))) { my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL"); return 1; @@ -2418,7 +2419,8 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type) if (default_tz_name) { String str(default_tz_name, &my_charset_latin1); - global_system_variables.time_zone= my_tz_find(thd, &str); + global_system_variables.time_zone= + my_tz_find(&str, thd->lex->time_zone_tables_used); } else global_system_variables.time_zone= my_tz_SYSTEM; diff --git a/sql/set_var.h b/sql/set_var.h index a51e44285d6..4a4e631d88c 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -908,6 +908,7 @@ ulong fix_sql_mode(ulong sql_mode); extern sys_var_str sys_charset_system; extern sys_var_str sys_init_connect; extern sys_var_str sys_init_slave; +extern sys_var_thd_time_zone sys_time_zone; CHARSET_INFO *get_old_charset_by_name(const char *old_name); gptr find_named(I_List *list, const char *name, uint length, NAMED_LIST **found); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index dd8283e057a..4efdd3edbcd 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1670,7 +1670,22 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) uint counter; if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter)) DBUG_RETURN(-1); /* purecov: inspected */ - fix_tables_pointers(thd->lex->all_selects_list); + /* + Let us propagate pointers to open tables from global table list + to table lists in particular selects if needed. + */ + if (thd->lex->all_selects_list->next_select_in_list() || + thd->lex->time_zone_tables_used) + { + for (SELECT_LEX *sl= thd->lex->all_selects_list; + sl; + sl= sl->next_select_in_list()) + for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first; + cursor; + cursor=cursor->next) + if (cursor->table_list) + cursor->table= cursor->table_list->table; + } DBUG_RETURN(mysql_handle_derived(thd->lex)); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 949eaba7311..2b6a307092c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -22,6 +22,16 @@ #include #include + +/* + Fake table list object, pointer to which is used as special value for + st_lex::time_zone_tables_used indicating that we implicitly use time + zone tables in this statement but real table list was not yet created. + Pointer to it is also returned by my_tz_get_tables_list() as indication + of transient error; +*/ +TABLE_LIST fake_time_zone_tables_list; + /* Macros to look like lex */ #define yyGet() *(lex->ptr++) @@ -1292,7 +1302,32 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, TABLE_LIST **result_arg) { *result_arg= 0; - res= create_total_list_n_last_return(thd_arg, lex, &result_arg); + if (!(res= create_total_list_n_last_return(thd_arg, lex, &result_arg))) + { + /* + If time zone tables were used implicitly in statement we should add + them to global table list. + */ + if (lex->time_zone_tables_used) + { + /* + Altough we are modifying lex data, it won't raise any problem in + case when this lex belongs to some prepared statement or stored + procedure: such modification does not change any invariants imposed + by requirement to reuse the same lex for multiple executions. + */ + if ((lex->time_zone_tables_used= my_tz_get_table_list(thd)) != + &fake_time_zone_tables_list) + { + *result_arg= lex->time_zone_tables_used; + } + else + { + send_error(thd, 0); + res= 1; + } + } + } return res; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5348d5e5646..053c85166f6 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -633,6 +633,12 @@ typedef struct st_lex bool prepared_stmt_code_is_varref; /* Names of user variables holding parameters (in EXECUTE) */ List prepared_stmt_params; + /* + If points to fake_time_zone_tables_list indicates that time zone + tables are implicitly used by statement, also is used for holding + list of those tables after they are opened. + */ + TABLE_LIST *time_zone_tables_used; st_lex() {} inline void uncacheable(uint8 cause) { @@ -661,6 +667,7 @@ typedef struct st_lex TABLE_LIST *local_first); } LEX; +extern TABLE_LIST fake_time_zone_tables_list; void lex_init(void); void lex_free(void); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b69d582f30b..1182f018ea4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1897,7 +1897,8 @@ mysql_execute_command(THD *thd) #endif } #endif /* !HAVE_REPLICATION */ - if (&lex->select_lex != lex->all_selects_list && + if ((&lex->select_lex != lex->all_selects_list || + lex->time_zone_tables_used) && lex->unit.create_total_list(thd, lex, &tables)) DBUG_VOID_RETURN; @@ -3875,6 +3876,7 @@ mysql_init_query(THD *thd, uchar *buf, uint length) lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; + lex->time_zone_tables_used= 0; lex_start(thd, buf, length); thd->select_number= lex->select_lex.select_number= 1; thd->free_list= 0; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d8deba2c939..db904d24bf7 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1407,7 +1407,8 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) DBUG_PRINT("enter",("command: %d, param_count: %ld", sql_command, stmt->param_count)); - if (select_lex != lex->all_selects_list && + if ((&lex->select_lex != lex->all_selects_list || + lex->time_zone_tables_used) && lex->unit.create_total_list(thd, lex, &tables)) DBUG_RETURN(1); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3b3d8303210..f8bc6210a2f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -213,39 +213,6 @@ int handle_select(THD *thd, LEX *lex, select_result *result) } -void relink_tables(SELECT_LEX *select_lex) -{ - for (TABLE_LIST *cursor= (TABLE_LIST *) select_lex->table_list.first; - cursor; - cursor=cursor->next) - if (cursor->table_list) - cursor->table= cursor->table_list->table; -} - - -void fix_tables_pointers(SELECT_LEX *select_lex) -{ - if (select_lex->next_select_in_list()) - { - /* Fix tables 'to-be-unioned-from' list to point at opened tables */ - for (SELECT_LEX *sl= select_lex; - sl; - sl= sl->next_select_in_list()) - relink_tables(sl); - } -} - -void fix_tables_pointers(SELECT_LEX_UNIT *unit) -{ - for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) - { - relink_tables(sl); - for (SELECT_LEX_UNIT *un= sl->first_inner_unit(); un; un= un->next_unit()) - fix_tables_pointers(un); - } -} - - /* Function to setup clauses without sum functions */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ccbaf7c0112..5d6ca5d5de5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -463,6 +463,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CASE_SYM %token CONCAT %token CONCAT_WS +%token CONVERT_TZ_SYM %token CURDATE %token CURTIME %token DATABASE @@ -2825,6 +2826,11 @@ simple_expr: { $$= new Item_func_concat(* $3); } | CONCAT_WS '(' expr ',' expr_list ')' { $$= new Item_func_concat_ws($3, *$5); } + | CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')' + { + Lex->time_zone_tables_used= &fake_time_zone_tables_list; + $$= new Item_func_convert_tz($3, $5, $7); + } | CURDATE optional_braces { $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; } | CURTIME optional_braces @@ -5308,6 +5314,12 @@ internal_variable_name: $$.var= tmp; $$.base_name.str=0; $$.base_name.length=0; + /* + If this is time_zone variable we should open time zone + describing tables + */ + if (tmp == &sys_time_zone) + Lex->time_zone_tables_used= &fake_time_zone_tables_list; } | ident '.' ident { diff --git a/sql/tztime.cc b/sql/tztime.cc index 2ed55f2fa4e..757272d332f 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1359,6 +1359,13 @@ static bool tz_inited= 0; static uint tz_leapcnt= 0; static LS_INFO *tz_lsis= 0; +/* + Shows whenever we have found time zone tables during start-up. + Used for avoiding of putting those tables to global table list + for queries that use time zone info. +*/ +static bool time_zone_tables_exist= 1; + typedef struct st_tz_names_entry: public Sql_alloc { @@ -1387,6 +1394,68 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, } +/* + Prepare table list with time zone related tables from preallocated array. + + SYNOPSIS + tz_init_table_list() + tz_tabs - pointer to preallocated array of 4 TABLE_LIST objects. + + DESCRIPTION + This function prepares list of TABLE_LIST objects which can be used + for opening of time zone tables from preallocated array. +*/ + +void +tz_init_table_list(TABLE_LIST *tz_tabs) +{ + bzero(tz_tabs, sizeof(TABLE_LIST) * 4); + tz_tabs[0].alias= tz_tabs[0].real_name= (char*)"time_zone_name"; + tz_tabs[1].alias= tz_tabs[1].real_name= (char*)"time_zone"; + tz_tabs[2].alias= tz_tabs[2].real_name= (char*)"time_zone_transition_type"; + tz_tabs[3].alias= tz_tabs[3].real_name= (char*)"time_zone_transition"; + tz_tabs[0].next= tz_tabs+1; + tz_tabs[1].next= tz_tabs+2; + tz_tabs[2].next= tz_tabs+3; + tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type= + tz_tabs[3].lock_type= TL_READ; + tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql"; +} + + +/* + Create table list with time zone related tables. + + SYNOPSIS + my_tz_get_table_list() + thd - current thread object + + DESCRIPTION + This function creates list of TABLE_LIST objects allocated in thd's + memroot, which can be used for opening of time zone tables. + + RETURN VALUES + Returns pointer to first TABLE_LIST object, (could be 0 if time zone + tables don't exist) and &fake_time_zone_tables_list in case of error. +*/ + +TABLE_LIST * +my_tz_get_table_list(THD *thd) +{ + TABLE_LIST *tz_tabs; + + if (!time_zone_tables_exist) + return 0; + + if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4))) + return &fake_time_zone_tables_list; + + tz_init_table_list(tz_tabs); + + return tz_tabs; +} + + /* Initialize time zone support infrastructure. @@ -1399,13 +1468,13 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, DESCRIPTION This function will init memory structures needed for time zone support, it will register mandatory SYSTEM time zone in them. It will try to open - mysql.time_zone_leap_seconds table and and load information which further - will be shared among all time zones loaded. It will also try to load - information about default time zone. If system tables with time zone - descriptions don't exist it won't fail (unless default_tzname is time zone - from tables). If bootstrap parameter is true then this routine assumes that - we are in bootstrap mode and won't load time zone descriptions unless someone - specifies default time zone which is supposedly stored in those tables. + mysql.time_zone* tables and load information about default time zone and + information which further will be shared among all time zones loaded. + If system tables with time zone descriptions don't exist it won't fail + (unless default_tzname is time zone from tables). If bootstrap parameter + is true then this routine assumes that we are in bootstrap mode and won't + load time zone descriptions unless someone specifies default time zone + which is supposedly stored in those tables. It'll also set default time zone if it is specified. RETURN VALUES @@ -1416,14 +1485,13 @@ my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { THD *thd; - TABLE_LIST tables; + TABLE_LIST *tables= 0; + TABLE_LIST tables_buff[5]; TABLE *table; - TABLE *lock_ptr; - MYSQL_LOCK *lock; TZ_NAMES_ENTRY *tmp_tzname; my_bool return_val= 1; int res; - uint not_used; + uint counter; DBUG_ENTER("my_tz_init"); /* @@ -1468,7 +1536,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) if (bootstrap) { /* If we are in bootstrap mode we should not load time zone tables */ - return_val= 0; + return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; } @@ -1480,28 +1548,25 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) thd->db= my_strdup("mysql",MYF(0)); thd->db_length= 5; // Safety - bzero((char*) &tables,sizeof(tables)); - tables.alias= tables.real_name= (char*)"time_zone_leap_second"; - tables.lock_type= TL_READ; - tables.db= thd->db; - - if (open_tables(thd, &tables, ¬_used)) + bzero((char*) &tables_buff, sizeof(TABLE_LIST)); + tables_buff[0].alias= tables_buff[0].real_name= + (char*)"time_zone_leap_second"; + tables_buff[0].lock_type= TL_READ; + tables_buff[0].db= thd->db; + tables_buff[0].next= tables_buff + 1; + /* Fill TABLE_LIST for rest of the time zone describing tables */ + tz_init_table_list(tables_buff + 1); + + if (open_tables(thd, tables_buff, &counter) || + lock_tables(thd, tables_buff, counter)) { - sql_print_error("Warning: Can't open time zone table: %s " + sql_print_error("Warning: Can't open and lock time zone table: %s " "trying to live without them", thd->net.last_error); /* We will try emulate that everything is ok */ - return_val= 0; + return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; } - - lock_ptr= tables.table; - if (!(lock= mysql_lock_tables(thd, &lock_ptr, 1))) - { - sql_print_error("Fatal error: Can't lock time zone table: %s", - thd->net.last_error); - goto end_with_close; - } - + tables= tables_buff + 1; /* Now we are going to load leap seconds descriptions that are shared @@ -1514,11 +1579,16 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { sql_print_error("Fatal error: Out of memory while loading " "mysql.time_zone_leap_second table"); - goto end_with_unlock; + goto end_with_close; } - table= tables.table; - table->file->ha_index_init(0); + table= tables_buff[0].table; + /* + It is OK to ignore ha_index_init()/ha_index_end() return values since + mysql.time_zone* tables are MyISAM and these operations always succeed + for MyISAM. + */ + (void)table->file->ha_index_init(0); tz_leapcnt= 0; res= table->file->index_first(table->record[0]); @@ -1530,7 +1600,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) sql_print_error("Fatal error: While loading mysql.time_zone_leap_second" " table: too much leaps"); table->file->ha_index_end(); - goto end_with_unlock; + goto end_with_close; } tz_lsis[tz_leapcnt].ls_trans= (my_time_t)table->field[0]->val_int(); @@ -1546,13 +1616,13 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) res= table->file->index_next(table->record[0]); } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); if (res != HA_ERR_END_OF_FILE) { sql_print_error("Fatal error: Error while loading " "mysql.time_zone_leap_second table"); - goto end_with_unlock; + goto end_with_close; } /* @@ -1562,19 +1632,12 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) return_val= 0; -end_with_unlock: - mysql_unlock_tables(thd, lock); - -end_with_close: - close_thread_tables(thd); - thd->version--; /* Force close to free memory */ - end_with_setting_default_tz: - /* If not an error and have default time zone try to load it */ - if (!return_val && default_tzname) + /* If we have default time zone try to load it */ + if (default_tzname) { String tzname(default_tzname, &my_charset_latin1); - if (!(global_system_variables.time_zone= my_tz_find(thd, &tzname))) + if (!(global_system_variables.time_zone= my_tz_find(&tzname, tables))) { sql_print_error("Fatal error: Illegal or unknown default time zone '%s'", default_tzname); @@ -1582,6 +1645,10 @@ end_with_setting_default_tz: } } +end_with_close: + thd->version--; /* Force close to free memory */ + close_thread_tables(thd); + end_with_cleanup: /* if there were error free time zone describing structs */ @@ -1625,29 +1692,27 @@ void my_tz_free() Load time zone description from system tables. SYNOPSIS - tz_load_from_db() - thd - current thread object - tz_name - name of time zone that should be loaded. + tz_load_from_open_tables() + tz_name - name of time zone that should be loaded. + tz_tables - list of tables from which time zone description + should be loaded DESCRIPTION - This function will try to open system tables describing time zones - and to load information about time zone specified. It will also update - information in hash used for time zones lookup. + This function will try to load information about time zone specified + from the list of the already opened and locked tables (first table in + tz_tables should be time_zone_name, next time_zone, then + time_zone_transition_type and time_zone_transition should be last). + It will also update information in hash used for time zones lookup. RETURN VALUES Returns pointer to newly created Time_zone object or 0 in case of error. */ + static Time_zone* -tz_load_from_db(THD *thd, const String *tz_name) +tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) { - TABLE_LIST tables[4]; TABLE *table= 0; - TABLE *lock_ptr[4]; - MYSQL_LOCK *lock; - char system_db_name[]= "mysql"; - char *db_save; - uint db_length_save; TIME_ZONE_INFO *tz_info; TZ_NAMES_ENTRY *tmp_tzname; Time_zone *return_val= 0; @@ -1667,9 +1732,8 @@ tz_load_from_db(THD *thd, const String *tz_name) #ifdef ABBR_ARE_USED char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))]; #endif - uint not_used; - DBUG_ENTER("tz_load_from_db"); + DBUG_ENTER("tz_load_from_open_tables"); /* Prepare tz_info for loading also let us make copy of time zone name */ @@ -1689,77 +1753,46 @@ tz_load_from_db(THD *thd, const String *tz_name) */ strmake(tz_name_buff, tz_name->ptr(), tz_name->length()); - /* - Open and lock time zone description tables - */ - db_save= thd->db; - db_length_save= thd->db_length; - thd->db= system_db_name; - thd->db_length= 5; - - bzero((char*) &tables,sizeof(tables)); - tables[0].alias= tables[0].real_name= (char*)"time_zone_name"; - tables[1].alias= tables[1].real_name= (char*)"time_zone"; - tables[2].alias= tables[2].real_name= (char*)"time_zone_transition"; - tables[3].alias= tables[3].real_name= (char*)"time_zone_transition_type"; - tables[0].next= tables+1; - tables[1].next= tables+2; - tables[2].next= tables+3; - tables[0].lock_type= tables[1].lock_type= tables[2].lock_type= - tables[3].lock_type= TL_READ; - tables[0].db= tables[1].db= tables[2].db= tables[3].db= thd->db; - if (open_tables(thd, tables, ¬_used)) - { - sql_print_error("Error: Can't open time zone tables: %s", - thd->net.last_error); - goto end; - } - - lock_ptr[0]= tables[0].table; - lock_ptr[1]= tables[1].table; - lock_ptr[2]= tables[2].table; - lock_ptr[3]= tables[3].table; - if (!(lock= mysql_lock_tables(thd, lock_ptr, 4))) - { - sql_print_error("Error: Can't lock time zone tables: %s", - thd->net.last_error); - goto end_with_close; - } - /* Let us find out time zone id by its name (there is only one index and it is specifically for this purpose). */ - table= tables[0].table; - + table= tz_tables->table; + tz_tables= tz_tables->next; table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); - table->file->ha_index_init(0); + /* + It is OK to ignore ha_index_init()/ha_index_end() return values since + mysql.time_zone* tables are MyISAM and these operations always succeed + for MyISAM. + */ + (void)table->file->ha_index_init(0); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { sql_print_error("Error: Can't find description of time zone."); - goto end_with_unlock; + goto end; } tzid= (uint)table->field[1]->val_int(); - table->file->ha_index_end(); + (void)table->file->ha_index_end(); /* Now we need to lookup record in mysql.time_zone table in order to understand whenever this timezone uses leap seconds (again we are using the only index in this table). */ - table= tables[1].table; + table= tz_tables->table; + tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); - table->file->ha_index_init(0); + (void)table->file->ha_index_init(0); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { sql_print_error("Error: Can't find description of time zone."); - goto end_with_unlock; + goto end; } /* If Uses_leap_seconds == 'Y' */ @@ -1769,7 +1802,7 @@ tz_load_from_db(THD *thd, const String *tz_name) tz_info->lsis= tz_lsis; } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); /* Now we will iterate through records for out time zone in @@ -1777,9 +1810,10 @@ tz_load_from_db(THD *thd, const String *tz_name) only for our time zone guess what are we doing? Right - using special index. */ - table= tables[3].table; + table= tz_tables->table; + tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); - table->file->ha_index_init(0); + (void)table->file->ha_index_init(0); // FIXME Is there any better approach than explicitly specifying 4 ??? res= table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, @@ -1793,7 +1827,7 @@ tz_load_from_db(THD *thd, const String *tz_name) sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table: too big " "transition type id"); - goto end_with_unlock; + goto end; } ttis[ttid].tt_gmtoff= (long)table->field[2]->val_int(); @@ -1807,7 +1841,7 @@ tz_load_from_db(THD *thd, const String *tz_name) sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table: not enough " "room for abbreviations"); - goto end_with_unlock; + goto end; } ttis[ttid].tt_abbrind= tz_info->charcnt; memcpy(chars + tz_info->charcnt, abbr.ptr(), abbr.length()); @@ -1838,10 +1872,10 @@ tz_load_from_db(THD *thd, const String *tz_name) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table"); - goto end_with_unlock; + goto end; } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); /* @@ -1849,9 +1883,9 @@ tz_load_from_db(THD *thd, const String *tz_name) mysql.time_zone_transition table. Here we additionaly need records in ascending order by index scan also satisfies us. */ - table= tables[2].table; + table= tz_tables->table; table->field[0]->store((longlong)tzid); - table->file->ha_index_init(0); + (void)table->file->ha_index_init(0); // FIXME Is there any better approach than explicitly specifying 4 ??? res= table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, @@ -1866,14 +1900,14 @@ tz_load_from_db(THD *thd, const String *tz_name) sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " "too much transitions"); - goto end_with_unlock; + goto end; } if (ttid + 1 > tz_info->typecnt) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " "bad transition type id"); - goto end_with_unlock; + goto end; } ats[tz_info->timecnt]= ttime; @@ -1896,10 +1930,10 @@ tz_load_from_db(THD *thd, const String *tz_name) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table"); - goto end_with_unlock; + goto end; } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); table= 0; /* @@ -1916,7 +1950,7 @@ tz_load_from_db(THD *thd, const String *tz_name) { sql_print_error("Error: Out of memory while loading time zone " "description"); - goto end_with_unlock; + goto end; } @@ -1941,12 +1975,12 @@ tz_load_from_db(THD *thd, const String *tz_name) if (tz_info->typecnt < 1) { sql_print_error("Error: loading time zone without transition types"); - goto end_with_unlock; + goto end; } if (prepare_tz_info(tz_info, &tz_storage)) { sql_print_error("Error: Unable to build mktime map for time zone"); - goto end_with_unlock; + goto end; } @@ -1958,7 +1992,7 @@ tz_load_from_db(THD *thd, const String *tz_name) my_hash_insert(&tz_names, (const byte *)tmp_tzname))) { sql_print_error("Error: Out of memory while loading time zone"); - goto end_with_unlock; + goto end; } /* @@ -1966,19 +2000,11 @@ tz_load_from_db(THD *thd, const String *tz_name) */ return_val= tmp_tzname->tz; -end_with_unlock: +end: if (table) - table->file->ha_index_end(); - - mysql_unlock_tables(thd, lock); + (void)table->file->ha_index_end(); -end_with_close: - close_thread_tables(thd); - -end: - thd->db= db_save; - thd->db_length= db_length_save; DBUG_RETURN(return_val); } @@ -2068,8 +2094,8 @@ str_to_offset(const char *str, uint length, long *offset) SYNOPSIS my_tz_find() - thd - current thread name - time zone specification + tz_tables - list of opened'n'locked time zone describing tables DESCRIPTION This function checks if name is one of time zones described in db, @@ -2091,7 +2117,11 @@ str_to_offset(const char *str, uint length, long *offset) values as parameter without additional external check and this property is used by @@time_zone variable handling code). - It will perform lookup in system tables (mysql.time_zone*) if needed. + It will perform lookup in system tables (mysql.time_zone*) if needed + using tz_tables as list of already opened tables (for info about this + list look at tz_load_from_open_tables() description). It won't perform + such lookup if no time zone describing tables were found during server + start up. RETURN VALUE Pointer to corresponding Time_zone object. 0 - in case of bad time zone @@ -2099,7 +2129,7 @@ str_to_offset(const char *str, uint length, long *offset) */ Time_zone * -my_tz_find(THD *thd, const String * name) +my_tz_find(const String * name, TABLE_LIST *tz_tables) { TZ_NAMES_ENTRY *tmp_tzname; Time_zone *result_tz= 0; @@ -2109,6 +2139,8 @@ my_tz_find(THD *thd, const String * name) DBUG_PRINT("enter", ("time zone name='%s'", name ? ((String *)name)->c_ptr() : "NULL")); + DBUG_ASSERT(!time_zone_tables_exist || tz_tables); + if (!name) DBUG_RETURN(0); @@ -2136,8 +2168,10 @@ my_tz_find(THD *thd, const String * name) (const byte *)name->ptr(), name->length()))) result_tz= tmp_tzname->tz; + else if(time_zone_tables_exist) + result_tz= tz_load_from_open_tables(name, tz_tables); else - result_tz= tz_load_from_db(thd, name); + result_tz= 0; } VOID(pthread_mutex_unlock(&tz_LOCK)); diff --git a/sql/tztime.h b/sql/tztime.h index 69ff176326e..aabec260ec7 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -59,7 +59,8 @@ public: extern Time_zone * my_tz_UTC; extern Time_zone * my_tz_SYSTEM; -extern Time_zone * my_tz_find(THD *thd, const String *name); +extern TABLE_LIST * my_tz_get_table_list(THD *thd); +extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables); extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap); extern void my_tz_free(); -- cgit v1.2.1 From 700c2d621dfc11c6c1c3778ae804a7beca74c553 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Aug 2004 15:48:22 +0600 Subject: BUG#4315 BUG#4535 BUG#4686 mysql-test/r/func_gconcat.result: add testes of blobs and null values mysql-test/t/func_gconcat.test: add testes of blobs and null values sql/item_sum.cc: replace code with maybe_null and change store mode of fields --- sql/item_sum.cc | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 7a8e15e0a9d..b7eb1b7219b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1966,14 +1966,13 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Fix fields for select list and ORDER clause */ - for (i= 0 ; i < arg_count ; i++) + for (uint i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) return 1; - if (i < arg_count_field && args[i]->maybe_null) - maybe_null= 0; + maybe_null |= args[i]->maybe_null; } - + result_field= 0; null_value= 1; max_length= group_concat_max_len; @@ -1993,6 +1992,8 @@ bool Item_func_group_concat::setup(THD *thd) uint const_fields; byte *record; qsort_cmp2 compare_key; + Copy_field *ptr; + Copy_field *end; DBUG_ENTER("Item_func_group_concat::setup"); if (select_lex->linkage == GLOBAL_OPTIONS_TYPE) @@ -2054,6 +2055,16 @@ bool Item_func_group_concat::setup(THD *thd) key_length= table->reclength; record= table->record[0]; + /* + We need to store value of blob in buffer of a record instead of a pointer of + one. + */ + ptr=tmp_table_param->copy_field; + end=tmp_table_param->copy_field_end; + + for (; ptr != end; ptr++) + ptr->set(ptr->to_field,ptr->from_field,1); + /* Offset to first result field in table */ field_list_offset= table->fields - (list.elements - const_fields); -- cgit v1.2.1 From 2c900be0efd39f971e5a9bebfe5c98e12b56058b Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Aug 2004 14:17:32 +0300 Subject: InnoDB: Use create_temp_file() when available innobase/include/os0file.h: Improve the comment of os_file_create_tmpfile() innobase/os/os0file.c: os_file_create_tmpfile(): Use create_temp_file() via innobase_mysql_tmpfile() unless UNIV_HOTBACKUP is defined sql/ha_innodb.cc: Added innobase_mysql_tmpfile(), a wrapper around create_temp_file() --- sql/ha_innodb.cc | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 6319c1494d3..f233dd5a5c5 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -406,6 +406,30 @@ innobase_mysql_print_thd( putc('\n', f); } +/************************************************************************* +Creates a temporary file. */ +extern "C" +int +innobase_mysql_tmpfile(void) +/*========================*/ + /* out: temporary file descriptor, or < 0 on error */ +{ + char filename[FN_REFLEN]; + File fd = create_temp_file(filename, NullS, "ib", +#ifdef __WIN__ + O_BINARY | O_TRUNC | O_SEQUENTIAL | + O_TEMPORARY | O_SHORT_LIVED | +#endif /* __WIN__ */ + O_CREAT | O_EXCL | O_RDWR, + MYF(MY_WME)); +#ifndef __WIN__ + if (fd >= 0) { + unlink(filename); + } +#endif /* !__WIN__ */ + return(fd); +} + /************************************************************************* Gets the InnoDB transaction handle for a MySQL handler object, creates an InnoDB transaction struct if the corresponding MySQL thread struct still -- cgit v1.2.1 From 89017ca5b02a5329be2bcba8e06b5d86bfce39e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 10 Aug 2004 14:38:24 +0200 Subject: Bug fix for bug#3912 --- sql/ha_ndbcluster.cc | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index cd2fb7f3eed..283aa67ddaf 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1281,7 +1281,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) int ha_ndbcluster::write_row(byte *record) { - bool has_auto_increment; + bool has_auto_increment, auto_increment_field_not_null; uint i; NdbConnection *trans= m_active_trans; NdbOperation *op; @@ -1292,7 +1292,8 @@ int ha_ndbcluster::write_row(byte *record) if (table->timestamp_default_now) update_timestamp(record+table->timestamp_default_now-1); has_auto_increment= (table->next_number_field && record == table->record[0]); - if (has_auto_increment) + auto_increment_field_not_null= table->auto_increment_field_not_null; + if ((has_auto_increment) && (!auto_increment_field_not_null)) update_auto_increment(); if (!(op= trans->getNdbOperation(m_tabname))) @@ -1346,11 +1347,14 @@ int ha_ndbcluster::write_row(byte *record) if (trans->execute(NoCommit) != 0) DBUG_RETURN(ndb_err(trans)); } - if ( (has_auto_increment) && (!auto_increment_column_changed) ) - { + if ((has_auto_increment) && (auto_increment_field_not_null)) + { Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1; - DBUG_PRINT("info", ("Setting next auto increment value to %u", next_val)); - m_ndb->setAutoIncrementValue(m_tabname, next_val, true); + DBUG_PRINT("info", + ("Trying to set next auto increment value to %u", next_val)); + if (m_ndb->setAutoIncrementValue(m_tabname, next_val, true)) + DBUG_PRINT("info", + ("Setting next auto increment value to %u", next_val)); } DBUG_RETURN(0); -- cgit v1.2.1 From 8746d743a544154edd9c4884d7a728733da4bec6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 10:27:19 +0200 Subject: allow get_format(TIMESTAMP, ...) syntax --- sql/sql_yacc.yy | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5d6ca5d5de5..8e3fb0884a9 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3533,12 +3533,15 @@ interval: | SECOND_MICROSECOND_SYM { $$=INTERVAL_SECOND_MICROSECOND; } | SECOND_SYM { $$=INTERVAL_SECOND; } | YEAR_MONTH_SYM { $$=INTERVAL_YEAR_MONTH; } - | YEAR_SYM { $$=INTERVAL_YEAR; }; + | YEAR_SYM { $$=INTERVAL_YEAR; } + ; date_time_type: - DATE_SYM {$$=MYSQL_TIMESTAMP_DATE;} - | TIME_SYM {$$=MYSQL_TIMESTAMP_TIME;} - | DATETIME {$$=MYSQL_TIMESTAMP_DATETIME;}; + DATE_SYM {$$=MYSQL_TIMESTAMP_DATE;} + | TIME_SYM {$$=MYSQL_TIMESTAMP_TIME;} + | DATETIME {$$=MYSQL_TIMESTAMP_DATETIME;} + | TIMESTAMP {$$=MYSQL_TIMESTAMP_DATETIME;} + ; table_alias: /* empty */ -- cgit v1.2.1 From cffa34d9fba41ca853e7f11c88e5962382b6219c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 14:03:24 +0500 Subject: ctype_recoding.result, ctype_recoding.test, sql_show.cc: Bug#4417: SHOW CREATE TABLE and SHOW COLUMNS now return consistent results when "SET NAMES BINARY", i.e. everything is sent in UTF8: column names, enum values, default values. sql/sql_show.cc: Bug#4417: SHOW CREATE TABLE and SHOW COLUMNS now return consistent results when "SET NAMES BINARY", i.e. everything is sent in UTF8: column names, enum values, default values. mysql-test/t/ctype_recoding.test: Bug#4417: SHOW CREATE TABLE and SHOW COLUMNS now return consistent results when "SET NAMES BINARY", i.e. everything is sent in UTF8: column names, enum values, default values. mysql-test/r/ctype_recoding.result: Bug#4417: SHOW CREATE TABLE and SHOW COLUMNS now return consistent results when "SET NAMES BINARY", i.e. everything is sent in UTF8: column names, enum values, default values. --- sql/sql_show.cc | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 6d328243a59..57c5f01d0bf 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -651,6 +651,7 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, TABLE *table; handler *file; char tmp[MAX_FIELD_WIDTH]; + char tmp1[MAX_FIELD_WIDTH]; Item *item; Protocol *protocol= thd->protocol; DBUG_ENTER("mysqld_show_fields"); @@ -735,9 +736,24 @@ mysqld_show_fields(THD *thd, TABLE_LIST *table_list,const char *wild, else if (field->unireg_check != Field::NEXT_NUMBER && !field->is_null()) { // Not null by default + /* + Note: we have to convert the default value into + system_charset_info before sending. + This is necessary for "SET NAMES binary": + If the client character set is binary, we want to + send metadata in UTF8 rather than in the column's + character set. + This conversion also makes "SHOW COLUMNS" and + "SHOW CREATE TABLE" output consistent. Without + this conversion the default values were displayed + differently. + */ + String def(tmp1,sizeof(tmp1), system_charset_info); type.set(tmp, sizeof(tmp), field->charset()); field->val_str(&type); - protocol->store(type.ptr(),type.length(),type.charset()); + def.copy(type.ptr(), type.length(), type.charset(), + system_charset_info); + protocol->store(def.ptr(), def.length(), def.charset()); } else if (field->unireg_check == Field::NEXT_NUMBER || field->maybe_null()) -- cgit v1.2.1 From 02b810d238c30ae34f07895f95644e69b34a3fc2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 15:15:37 +0600 Subject: BUG#4315 BUG#4535 BUG#4686 sql/item_sum.cc: Changed code of fix_fields Fixed wrong order of parameters in create_tmp_table Changed value set_sum_field in create_tmp_table --- sql/item_sum.cc | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) (limited to 'sql') diff --git a/sql/item_sum.cc b/sql/item_sum.cc index b7eb1b7219b..c256055d5bb 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1966,13 +1966,14 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Fix fields for select list and ORDER clause */ - for (uint i=0 ; i < arg_count ; i++) + for (i=0 ; i < arg_count ; i++) { if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) return 1; - maybe_null |= args[i]->maybe_null; + if (i < arg_count_field) + maybe_null |= args[i]->maybe_null; } - + result_field= 0; null_value= 1; max_length= group_concat_max_len; @@ -1992,8 +1993,6 @@ bool Item_func_group_concat::setup(THD *thd) uint const_fields; byte *record; qsort_cmp2 compare_key; - Copy_field *ptr; - Copy_field *end; DBUG_ENTER("Item_func_group_concat::setup"); if (select_lex->linkage == GLOBAL_OPTIONS_TYPE) @@ -2044,10 +2043,13 @@ bool Item_func_group_concat::setup(THD *thd) Note that in the table, we first have the ORDER BY fields, then the field list. + + We need to set set_sum_field in true for storing value of blob in buffer + of a record instead of a pointer of one. */ - if (!(table=create_tmp_table(thd, tmp_table_param, all_fields, 0, - 0, 0, 0,select_lex->options | thd->options, - (char *) ""))) + if (!(table=create_tmp_table(thd, tmp_table_param, all_fields, + (ORDER*) 0, 0, TRUE,select_lex->options | thd->options, + HA_POS_ERROR,(char *) ""))) DBUG_RETURN(1); table->file->extra(HA_EXTRA_NO_ROWS); table->no_rows= 1; @@ -2055,16 +2057,6 @@ bool Item_func_group_concat::setup(THD *thd) key_length= table->reclength; record= table->record[0]; - /* - We need to store value of blob in buffer of a record instead of a pointer of - one. - */ - ptr=tmp_table_param->copy_field; - end=tmp_table_param->copy_field_end; - - for (; ptr != end; ptr++) - ptr->set(ptr->to_field,ptr->from_field,1); - /* Offset to first result field in table */ field_list_offset= table->fields - (list.elements - const_fields); -- cgit v1.2.1 From 732ccc5cccffcff1fecf4d6852dde50c13c813b7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 15:06:17 +0200 Subject: Fix for bug#4730 --- sql/ha_ndbcluster.cc | 14 +++++++++----- sql/ha_ndbcluster.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 283aa67ddaf..b6db9b96308 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1281,7 +1281,7 @@ int ha_ndbcluster::define_read_attrs(byte* buf, NdbOperation* op) int ha_ndbcluster::write_row(byte *record) { - bool has_auto_increment, auto_increment_field_not_null; + bool has_auto_increment; uint i; NdbConnection *trans= m_active_trans; NdbOperation *op; @@ -1292,8 +1292,8 @@ int ha_ndbcluster::write_row(byte *record) if (table->timestamp_default_now) update_timestamp(record+table->timestamp_default_now-1); has_auto_increment= (table->next_number_field && record == table->record[0]); - auto_increment_field_not_null= table->auto_increment_field_not_null; - if ((has_auto_increment) && (!auto_increment_field_not_null)) + skip_auto_increment= table->auto_increment_field_not_null; + if ((has_auto_increment) && (!skip_auto_increment)) update_auto_increment(); if (!(op= trans->getNdbOperation(m_tabname))) @@ -1347,7 +1347,7 @@ int ha_ndbcluster::write_row(byte *record) if (trans->execute(NoCommit) != 0) DBUG_RETURN(ndb_err(trans)); } - if ((has_auto_increment) && (auto_increment_field_not_null)) + if ((has_auto_increment) && (skip_auto_increment)) { Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1; DBUG_PRINT("info", @@ -1356,6 +1356,7 @@ int ha_ndbcluster::write_row(byte *record) DBUG_PRINT("info", ("Setting next auto increment value to %u", next_val)); } + skip_auto_increment= true; DBUG_RETURN(0); } @@ -3049,7 +3050,9 @@ longlong ha_ndbcluster::get_auto_increment() rows_to_insert : autoincrement_prefetch; Uint64 auto_value= - m_ndb->getAutoIncrementValue(m_tabname, cache_size); + (skip_auto_increment) ? + m_ndb->readAutoIncrementValue(m_tabname) + : m_ndb->getAutoIncrementValue(m_tabname, cache_size); DBUG_RETURN((longlong)auto_value); } @@ -3074,6 +3077,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): bulk_insert_rows(1024), bulk_insert_not_flushed(false), ops_pending(0), + skip_auto_increment(true), blobs_buffer(0), blobs_buffer_size(0) { diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 31dd9a52331..a207e974a16 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -223,6 +223,7 @@ class ha_ndbcluster: public handler ha_rows bulk_insert_rows; bool bulk_insert_not_flushed; ha_rows ops_pending; + bool skip_auto_increment; bool blobs_pending; // memory for blobs in one tuple char *blobs_buffer; -- cgit v1.2.1 From b0fcf80b23c52bb44e91537d69d5ae2c43a3bfe2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 18:55:12 +0500 Subject: fixed Bug #4973 Memory is not released when HEAP table is dropped sql/ha_heap.cc: added calling fn_format(name,..) for name before heap_delete_table as it's done before heap_create fixed Bug #4973 Memory is not released when HEAP table is dropped --- sql/ha_heap.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index eb4bf517374..5aa42fa1beb 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -264,7 +264,8 @@ THR_LOCK_DATA **ha_heap::store_lock(THD *thd, int ha_heap::delete_table(const char *name) { - int error=heap_delete_table(name); + char buff[FN_REFLEN]; + int error= heap_delete_table(fn_format(buff,name,"","",4+2)); return error == ENOENT ? 0 : error; } -- cgit v1.2.1 From b37a73611024d78de35145c5f6cb394a7c3f225c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 23:08:20 +0400 Subject: Fix for BUG#4488: first portion: sign aware '<' and '>' comparisons. --- sql/item.h | 6 ++-- sql/item_cmpfunc.cc | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/item_cmpfunc.h | 3 ++ 3 files changed, 94 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item.h b/sql/item.h index e1bed6bd1d8..6900fa11b90 100644 --- a/sql/item.h +++ b/sql/item.h @@ -862,7 +862,7 @@ public: }; /* - The following class is used to optimize comparing of date columns + The following class is used to optimize comparing of date and bigint columns We need to save the original item, to be able to set the field to the original value in 'opt_range'. */ @@ -872,7 +872,9 @@ class Item_int_with_ref :public Item_int Item *ref; public: Item_int_with_ref(longlong i, Item *ref_arg) :Item_int(i), ref(ref_arg) - {} + { + unsigned_flag= ref_arg->unsigned_flag; + } int save_in_field(Field *field, bool no_conversions) { return ref->save_in_field(field, no_conversions); diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 14c0d996360..e7531e17d34 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -315,6 +315,17 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) func= &Arg_comparator::compare_e_binary_string; } } + else if (type == INT_RESULT) + { + if (func == &Arg_comparator::compare_int) + { + if ((*a)->unsigned_flag) + func= ((*b)->unsigned_flag)? &Arg_comparator::compare_int_unsigned : + &Arg_comparator::compare_int_unsigned_signed; + else if ((*b)->unsigned_flag) + func= &Arg_comparator::compare_int_signed_unsigned; + } + } return 0; } @@ -434,6 +445,82 @@ int Arg_comparator::compare_int() return -1; } + +/* + Compare values as BIGINT UNSIGNED. +*/ + +int Arg_comparator::compare_int_unsigned() +{ + ulonglong val1= (*a)->val_int(); + if (!(*a)->null_value) + { + ulonglong val2= (*b)->val_int(); + if (!(*b)->null_value) + { + owner->null_value= 0; + if (val1 < val2) return -1; + if (val1 == val2) return 0; + return 1; + } + } + owner->null_value= 1; + return -1; +} + + +/* + Compare signed (*a) with unsigned (*B) +*/ + +int Arg_comparator::compare_int_signed_unsigned() +{ + longlong sval1= (*a)->val_int(); + if (!(*a)->null_value) + { + ulonglong uval2= (ulonglong)(*b)->val_int(); + if (!(*b)->null_value) + { + owner->null_value= 0; + if (sval1 < 0 || (ulonglong)sval1 < uval2) + return -1; + if ((ulonglong)sval1 == uval2) + return 0; + return 1; + } + } + owner->null_value= 1; + return -1; +} + + +/* + Compare unsigned (*a) with signed (*B) +*/ + +int Arg_comparator::compare_int_unsigned_signed() +{ + ulonglong uval1= (ulonglong)(*a)->val_int(); + if (!(*a)->null_value) + { + longlong sval2= (*b)->val_int(); + if (!(*b)->null_value) + { + owner->null_value= 0; + if (sval2 < 0) + return 1; + if (uval1 < (ulonglong)sval2) + return -1; + if (uval1 == (ulonglong)sval2) + return 0; + return 1; + } + } + owner->null_value= 1; + return -1; +} + + int Arg_comparator::compare_e_int() { longlong val1= (*a)->val_int(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7c96226b08a..de2b5e84038 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -66,6 +66,9 @@ public: int compare_binary_string(); // compare args[0] & args[1] int compare_real(); // compare args[0] & args[1] int compare_int(); // compare args[0] & args[1] + int compare_int_signed_unsigned(); + int compare_int_unsigned_signed(); + int compare_int_unsigned(); int compare_row(); // compare args[0] & args[1] int compare_e_string(); // compare args[0] & args[1] int compare_e_binary_string(); // compare args[0] & args[1] -- cgit v1.2.1 From ab64eb64af00da22dad43bb4ea4f0d2dfe51438a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 23:43:41 +0200 Subject: Bug #4797 - 32 bit and 64 bit builds behave differently on int32 overflow include/my_global.h: uint_max constants moved from sql_analyse.cc sql/sql_analyse.cc: cleanup --- sql/field.cc | 29 +++++++++++++++++++++++++++-- sql/sql_analyse.cc | 3 --- 2 files changed, 27 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index e3bdf78e718..946f5ed8621 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1504,7 +1504,7 @@ void Field_long::store(const char *from,uint len) { len--; from++; } - long tmp; + long tmp, cuted_fields=0; String tmp_str(from,len); from= tmp_str.c_ptr(); // Add end null if needed errno=0; @@ -1520,9 +1520,34 @@ void Field_long::store(const char *from,uint len) } else tmp=strtol(from, &end, 10); - if (errno || + if (errno || (from+len != end && current_thd->count_cuted_fields && !test_if_int(from,len))) + cuted_fields=1; +#if SIZEOF_LONG > 4 + if (unsigned_flag) + { + if (tmp > UINT_MAX32) + { + tmp= UINT_MAX32; + cuted_fields=1; + } + } + else + { + if (tmp > INT_MAX32) + { + tmp= INT_MAX32; + cuted_fields=1; + } + else if (tmp < INT_MIN32) + { + tmp= INT_MIN32; + cuted_fields=1; + } + } +#endif + if (cuted_fields) current_thd->cuted_fields++; #ifdef WORDS_BIGENDIAN if (table->db_low_byte_first) diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc index bd8c0e5ba87..3847849d6a7 100644 --- a/sql/sql_analyse.cc +++ b/sql/sql_analyse.cc @@ -34,9 +34,6 @@ #define MAX_TREEMEM 8192 #define MAX_TREE_ELEMENTS 256 -#define UINT_MAX16 0xffff -#define UINT_MAX24 0xffffff -#define UINT_MAX32 0xffffffff int sortcmp2(void* cmp_arg __attribute__((unused)), const String *a,const String *b) -- cgit v1.2.1 From 4f08c4b72686a258800d950293e2a9827879707e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Aug 2004 23:24:36 +0100 Subject: Bug#4411 Fix for server hang bug mysql-test/r/heap.result: Bug#4411 Test for server hang bug mysql-test/t/heap.test: Bug#4411 Test for server hang bug sql/opt_sum.cc: Bug#4411 Allow code to exit the loop. BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/opt_sum.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index b5eec2d5dd4..0831c375f7a 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -401,6 +401,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) /* Can't use this key, for looking up min() or max(), end if last one */ if (key == 1) return 0; + key>>=1; idx++; } ref->key_length=0; ref->key=idx; -- cgit v1.2.1 From bb10ca26ec92adc7caaafe63468ba56bb48a53a6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 09:41:35 +0500 Subject: A fix (Bug#4898: User privileges depending on ORDER BY Settings of table db) --- sql/sql_acl.cc | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4af6f407b57..58d0fe9a7fa 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -460,22 +460,30 @@ static ulong get_sort(uint count,...) va_start(args,count); ulong sort=0; + /* Should not use this function with more than 4 arguments for compare. */ + DBUG_ASSERT(count <= 4); + while (count--) { - char *str=va_arg(args,char*); - uint chars=0,wild=0; + char *start, *str= va_arg(args,char*); + uint chars= 0; + uint wild_pos= 0; /* first wildcard position */ - if (str) + if (start= str) { for (; *str ; str++) { if (*str == wild_many || *str == wild_one || *str == wild_prefix) - wild++; + { + wild_pos= str - start + 1; + break; + } else chars++; } } - sort= (sort << 8) + (wild ? 1 : chars ? 2 : 0); + sort= (sort << 8) + (wild_pos ? (wild_pos > 127 ? 127 : wild_pos) : + (chars ? 128 : 0)); } va_end(args); return sort; -- cgit v1.2.1 From 0ce3a41e71a94ac68ea3765eb19641041b0e296b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 10:46:16 +0500 Subject: Bug#5005 collation cp852_bin makes server crash ctype-simple.c: Check that unicode map was loaded cp852.xml: Missing cp852_bin was added. sql/share/charsets/cp852.xml: Missing cp852_bin was added. strings/ctype-simple.c: Check that unicode map was loaded --- sql/share/charsets/cp852.xml | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sql') diff --git a/sql/share/charsets/cp852.xml b/sql/share/charsets/cp852.xml index ee434859233..958587d0399 100644 --- a/sql/share/charsets/cp852.xml +++ b/sql/share/charsets/cp852.xml @@ -114,6 +114,8 @@ + + -- cgit v1.2.1 From a7d2c573f11d928269ee3097edd73b8fd5adae76 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 11:28:39 +0500 Subject: A fix (Bug #4878: Service crashes on query execution) --- sql/item_strfunc.cc | 5 ++++- sql/sql_string.h | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d3493e1fad1..995627766c0 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -984,7 +984,10 @@ String *Item_func_left::val_str(String *str) return &my_empty_string; if (res->length() <= (uint) length) return res; - str_value.set(*res, 0, res->charpos(length)); + if (&str_value == res) + str_value.length(res->charpos(length)); + else + str_value.set(*res, 0, res->charpos(length)); return &str_value; } diff --git a/sql/sql_string.h b/sql/sql_string.h index 01329c45a98..0179b3ebadc 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -98,6 +98,7 @@ public: void set(String &str,uint32 offset,uint32 arg_length) { + DBUG_ASSERT(&str != this); free(); Ptr=(char*) str.ptr()+offset; str_length=arg_length; alloced=0; if (str.Alloced_length) -- cgit v1.2.1 From 090bc713a4ebae95ac07a862800a69e723833b29 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 00:02:29 -0700 Subject: olap.test, olap.result: Added test case for bug #4767. item_sum.cc: Added a correct setting of the maybe_null flag for a copy of an Item_sum object where the argument was a field of an inner table in an outer join read from a temporary table. It's part of the fix for bug #4767. sql_select.cc: Made change_refs_to_tmp_fields work correctly for test case of bug #4767 where Item_sum::get_tmp_table_item failed to build a correct copy of an Item_sum object referring to a field in a temporary table. It looks like a hack yet. sql/sql_select.cc: Made change_refs_to_tmp_fields work correctly for test case of bug #4767 where Item_sum::get_tmp_table_item failed to build a copy of an Item_sum object referring to a field in a temporary table. It looks like a hack yet. sql/item_sum.cc: Added a correct setting of maybe_null flag for copy of a Item_sum object where there argument is a field of nullable table read from the temporary table. It's part of the fix for bug #4767. mysql-test/r/olap.result: Added test case for bug #4767. mysql-test/t/olap.test: Added test case for bug #4767. --- sql/item_sum.cc | 3 +++ sql/sql_select.cc | 2 ++ 2 files changed, 5 insertions(+) (limited to 'sql') diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 7a8e15e0a9d..8411e7d1b9b 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -159,7 +159,10 @@ Item *Item_sum::get_tmp_table_item(THD *thd) if (!arg->const_item()) { if (arg->type() == Item::FIELD_ITEM) + { + arg->maybe_null= result_field_tmp->maybe_null(); ((Item_field*) arg)->field= result_field_tmp++; + } else sum_item->args[i]= new Item_field(result_field_tmp++); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f8bc6210a2f..87b869df658 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4995,6 +4995,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, blob_count++; } ((Item_sum*) item)->args[i]= new Item_field(new_field); + if (((Item_sum*) item)->arg_count == 1) + ((Item_sum*) item)->result_field= new_field; } } } -- cgit v1.2.1 From c190de541fb2b278dbfd380dd1c6ebe01b2e9fea Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 09:40:32 +0200 Subject: bug#4997 - --log-error sometimes generates incorrect default name. Now replacing domain name by 'err'. If host name doesn't have a domain name, '.err' is appended as before. --- sql/mysqld.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c81a888d2e9..48a2e1fbc71 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2535,7 +2535,8 @@ server."); if (opt_error_log) { if (!log_error_file_ptr[0]) - fn_format(log_error_file, glob_hostname, mysql_data_home, ".err", 0); + fn_format(log_error_file, glob_hostname, mysql_data_home, ".err", + MY_REPLACE_EXT); /* replace '.' by '.err', bug#4997 */ else fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err", MY_UNPACK_FILENAME | MY_SAFE_PATH); -- cgit v1.2.1 From f6e5d6ce9dc3f367cb7c665bca94316ee31cf384 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 13:12:09 +0200 Subject: Fix for BUG#4678 "mysql-test-run fails on grant_cache": do not use '' as user in tests, because it picks the Unix login (which gives unexpected results if it is 'root') (such behaviour is a feature of mysql_real_connect(), see the manual). mysql-test/t/grant_cache.test: do not use '' as user in tests, because it picks the Unix login (which gives unexpected results if it is 'root'). sql/slave.cc: a comment --- sql/slave.cc | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sql') diff --git a/sql/slave.cc b/sql/slave.cc index 7e46fb81053..0fe525d766f 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1236,6 +1236,12 @@ not always make sense; please check the manual before using it)."; /* Check that the master's global character_set_server and ours are the same. Not fatal if query fails (old master?). + Note that we don't check for equality of global character_set_client and + collation_connection (neither do we prevent their setting in + set_var.cc). That's because from what I (Guilhem) have tested, the global + values of these 2 are never used (new connections don't use them). + We don't test equality of global collation_database either as it's is + going to be deprecated (made read-only) in 4.1 very soon. */ if (!mysql_real_query(mysql, "SELECT @@GLOBAL.COLLATION_SERVER", 32) && (master_res= mysql_store_result(mysql))) -- cgit v1.2.1 From e03c854011f8f2d6458e790985ec6b7286565350 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 08:47:45 -0500 Subject: mysqld.cc: Help message edit. sql/mysqld.cc: Help message edit. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 48a2e1fbc71..e184be4111a 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4224,7 +4224,7 @@ Disable with --skip-isam.", "Log updates to file.# where # is a unique number if not given.", (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"log-warnings", 'W', "Log some not critical warnings to the log file. Use this option twice, or --log-warnings=2 if you want 'Aborted connections' warning to be logged in the error log file.", + {"log-warnings", 'W', "Log some non-critical warnings to the error log file. Use this option twice or --log-warnings=2 if you also want 'Aborted connections' warnings.", (gptr*) &global_system_variables.log_warnings, (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, 0, 0, 0}, -- cgit v1.2.1 From 694103472b92b91e5d3f35b565f9d64b290fa8e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 17:31:23 +0300 Subject: in case of compound index fill all parts in optimized IN (BUG#4435) mysql-test/r/subselect.result: Optimized IN with compound index test mysql-test/t/subselect.test: Optimized IN with compound index test sql/item_subselect.cc: in case of compound index fill all parts --- sql/item_subselect.cc | 125 ++++++++++++++++++++++++++------------------------ 1 file changed, 64 insertions(+), 61 deletions(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8c4dae92ddc..36f5c891186 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1243,29 +1243,31 @@ int subselect_uniquesubquery_engine::exec() DBUG_ENTER("subselect_uniquesubquery_engine::exec"); int error; TABLE *table= tab->table; - if ((tab->ref.key_err= (*tab->ref.key_copy)->copy())) + for (store_key **copy=tab->ref.key_copy ; *copy ; copy++) { - table->status= STATUS_NOT_FOUND; - error= -1; + if (tab->ref.key_err= (*copy)->copy()) + { + table->status= STATUS_NOT_FOUND; + DBUG_RETURN(1); + } } + + if (!table->file->inited) + table->file->ha_index_init(tab->ref.key); + error= table->file->index_read(table->record[0], + tab->ref.key_buff, + tab->ref.key_length,HA_READ_KEY_EXACT); + if (error && error != HA_ERR_KEY_NOT_FOUND) + error= report_error(table, error); else { - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key); - error= table->file->index_read(table->record[0], - tab->ref.key_buff, - tab->ref.key_length,HA_READ_KEY_EXACT); - if (error && error != HA_ERR_KEY_NOT_FOUND) - error= report_error(table, error); - else - { - error= 0; - table->null_row= 0; - ((Item_in_subselect *) item)->value= (!table->status && - (!cond || cond->val_int()) ? 1 : - 0); - } + error= 0; + table->null_row= 0; + ((Item_in_subselect *) item)->value= (!table->status && + (!cond || cond->val_int()) ? 1 : + 0); } + DBUG_RETURN(error != 0); } @@ -1293,55 +1295,56 @@ int subselect_indexsubquery_engine::exec() ((Item_in_subselect *) item)->was_null= 0; } - if ((*tab->ref.key_copy) && (tab->ref.key_err= (*tab->ref.key_copy)->copy())) + for (store_key **copy=tab->ref.key_copy ; *copy ; copy++) { - table->status= STATUS_NOT_FOUND; - error= -1; + if (tab->ref.key_err= (*copy)->copy()) + { + table->status= STATUS_NOT_FOUND; + DBUG_RETURN(1); + } } + + if (!table->file->inited) + table->file->ha_index_init(tab->ref.key); + error= table->file->index_read(table->record[0], + tab->ref.key_buff, + tab->ref.key_length,HA_READ_KEY_EXACT); + if (error && error != HA_ERR_KEY_NOT_FOUND) + error= report_error(table, error); else { - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key); - error= table->file->index_read(table->record[0], - tab->ref.key_buff, - tab->ref.key_length,HA_READ_KEY_EXACT); - if (error && error != HA_ERR_KEY_NOT_FOUND) - error= report_error(table, error); - else + for (;;) { - for (;;) + error= 0; + table->null_row= 0; + if (!table->status) { - error= 0; - table->null_row= 0; - if (!table->status) - { - if (!cond || cond->val_int()) - { - if (null_finding) - ((Item_in_subselect *) item)->was_null= 1; - else - ((Item_in_subselect *) item)->value= 1; - break; - } - error= table->file->index_next_same(table->record[0], - tab->ref.key_buff, - tab->ref.key_length); - if (error && error != HA_ERR_END_OF_FILE) - { - error= report_error(table, error); - break; - } - } - else - { - if (!check_null || null_finding) - break; /* We don't need to check nulls */ - *tab->ref.null_ref_key= 1; - null_finding= 1; - /* Check if there exists a row with a null value in the index */ - if ((error= (safe_index_read(tab) == 1))) - break; - } + if (!cond || cond->val_int()) + { + if (null_finding) + ((Item_in_subselect *) item)->was_null= 1; + else + ((Item_in_subselect *) item)->value= 1; + break; + } + error= table->file->index_next_same(table->record[0], + tab->ref.key_buff, + tab->ref.key_length); + if (error && error != HA_ERR_END_OF_FILE) + { + error= report_error(table, error); + break; + } + } + else + { + if (!check_null || null_finding) + break; /* We don't need to check nulls */ + *tab->ref.null_ref_key= 1; + null_finding= 1; + /* Check if there exists a row with a null value in the index */ + if ((error= (safe_index_read(tab) == 1))) + break; } } } -- cgit v1.2.1 From 7e5247aadeeaddc08f0d2c4405095e3c19e3a0a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 20:37:31 +0500 Subject: fixed Bug #4358 Problem with HAVING clause that uses alias from the select list and TEXT field make setup_copy_fields to insert Item_copy_string for blobs in the beginning of the copy_funcs (push_back instead of push_front) the thing is that Item_copy_string::copy for function can call Item_copy_string::val_int for blob via Item_ref. But if Item_copy_string::copy for blob isn't called before, it's value will be wrong. So all the Item_copy_string::copy for blobs should be called before Item_copy_string::copy for functions. mysql-test/r/having.result: added test case for Bug #4358 Problem with HAVING clause that uses alias from the select list and TEXT field mysql-test/t/having.test: added test case for Bug #4358 Problem with HAVING clause that uses alias from the select list and TEXT field sql/sql_select.cc: make setup_copy_fields to insert Item_copy_string for blobs in the beginning of the copy_funcs (push_back instead of push_front) the thing is that Item_copy_string::copy for function can call Item_copy_string::val_int for blob via Item_ref. But if Item_copy_string::copy for blob isn't called before, it's value will be wrong. So all the Item_copy_string::copy for blobs should be called before Item_copy_string::copy for functions. fixed Bug #4358 Problem with HAVING clause that uses alias from the select list and TEXT field --- sql/sql_select.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 096b73c482f..8c30a1684b4 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7158,7 +7158,16 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param, List &fields) if (!(pos=new Item_copy_string(pos))) goto err; VOID(li.replace(pos)); - if (param->copy_funcs.push_back(pos)) + /* + Item_copy_string::copy for function can call + Item_copy_string::val_int for blob via Item_ref. + But if Item_copy_string::copy for blob isn't called before, + it's value will be wrong + so let's insert Item_copy_string for blobs in the beginning of + copy_funcs + (to see full test case look at having.test, BUG #4358) + */ + if (param->copy_funcs.push_front(pos)) goto err; continue; } -- cgit v1.2.1 From 89987fa1044438f01c4a2efdf5563ec1c50a2102 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Aug 2004 20:57:18 -0700 Subject: This is the addition of the CSV engine "aka tina". Its an example engine that works as a plain text file. acconfig.h: Adding HAVE CSV rule acinclude.m4: Build option of csv engine configure.in: Update for building CSV sql/Makefile.am: Added files for CSV build sql/handler.cc: Needed options for CSV to be created. sql/handler.h: CSV type engine enum. sql/mysql_priv.h: Addition of the have_csv_db variable. sql/mysqld.cc: Code to show csv option. sql/set_var.cc: Adding have show variables for both csv and example. --- sql/Makefile.am | 6 +- sql/examples/ha_tina.cc | 846 ++++++++++++++++++++++++++++++++++++++++++++++++ sql/examples/ha_tina.h | 132 ++++++++ sql/handler.cc | 9 + sql/handler.h | 2 +- sql/mysql_priv.h | 2 +- sql/mysqld.cc | 7 +- sql/set_var.cc | 2 + 8 files changed, 1001 insertions(+), 5 deletions(-) create mode 100644 sql/examples/ha_tina.cc create mode 100644 sql/examples/ha_tina.h (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index 007239f2e8c..e2d857aaa96 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -59,7 +59,8 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.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 tzfile.h \ - tztime.h examples/ha_example.h examples/ha_archive.h + tztime.h examples/ha_example.h examples/ha_archive.h \ + examples/ha_tina.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ item.cc item_sum.cc item_buff.cc item_func.cc \ item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \ @@ -90,7 +91,8 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ stacktrace.c repl_failsafe.h repl_failsafe.cc \ gstream.cc spatial.cc sql_help.cc protocol_cursor.cc \ tztime.cc my_time.c \ - examples/ha_example.cc examples/ha_archive.cc + examples/ha_example.cc examples/ha_archive.cc \ + examples/ha_tina.cc gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc new file mode 100644 index 00000000000..728af469bb0 --- /dev/null +++ b/sql/examples/ha_tina.cc @@ -0,0 +1,846 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* + Make sure to look at ha_tina.h for more details. + + First off, this is a play thing for me, there are a number of things wrong with it: + *) It was designed for csv and therefor its performance is highly questionable. + *) Indexes have not been implemented. This is because the files can be traded in + and out of the table directory without having to worry about rebuilding anything. + *) NULLs and "" are treated equally (like a spreadsheet). + *) There was in the beginning no point to anyone seeing this other then me, so there + is a good chance that I haven't quite documented it well. + *) Less design, more "make it work" + + Now there are a few cool things with it: + *) Errors can result in corrupted data files. + *) Data files can be read by spreadsheets directly. + +TODO: + *) Move to a block system for larger files + *) Error recovery, its all there, just need to finish it + *) Document how the chains work. + + -Brian +*/ + +#ifdef __GNUC__ +#pragma implementation // gcc: Class implementation +#endif + +#include "mysql_priv.h" +#include "ha_tina.h" +#include + +/* Stuff for shares */ +pthread_mutex_t tina_mutex; +static HASH tina_open_tables; +static int tina_init= 0; + +/***************************************************************************** + ** TINA tables + *****************************************************************************/ + +/* + Used for sorting chains. +*/ +int sort_set (tina_set *a, tina_set *b) +{ + return ( a->begin > b->begin ? 1 : ( a->begin < b->begin ? -1 : 0 ) ); +} + +static byte* tina_get_key(TINA_SHARE *share,uint *length, + my_bool not_used __attribute__((unused))) +{ + *length=share->table_name_length; + return (byte*) share->table_name; +} + +/* + Reloads the mmap file. +*/ +int get_mmap(TINA_SHARE *share, int write) +{ + DBUG_ENTER("ha_tina::get_mmap"); + if (share->mapped_file && munmap(share->mapped_file, share->file_stat.st_size)) + DBUG_RETURN(1); + + if (my_fstat(share->data_file, &share->file_stat, MYF(MY_WME)) == -1) + DBUG_RETURN(1); + + if (share->file_stat.st_size) + { + if (write) + share->mapped_file= (byte *)mmap(NULL, share->file_stat.st_size, + PROT_READ|PROT_WRITE, MAP_SHARED, + share->data_file, 0); + else + share->mapped_file= (byte *)mmap(NULL, share->file_stat.st_size, + PROT_READ, MAP_PRIVATE, + share->data_file, 0); + if ((share->mapped_file ==(caddr_t)-1)) + { + /* + Bad idea you think? See the problem is that nothing actually checks + the return value of ::rnd_init(), so tossing an error is about + it for us. + Never going to happen right? :) + */ + my_message(errno, "Woops, blew up opening a mapped file", 0); + DBUG_ASSERT(0); + DBUG_RETURN(1); + } + } + else + share->mapped_file= NULL; + + DBUG_RETURN(0); +} + +/* + Simple lock controls. +*/ +static TINA_SHARE *get_share(const char *table_name, TABLE *table) +{ + TINA_SHARE *share; + char *tmp_name; + uint length; + + if (!tina_init) + { + /* Hijack a mutex for init'ing the storage engine */ + pthread_mutex_lock(&LOCK_mysql_create_db); + if (!tina_init) + { + tina_init++; + VOID(pthread_mutex_init(&tina_mutex,MY_MUTEX_INIT_FAST)); + (void) hash_init(&tina_open_tables,system_charset_info,32,0,0, + (hash_get_key) tina_get_key,0,0); + } + pthread_mutex_unlock(&LOCK_mysql_create_db); + } + pthread_mutex_lock(&tina_mutex); + length=(uint) strlen(table_name); + if (!(share=(TINA_SHARE*) hash_search(&tina_open_tables, + (byte*) table_name, + length))) + { + char data_file_name[FN_REFLEN]; + if (!my_multi_malloc(MYF(MY_WME | MY_ZEROFILL), + &share, sizeof(*share), + &tmp_name, length+1, + NullS)) + { + pthread_mutex_unlock(&tina_mutex); + return NULL; + } + + share->use_count=0; + share->table_name_length=length; + share->table_name=tmp_name; + strmov(share->table_name,table_name); + fn_format(data_file_name, table_name, "", ".CSV",MY_REPLACE_EXT|MY_UNPACK_FILENAME); + if (my_hash_insert(&tina_open_tables, (byte*) share)) + goto error; + thr_lock_init(&share->lock); + pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST); + + if ((share->data_file= my_open(data_file_name, O_RDWR, MYF(0))) == -1) + goto error2; + + /* We only use share->data_file for writing, so we scan to the end to append */ + if (my_seek(share->data_file, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR) + goto error2; + + share->mapped_file= NULL; // We don't know the state since we just allocated it + if (get_mmap(share, 0) > 0) + goto error3; + } + share->use_count++; + pthread_mutex_unlock(&tina_mutex); + + return share; + +error3: + my_close(share->data_file,MYF(0)); +error2: + thr_lock_delete(&share->lock); + pthread_mutex_destroy(&share->mutex); +error: + pthread_mutex_unlock(&tina_mutex); + my_free((gptr) share, MYF(0)); + + return NULL; +} + + +/* + Free lock controls. +*/ +static int free_share(TINA_SHARE *share) +{ + DBUG_ENTER("ha_tina::free_share"); + pthread_mutex_lock(&tina_mutex); + int result_code= 0; + if (!--share->use_count){ + /* Drop the mapped file */ + if (share->mapped_file) + munmap(share->mapped_file, share->file_stat.st_size); + result_code= my_close(share->data_file,MYF(0)); + hash_delete(&tina_open_tables, (byte*) share); + thr_lock_delete(&share->lock); + pthread_mutex_destroy(&share->mutex); + my_free((gptr) share, MYF(0)); + } + pthread_mutex_unlock(&tina_mutex); + + DBUG_RETURN(result_code); +} + + +/* + Finds the end of a line. + Currently only supports files written on a UNIX OS. +*/ +byte * find_eoln(byte *data, off_t begin, off_t end) +{ + for (off_t x= begin; x < end; x++) + if (data[x] == '\n') + return data + x; + + return 0; +} + +/* + Encode a buffer into the quoted format. +*/ +int ha_tina::encode_quote(byte *buf) +{ + char attribute_buffer[1024]; + String attribute(attribute_buffer, sizeof(attribute_buffer), &my_charset_bin); + + buffer.length(0); + for (Field **field=table->field ; *field ; field++) + { + const char *ptr; + const char *end_ptr; + + (*field)->val_str(&attribute,&attribute); + ptr= attribute.ptr(); + end_ptr= attribute.length() + ptr; + + buffer.append('"'); + + while (ptr < end_ptr) + { + if (*ptr == '"') + { + buffer.append('\\'); + buffer.append('"'); + *ptr++; + } + else if (*ptr == '\r') + { + buffer.append('\\'); + buffer.append('r'); + *ptr++; + } + else if (*ptr == '\\') + { + buffer.append('\\'); + buffer.append('\\'); + *ptr++; + } + else if (*ptr == '\n') + { + buffer.append('\\'); + buffer.append('n'); + *ptr++; + } + else + buffer.append(*ptr++); + } + buffer.append('"'); + buffer.append(','); + } + // Remove the comma, add a line feed + buffer.length(buffer.length() - 1); + buffer.append('\n'); + //buffer.replace(buffer.length(), 0, "\n", 1); + + return (buffer.length()); +} + +/* + chain_append() adds delete positions to the chain that we use to keep track of space. +*/ +int ha_tina::chain_append() +{ + if ( chain_ptr != chain && (chain_ptr -1)->end == current_position) + (chain_ptr -1)->end= next_position; + else + { + /* We set up for the next position */ + if ((off_t)(chain_ptr - chain) == (chain_size -1)) + { + off_t location= chain_ptr - chain; + chain_size += DEFAULT_CHAIN_LENGTH; + if (chain_alloced) + { + /* Must cast since my_malloc unlike malloc doesn't have a void ptr */ + if ((chain= (tina_set *)my_realloc((gptr)chain,chain_size,MYF(MY_WME))) == NULL) + return -1; + } + else + { + tina_set *ptr= (tina_set *)my_malloc(chain_size * sizeof(tina_set),MYF(MY_WME)); + memcpy(ptr, chain, DEFAULT_CHAIN_LENGTH * sizeof(tina_set)); + chain= ptr; + chain_alloced++; + } + chain_ptr= chain + location; + } + chain_ptr->begin= current_position; + chain_ptr->end= next_position; + chain_ptr++; + } + + return 0; +} + + +/* + Scans for a row. +*/ +int ha_tina::find_current_row(byte *buf) +{ + byte *mapped_ptr= (byte *)share->mapped_file + current_position; + byte *end_ptr; + DBUG_ENTER("ha_tina::find_current_row"); + + /* EOF should be counted as new line */ + if ((end_ptr= find_eoln(share->mapped_file, current_position, share->file_stat.st_size)) == 0) + DBUG_RETURN(HA_ERR_END_OF_FILE); + + for (Field **field=table->field ; *field ; field++) + { + int x; + buffer.length(0); + mapped_ptr++; // Increment past the first quote + for(;mapped_ptr != end_ptr; mapped_ptr++) + { + //Need to convert line feeds! + if (*mapped_ptr == '"' && + (((mapped_ptr[1] == ',') && (mapped_ptr[2] == '"')) || (mapped_ptr == end_ptr -1 ))) + { + mapped_ptr += 2; // Move past the , and the " + break; + } + if (*mapped_ptr == '\\' && mapped_ptr != (end_ptr - 1)) + { + mapped_ptr++; + if (*mapped_ptr == 'r') + buffer.append('\r'); + else if (*mapped_ptr == 'n' ) + buffer.append('\n'); + else if ((*mapped_ptr == '\\') || (*mapped_ptr == '"')) + buffer.append(*mapped_ptr); + else /* This could only happed with an externally created file */ + { + buffer.append('\\'); + buffer.append(*mapped_ptr); + } + } + else + buffer.append(*mapped_ptr); + } + (*field)->store(buffer.ptr(), buffer.length(), system_charset_info); + } + next_position= (end_ptr - share->mapped_file)+1; + /* Maybe use \N for null? */ + memset(buf, 0, table->null_bytes); /* We do not implement nulls! */ + + DBUG_RETURN(0); +} + +/* + If frm_error() is called in table.cc this is called to find out what file + extensions exist for this handler. +*/ +const char **ha_tina::bas_ext() const +{ static const char *ext[]= { ".CSV", NullS }; return ext; } + + +/* + Open a database file. Keep in mind that tables are caches, so + this will not be called for every request. Any sort of positions + that need to be reset should be kept in the ::extra() call. +*/ +int ha_tina::open(const char *name, int mode, uint test_if_locked) +{ + DBUG_ENTER("ha_tina::open"); + + if (!(share= get_share(name, table))) + DBUG_RETURN(1); + thr_lock_data_init(&share->lock,&lock,NULL); + ref_length=sizeof(off_t); + + DBUG_RETURN(0); +} + + +/* + Close a database file. We remove ourselves from the shared strucutre. + If it is empty we destroy it and free the mapped file. +*/ +int ha_tina::close(void) +{ + DBUG_ENTER("ha_tina::close"); + DBUG_RETURN(free_share(share)); +} + +/* + This is an INSERT. At the moment this handler just seeks to the end + of the file and appends the data. In an error case it really should + just truncate to the original position (this is not done yet). +*/ +int ha_tina::write_row(byte * buf) +{ + int size; + DBUG_ENTER("ha_tina::write_row"); + + statistic_increment(ha_write_count,&LOCK_status); + + if (table->timestamp_default_now) + update_timestamp(buf+table->timestamp_default_now-1); + + size= encode_quote(buf); + + if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP))) + DBUG_RETURN(-1); + + /* + Ok, this is means that we will be doing potentially bad things + during a bulk insert on some OS'es. What we need is a cleanup + call for ::write_row that would let us fix up everything after the bulk + insert. The archive handler does this with an extra mutx call, which + might be a solution for this. + */ + if (get_mmap(share, 0) > 0) + DBUG_RETURN(-1); + DBUG_RETURN(0); +} + + +/* + This is called for an update. + Make sure you put in code to increment the auto increment, also + update any timestamp data. Currently auto increment is not being + fixed since autoincrements have yet to be added to this table handler. + This will be called in a table scan right before the previous ::rnd_next() + call. +*/ +int ha_tina::update_row(const byte * old_data, byte * new_data) +{ + int size; + DBUG_ENTER("ha_tina::update_row"); + + statistic_increment(ha_update_count,&LOCK_status); + + if (table->timestamp_default_now) + update_timestamp(new_data+table->timestamp_default_now-1); + + size= encode_quote(new_data); + + if (chain_append()) + DBUG_RETURN(-1); + + if (my_write(share->data_file, buffer.ptr(), size, MYF(MY_WME | MY_NABP))) + DBUG_RETURN(-1); + DBUG_RETURN(0); +} + + +/* + Deletes a row. First the database will find the row, and then call this method. + In the case of a table scan, the previous call to this will be the ::rnd_next() + that found this row. + The exception to this is an ORDER BY. This will cause the table handler to walk + the table noting the positions of all rows that match a query. The table will + then be deleted/positioned based on the ORDER (so RANDOM, DESC, ASC). +*/ +int ha_tina::delete_row(const byte * buf) +{ + DBUG_ENTER("ha_tina::delete_row"); + statistic_increment(ha_delete_count,&LOCK_status); + + if (chain_append()) + DBUG_RETURN(-1); + + --records; + + DBUG_RETURN(0); +} + +/* + Fill buf with value from key. Simply this is used for a single index read + with a key. +*/ +int ha_tina::index_read(byte * buf, const byte * key, + uint key_len __attribute__((unused)), + enum ha_rkey_function find_flag + __attribute__((unused))) +{ + DBUG_ENTER("ha_tina::index_read"); + DBUG_ASSERT(0); + DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED); +} + +/* + Fill buf with value from key. Simply this is used for a single index read + with a key. + Whatever the current key is we will use it. This is what will be in "index". +*/ +int ha_tina::index_read_idx(byte * buf, uint index, const byte * key, + uint key_len __attribute__((unused)), + enum ha_rkey_function find_flag + __attribute__((unused))) +{ + DBUG_ENTER("ha_tina::index_read_idx"); + DBUG_ASSERT(0); + DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED); +} + + +/* + Read the next position in the index. +*/ +int ha_tina::index_next(byte * buf) +{ + DBUG_ENTER("ha_tina::index_next"); + DBUG_ASSERT(0); + DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED); +} + +/* + Read the previous position in the index. +*/ +int ha_tina::index_prev(byte * buf) +{ + DBUG_ENTER("ha_tina::index_prev"); + DBUG_ASSERT(0); + DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED); +} + +/* + Read the first position in the index +*/ +int ha_tina::index_first(byte * buf) +{ + DBUG_ENTER("ha_tina::index_first"); + DBUG_ASSERT(0); + DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED); +} + +/* + Read the last position in the index + With this we don't need to do a filesort() with index. + We just read the last row and call previous. +*/ +int ha_tina::index_last(byte * buf) +{ + DBUG_ENTER("ha_tina::index_last"); + DBUG_ASSERT(0); + DBUG_RETURN(HA_ADMIN_NOT_IMPLEMENTED); +} + +/* + All table scans call this first. + The order of a table scan is: + + ha_tina::store_lock + ha_tina::external_lock + ha_tina::info + ha_tina::rnd_init + ha_tina::extra + ENUM HA_EXTRA_CACHE Cash record in HA_rrnd() + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::rnd_next + ha_tina::extra + ENUM HA_EXTRA_NO_CACHE End cacheing of records (def) + ha_tina::external_lock + ha_tina::extra + ENUM HA_EXTRA_RESET Reset database to after open + + Each call to ::rnd_next() represents a row returned in the can. When no more + rows can be returned, rnd_next() returns a value of HA_ERR_END_OF_FILE. + The ::info() call is just for the optimizer. + +*/ + +int ha_tina::rnd_init(bool scan) +{ + DBUG_ENTER("ha_tina::rnd_init"); + + current_position= next_position= 0; + records= 0; + chain_ptr= chain; + (void)madvise(share->mapped_file,share->file_stat.st_size,MADV_SEQUENTIAL); + + DBUG_RETURN(0); +} + +/* + ::rnd_next() does all the heavy lifting for a table scan. You will need to populate *buf + with the correct field data. You can walk the field to determine at what position you + should store the data (take a look at how ::find_current_row() works). The structure + is something like: + 0Foo Dog Friend + The first offset is for the first attribute. All space before that is reserved for null count. + Basically this works as a mask for which rows are nulled (compared to just empty). + This table handler doesn't do nulls and does not know the difference between NULL and "". This + is ok since this table handler is for spreadsheets and they don't know about them either :) +*/ +int ha_tina::rnd_next(byte *buf) +{ + DBUG_ENTER("ha_tina::rnd_next"); + + statistic_increment(ha_read_rnd_next_count,&LOCK_status); + + current_position= next_position; + if (!share->mapped_file) + DBUG_RETURN(HA_ERR_END_OF_FILE); + if (HA_ERR_END_OF_FILE == find_current_row(buf) ) + DBUG_RETURN(HA_ERR_END_OF_FILE); + + records++; + DBUG_RETURN(0); +} + +/* + In the case of an order by rows will need to be sorted. + ::position() is called after each call to ::rnd_next(), + the data it stores is to a byte array. You can store this + data via ha_store_ptr(). ref_length is a variable defined to the + class that is the sizeof() of position being stored. In our case + its just a position. Look at the bdb code if you want to see a case + where something other then a number is stored. +*/ +void ha_tina::position(const byte *record) +{ + DBUG_ENTER("ha_tina::position"); + ha_store_ptr(ref, ref_length, current_position); + DBUG_VOID_RETURN; +} + + +/* + Used to fetch a row from a posiion stored with ::position(). + ha_get_ptr() retrieves the data for you. +*/ + +int ha_tina::rnd_pos(byte * buf, byte *pos) +{ + DBUG_ENTER("ha_tina::rnd_pos"); + statistic_increment(ha_read_rnd_count,&LOCK_status); + current_position= ha_get_ptr(pos,ref_length); + DBUG_RETURN(find_current_row(buf)); +} + +/* + ::info() is used to return information to the optimizer. + Currently this table handler doesn't implement most of the fields + really needed. SHOW also makes use of this data +*/ +void ha_tina::info(uint flag) +{ + DBUG_ENTER("ha_tina::info"); + /* This is a lie, but you don't want the optimizer to see zero or 1 */ + if (records < 2) + records= 2; + DBUG_VOID_RETURN; +} + +/* + Grab bag of flags that are sent to the able handler every so often. + HA_EXTRA_RESET and HA_EXTRA_RESET_STATE are the most frequently called. + You are not required to implement any of these. +*/ +int ha_tina::extra(enum ha_extra_function operation) +{ + DBUG_ENTER("ha_tina::extra"); + DBUG_RETURN(0); +} + +/* + This is no longer used. +*/ +int ha_tina::reset(void) +{ + DBUG_ENTER("ha_tina::reset"); + ha_tina::extra(HA_EXTRA_RESET); + DBUG_RETURN(0); +} + + +/* + Called after deletes, inserts, and updates. This is where we clean up all of + the dead space we have collected while writing the file. +*/ +int ha_tina::rnd_end() +{ + DBUG_ENTER("ha_tina::rnd_end"); + + /* First position will be truncate position, second will be increment */ + if ((chain_ptr - chain) > 0) + { + tina_set *ptr; + off_t length; + + /* + Setting up writable map, this will contain all of the data after the + get_mmap call that we have added to the file. + */ + if (get_mmap(share, 1) > 0) + DBUG_RETURN(-1); + length= share->file_stat.st_size; + + /* + The sort handles updates/deletes with random orders. + It also sorts so that we move the final blocks to the + beginning so that we move the smallest amount of data possible. + */ + qsort(chain, (size_t)(chain_ptr - chain), sizeof(tina_set), (qsort_cmp)sort_set); + for (ptr= chain; ptr < chain_ptr; ptr++) + printf("Chain %d, %d\n", (int)ptr->begin, (int)ptr->end); + for (ptr= chain; ptr < chain_ptr; ptr++) + { + //memmove(share->mapped_file + ptr->begin, share->mapped_file + //+ ptr->end, length - (size_t)ptr->end); + /* We peek a head to see if this is the last chain */ + printf("Delete %d, %d, %d\n", (int)ptr->begin, (int)ptr->end, (int)length); + if (ptr+1 == chain_ptr) + { + printf("Shiftina(end) %d(%d) to %d\n", (int)ptr->end, (int)(length - (size_t)ptr->end), (int)ptr->begin); + memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end, + length - (size_t)ptr->end); + } + else + { + printf("Shifting %d(%d) to %d\n", (int)ptr->end, (int)((ptr++)->begin - (size_t)ptr->end), (int)ptr->begin); + memmove(share->mapped_file + ptr->begin, share->mapped_file + ptr->end, + (size_t)(ptr++)->begin - (size_t)ptr->end); + } + length= length - (size_t)(ptr->end - ptr->begin); + } + printf("Buffer %s\n",share->mapped_file); + + /* Truncate the file to the new size */ + if (my_chsize(share->data_file, length, 0, MYF(MY_WME))) + DBUG_RETURN(-1); + + if (munmap(share->mapped_file, length)) + DBUG_RETURN(-1); + + /* We set it to null so that get_mmap() won't try to unmap it */ + share->mapped_file= NULL; + if (get_mmap(share, 0) > 0) + DBUG_RETURN(-1); + } + + DBUG_RETURN(0); +} + +/* + Truncate table and others of its ilk call this. +*/ +int ha_tina::delete_all_rows() +{ + DBUG_ENTER("ha_tina::delete_all_rows"); + + int rc= my_chsize(share->data_file, 0, 0, MYF(MY_WME)); + + if (get_mmap(share, 0) > 0) + DBUG_RETURN(-1); + + DBUG_RETURN(rc); +} + +/* + Always called by the start of a transaction (or by "lock tables"); +*/ +int ha_tina::external_lock(THD *thd, int lock_type) +{ + DBUG_ENTER("ha_tina::external_lock"); + DBUG_RETURN(0); // No external locking +} + +/* + Called by the database to lock the table. Keep in mind that this + is an internal lock. +*/ +THR_LOCK_DATA **ha_tina::store_lock(THD *thd, + THR_LOCK_DATA **to, + enum thr_lock_type lock_type) +{ + if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) + lock.type=lock_type; + *to++= &lock; + return to; +} + +/* + Range optimizer calls this. + I need to update the information on this. +*/ +ha_rows ha_tina::records_in_range(int inx, + const byte *start_key,uint start_key_len, + enum ha_rkey_function start_search_flag, + const byte *end_key,uint end_key_len, + enum ha_rkey_function end_search_flag) +{ + DBUG_ENTER("ha_tina::records_in_range "); + DBUG_RETURN(records); // Good guess +} + + +/* + Create a table. You do not want to leave the table open after a call to + this (the database will call ::open() if it needs to). +*/ + +int ha_tina::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) +{ + char name_buff[FN_REFLEN]; + File create_file; + DBUG_ENTER("ha_tina::create"); + + if ((create_file= my_create(fn_format(name_buff,name,"",".CSV",MY_REPLACE_EXT|MY_UNPACK_FILENAME),0, + O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + DBUG_RETURN(-1); + + my_close(create_file,MYF(0)); + + DBUG_RETURN(0); +} diff --git a/sql/examples/ha_tina.h b/sql/examples/ha_tina.h new file mode 100644 index 00000000000..67a907fddb6 --- /dev/null +++ b/sql/examples/ha_tina.h @@ -0,0 +1,132 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include +#include +#include + +#define DEFAULT_CHAIN_LENGTH 512 + +typedef struct st_tina_share { + char *table_name; + byte *mapped_file; /* mapped region of file */ + uint table_name_length,use_count; + MY_STAT file_stat; /* Stat information for the data file */ + File data_file; /* Current open data file */ + pthread_mutex_t mutex; + THR_LOCK lock; +} TINA_SHARE; + +typedef struct tina_set { + off_t begin; + off_t end; +}; + +class ha_tina: public handler +{ + THR_LOCK_DATA lock; /* MySQL lock */ + TINA_SHARE *share; /* Shared lock info */ + off_t current_position; /* Current position in the file during a file scan */ + off_t next_position; /* Next position in the file scan */ + byte byte_buffer[IO_SIZE]; + String buffer; + tina_set chain_buffer[DEFAULT_CHAIN_LENGTH]; + tina_set *chain; + tina_set *chain_ptr; + byte chain_alloced; + uint32 chain_size; + + public: + ha_tina(TABLE *table): handler(table), + /* + These definitions are found in hanler.h + Theses are not probably completely right. + */ + current_position(0), next_position(0), chain_alloced(0), chain_size(DEFAULT_CHAIN_LENGTH) + { + /* Set our original buffers from pre-allocated memory */ + buffer.set(byte_buffer, IO_SIZE, system_charset_info); + chain = chain_buffer; + } + ~ha_tina() + { + if (chain_alloced) + my_free((gptr)chain,0); + } + const char *table_type() const { return "CSV"; } + const char *index_type(uint inx) { return "NONE"; } + const char **bas_ext() const; + ulong table_flags() const + { + return (HA_REC_NOT_IN_SEQ | HA_NOT_EXACT_COUNT | + HA_NO_AUTO_INCREMENT ); + } + ulong index_flags(uint idx, uint part, bool all_parts) const + { + /* We will never have indexes so this will never be called(AKA we return zero) */ + return 0; + } + uint max_record_length() const { return HA_MAX_REC_LENGTH; } + uint max_keys() const { return 0; } + uint max_key_parts() const { return 0; } + uint max_key_length() const { return 0; } + /* + Called in test_quick_select to determine if indexes should be used. + */ + virtual double scan_time() { return (double) (records+deleted) / 20.0+10; } + /* The next method will never be called */ + virtual double read_time(ha_rows rows) { DBUG_ASSERT(0); return((double) rows / 20.0+1); } + virtual bool fast_key_read() { return 1;} + + int open(const char *name, int mode, uint test_if_locked); + int close(void); + int write_row(byte * buf); + int update_row(const byte * old_data, byte * new_data); + int delete_row(const byte * buf); + int index_read(byte * buf, const byte * key, + uint key_len, enum ha_rkey_function find_flag); + int index_read_idx(byte * buf, uint idx, const byte * key, + uint key_len, enum ha_rkey_function find_flag); + int index_next(byte * buf); + int index_prev(byte * buf); + int index_first(byte * buf); + int index_last(byte * buf); + int rnd_init(bool scan=1); + int rnd_next(byte *buf); + int rnd_pos(byte * buf, byte *pos); + int rnd_end(); + void position(const byte *record); + void info(uint); + int extra(enum ha_extra_function operation); + int reset(void); + int external_lock(THD *thd, int lock_type); + int delete_all_rows(void); + ha_rows records_in_range(int inx, const byte *start_key,uint start_key_len, + enum ha_rkey_function start_search_flag, + const byte *end_key,uint end_key_len, + enum ha_rkey_function end_search_flag); +// int delete_table(const char *from); +// int rename_table(const char * from, const char * to); + int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); + + THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, + enum thr_lock_type lock_type); + + /* The following methods were added just for TINA */ + int encode_quote(byte *buf); + int find_current_row(byte *buf); + int chain_append(); +}; diff --git a/sql/handler.cc b/sql/handler.cc index 41a252e3088..7010b5284b8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -38,6 +38,9 @@ #ifdef HAVE_ARCHIVE_DB #include "examples/ha_archive.h" #endif +#ifdef HAVE_CSV_DB +#include "examples/ha_tina.h" +#endif #ifdef HAVE_INNOBASE_DB #include "ha_innodb.h" #endif @@ -91,6 +94,8 @@ struct show_table_type_st sys_table_types[]= "Example storage engine", DB_TYPE_EXAMPLE_DB}, {"ARCHIVE",&have_archive_db, "Archive storage engine", DB_TYPE_ARCHIVE_DB}, + {"CSV",&have_csv_db, + "CSV storage engine", DB_TYPE_CSV_DB}, {NullS, NULL, NullS, DB_TYPE_UNKNOWN} }; @@ -196,6 +201,10 @@ handler *get_new_handler(TABLE *table, enum db_type db_type) case DB_TYPE_ARCHIVE_DB: return new ha_archive(table); #endif +#ifdef HAVE_CSV_DB + case DB_TYPE_CSV_DB: + return new ha_tina(table); +#endif #ifdef HAVE_NDBCLUSTER_DB case DB_TYPE_NDBCLUSTER: return new ha_ndbcluster(table); diff --git a/sql/handler.h b/sql/handler.h index 28b0b8df6e2..542229dcaf2 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -147,7 +147,7 @@ enum db_type DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM, DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER, - DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, + DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB, DB_TYPE_DEFAULT // Must be last }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 8707bc205df..2f2fc156af1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -930,7 +930,7 @@ extern struct my_option my_long_options[]; /* optional things, have_* variables */ extern SHOW_COMP_OPTION have_isam, have_innodb, have_berkeley_db; -extern SHOW_COMP_OPTION have_example_db, have_archive_db; +extern SHOW_COMP_OPTION have_example_db, have_archive_db, have_csv_db; extern SHOW_COMP_OPTION have_raid, have_openssl, have_symlink; extern SHOW_COMP_OPTION have_query_cache, have_berkeley_db, have_innodb; extern SHOW_COMP_OPTION have_geometry, have_rtree_keys; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 4fd13d33bab..4f0a2f63a7f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -366,7 +366,7 @@ CHARSET_INFO *system_charset_info, *files_charset_info ; CHARSET_INFO *national_charset_info, *table_alias_charset; SHOW_COMP_OPTION have_berkeley_db, have_innodb, have_isam, have_ndbcluster, - have_example_db, have_archive_db; + have_example_db, have_archive_db, have_csv_db; SHOW_COMP_OPTION have_raid, have_openssl, have_symlink, have_query_cache; SHOW_COMP_OPTION have_geometry, have_rtree_keys; SHOW_COMP_OPTION have_crypt, have_compress; @@ -5456,6 +5456,11 @@ static void mysql_init_variables(void) #else have_archive_db= SHOW_OPTION_NO; #endif +#ifdef HAVE_CSV_DB + have_csv_db= SHOW_OPTION_YES; +#else + have_csv_db= SHOW_OPTION_NO; +#endif #ifdef HAVE_NDBCLUSTER_DB have_ndbcluster=SHOW_OPTION_DISABLED; #else diff --git a/sql/set_var.cc b/sql/set_var.cc index e1cfb77d297..93123b12c38 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -652,6 +652,8 @@ struct show_var_st init_vars[]= { {"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE}, {"have_compress", (char*) &have_compress, SHOW_HAVE}, {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, + {"have_csv", (char*) &have_csv_db, SHOW_HAVE}, + {"have_example", (char*) &have_example_db, SHOW_HAVE}, {"have_innodb", (char*) &have_innodb, SHOW_HAVE}, {"have_isam", (char*) &have_isam, SHOW_HAVE}, {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, -- cgit v1.2.1 From 16987e1ce2e047d088707f85c31e967fff1d4d88 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 11:13:56 +0500 Subject: ctype_ucs.result, ctype_ucs.test, item.cc: #5024 [Ver]: Server crashes with queries on fields with certain charset/collation settings sql/item.cc: #5024 [Ver]: Server crashes with queries on fields with certain charset/collation settings mysql-test/t/ctype_ucs.test: #5024 [Ver]: Server crashes with queries on fields with certain charset/collation settings mysql-test/r/ctype_ucs.result: #5024 [Ver]: Server crashes with queries on fields with certain charset/collation settings --- sql/item.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 658f5c42a43..c85aee724cb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -176,10 +176,15 @@ void Item::set_name(const char *str, uint length, CHARSET_INFO *cs) name= (char*) str; return; } - while (length && !my_isgraph(cs,*str)) - { // Fix problem with yacc - length--; - str++; + if (cs->ctype) + { + // This will probably need a better implementation in the future: + // a function in CHARSET_INFO structure. + while (length && !my_isgraph(cs,*str)) + { // Fix problem with yacc + length--; + str++; + } } if (!my_charset_same(cs, system_charset_info)) { -- cgit v1.2.1 From d0c87702f70ff6c0116555fd40e92aef7bb79b46 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 10:01:30 +0300 Subject: skip resolving field in table list if table list is not accessable due to groupping (BUG#4814) mysql-test/r/func_gconcat.result: fix of test queries mysql-test/r/subselect.result: resolving fields of grouped outer SELECT mysql-test/t/func_gconcat.test: fix of test queries mysql-test/t/subselect.test: resolving fields of grouped outer SELECT sql/item.cc: skip resolving field in table list if table list is not accessable due to groupping layout fixed sql/item_subselect.cc: detection of place of subquery sql/item_subselect.h: detection of place of subquery sql/mysql_priv.h: enum_parsing_place made global type sql/sql_lex.cc: enum_parsing_place made global type sql/sql_lex.h: enum_parsing_place made global type sql/sql_yacc.yy: enum_parsing_place made global type --- sql/item.cc | 70 +++++++++++++++++++++++++++++++++------------------ sql/item_subselect.cc | 4 ++- sql/item_subselect.h | 2 ++ sql/mysql_priv.h | 7 ++++++ sql/sql_lex.cc | 2 +- sql/sql_lex.h | 6 ----- sql/sql_yacc.yy | 24 +++++++++--------- 7 files changed, 71 insertions(+), 44 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 658f5c42a43..09d5ee0a6ed 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -60,10 +60,10 @@ Item::Item(): */ if (thd->lex->current_select) { - SELECT_LEX_NODE::enum_parsing_place place= + enum_parsing_place place= thd->lex->current_select->parsing_place; - if (place == SELECT_LEX_NODE::SELECT_LIST || - place == SELECT_LEX_NODE::IN_HAVING) + if (place == SELECT_LIST || + place == IN_HAVING) thd->lex->current_select->select_n_having_items++; } } @@ -1228,21 +1228,34 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) table_list= (last= sl)->get_table_list(); if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) { - // it is primary INSERT st_select_lex => skip first table resolving + /* + it is primary INSERT st_select_lex => skip first table + resolving + */ table_list= table_list->next; } Item_subselect *prev_subselect_item= prev_unit->item; - if ((tmp= find_field_in_tables(thd, this, - table_list, &where, - 0)) != not_found_field) - { - if (!tmp) - return -1; - prev_subselect_item->used_tables_cache|= tmp->table->map; - prev_subselect_item->const_item_cache= 0; - break; - } + enum_parsing_place place= + prev_subselect_item->parsing_place; + /* + check table fields only if subquery used somewhere out of HAVING + or SELECT list or outer SELECT do not use groupping (i.e. tables + are accessable) + */ + if (((place != IN_HAVING && + place != SELECT_LIST) || + (sl->with_sum_func == 0 && sl->group_list.elements == 0)) && + (tmp= find_field_in_tables(thd, this, + table_list, &where, + 0)) != not_found_field) + { + if (!tmp) + return -1; + prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->const_item_cache= 0; + break; + } if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && (refer= find_item_in_list(this, sl->item_list, &counter, REPORT_EXCEPT_NOT_FOUND)) != @@ -1901,16 +1914,25 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) // it is primary INSERT st_select_lex => skip first table resolving table_list= table_list->next; } - if ((tmp= find_field_in_tables(thd, this, - table_list, &where, - 0)) != not_found_field) - { - prev_subselect_item->used_tables_cache|= tmp->table->map; - prev_subselect_item->const_item_cache= 0; - break; - } - - // Reference is not found => depend from outer (or just error) + enum_parsing_place place= + prev_subselect_item->parsing_place; + /* + check table fields only if subquery used somewhere out of HAVING + or SELECT list or outer SELECT do not use groupping (i.e. tables + are accessable) + */ + if (((place != IN_HAVING && + place != SELECT_LIST) || + (sl->with_sum_func == 0 && sl->group_list.elements == 0)) && + (tmp= find_field_in_tables(thd, this, + table_list, &where, + 0)) != not_found_field) + { + prev_subselect_item->used_tables_cache|= tmp->table->map; + prev_subselect_item->const_item_cache= 0; + break; + } + // Reference is not found => depend from outer (or just error) prev_subselect_item->used_tables_cache|= OUTER_REF_TABLE_BIT; prev_subselect_item->const_item_cache= 0; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 36f5c891186..750fd4aa4af 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -63,12 +63,14 @@ void Item_subselect::init(st_select_lex *select_lex, => we do not copy old_engine here */ engine= unit->item->engine; + parsing_place= unit->item->parsing_place; unit->item->engine= 0; unit->item= this; engine->change_item(this, result); } else { + parsing_place= unit->outer_select()->parsing_place; if (select_lex->next_select()) engine= new subselect_union_engine(unit, result, this); else @@ -76,7 +78,7 @@ void Item_subselect::init(st_select_lex *select_lex, } { SELECT_LEX *upper= unit->outer_select(); - if (upper->parsing_place == SELECT_LEX_NODE::IN_HAVING) + if (upper->parsing_place == IN_HAVING) upper->subquery_in_having= 1; } DBUG_VOID_RETURN; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 6b8b8b0b3a7..5668b91263f 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -50,6 +50,8 @@ protected: table_map used_tables_cache; /* allowed number of columns (1 for single value subqueries) */ uint max_columns; + /* where subquery is placed */ + enum_parsing_place parsing_place; /* work with 'substitution' */ bool have_to_be_excluded; /* cache of constant state */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b3b79c16787..2f785e3f502 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -293,6 +293,13 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); */ #define MAX_DATE_REP_LENGTH 30 +enum enum_parsing_place +{ + NO_MATTER, + IN_HAVING, + SELECT_LIST +}; + struct st_table; class THD; class Statement; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2b6a307092c..f39cbc43b8b 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1017,7 +1017,7 @@ void st_select_lex::init_query() select_n_having_items= 0; prep_where= 0; subquery_in_having= explicit_limit= 0; - parsing_place= SELECT_LEX_NODE::NO_MATTER; + parsing_place= NO_MATTER; } void st_select_lex::init_select() diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 053c85166f6..da2c3fba097 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -220,12 +220,6 @@ protected: *master, *slave, /* vertical links */ *link_next, **link_prev; /* list of whole SELECT_LEX */ public: - enum enum_parsing_place - { - NO_MATTER, - IN_HAVING, - SELECT_LIST - }; ulong options; /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 8e3fb0884a9..de560041ba7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1113,11 +1113,11 @@ create_select: lex->sql_command= SQLCOM_REPLACE_SELECT; lex->current_select->table_list.save_and_clear(&lex->save_list); mysql_init_select(lex); - lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST; + lex->current_select->parsing_place= SELECT_LIST; } select_options select_item_list { - Select->parsing_place= SELECT_LEX_NODE::NO_MATTER; + Select->parsing_place= NO_MATTER; } opt_select_from { Lex->current_select->table_list.push_front(&Lex->save_list); } @@ -2370,11 +2370,11 @@ select_part2: lex->lock_option= TL_READ; if (sel->linkage != UNION_TYPE) mysql_init_select(lex); - lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST; + lex->current_select->parsing_place= SELECT_LIST; } select_options select_item_list { - Select->parsing_place= SELECT_LEX_NODE::NO_MATTER; + Select->parsing_place= NO_MATTER; } select_into select_lock_type; @@ -3438,11 +3438,11 @@ select_derived: YYABORT; mysql_init_select(lex); lex->current_select->linkage= DERIVED_TABLE_TYPE; - lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST; + lex->current_select->parsing_place= SELECT_LIST; } select_options select_item_list { - Select->parsing_place= SELECT_LEX_NODE::NO_MATTER; + Select->parsing_place= NO_MATTER; } opt_select_from union_opt ; @@ -3572,13 +3572,13 @@ having_clause: /* empty */ | HAVING { - Select->parsing_place= SELECT_LEX_NODE::IN_HAVING; + Select->parsing_place= IN_HAVING; } expr { SELECT_LEX *sel= Select; sel->having= $3; - sel->parsing_place= SELECT_LEX_NODE::NO_MATTER; + sel->parsing_place= NO_MATTER; if ($3) $3->top_level_item(); } @@ -4813,7 +4813,7 @@ simple_ident: ident { SELECT_LEX *sel=Select; - $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || + $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(0,0, NullS,NullS,$1.str); @@ -4829,7 +4829,7 @@ simple_ident: ER(ER_TABLENAME_NOT_ALLOWED_HERE), MYF(0), $1.str, thd->where); } - $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || + $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(0,0,NullS,$1.str,$3.str); @@ -4845,7 +4845,7 @@ simple_ident: ER(ER_TABLENAME_NOT_ALLOWED_HERE), MYF(0), $2.str, thd->where); } - $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || + $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(0,0,NullS,$2.str,$4.str); @@ -4861,7 +4861,7 @@ simple_ident: ER(ER_TABLENAME_NOT_ALLOWED_HERE), MYF(0), $3.str, thd->where); } - $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || + $$= (sel->parsing_place != IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str), -- cgit v1.2.1 From e2cfe7b60771610aff0d287ad243249099f4f629 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 15:04:10 +0500 Subject: ctype_utf8.result, ctype_utf8.test, item_strfunc.cc: LEFT() didn't work well in some cases. sql/item_strfunc.cc: LEFT() didn't work well in some cases. mysql-test/t/ctype_utf8.test: LEFT() didn't work well in some cases. mysql-test/r/ctype_utf8.result: LEFT() didn't work well in some cases. --- sql/item_strfunc.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 995627766c0..ecfeff02cac 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -977,17 +977,19 @@ String *Item_func_left::val_str(String *str) DBUG_ASSERT(fixed == 1); String *res =args[0]->val_str(str); long length =(long) args[1]->val_int(); + uint char_pos; if ((null_value=args[0]->null_value)) return 0; if (length <= 0) return &my_empty_string; - if (res->length() <= (uint) length) + if (res->length() <= (uint) length || + res->length() <= (char_pos= res->charpos(length))) return res; if (&str_value == res) - str_value.length(res->charpos(length)); + str_value.length(char_pos); else - str_value.set(*res, 0, res->charpos(length)); + str_value.set(*res, 0, char_pos); return &str_value; } -- cgit v1.2.1 From 55cc6be43c85b40b0a9c510c9a6630c8df7d3137 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 13:51:18 +0200 Subject: Added support for NULL in unique index --- sql/ha_ndbcluster.cc | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b6db9b96308..702be862328 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1040,11 +1040,11 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, bounds[bound], field->field_name)); DBUG_DUMP("key", (char*)key_ptr, field_len); - + if (op->setBound(field->field_name, bound, - key_ptr, - field_len) != 0) + field->is_null() ? 0 : key_ptr, + field->is_null() ? 0 : field_len) != 0) ERR_RETURN(op->getNdbError()); key_ptr+= field_len; @@ -1293,8 +1293,6 @@ int ha_ndbcluster::write_row(byte *record) update_timestamp(record+table->timestamp_default_now-1); has_auto_increment= (table->next_number_field && record == table->record[0]); skip_auto_increment= table->auto_increment_field_not_null; - if ((has_auto_increment) && (!skip_auto_increment)) - update_auto_increment(); if (!(op= trans->getNdbOperation(m_tabname))) ERR_RETURN(trans->getNdbError()); @@ -1313,6 +1311,10 @@ int ha_ndbcluster::write_row(byte *record) else { int res; + + if ((has_auto_increment) && (!skip_auto_increment)) + update_auto_increment(); + if ((res= set_primary_key(op))) return res; } @@ -1323,7 +1325,10 @@ int ha_ndbcluster::write_row(byte *record) Field *field= table->field[i]; if (!(field->flags & PRI_KEY_FLAG) && set_ndb_value(op, field, i)) + { + skip_auto_increment= true; ERR_RETURN(op->getNdbError()); + } } /* @@ -1345,7 +1350,10 @@ int ha_ndbcluster::write_row(byte *record) (int)rows_inserted, (int)bulk_insert_rows)); bulk_insert_not_flushed= false; if (trans->execute(NoCommit) != 0) + { + skip_auto_increment= true; DBUG_RETURN(ndb_err(trans)); + } } if ((has_auto_increment) && (skip_auto_increment)) { @@ -3068,6 +3076,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_ndb(NULL), m_table(NULL), m_table_flags(HA_REC_NOT_IN_SEQ | + //HA_NULL_IN_KEY | HA_NOT_EXACT_COUNT | HA_NO_PREFIX_CHAR_KEYS), m_use_write(false), -- cgit v1.2.1 From 621506815f343abc29ab1b8a89adc757f6e32bf9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 15:29:47 +0200 Subject: Escaping [] so that darwin[7-8] gets into 'configure' and not darwin7-8 Adding a compilation define so that on recent Darwin mysqld does not react to SIGHUP and SIGQUIT: this fixes a rpl000001 problem on our Powermac G5 machine (popping after an upgrade from 10.3.4 to 10.3.5) and is expected to fix BUG#2030 "relay bin log on slave resets multiple times a second" (i.e. under some Mac OS X Panther versions, mysqld receives many SIGHUP and SIGQUIT). So this fix is more a problem-hider than a real understanding of why mysqld receives so many signals. Note that we saw other problems on this OS where mysqld reacts to Ctrl-Z but apparently only once, where using SSL seems to make the problem more frequent... configure.in: Escaping [] so that darwin[7-8] gets into 'configure' and not darwin7-8 Adding a compilation define so that on recent Darwin mysqld does not react to SIGHUP and SIGQUIT. sql/mysqld.cc: optionally ignore SIGHUP and SIGQUIT, for some Mac OS X Panther versions which send too many of those. --- sql/mysqld.cc | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3f7c187ccdd..8f08099f340 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1836,9 +1836,11 @@ static void init_signals(void) sigaddset(&set,SIGPIPE); #endif sigaddset(&set,SIGINT); +#ifndef IGNORE_SIGHUP_SIGQUIT sigaddset(&set,SIGQUIT); - sigaddset(&set,SIGTERM); sigaddset(&set,SIGHUP); +#endif + sigaddset(&set,SIGTERM); /* Fix signals if blocked by parents (can happen on Mac OS X) */ sigemptyset(&sa.sa_mask); @@ -1921,11 +1923,13 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) #ifdef USE_ONE_SIGNAL_HAND (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms #endif +#ifndef IGNORE_SIGHUP_SIGQUIT (void) sigaddset(&set,SIGQUIT); - (void) sigaddset(&set,SIGTERM); #if THR_CLIENT_ALARM != SIGHUP (void) sigaddset(&set,SIGHUP); #endif +#endif + (void) sigaddset(&set,SIGTERM); (void) sigaddset(&set,SIGTSTP); /* Save pid to this process (or thread on Linux) */ -- cgit v1.2.1 From 467f5956ebc178d71ed8cd1727e915ba8a047920 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 19:06:24 +0500 Subject: CSC issue # 3299 fix: ENUM and SET type didn't compute their length correctly. That showed up for example while converting into a CHAR column. --- sql/field.cc | 4 ++++ sql/sql_parse.cc | 11 ++++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 8fba132738c..af9ad110f0e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5667,6 +5667,10 @@ void create_field::create_length_to_internal_length(void) pack_length= calc_pack_length(sql_type == FIELD_TYPE_VAR_STRING ? FIELD_TYPE_STRING : sql_type, length); break; + case MYSQL_TYPE_ENUM: + case MYSQL_TYPE_SET: + length*= charset->mbmaxlen; + break; default: /* do nothing */ break; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1182f018ea4..77ac730b6dc 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4381,7 +4381,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->length=0; for (const char **pos=interval->type_names; *pos ; pos++) { - new_field->length+=(uint) strip_sp((char*) *pos)+1; + uint length= (uint) strip_sp((char*) *pos)+1; + CHARSET_INFO *cs= thd->variables.character_set_client; + length= cs->cset->numchars(cs, *pos, *pos+length); + new_field->length+= length; } new_field->length--; set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); @@ -4411,8 +4414,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->length=(uint) strip_sp((char*) interval->type_names[0]); for (const char **pos=interval->type_names+1; *pos ; pos++) { - uint length=(uint) strip_sp((char*) *pos); - set_if_bigger(new_field->length,length); + uint length=(uint) strip_sp((char*) *pos); + CHARSET_INFO *cs= thd->variables.character_set_client; + length= cs->cset->numchars(cs, *pos, *pos+length); + set_if_bigger(new_field->length,length); } set_if_smaller(new_field->length,MAX_FIELD_WIDTH-1); if (default_value) -- cgit v1.2.1 From 1dda5f60a0fc304c9f1a9a147e238a54eb85ec88 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 14:31:30 -0500 Subject: set_var.cc: Make query_cache_wlock_invalidate show up in SHOW VARIABLES. (Sanja agrees that it should show up, has seen the patch, and agrees that it's correct.) sql/set_var.cc: Make query_cache_wlock_invalidate show up in SHOW VARIABLES. --- sql/set_var.cc | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sql') diff --git a/sql/set_var.cc b/sql/set_var.cc index fc1332695d6..393f35a7d1f 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -769,6 +769,8 @@ struct show_var_st init_vars[]= { SHOW_SYS}, {sys_query_cache_size.name, (char*) &sys_query_cache_size, SHOW_SYS}, {sys_query_cache_type.name, (char*) &sys_query_cache_type, SHOW_SYS}, + {sys_query_cache_wlock_invalidate.name, + (char *) &sys_query_cache_wlock_invalidate, SHOW_SYS}, #endif /* HAVE_QUERY_CACHE */ {sys_query_prealloc_size.name, (char*) &sys_query_prealloc_size, SHOW_SYS}, {sys_range_alloc_block_size.name, (char*) &sys_range_alloc_block_size, -- cgit v1.2.1 From ff5ade15bd2536cd15ba3fa3bfb8f325d83283fa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Aug 2004 16:24:46 -0700 Subject: Merge resolve. Changed name of ha_example to ha_example_engine. sql/set_var.cc: Changed have_example to have_example_engine (easier to understand when reading output). Also resolved merge problem. --- sql/set_var.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/set_var.cc b/sql/set_var.cc index 93123b12c38..513c62cdd53 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -653,10 +653,10 @@ struct show_var_st init_vars[]= { {"have_compress", (char*) &have_compress, SHOW_HAVE}, {"have_crypt", (char*) &have_crypt, SHOW_HAVE}, {"have_csv", (char*) &have_csv_db, SHOW_HAVE}, - {"have_example", (char*) &have_example_db, SHOW_HAVE}, + {"have_example_engine", (char*) &have_example_db, SHOW_HAVE}, + {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, {"have_innodb", (char*) &have_innodb, SHOW_HAVE}, {"have_isam", (char*) &have_isam, SHOW_HAVE}, - {"have_geometry", (char*) &have_geometry, SHOW_HAVE}, {"have_ndbcluster", (char*) &have_ndbcluster, SHOW_HAVE}, {"have_openssl", (char*) &have_openssl, SHOW_HAVE}, {"have_query_cache", (char*) &have_query_cache, SHOW_HAVE}, -- cgit v1.2.1 From 767d880f9c641746ed0087c4a2395e2a66d43374 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Aug 2004 03:38:37 +0200 Subject: mysql_priv.h: Added declarations for print_msg_to_log and vprint_msg_to_log. sql_print_error are simple functions that wrap calls to print_msg_to_log. Define the different error types with MY_ERROR_TYPE, MY_WARNING_TYPE, and MY_INFORMATION_TYPE gen_lex_hash.cc: Added NULL error reporting parameter to handle_options log.cc: Add print_msg_to_log, print_buffer_to_log, and vprint_msg_to_log. Print_msg_to_log will write the message to the windows event log if on NT. We now have error, warning, and information versions of sql_print_xxxx. T his is a variation of a similar changeset WAX did. mysqld.cc: Added option_error_reporter callback function and pass that into handle_options mysql.cc: Added NULL as error reporter arg to the end of handle_options Many files: Added NULL error reporter parameter as the last paramter to handle_options my_getopt.c: Added second function pointer to server as an error reporting callback. Added local function report_option_error that will either write the error to stderr or to the error reporting callback. changed all calls in handle_options from fprintf(stderr, ... ) to report_option_error my_getopt.h: Changed declaration of handle_options to use typedefs for the two function pointers. added second function pointer to server as an error reporting callback mysqld.dsp: Added custom build step for compiling message file and added message resource file (output of mc) VC++Files/sql/mysqld.dsp: Added custom build step for compiling message file and added message resource file (output of mc) client/mysqladmin.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysqlcheck.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysqldump.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysqlimport.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysqlmanager-pwgen.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysqlmanagerc.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysqlbinlog.cc: Added NULL error reporter parameter as the last paramter to handle_options client/mysqlshow.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysqltest.c: Added NULL error reporter parameter as the last paramter to handle_options extra/my_print_defaults.c: Added NULL error reporter parameter as the last paramter to handle_options extra/mysql_install.c: Added NULL error reporter parameter as the last paramter to handle_options extra/mysql_waitpid.c: Added NULL error reporter parameter as the last paramter to handle_options extra/perror.c: Added NULL error reporter parameter as the last paramter to handle_options extra/resolve_stack_dump.c: Added NULL error reporter parameter as the last paramter to handle_options extra/resolveip.c: Added NULL error reporter parameter as the last paramter to handle_options isam/isamchk.c: Added NULL error reporter parameter as the last paramter to handle_options isam/pack_isam.c: Added NULL error reporter parameter as the last paramter to handle_options myisam/mi_test1.c: Added NULL error reporter parameter as the last paramter to handle_options myisam/myisam_ftdump.c: Added NULL error reporter parameter as the last paramter to handle_options myisam/myisamchk.c: Added NULL error reporter parameter as the last paramter to handle_options myisam/myisampack.c: Added NULL error reporter parameter as the last paramter to handle_options include/my_getopt.h: Changed declaration of handle_options to use typedefs for the two function pointers. added second function pointer to server as an error reporting callback mysys/my_getopt.c: Added second function pointer to server as an error reporting callback. Added local function report_option_error that will either write the error to stderr or to the error reporting callback. changed all calls in handle_options from fprintf(stderr, ... ) to report_option_error tools/mysqlmanager.c: Added NULL error reporter parameter as the last paramter to handle_options client/mysql.cc: Added NULL as error reporter arg to the end of handle_options sql/mysqld.cc: Added option_error_reporter callback function and pass that into handle_options sql/log.cc: Add print_msg_to_log, print_buffer_to_log, and vprint_msg_to_log. Print_msg_to_log will write the message to the windows event log if on NT. We now have error, warning, and information versions of sql_print_xxxx. T his is a variation of a similar changeset WAX did. sql/gen_lex_hash.cc: Added NULL error reporting parameter to handle_options sql/mysql_priv.h: Added declarations for print_msg_to_log and vprint_msg_to_log. sql_print_error are simple functions that wrap calls to print_msg_to_log. Define the different error types with MY_ERROR_TYPE, MY_WARNING_TYPE, and MY_INFORMATION_TYPE BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/gen_lex_hash.cc | 2 +- sql/log.cc | 206 ++++++++++++++++++++++++++++++++++++++++++++++------ sql/mysql_priv.h | 22 +++++- sql/mysqld.cc | 7 +- 4 files changed, 211 insertions(+), 26 deletions(-) (limited to 'sql') diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 1f604659272..72ab1184533 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -384,7 +384,7 @@ static int get_options(int argc, char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, 0))) exit(ho_error); if (argc >= 1) diff --git a/sql/log.cc b/sql/log.cc index e031656cc6e..3d76f9d5634 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -31,12 +31,51 @@ #include // For test_if_number #include +#ifdef __NT__ +#include "message.h" +#endif + MYSQL_LOG mysql_log,mysql_update_log,mysql_slow_log,mysql_bin_log; extern I_List binlog_do_db, binlog_ignore_db; static bool test_if_number(const char *str, long *res, bool allow_wildcards); +#ifdef __NT__ +static int eventSource = 0; +void setupWindowsEventSource() +{ + if (eventSource) return; + + eventSource = 1; + HKEY hRegKey = NULL; + DWORD dwError = 0; + TCHAR szPath[ MAX_PATH ]; + + // Create the event source registry key + dwError = RegCreateKey( HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\MySQL", + &hRegKey ); + + // Name of the PE module that contains the message resource + GetModuleFileName( NULL, szPath, MAX_PATH ); + + // Register EventMessageFile + dwError = RegSetValueEx( hRegKey, "EventMessageFile", 0, REG_EXPAND_SZ, + (PBYTE) szPath, strlen(szPath)+1 ); + + + // Register supported event types + DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; + dwError = RegSetValueEx( hRegKey, "TypesSupported", 0, REG_DWORD, + (LPBYTE) &dwTypes, sizeof dwTypes ); + + RegCloseKey( hRegKey ); +} + +#endif + + /**************************************************************************** ** Find a uniq filename for 'filename.#'. ** Set # to a number as low as possible @@ -1677,41 +1716,42 @@ static bool test_if_number(register const char *str, } /* test_if_number */ -void sql_print_error(const char *format,...) +void print_buffer_to_log( my_bool timestamp, const char *buffer ) { - va_list args; time_t skr; struct tm tm_tmp; struct tm *start; - va_start(args,format); - DBUG_ENTER("sql_print_error"); + DBUG_ENTER("sql_print_buffer_to_log"); + +#if !defined(__WIN__) && !defined(__NT__) VOID(pthread_mutex_lock(&LOCK_error_log)); -#ifndef DBUG_OFF - { - char buff[1024]; - my_vsnprintf(buff,sizeof(buff)-1,format,args); - DBUG_PRINT("error",("%s",buff)); - va_end(args); - va_start(args,format); - } #endif - skr=time(NULL); - localtime_r(&skr,&tm_tmp); - start=&tm_tmp; - fprintf(stderr,"%02d%02d%02d %2d:%02d:%02d ", - start->tm_year % 100, - start->tm_mon+1, + + if (timestamp) + { + skr=time(NULL); + localtime_r(&skr, &tm_tmp); + start=&tm_tmp; + fprintf( stderr, "%02d%02d%02d %2d:%02d:%02d %s", + start->tm_year % 100, + start->tm_mon+1, start->tm_mday, start->tm_hour, start->tm_min, - start->tm_sec); - (void) vfprintf(stderr,format,args); - (void) fputc('\n',stderr); + start->tm_sec, + buffer ); + } + else + fprintf( stderr, "%s", buffer ); + + fputc('\n', stderr); fflush(stderr); - va_end(args); +#if !defined(__WIN__) && !defined(__NT__) VOID(pthread_mutex_unlock(&LOCK_error_log)); +#endif + DBUG_VOID_RETURN; } @@ -1770,3 +1810,125 @@ bool flush_error_log() } return result; } + +/** + * prints a printf style message to the error log and, under NT, to the Windows event log. + * @param event_type type of even to log. + * @param timestamp true to add a timestamp to the entry, false otherwise. + * @param format The printf style format of the message + * @param ... values for the message + * @return void +*/ +void print_msg_to_log( long event_type, my_bool timestamp, const char *format, ... ) +{ + va_list args; + + DBUG_ENTER("startup_print_msg_to_logo"); + + va_start( args, format ); + vprint_msg_to_log( event_type, timestamp, format, args ); + va_end( args ); + + DBUG_VOID_RETURN; +} + +/** + * prints a printf style message to the error log and, under NT, to the Windows event log. + * @param event_type type of even to log. + * @param timestamp true to add a timestamp to the entry, false otherwise. + * @param format The printf style format of the message + * @param args va_list prepped arument list + * @return void +*/ +void vprint_msg_to_log(long event_type, my_bool timestamp, const char *format, va_list args) +{ + char buff[1024]; + + DBUG_ENTER("startup_vprint_msg_to_log"); + + my_vsnprintf( buff, sizeof(buff)-5, format, args ); + + print_buffer_to_log( timestamp, buff ); + +#ifndef DBUG_OFF + DBUG_PRINT("error",("%s",buff)); +#endif + +#ifdef __NT__ + HANDLE event; + LPSTR buffptr; + + strcat( buff, "\r\n\r\n" ); + buffptr = (LPSTR)&buff; + setupWindowsEventSource(); + if (event = RegisterEventSource(NULL,"MySQL")) + { + switch (event_type){ + case MY_ERROR_TYPE: + ReportEvent(event, (WORD)event_type, 0, MSG_DEFAULT, NULL, 1, 0, (LPCSTR*)&buffptr, NULL); + break; + case MY_WARNING_TYPE: + ReportEvent(event, (WORD)event_type, 0, MSG_DEFAULT, NULL, 1, 0, (LPCSTR*)&buffptr, NULL); + break; + case MY_INFORMATION_TYPE: + ReportEvent(event, (WORD)event_type, 0, MSG_DEFAULT, NULL, 1, 0, (LPCSTR*)&buffptr, NULL); + break; + } + DeregisterEventSource(event); + } +#endif + DBUG_VOID_RETURN; +} + +void sql_print_error( const char *format, ... ) +{ + DBUG_ENTER( "startup_sql_print_error" ); + + va_list args; + va_start( args, format ); + print_msg_to_log( MY_ERROR_TYPE, true, format, args ); + va_end( args ); + + DBUG_VOID_RETURN; +} + +void sql_print_warning( const char *format, ... ) +{ + DBUG_ENTER( "startup_sql_print_warning" ); + + va_list args; + va_start( args, format ); + print_msg_to_log( MY_WARNING_TYPE, true, format, args ); + va_end( args ); + + DBUG_VOID_RETURN; +} + +void sql_print_information( const char *format, ... ) +{ + DBUG_ENTER( "startup_sql_print_information" ); + + va_list args; + va_start( args, format ); + print_msg_to_log( MY_INFORMATION_TYPE, true, format, args ); + va_end( args ); + + DBUG_VOID_RETURN; +} + +/*void sql_init_fprintf(const char *format,...) +{ + va_list args; + char buff[255]; + buff[0]= 0; + va_start(args,format); + my_vsnprintf(buff,sizeof(buff)-1,format,args); +#ifdef __NT__ + sql_nt_print_error(MY_ERROR_TYPE,buff); +#else + sql_win_print_error(buff); +#endif + va_end(args); +} +*/ + diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2e893ead407..1bc6544b72e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -639,9 +639,27 @@ void key_unpack(String *to,TABLE *form,uint index); bool check_if_key_used(TABLE *table, uint idx, List &fields); void init_errmessage(void); +void vprint_msg_to_log( long errType, my_bool timestamp, const char *format, va_list args ); +void print_msg_to_log( long errType, my_bool timestamp, const char *format, ... ); void sql_perror(const char *message); -void sql_print_error(const char *format,...) - __attribute__ ((format (printf, 1, 2))); + /* __attribute__ ((format (printf, 1, 2))); +*/ + +#define MY_ERROR_TYPE 0x0001 +#define MY_WARNING_TYPE 0x0002 +#define MY_INFORMATION_TYPE 0x0004 + +/*void sql_init_perror(const char *message);*/ +/*void sql_fprintf(const char *format,...) + __attribute__ ((format (printf, 1, 2)));*/ + +/*#define sql_fprintf(format, args...) fprintf (stderr, format, ##args) */ +void sql_print_error( const char *format, ... ); +void sql_print_warning( const char *format, ...); +void sql_print_information( const char *format, ...); + + + bool fn_format_relative_to_data_home(my_string to, const char *name, const char *dir, const char *extension); bool open_log(MYSQL_LOG *log, const char *hostname, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3f7c187ccdd..9191759b2d2 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5095,11 +5095,16 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } /* Initiates DEBUG - but no debugging here ! */ +void option_error_reporter( const char *format, va_list args ) +{ + vprint_msg_to_log( MY_ERROR_TYPE, false, format, args ); +} + static void get_options(int argc,char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, option_error_reporter ))) exit(ho_error); #if defined(HAVE_BROKEN_REALPATH) -- cgit v1.2.1 From a15233457aff295f79abd962f15dc4619e819115 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Aug 2004 17:00:48 +0200 Subject: Fix for BUG#5064 "SET GLOBAL SYNC_BINLOG does not work on some platforms": var->save_result.ulong_value was 0 on Mac OS X probably due to positions of members in the union. sys_var::check() only sets ulonglong_value sql/set_var.cc: Of the save_result union, sys_var::check() only updates ulonglong_value; so other types of the union are garbage. Here we must use ulonglong_value in sys_var_sync_binlog_period::update(), not ulong_value (which is ) --- sql/set_var.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/set_var.cc b/sql/set_var.cc index 2189356e51d..5db4b1476a6 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -34,6 +34,12 @@ - If the variable should show up in 'show variables' add it to the init_vars[] struct in this file + NOTES: + - Be careful with var->save_result: sys_var::check() only updates + ulonglong_value; so other members of the union are garbage then; to use + them you must first assign a value to them (in specific ::check() for + example). + TODO: - Add full support for the variable character_set (for 4.1) @@ -2332,7 +2338,7 @@ bool sys_var_slave_skip_counter::update(THD *thd, set_var *var) bool sys_var_sync_binlog_period::update(THD *thd, set_var *var) { pthread_mutex_t *lock_log= mysql_bin_log.get_log_lock(); - sync_binlog_period= var->save_result.ulong_value; + sync_binlog_period= (ulong) var->save_result.ulonglong_value; /* Must reset the counter otherwise it may already be beyond the new period and so the new period will not be taken into account. Need mutex otherwise -- cgit v1.2.1 From b5ea2224a6a85da3e2192c266a1316dafee05414 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Aug 2004 15:07:45 -0700 Subject: A desperate attempt to comment one place where we do conversions. --- sql/field.cc | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 946f5ed8621..aca1f8846f0 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2332,6 +2332,33 @@ String *Field_double::val_str(String *val_buffer, if (dec >= NOT_FIXED_DEC) { + /* + Let's try to pretty print a floating point number. Here we use + '%-*.*g' conversion string: + '-' stands for left-padding with spaces, if such padding will take + place + '*' is a placeholder for the first argument, field_length, and + signifies minimal width of result string. If result is less than + field length it will be space-padded. Note, however, that we'll not + pass spaces to Field_string::store(const char *, ...), due to + strcend in the next line. + '.*' is a placeholder for DBL_DIG and defines maximum number of + significant digits in the result string. DBL_DIG is a hardware + specific C define for maximum number of decimal digits of a floating + point number, such that rounding to hardware floating point + representation and back to decimal will not lead to loss of + precision. I.e if DBL_DIG is 15, number 123456789111315 can be + represented as double without precision loss. As one can judge from + this description, chosing DBL_DIG here is questionable, especially + because it introduces a system dependency. + 'g' means that conversion will use [-]ddd.ddd (conventional) style, + and fall back to [-]d.ddde[+|i]ddd (scientific) style if there is no + enough space for all digits. + Maximum length of result string (not counting spaces) is (I guess) + DBL_DIG + 8, where 8 is 1 for sign, 1 for decimal point, 1 for + exponent sign, 1 for exponent, and 4 for exponent value. + XXX: why do we use space-padding and trim spaces in the next line? + */ sprintf(to,"%-*.*g",(int) field_length,DBL_DIG,nr); to=strcend(to,' '); } -- cgit v1.2.1 From 5a7dd14edf990e6b23312ad305a92d05874be04c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Aug 2004 02:59:24 +0400 Subject: Fix for bug#4488: sign-aware equality check mysql-test/r/range.result: Fix for bug#4488: more tests mysql-test/t/range.test: Fix for bug#4488: more tests --- sql/item_cmpfunc.cc | 16 ++++++++++++++++ sql/item_cmpfunc.h | 1 + 2 files changed, 17 insertions(+) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e7531e17d34..45a1918de1c 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -325,6 +325,11 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) else if ((*b)->unsigned_flag) func= &Arg_comparator::compare_int_signed_unsigned; } + else if (func== &Arg_comparator::compare_e_int) + { + if ((*a)->unsigned_flag ^ (*b)->unsigned_flag) + func= &Arg_comparator::compare_e_int_diff_signedness; + } } return 0; } @@ -530,6 +535,17 @@ int Arg_comparator::compare_e_int() return test(val1 == val2); } +/* + Compare unsigned *a with signed *b or signed *a with unsigned *b. +*/ +int Arg_comparator::compare_e_int_diff_signedness() +{ + longlong val1= (*a)->val_int(); + longlong val2= (*b)->val_int(); + if ((*a)->null_value || (*b)->null_value) + return test((*a)->null_value && (*b)->null_value); + return (val1 >= 0) && test(val1 == val2); +} int Arg_comparator::compare_row() { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index de2b5e84038..415fae59de9 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -74,6 +74,7 @@ public: int compare_e_binary_string(); // compare args[0] & args[1] int compare_e_real(); // compare args[0] & args[1] int compare_e_int(); // compare args[0] & args[1] + int compare_e_int_diff_signedness(); int compare_e_row(); // compare args[0] & args[1] static arg_cmp_func comparator_matrix [4][2]; -- cgit v1.2.1 From 62c3acac18d629152113aa27f80f4abf98a742ea Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Aug 2004 12:05:34 +0400 Subject: Portablity fix. hpux11 compiler dislikes empty array initializers. --- sql/item_timefunc.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 73aec7e8bdd..5d9a6dd9490 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -113,10 +113,15 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, } -/* Date formats corresponding to compound %r and %T conversion specifiers */ -static DATE_TIME_FORMAT time_ampm_format= {{}, '\0', 0, +/* + Date formats corresponding to compound %r and %T conversion specifiers + + Note: We should init at least first element of "positions" array + (first member) or hpux11 compiler will die horribly. +*/ +static DATE_TIME_FORMAT time_ampm_format= {{0}, '\0', 0, {(char *)"%I:%i:%S %p", 11}}; -static DATE_TIME_FORMAT time_24hrs_format= {{}, '\0', 0, +static DATE_TIME_FORMAT time_24hrs_format= {{0}, '\0', 0, {(char *)"%H:%i:%S", 8}}; /* -- cgit v1.2.1 From ff24b4d5d4142d5e98714b57cfa088a4f661a656 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Aug 2004 01:29:19 -0700 Subject: Fix for not compiling ha_tina. sql/examples/ha_tina.cc: Adding in pieces to remove from compile (aka ifdef). --- sql/examples/ha_tina.cc | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'sql') diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 728af469bb0..06a19e478ae 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -43,6 +43,9 @@ TODO: #endif #include "mysql_priv.h" + +#ifdef HAVE_CSV_DB + #include "ha_tina.h" #include @@ -844,3 +847,5 @@ int ha_tina::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_i DBUG_RETURN(0); } + +#endif /* enable CSV */ -- cgit v1.2.1 From 33ea8b103fb524e1b7939eaa3970ee590f853d6d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Aug 2004 14:03:20 +0000 Subject: automake fix for getting dependencies right for ndb --- sql/Makefile.am | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index 1a984604dbf..3f8a228b94b 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -45,6 +45,7 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @innodb_system_libs@ \ @ndbcluster_libs@ @ndbcluster_system_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ +mysqld_DEPENDENCIES = @ndbcluster_libs@ @ndbcluster_system_libs@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h item_uniq.h \ item_create.h item_subselect.h item_row.h \ -- cgit v1.2.1 From 21a264cc4c39e5aa9c9781d06815bb673c7de39d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Aug 2004 12:20:01 -0300 Subject: Removed non-used variable BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/sql_db.cc | 1 - 1 file changed, 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 82fef3f7c7b..3b12cbe3422 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -560,7 +560,6 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) char path[FN_REFLEN+16], tmp_db[NAME_LEN+1]; MY_DIR *dirp; uint length; - my_dbopt_t *dbopt; DBUG_ENTER("mysql_rm_db"); VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); -- cgit v1.2.1 From fdc8712cb0231a622a53e38ba0d048aa9da4253a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Aug 2004 00:04:43 +0200 Subject: use my_vsnprintf() just in case bug#4925 --- sql/net_pkg.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/net_pkg.cc b/sql/net_pkg.cc index 315cad5ca6d..cc9147fe90a 100644 --- a/sql/net_pkg.cc +++ b/sql/net_pkg.cc @@ -124,7 +124,9 @@ net_printf(NET *net, uint errcode, ...) } offset= net->return_errno ? 2 : 0; text_pos=(char*) net->buff+head_length+offset+1; - (void) vsprintf(my_const_cast(char*) (text_pos),format,args); + (void) my_vsnprintf(my_const_cast(char*) (text_pos), + (char*)net->buff_end-text_pos, + format,args); length=(uint) strlen((char*) text_pos); if (length >= sizeof(net->last_error)) length=sizeof(net->last_error)-1; /* purecov: inspected */ -- cgit v1.2.1 From 002dda7aca32d59807b1b4e2c893a92d639e1dd6 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Aug 2004 02:37:31 +0400 Subject: Renamed Arg_comparator::compare_int -> compare_int_signed --- sql/item_cmpfunc.cc | 4 ++-- sql/item_cmpfunc.h | 2 +- sql/mysqld.cc | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 45a1918de1c..c440a0491c5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -317,7 +317,7 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) } else if (type == INT_RESULT) { - if (func == &Arg_comparator::compare_int) + if (func == &Arg_comparator::compare_int_signed) { if ((*a)->unsigned_flag) func= ((*b)->unsigned_flag)? &Arg_comparator::compare_int_unsigned : @@ -432,7 +432,7 @@ int Arg_comparator::compare_e_real() return test(val1 == val2); } -int Arg_comparator::compare_int() +int Arg_comparator::compare_int_signed() { longlong val1= (*a)->val_int(); if (!(*a)->null_value) diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 415fae59de9..4f2dcb6a412 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -65,7 +65,7 @@ public: int compare_string(); // compare args[0] & args[1] int compare_binary_string(); // compare args[0] & args[1] int compare_real(); // compare args[0] & args[1] - int compare_int(); // compare args[0] & args[1] + int compare_int_signed(); // compare args[0] & args[1] int compare_int_signed_unsigned(); int compare_int_unsigned_signed(); int compare_int_unsigned(); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7522cbc7c41..be3d9f01a8b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -237,10 +237,10 @@ bool opt_help= 0; bool opt_verbose= 0; arg_cmp_func Arg_comparator::comparator_matrix[4][2] = -{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string}, - {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real}, - {&Arg_comparator::compare_int, &Arg_comparator::compare_e_int}, - {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row}}; +{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string}, + {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real}, + {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int}, + {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row}}; /* Global variables */ -- cgit v1.2.1 From 0c062ae60f9dbb21ce3702389f89e4441451d02b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Aug 2004 01:48:01 +0300 Subject: srv0start.c, ut0mem.c, ut0dbg.c, ut0dbg.h, srv0start.h: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) mysqld.cc, ha_innodb.cc: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) sql/ha_innodb.cc: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) sql/mysqld.cc: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) innobase/include/srv0start.h: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) innobase/include/ut0dbg.h: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) innobase/ut/ut0dbg.c: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) innobase/ut/ut0mem.c: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) innobase/srv/srv0start.c: Changes for NetWare to exit the InnoDB gracefully instead of crashing the server (patch by PRam@novell.com, polished a little by Heikki Tuuri) --- sql/ha_innodb.cc | 9 +++++++++ sql/mysqld.cc | 3 +++ 2 files changed, 12 insertions(+) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index f233dd5a5c5..22ddfe779d5 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -121,6 +121,10 @@ char innodb_dummy_stmt_trx_handle = 'D'; static HASH innobase_open_tables; +#ifdef __NETWARE__ /* some special cleanup for NetWare */ +bool nw_panic = FALSE; +#endif + static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length, my_bool not_used __attribute__((unused))); static INNOBASE_SHARE *get_share(const char *table_name); @@ -950,6 +954,11 @@ innobase_end(void) DBUG_ENTER("innobase_end"); +#ifdef __NETWARE__ /* some special cleanup for NetWare */ + if (nw_panic) { + set_panic_flag_for_netware(); + } +#endif err = innobase_shutdown_for_mysql(); hash_free(&innobase_open_tables); my_free(internal_innobase_data_file_path,MYF(MY_ALLOW_ZERO_PTR)); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8f08099f340..e4d60fc9e7c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1547,6 +1547,8 @@ void registerwithneb() ulong neb_event_callback(struct EventBlock *eblock) { EventChangeVolStateEnter_s *voldata; + extern bool nw_panic; + voldata= (EventChangeVolStateEnter_s *)eblock->EBEventData; /* Deactivation of a volume */ @@ -1559,6 +1561,7 @@ ulong neb_event_callback(struct EventBlock *eblock) if (!memcmp(&voldata->volID, &datavolid, sizeof(VolumeID_t))) { consoleprintf("MySQL data volume is deactivated, shutting down MySQL Server \n"); + nw_panic = TRUE; kill_server(0); } } -- cgit v1.2.1 From eda663a155d6127d05bfd1beadc648136122b820 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Aug 2004 12:07:54 +0500 Subject: Many files: LIKE crashed mysqld for binary collations in some cases strings/ctype-big5.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-euc_kr.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-gb2312.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-gbk.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-latin1.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-sjis.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-tis620.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-ucs2.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-ujis.c: LIKE crashed mysqld for binary collations in some cases strings/ctype-utf8.c: LIKE crashed mysqld for binary collations in some cases sql/item_cmpfunc.cc: LIKE crashed mysqld for binary collations in some cases --- sql/item_cmpfunc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c440a0491c5..23bdad1aae5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2459,7 +2459,7 @@ void Item_func_like::turboBM_compute_suffixes(int *suff) *splm1 = pattern_len; - if (cs == &my_charset_bin) + if (!cs->sort_order) { int i; for (i = pattern_len - 2; i >= 0; i--) @@ -2562,7 +2562,7 @@ void Item_func_like::turboBM_compute_bad_character_shifts() for (i = bmBc; i < end; i++) *i = pattern_len; - if (cs == &my_charset_bin) + if (!cs->sort_order) { for (j = 0; j < plm1; j++) bmBc[(uint) (uchar) pattern[j]] = plm1 - j; @@ -2593,7 +2593,7 @@ bool Item_func_like::turboBM_matches(const char* text, int text_len) const const int tlmpl= text_len - pattern_len; /* Searching */ - if (cs == &my_charset_bin) + if (!cs->sort_order) { while (j <= tlmpl) { -- cgit v1.2.1 From 0c6b96658e96cc604c9c5fedb41a5e43bad4f74b Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Aug 2004 14:46:31 +0200 Subject: Bug 4937: different date -> string conversion when using SELECT ... UNION and INSERT ... SELECT ... UNION --- sql/field.cc | 90 +++++++++++++++++++++++++++++++++--------------------------- sql/field.h | 3 +- 2 files changed, 52 insertions(+), 41 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index aca1f8846f0..33717d99583 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -37,6 +37,7 @@ #include "sql_select.h" #include #include +#include #ifdef HAVE_FCONVERT #include #endif @@ -58,6 +59,8 @@ template class List_iterator; uchar Field_null::null[1]={1}; const char field_separator=','; +#define DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE 320 + /***************************************************************************** Static help functions *****************************************************************************/ @@ -739,7 +742,7 @@ void Field_decimal::store(double nr) reg4 uint i,length; char fyllchar,*to; - char buff[320]; + char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; fyllchar = zerofill ? (char) '0' : (char) ' '; #ifdef HAVE_SNPRINTF @@ -2326,46 +2329,20 @@ String *Field_double::val_str(String *val_buffer, #endif doubleget(nr,ptr); - uint to_length=max(field_length,320); + uint to_length=max(field_length, DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE); val_buffer->alloc(to_length); char *to=(char*) val_buffer->ptr(); if (dec >= NOT_FIXED_DEC) { - /* - Let's try to pretty print a floating point number. Here we use - '%-*.*g' conversion string: - '-' stands for left-padding with spaces, if such padding will take - place - '*' is a placeholder for the first argument, field_length, and - signifies minimal width of result string. If result is less than - field length it will be space-padded. Note, however, that we'll not - pass spaces to Field_string::store(const char *, ...), due to - strcend in the next line. - '.*' is a placeholder for DBL_DIG and defines maximum number of - significant digits in the result string. DBL_DIG is a hardware - specific C define for maximum number of decimal digits of a floating - point number, such that rounding to hardware floating point - representation and back to decimal will not lead to loss of - precision. I.e if DBL_DIG is 15, number 123456789111315 can be - represented as double without precision loss. As one can judge from - this description, chosing DBL_DIG here is questionable, especially - because it introduces a system dependency. - 'g' means that conversion will use [-]ddd.ddd (conventional) style, - and fall back to [-]d.ddde[+|i]ddd (scientific) style if there is no - enough space for all digits. - Maximum length of result string (not counting spaces) is (I guess) - DBL_DIG + 8, where 8 is 1 for sign, 1 for decimal point, 1 for - exponent sign, 1 for exponent, and 4 for exponent value. - XXX: why do we use space-padding and trim spaces in the next line? - */ sprintf(to,"%-*.*g",(int) field_length,DBL_DIG,nr); to=strcend(to,' '); } else { #ifdef HAVE_FCONVERT - char buff[320],*pos=buff; + char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE], + char *pos= buff; int decpt,sign,tmp_dec=dec; VOID(fconvert(nr,tmp_dec,&decpt,&sign,buff)); @@ -3721,13 +3698,50 @@ void Field_string::store(const char *from,uint length) } +/* + Store double value in Field_string or Field_varstring. + + SYNOPSIS + store_double_in_string_field() + field field to store value in + field_length number of characters in the field + nr number + + DESCRIPTION + Pretty prints double number into field_length characters buffer. +*/ + +static void store_double_in_string_field(Field_str *field, uint32 field_length, + double nr) +{ + bool use_scientific_notation=TRUE; + char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; + int length; + if (field_length < 32 && nr > 1) + { + if (field->ceiling == 0) + { + static double e[]= {1e1, 1e2, 1e4, 1e8, 1e16 }; + double p= 1; + for (int i= sizeof(e)/sizeof(e[0]), j= 1<>= 1 ) + { + if (field_length & j) + p*= e[i]; + } + field->ceiling= p-1; + } + use_scientific_notation= (field->ceiling < nr); + } + length= sprintf(buff, "%-.*g", + use_scientific_notation ? max(0,field_length-5) : field_length, + nr); + DBUG_ASSERT(length <= field_length); + field->store(buff, (uint) length); +} + void Field_string::store(double nr) { - char buff[MAX_FIELD_WIDTH],*end; - int width=min(field_length,DBL_DIG+5); - sprintf(buff,"%-*.*g",width,max(width-5,0),nr); - end=strcend(buff,' '); - Field_string::store(buff,(uint) (end - buff)); + store_double_in_string_field(this, field_length, nr); } @@ -3927,11 +3941,7 @@ void Field_varstring::store(const char *from,uint length) void Field_varstring::store(double nr) { - char buff[MAX_FIELD_WIDTH],*end; - int width=min(field_length,DBL_DIG+5); - sprintf(buff,"%-*.*g",width,max(width-5,0),nr); - end=strcend(buff,' '); - Field_varstring::store(buff,(uint) (end - buff)); + store_double_in_string_field(this, field_length, nr); } diff --git a/sql/field.h b/sql/field.h index d93ed1db9b5..d25ce8d4774 100644 --- a/sql/field.h +++ b/sql/field.h @@ -255,12 +255,13 @@ public: class Field_str :public Field { public: + double ceiling; // for ::store(double nr) Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg) :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg) + unireg_check_arg, field_name_arg, table_arg), ceiling(0.0) {} Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } -- cgit v1.2.1 From 86fdb8b977a57d074d245df4b5a9df4a79b42394 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Aug 2004 19:13:39 +0200 Subject: Fix for WL#1731 Handler: multiple databases --- sql/ha_ndbcluster.cc | 104 ++++++++++++++++++++++++++++++++++++++------------- sql/ha_ndbcluster.h | 12 +++++- 2 files changed, 87 insertions(+), 29 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 702be862328..1c5ed940c7c 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -545,20 +545,19 @@ int ha_ndbcluster::get_metadata(const char *path) DBUG_RETURN(build_index_list()); } -int ha_ndbcluster::build_index_list() +int ha_ndbcluster::build_index_list0() { char *name; const char *index_name; static const char* unique_suffix= "$unique"; uint i, name_len; - DBUG_ENTER("build_index_list"); + DBUG_ENTER("build_index_list0"); // Save information about all known indexes for (i= 0; i < table->keys; i++) { NDB_INDEX_TYPE idx_type= get_index_type_from_table(i); - m_indextype[i]= idx_type; - + m_index[i].type= idx_type; if (idx_type == UNIQUE_ORDERED_INDEX || idx_type == UNIQUE_INDEX) { index_name= get_index_name(i); @@ -567,7 +566,7 @@ int ha_ndbcluster::build_index_list() if (!(name= my_malloc(name_len, MYF(MY_WME)))) DBUG_RETURN(2); strxnmov(name, name_len, index_name, unique_suffix, NullS); - m_unique_index_name[i]= name; + m_index[i].unique_name = name; DBUG_PRINT("info", ("Created unique index name: %s for index %d", name, i)); } @@ -575,7 +574,44 @@ int ha_ndbcluster::build_index_list() DBUG_RETURN(0); } +int ha_ndbcluster::build_index_list1() +{ + uint i; + NdbDictionary::Dictionary *dict= m_ndb->getDictionary(); + DBUG_ENTER("build_index_object_list1"); + // Add direct references to index objects + for (i= 0; i < table->keys; i++) + { + DBUG_PRINT("info", ("Trying to add handle to index %s", get_index_name(i))); + if ((m_index[i].type != PRIMARY_KEY_INDEX) && + (m_index[i].type != UNIQUE_INDEX)) + { + const NDBINDEX *index= dict->getIndex(get_index_name(i), m_tabname); + if (!index) DBUG_RETURN(1); + m_index[i].index = (void *) index; + } + if (m_index[i].unique_name) + { + const NDBINDEX *index= dict->getIndex(m_index[i].unique_name, m_tabname); + if (!index) DBUG_RETURN(1); + m_index[i].unique_index = (void *) index; + } + DBUG_PRINT("info", ("Added handle to index %s", get_index_name(i))); + } + DBUG_RETURN(0); +} + +int ha_ndbcluster::build_index_list() +{ + int res; + DBUG_ENTER("build_index_list"); + if ((res= build_index_list0())) + DBUG_RETURN(res); + if ((res= build_index_list1())) + DBUG_RETURN(res); + DBUG_RETURN(0); +} /* Decode the type of an index from information @@ -605,9 +641,11 @@ void ha_ndbcluster::release_metadata() // Release index list for (i= 0; i < MAX_KEY; i++) { - if (m_unique_index_name[i]) - my_free((char*)m_unique_index_name[i], MYF(0)); - m_unique_index_name[i]= NULL; + if (m_index[i].unique_name) + my_free((char*)m_index[i].unique_name, MYF(0)); + m_index[i].unique_name= NULL; + m_index[i].unique_index= NULL; + m_index[i].index= NULL; } DBUG_VOID_RETURN; @@ -667,13 +705,13 @@ inline const char* ha_ndbcluster::get_index_name(uint idx_no) const inline const char* ha_ndbcluster::get_unique_index_name(uint idx_no) const { - return m_unique_index_name[idx_no]; + return m_index[idx_no].unique_name; } inline NDB_INDEX_TYPE ha_ndbcluster::get_index_type(uint idx_no) const { DBUG_ASSERT(idx_no < MAX_KEY); - return m_indextype[idx_no]; + return m_index[idx_no].type; } @@ -763,7 +801,8 @@ int ha_ndbcluster::pk_read(const byte *key, uint key_len, byte *buf) DBUG_PRINT("enter", ("key_len: %u", key_len)); DBUG_DUMP("key", (char*)key, key_len); - if (!(op= trans->getNdbOperation(m_tabname)) || op->readTuple() != 0) + if (!(op= trans->getNdbOperation((NDBTAB *) m_table)) || + op->readTuple() != 0) ERR_RETURN(trans->getNdbError()); if (table->primary_key == MAX_KEY) @@ -831,7 +870,8 @@ int ha_ndbcluster::complemented_pk_read(const byte *old_data, byte *new_data) // We have allready retrieved all fields, nothing to complement DBUG_RETURN(0); - if (!(op= trans->getNdbOperation(m_tabname)) || op->readTuple() != 0) + if (!(op= trans->getNdbOperation((NDBTAB *) m_table)) || + op->readTuple() != 0) ERR_RETURN(trans->getNdbError()); int res; @@ -882,8 +922,9 @@ int ha_ndbcluster::unique_index_read(const byte *key, DBUG_DUMP("key", (char*)key, key_len); DBUG_PRINT("enter", ("name: %s", get_unique_index_name(active_index))); - if (!(op= trans->getNdbIndexOperation(get_unique_index_name(active_index), - m_tabname)) || + if (!(op= trans->getNdbIndexOperation((NDBINDEX *) + m_index[active_index].unique_index, + (NDBTAB *) m_table)) || op->readTuple() != 0) ERR_RETURN(trans->getNdbError()); @@ -1083,7 +1124,9 @@ int ha_ndbcluster::ordered_index_scan(const key_range *start_key, DBUG_PRINT("enter", ("Starting new ordered scan on %s", m_tabname)); index_name= get_index_name(active_index); - if (!(op= trans->getNdbIndexScanOperation(index_name, m_tabname))) + if (!(op= trans->getNdbIndexScanOperation((NDBINDEX *) + m_index[active_index].index, + (NDBTAB *) m_table))) ERR_RETURN(trans->getNdbError()); NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) @@ -1146,7 +1189,7 @@ int ha_ndbcluster::filtered_scan(const byte *key, uint key_len, DBUG_PRINT("info", ("Starting a new filtered scan on %s", m_tabname)); - if (!(op= trans->getNdbScanOperation(m_tabname))) + if (!(op= trans->getNdbScanOperation((NDBTAB *) m_table))) ERR_RETURN(trans->getNdbError()); NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) get_ndb_lock_type(m_lock.type); @@ -1217,7 +1260,7 @@ int ha_ndbcluster::full_table_scan(byte *buf) DBUG_ENTER("full_table_scan"); DBUG_PRINT("enter", ("Starting new scan on %s", m_tabname)); - if (!(op=trans->getNdbScanOperation(m_tabname))) + if (!(op=trans->getNdbScanOperation((NDBTAB *) m_table))) ERR_RETURN(trans->getNdbError()); NdbScanOperation::LockMode lm= (NdbScanOperation::LockMode) get_ndb_lock_type(m_lock.type); @@ -1294,7 +1337,7 @@ int ha_ndbcluster::write_row(byte *record) has_auto_increment= (table->next_number_field && record == table->record[0]); skip_auto_increment= table->auto_increment_field_not_null; - if (!(op= trans->getNdbOperation(m_tabname))) + if (!(op= trans->getNdbOperation((NDBTAB *) m_table))) ERR_RETURN(trans->getNdbError()); res= (m_use_write) ? op->writeTuple() :op->insertTuple(); @@ -1304,7 +1347,7 @@ int ha_ndbcluster::write_row(byte *record) if (table->primary_key == MAX_KEY) { // Table has hidden primary key - Uint64 auto_value= m_ndb->getAutoIncrementValue(m_tabname); + Uint64 auto_value= m_ndb->getAutoIncrementValue((NDBTAB *) m_table); if (set_hidden_key(op, table->fields, (const byte*)&auto_value)) ERR_RETURN(op->getNdbError()); } @@ -1360,7 +1403,7 @@ int ha_ndbcluster::write_row(byte *record) Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1; DBUG_PRINT("info", ("Trying to set next auto increment value to %u", next_val)); - if (m_ndb->setAutoIncrementValue(m_tabname, next_val, true)) + if (m_ndb->setAutoIncrementValue((NDBTAB *) m_table, next_val, true)) DBUG_PRINT("info", ("Setting next auto increment value to %u", next_val)); } @@ -1473,7 +1516,7 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) } else { - if (!(op= trans->getNdbOperation(m_tabname)) || + if (!(op= trans->getNdbOperation((NDBTAB *) m_table)) || op->updateTuple() != 0) ERR_RETURN(trans->getNdbError()); @@ -1551,7 +1594,7 @@ int ha_ndbcluster::delete_row(const byte *record) else { - if (!(op=trans->getNdbOperation(m_tabname)) || + if (!(op=trans->getNdbOperation((NDBTAB *) m_table)) || op->deleteTuple() != 0) ERR_RETURN(trans->getNdbError()); @@ -2840,7 +2883,7 @@ int ha_ndbcluster::create(const char *name, DBUG_PRINT("info", ("Table %s/%s created successfully", m_dbname, m_tabname)); - if ((my_errno= build_index_list())) + if ((my_errno= build_index_list0())) DBUG_RETURN(my_errno); // Create secondary indexes @@ -2882,6 +2925,10 @@ int ha_ndbcluster::create(const char *name, break; } } + + if (!(my_errno) && (my_errno= build_index_list1())) + DBUG_RETURN(my_errno); + DBUG_RETURN(my_errno); } @@ -2918,6 +2965,7 @@ int ha_ndbcluster::create_index(const char *name, DBUG_ENTER("create_index"); DBUG_PRINT("enter", ("name: %s ", name)); + // NdbDictionary::Index ndb_index(name); NdbDictionary::Index ndb_index(name); if (unique) ndb_index.setType(NdbDictionary::Index::UniqueHashIndex); @@ -3059,8 +3107,8 @@ longlong ha_ndbcluster::get_auto_increment() : autoincrement_prefetch; Uint64 auto_value= (skip_auto_increment) ? - m_ndb->readAutoIncrementValue(m_tabname) - : m_ndb->getAutoIncrementValue(m_tabname, cache_size); + m_ndb->readAutoIncrementValue((NDBTAB *) m_table) + : m_ndb->getAutoIncrementValue((NDBTAB *) m_table, cache_size); DBUG_RETURN((longlong)auto_value); } @@ -3104,8 +3152,10 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): for (i= 0; i < MAX_KEY; i++) { - m_indextype[i]= UNDEFINED_INDEX; - m_unique_index_name[i]= NULL; + m_index[i].type= UNDEFINED_INDEX; + m_index[i].unique_name= NULL; + m_index[i].unique_index= NULL; + m_index[i].index= NULL; } DBUG_VOID_RETURN; diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index a207e974a16..84c3d2092e8 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -37,6 +37,7 @@ class NdbScanOperation; class NdbIndexScanOperation; class NdbBlob; + typedef enum ndb_index_type { UNDEFINED_INDEX = 0, PRIMARY_KEY_INDEX = 1, @@ -46,6 +47,12 @@ typedef enum ndb_index_type { ORDERED_INDEX = 5 } NDB_INDEX_TYPE; +typedef struct ndb_index_data { + NDB_INDEX_TYPE type; + void *index; + const char * unique_name; + void *unique_index; +} NDB_INDEX_DATA; typedef struct st_ndbcluster_share { THR_LOCK lock; @@ -149,6 +156,8 @@ class ha_ndbcluster: public handler int create_ordered_index(const char *name, KEY *key_info); int create_unique_index(const char *name, KEY *key_info); int initialize_autoincrement(const void* table); + int build_index_list0(); + int build_index_list1(); int build_index_list(); int get_metadata(const char* path); void release_metadata(); @@ -211,8 +220,7 @@ class ha_ndbcluster: public handler ulong m_table_flags; THR_LOCK_DATA m_lock; NDB_SHARE *m_share; - NDB_INDEX_TYPE m_indextype[MAX_KEY]; - const char* m_unique_index_name[MAX_KEY]; + NDB_INDEX_DATA m_index[MAX_KEY]; // NdbRecAttr has no reference to blob typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue; NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE]; -- cgit v1.2.1 From 4736e7d4bdcde029923518826db33da6a38a6c01 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Aug 2004 22:31:01 +0200 Subject: BUG# 4466 - Nothing in .err when mysql service ends because of malformed my.ini options mysqld.cc: Changed option_error_reporter to match new function header that includes LOGLEVEL enum mysql_priv.h: Removed the MY_ERROR style bitmask. Changed function headers to use new LOGLEVEL enum log.cc: Changed print_buffer_to_log to print_buffer_to_file. Remove the timestamp bool and now all log entries written to stderr are timestamped. Removed some unused commented code. changed to use the new LOGLEVEL enum. my_getopt.c: Changed functions to use the new LOGLEVEL enum and changed the included error reporter to be default_reporter. This reporter is used in handle_options if a reporter is not given my_getopt.h: changed typedefs to use better naming convention. Moved error bitmask into the LOGLEVEL enum and included it here. include/my_getopt.h: changed typedefs to use better naming convention. Moved error bitmask into the LOGLEVEL enum and included it here. mysys/my_getopt.c: Changed functions to use the new LOGLEVEL enum and changed the included error reporter to be default_reporter. This reporter is used in handle_options if a reporter is not given sql/log.cc: Changed print_buffer_to_log to print_buffer_to_file. Remove the timestamp bool and now all log entries written to stderr are timestamped. Removed some unused commented code. changed to use the new LOGLEVEL enum. sql/mysql_priv.h: Removed the MY_ERROR style bitmask. Changed function headers to use new LOGLEVEL enum sql/mysqld.cc: Changed option_error_reporter to match new function header that includes LOGLEVEL enum --- sql/log.cc | 148 +++++++++++++++++++++++++++++-------------------------- sql/mysql_priv.h | 16 ++---- sql/mysqld.cc | 7 ++- 3 files changed, 87 insertions(+), 84 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index 3d76f9d5634..a487de250db 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1716,41 +1716,32 @@ static bool test_if_number(register const char *str, } /* test_if_number */ -void print_buffer_to_log( my_bool timestamp, const char *buffer ) +void print_buffer_to_file( enum LOGLEVEL level, const char *buffer ) { time_t skr; struct tm tm_tmp; struct tm *start; - DBUG_ENTER("sql_print_buffer_to_log"); + DBUG_ENTER("startup_print_buffer_to_log"); -#if !defined(__WIN__) && !defined(__NT__) VOID(pthread_mutex_lock(&LOCK_error_log)); -#endif - if (timestamp) - { - skr=time(NULL); - localtime_r(&skr, &tm_tmp); - start=&tm_tmp; - fprintf( stderr, "%02d%02d%02d %2d:%02d:%02d %s", + skr=time(NULL); + localtime_r(&skr, &tm_tmp); + start=&tm_tmp; + fprintf( stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", start->tm_year % 100, start->tm_mon+1, start->tm_mday, start->tm_hour, start->tm_min, start->tm_sec, + level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? "WARNING" : "INFORMATION", buffer ); - } - else - fprintf( stderr, "%s", buffer ); - fputc('\n', stderr); fflush(stderr); -#if !defined(__WIN__) && !defined(__NT__) VOID(pthread_mutex_unlock(&LOCK_error_log)); -#endif DBUG_VOID_RETURN; } @@ -1819,28 +1810,82 @@ bool flush_error_log() * @param ... values for the message * @return void */ -void print_msg_to_log( long event_type, my_bool timestamp, const char *format, ... ) +void print_msg_to_log( LOGLEVEL level, const char *format, ... ) { va_list args; - DBUG_ENTER("startup_print_msg_to_logo"); + DBUG_ENTER("startup_print_msg_to_log"); va_start( args, format ); - vprint_msg_to_log( event_type, timestamp, format, args ); + vprint_msg_to_log( level, format, args ); va_end( args ); DBUG_VOID_RETURN; } -/** - * prints a printf style message to the error log and, under NT, to the Windows event log. - * @param event_type type of even to log. - * @param timestamp true to add a timestamp to the entry, false otherwise. - * @param format The printf style format of the message - * @param args va_list prepped arument list - * @return void + +#ifdef __NT__ +void print_buffer_to_nt_eventlog( enum LOGLEVEL level, char *buff, int buffLen ) +{ + HANDLE event; + char *buffptr; + LPCSTR *buffmsgptr; + + buffptr = buff; + if (strlen(buff) > (uint)(buffLen-4)) + { + char *newBuff = new char[ strlen(buff) + 4 ]; + strcpy( newBuff, buff ); + buffptr = newBuff; + } + strcat( buffptr, "\r\n\r\n" ); + buffmsgptr = (LPCSTR*)&buffptr; + + setupWindowsEventSource(); + if (event = RegisterEventSource(NULL,"MySQL")) + { + switch (level){ + case ERROR_LEVEL: + ReportEvent(event, EVENTLOG_ERROR_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + break; + case WARNING_LEVEL: + ReportEvent(event, EVENTLOG_WARNING_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + break; + case INFORMATION_LEVEL: + ReportEvent(event, EVENTLOG_INFORMATION_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + break; + } + DeregisterEventSource(event); + } + + // if we created a string buffer, then delete it + if ( buffptr != buff ) + delete[] buffptr; + + + DBUG_VOID_RETURN; +} +#endif + +/* + Prints a printf style message to the error log and, under NT, to the Windows event log. + + SYNOPSIS + vprint_msg_to_log() + event_type Type of event to write (Error, Warning, or Info) + format Printf style format of message + args va_list list of arguments for the message + + NOTE + + IMPLEMENTATION + This function prints the message into a buffer and then sends that buffer to other + functions to write that message to other logging sources. + + RETURN VALUES + void */ -void vprint_msg_to_log(long event_type, my_bool timestamp, const char *format, va_list args) +void vprint_msg_to_log(enum LOGLEVEL level, const char *format, va_list args) { char buff[1024]; @@ -1848,45 +1893,27 @@ void vprint_msg_to_log(long event_type, my_bool timestamp, const char *format, v my_vsnprintf( buff, sizeof(buff)-5, format, args ); - print_buffer_to_log( timestamp, buff ); + print_buffer_to_file( level, buff ); #ifndef DBUG_OFF DBUG_PRINT("error",("%s",buff)); #endif #ifdef __NT__ - HANDLE event; - LPSTR buffptr; - - strcat( buff, "\r\n\r\n" ); - buffptr = (LPSTR)&buff; - setupWindowsEventSource(); - if (event = RegisterEventSource(NULL,"MySQL")) - { - switch (event_type){ - case MY_ERROR_TYPE: - ReportEvent(event, (WORD)event_type, 0, MSG_DEFAULT, NULL, 1, 0, (LPCSTR*)&buffptr, NULL); - break; - case MY_WARNING_TYPE: - ReportEvent(event, (WORD)event_type, 0, MSG_DEFAULT, NULL, 1, 0, (LPCSTR*)&buffptr, NULL); - break; - case MY_INFORMATION_TYPE: - ReportEvent(event, (WORD)event_type, 0, MSG_DEFAULT, NULL, 1, 0, (LPCSTR*)&buffptr, NULL); - break; - } - DeregisterEventSource(event); - } + print_buffer_to_nt_eventlog( level, buff, sizeof(buff) ); #endif + DBUG_VOID_RETURN; } + void sql_print_error( const char *format, ... ) { DBUG_ENTER( "startup_sql_print_error" ); va_list args; va_start( args, format ); - print_msg_to_log( MY_ERROR_TYPE, true, format, args ); + print_msg_to_log( ERROR_LEVEL, format, args ); va_end( args ); DBUG_VOID_RETURN; @@ -1898,7 +1925,7 @@ void sql_print_warning( const char *format, ... ) va_list args; va_start( args, format ); - print_msg_to_log( MY_WARNING_TYPE, true, format, args ); + print_msg_to_log( WARNING_LEVEL, format, args ); va_end( args ); DBUG_VOID_RETURN; @@ -1910,25 +1937,8 @@ void sql_print_information( const char *format, ... ) va_list args; va_start( args, format ); - print_msg_to_log( MY_INFORMATION_TYPE, true, format, args ); + print_msg_to_log( INFORMATION_LEVEL, format, args ); va_end( args ); DBUG_VOID_RETURN; } - -/*void sql_init_fprintf(const char *format,...) -{ - va_list args; - char buff[255]; - buff[0]= 0; - va_start(args,format); - my_vsnprintf(buff,sizeof(buff)-1,format,args); -#ifdef __NT__ - sql_nt_print_error(MY_ERROR_TYPE,buff); -#else - sql_win_print_error(buff); -#endif - va_end(args); -} -*/ - diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1bc6544b72e..ed8b4bd2457 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -24,6 +24,7 @@ #include #include /* Needed by field.h */ #include +#include #ifdef __EMX__ #undef write /* remove pthread.h macro definition for EMX */ @@ -639,21 +640,10 @@ void key_unpack(String *to,TABLE *form,uint index); bool check_if_key_used(TABLE *table, uint idx, List &fields); void init_errmessage(void); -void vprint_msg_to_log( long errType, my_bool timestamp, const char *format, va_list args ); -void print_msg_to_log( long errType, my_bool timestamp, const char *format, ... ); +void vprint_msg_to_log( enum LOGLEVEL level, const char *format, va_list args ); +void print_msg_to_log( enum LOGLEVEL level, const char *format, ... ); void sql_perror(const char *message); - /* __attribute__ ((format (printf, 1, 2))); -*/ - -#define MY_ERROR_TYPE 0x0001 -#define MY_WARNING_TYPE 0x0002 -#define MY_INFORMATION_TYPE 0x0004 - -/*void sql_init_perror(const char *message);*/ -/*void sql_fprintf(const char *format,...) - __attribute__ ((format (printf, 1, 2)));*/ -/*#define sql_fprintf(format, args...) fprintf (stderr, format, ##args) */ void sql_print_error( const char *format, ... ); void sql_print_warning( const char *format, ...); void sql_print_information( const char *format, ...); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9191759b2d2..d70f61c5c22 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5095,9 +5095,12 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } /* Initiates DEBUG - but no debugging here ! */ -void option_error_reporter( const char *format, va_list args ) +void option_error_reporter( enum LOGLEVEL level, const char *format, ... ) { - vprint_msg_to_log( MY_ERROR_TYPE, false, format, args ); + va_list args; + va_start( args, format ); + vprint_msg_to_log( level, format, args ); + va_end( args ); } static void get_options(int argc,char **argv) -- cgit v1.2.1 From 95334ac6c724b42da5c1960f4546b6e9670e83d6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 00:29:11 +0200 Subject: Fix for BUG#4971 "CREATE TABLE ... TYPE=HEAP SELECT ... stops slave (wrong DELETE in binlog)": replacing the no_log argument of mysql_create_table() by some safer method (temporarily setting OPTION_BIN_LOG to 0) which guarantees that even the automatic DELETE FROM heap_table does not get into the binlog when a not-yet-existing HEAP table is opened by mysql_create_table(). mysql-test/r/rpl_heap.result: result update mysql-test/t/rpl_heap.test: testing a bug sql/log.cc: new class Disable_binlog used to temporarily disable binlogging for one thread. sql/mysql_priv.h: removing argument no_log from mysql_create_table(); no_log was perfect as some binlogging could still be done by open_unireg_entry() for a HEAP table. sql/sql_class.h: new class Disable_binlog used to temporarily disable binlogging for one thread. sql/sql_parse.cc: removing no_log sql/sql_table.cc: removing no_log from mysql_create_table(); instead using new class Disable_binlog. Disabling binlogging in some cases, where the binlogging is done later by some other code (case of CREATE SELECT and ALTER). --- sql/log.cc | 16 ++++++++++++++++ sql/mysql_priv.h | 2 +- sql/sql_class.h | 21 +++++++++++++++++++++ sql/sql_parse.cc | 2 +- sql/sql_table.cc | 28 +++++++++++++++++++++------- 5 files changed, 60 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index e031656cc6e..2956efc047f 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1627,6 +1627,22 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg) } +Disable_binlog::Disable_binlog(THD *thd_arg) : + thd(thd_arg), + save_options(thd_arg->options), save_master_access(thd_arg->master_access) +{ + thd_arg->options&= ~OPTION_BIN_LOG; + thd_arg->master_access|= SUPER_ACL; // unneeded in 4.1 +}; + + +Disable_binlog::~Disable_binlog() +{ + thd->options= save_options; + thd->master_access= save_master_access; +} + + /* Check if a string is a valid number diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2e893ead407..ca4b8d2c2b9 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -438,7 +438,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, List &fields, List &keys, - bool tmp_table, bool no_log); + bool tmp_table); TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, const char *db, const char *name, List *extra_fields, diff --git a/sql/sql_class.h b/sql/sql_class.h index e646d33fe5d..8284cd23b9e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -638,6 +638,27 @@ public: #define SYSTEM_THREAD_SLAVE_IO 2 #define SYSTEM_THREAD_SLAVE_SQL 4 +/* + Disables binary logging for one thread, and resets it back to what it was + before being disabled. + Some functions (like the internal mysql_create_table() when it's called by + mysql_alter_table()) must NOT write to the binlog (binlogging is done at the + at a later stage of the command already, and must be, for locking reasons); + so we internally disable it temporarily by creating the Disable_binlog + object and reset the state by destroying the object (don't forget that! or + write code so that the object gets automatically destroyed when leaving a + function...). +*/ +class Disable_binlog { +private: + THD *thd; + ulong save_options; + ulong save_master_access; +public: + Disable_binlog(THD *thd_arg); + ~Disable_binlog(); +}; + /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 39c1a78b081..7a5260a78f0 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1692,7 +1692,7 @@ mysql_execute_command(void) tables->real_name, &lex->create_info, lex->create_list, - lex->key_list,0, 0); // do logging + lex->key_list,0); if (!res) send_ok(&thd->net); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7f4a8583b78..c09892ac48b 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -336,7 +336,6 @@ static int sort_keys(KEY *a, KEY *b) keys List of keys to create tmp_table Set to 1 if this is an internal temporary table (From ALTER TABLE) - no_log Don't log the query to binary log. DESCRIPTION If one creates a temporary table, this is automaticly opened @@ -354,7 +353,7 @@ static int sort_keys(KEY *a, KEY *b) int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, List &fields, - List &keys,bool tmp_table,bool no_log) + List &keys,bool tmp_table) { char path[FN_REFLEN]; const char *key_name, *alias; @@ -779,7 +778,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, goto end; } } - if (!tmp_table && !no_log) + if (!tmp_table) { // Must be written before unlock mysql_update_log.write(thd,thd->query, thd->query_length); @@ -843,6 +842,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE tmp_table; // Used during 'create_field()' TABLE *table; tmp_table.table_name=0; + Disable_binlog disable_binlog(thd); DBUG_ENTER("create_table_from_items"); /* Add selected items to field list */ @@ -873,9 +873,17 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } /* create and lock table */ /* QQ: This should be done atomic ! */ + /* We don't log the statement, it will be logged later */ if (mysql_create_table(thd,db,name,create_info,*extra_fields, - *keys,0,1)) // no logging + *keys,0)) DBUG_RETURN(0); + /* + If this is a HEAP table, the automatic DELETE FROM which is written to the + binlog when a HEAP table is opened for the first time since startup, must + not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we + don't want to delete from it) 2) it would be written before the CREATE + TABLE, which is a wrong order. So we keep binary logging disabled. + */ if (!(table=open_table(thd,db,name,name,(bool*) 0))) { quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); @@ -892,6 +900,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } table->file->extra(HA_EXTRA_WRITE_CACHE); DBUG_RETURN(table); + /* Note that leaving the function resets binlogging properties */ } @@ -1753,6 +1762,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, List_iterator key_it(keys); List_iterator field_it(create_list); List key_parts; + Disable_binlog *disable_binlog; KEY *key_info=table->key_info; for (uint i=0 ; i < table->keys ; i++,key_info++) @@ -1915,12 +1925,16 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } else create_info->data_file_name=create_info->index_file_name=0; - + /* We don't log the statement, it will be logged later */ + disable_binlog= new Disable_binlog(thd); if ((error=mysql_create_table(thd, new_db, tmp_name, create_info, - create_list,key_list,1,1))) // no logging + create_list,key_list,1))) + { + delete disable_binlog; DBUG_RETURN(error); - + } + delete disable_binlog; // reset binlogging properties for next code lines if (table->tmp_table) new_table=open_table(thd,new_db,tmp_name,tmp_name,0); else -- cgit v1.2.1 From ae2bf6275e971f45cdfda8dada9a9bfd6f75e746 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 03:02:09 +0200 Subject: after merge fixes strings/my_vsnprintf.c: %.#s support in my_vsnprintf BitKeeper/etc/ignore: Added EXCEPTIONS-CLIENT to the ignore list --- sql/field.cc | 29 +++++++---------------------- sql/field.h | 8 ++++---- sql/protocol.cc | 10 +++++----- sql/sql_string.h | 8 ++++++++ sql/sql_yacc.yy | 2 +- 5 files changed, 25 insertions(+), 32 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 4458c14160d..caf4e22f4ca 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4268,24 +4268,21 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) Store double value in Field_string or Field_varstring. SYNOPSIS - store_double_in_string_field() - field field to store value in - field_length number of characters in the field + store(double nr) nr number DESCRIPTION Pretty prints double number into field_length characters buffer. */ -static int store_double_in_string_field(Field_str *field, uint32 field_length, - double nr) +int Field_str::store(double nr) { bool use_scientific_notation=TRUE; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; int length; - if (field_length < 32 && nr > 1) + if (field_length < 32 && nr > 1) // TODO: negative numbers { - if (field->ceiling == 0) + if (ceiling == 0) { static double e[]= {1e1, 1e2, 1e4, 1e8, 1e16 }; double p= 1; @@ -4294,23 +4291,17 @@ static int store_double_in_string_field(Field_str *field, uint32 field_length, if (field_length & j) p*= e[i]; } - field->ceiling= p-1; + ceiling= p-1; } - use_scientific_notation= (field->ceiling < nr); + use_scientific_notation= (ceiling < nr); } length= sprintf(buff, "%-.*g", use_scientific_notation ? max(0,field_length-5) : field_length, nr); DBUG_ASSERT(length <= field_length); - return field->store(buff, (uint) length); + return store((const char *)buff, (uint) length, charset()); } -int Field_string::store(double nr) - { - return store_double_in_string_field(this, field_length, nr); -} - - int Field_string::store(longlong nr) { char buff[64]; @@ -4479,12 +4470,6 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs) } -int Field_varstring::store(double nr) -{ - return store_double_in_string_field(this, field_length, nr); -} - - int Field_varstring::store(longlong nr) { char buff[64]; diff --git a/sql/field.h b/sql/field.h index 694d1efa285..fe06cd96f1a 100644 --- a/sql/field.h +++ b/sql/field.h @@ -336,21 +336,23 @@ public: class Field_str :public Field { protected: CHARSET_INFO *field_charset; -public: double ceiling; // for ::store(double nr) +public: Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg,CHARSET_INFO *charset) :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg, table_arg), ceiling(0.0) - { + { field_charset=charset; if (charset->state & MY_CS_BINSORT) flags|=BINARY_FLAG; } Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } + int store(double nr); + int store(const char *to,uint length,CHARSET_INFO *cs)=0; void make_field(Send_field *); uint size_of() const { return sizeof(*this); } CHARSET_INFO *charset(void) const { return field_charset; } @@ -905,7 +907,6 @@ public: bool zero_pack() const { return 0; } void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); } int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); int store(longlong nr); double val_real(void); longlong val_int(void); @@ -951,7 +952,6 @@ public: uint32 pack_length() const { return (uint32) field_length+2; } uint32 key_length() const { return (uint32) field_length; } int store(const char *to,uint length,CHARSET_INFO *charset); - int store(double nr); int store(longlong nr); double val_real(void); longlong val_int(void); diff --git a/sql/protocol.cc b/sql/protocol.cc index 2812a92497f..7c4b09ac3e3 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -200,13 +200,13 @@ net_printf(THD *thd, uint errcode, ...) 2+SQLSTATE_LENGTH+1 : 2) : 0); #ifndef EMBEDDED_LIBRARY text_pos=(char*) net->buff + head_length + offset + 1; + length=(char*)net->buff_end-text_pos; +#else + length=sizeof(text_pos)-1; #endif - (void) my_vsnprintf(my_const_cast(char*) (text_pos), - (char*)net->buff_end-text_pos, + length=my_vsnprintf(my_const_cast(char*) (text_pos), + min(length, sizeof(net->last_error)), format,args); - length=(uint) strlen((char*) text_pos); - if (length >= sizeof(net->last_error)) - length=sizeof(net->last_error)-1; /* purecov: inspected */ va_end(args); #ifndef EMBEDDED_LIBRARY diff --git a/sql/sql_string.h b/sql/sql_string.h index 0179b3ebadc..d8c4c3a87a1 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -95,6 +95,14 @@ public: Ptr[str_length]=0; return Ptr; } + inline char *c_ptr_safe() + { + if (Ptr && str_length < Alloced_length) + Ptr[str_length]=0; + else + (void) realloc(str_length); + return Ptr; + } void set(String &str,uint32 offset,uint32 arg_length) { diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index be3ac10c398..1b091c26a6d 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1936,7 +1936,7 @@ alter_list_item: if (check_table_name($3->table.str,$3->table.length) || $3->db.str && check_db_name($3->db.str)) { - net_printf(&lex->thd->net,ER_WRONG_TABLE_NAME,$3->table.str); + net_printf(lex->thd,ER_WRONG_TABLE_NAME,$3->table.str); YYABORT; } lex->alter_info.flags|= ALTER_RENAME; -- cgit v1.2.1 From f9b8ffc2ae5d9f86ea9eaea403b9afda58e43d6a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 10:28:40 +0500 Subject: field.cc: Serg's typo fix :) sql/field.cc: Serg's typo fix :) --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index caf4e22f4ca..522daa9e2cd 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2738,7 +2738,7 @@ String *Field_double::val_str(String *val_buffer, else { #ifdef HAVE_FCONVERT - char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE], + char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; char *pos= buff; int decpt,sign,tmp_dec=dec; -- cgit v1.2.1 From 32efeee47be06f072445ea389b8a9a4c7f431f8e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 07:33:35 +0200 Subject: Minor cosmetic fix --- sql/ha_ndbcluster.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1c5ed940c7c..2ba1bb04cc5 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -566,7 +566,7 @@ int ha_ndbcluster::build_index_list0() if (!(name= my_malloc(name_len, MYF(MY_WME)))) DBUG_RETURN(2); strxnmov(name, name_len, index_name, unique_suffix, NullS); - m_index[i].unique_name = name; + m_index[i].unique_name= name; DBUG_PRINT("info", ("Created unique index name: %s for index %d", name, i)); } @@ -588,13 +588,13 @@ int ha_ndbcluster::build_index_list1() { const NDBINDEX *index= dict->getIndex(get_index_name(i), m_tabname); if (!index) DBUG_RETURN(1); - m_index[i].index = (void *) index; + m_index[i].index= (void *) index; } if (m_index[i].unique_name) { const NDBINDEX *index= dict->getIndex(m_index[i].unique_name, m_tabname); if (!index) DBUG_RETURN(1); - m_index[i].unique_index = (void *) index; + m_index[i].unique_index= (void *) index; } DBUG_PRINT("info", ("Added handle to index %s", get_index_name(i))); } -- cgit v1.2.1 From 0281941158ba4c7588b89f9f1bd611d8d42863df Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 11:59:33 +0500 Subject: Bug#5081: UCS2 fields are filled with '0x2020' after extending field length --- sql/field_conv.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/field_conv.cc b/sql/field_conv.cc index e98068ef974..d7993939092 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -340,8 +340,10 @@ static void do_cut_string(Copy_field *copy) static void do_expand_string(Copy_field *copy) { + CHARSET_INFO *cs= copy->from_field->charset(); memcpy(copy->to_ptr,copy->from_ptr,copy->from_length); - bfill(copy->to_ptr+copy->from_length,copy->to_length-copy->from_length,' '); + cs->cset->fill(cs, copy->to_ptr+copy->from_length, + copy->to_length-copy->from_length, ' '); } static void do_varstring(Copy_field *copy) -- cgit v1.2.1 From ff568c0fa2c4114e746a54e313803b004d105ff2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 09:02:29 +0200 Subject: dependencies are auto-generated --- sql/Makefile.am | 1 - 1 file changed, 1 deletion(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index d1dfbfb390e..ec4e729bedb 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -45,7 +45,6 @@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @innodb_system_libs@ \ @ndbcluster_libs@ @ndbcluster_system_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ -mysqld_DEPENDENCIES = @ndbcluster_libs@ @ndbcluster_system_libs@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h item_uniq.h \ item_create.h item_subselect.h item_row.h \ -- cgit v1.2.1 From f758ada4bcfdf9b22b1603bc273b5e2a6436037b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 10:01:01 +0200 Subject: cosmetic change sql/sql_class.h: comment sql/sql_table.cc: smarter use of the Disable_binlog object (using a block so that when leaving it either way, the object gets destroyed and so properties of the thread get reset). --- sql/sql_class.h | 2 +- sql/sql_table.cc | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 8284cd23b9e..3c968c6a8ae 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -647,7 +647,7 @@ public: so we internally disable it temporarily by creating the Disable_binlog object and reset the state by destroying the object (don't forget that! or write code so that the object gets automatically destroyed when leaving a - function...). + block, see example in sql_table.cc). */ class Disable_binlog { private: diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c09892ac48b..96eebd98ac3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1762,7 +1762,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, List_iterator key_it(keys); List_iterator field_it(create_list); List key_parts; - Disable_binlog *disable_binlog; KEY *key_info=table->key_info; for (uint i=0 ; i < table->keys ; i++,key_info++) @@ -1925,16 +1924,17 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } else create_info->data_file_name=create_info->index_file_name=0; - /* We don't log the statement, it will be logged later */ - disable_binlog= new Disable_binlog(thd); - if ((error=mysql_create_table(thd, new_db, tmp_name, - create_info, - create_list,key_list,1))) { - delete disable_binlog; - DBUG_RETURN(error); + /* + We don't log the statement, it will be logged later. Using a block so + that disable_binlog is deleted when we leave it in either way. + */ + Disable_binlog disable_binlog(thd); + if ((error=mysql_create_table(thd, new_db, tmp_name, + create_info, + create_list,key_list,1))) + DBUG_RETURN(error); } - delete disable_binlog; // reset binlogging properties for next code lines if (table->tmp_table) new_table=open_table(thd,new_db,tmp_name,tmp_name,0); else -- cgit v1.2.1 From 939db862a6216ff8c636274043ecc8e2cd3990b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 11:10:35 +0200 Subject: Cleaned up build of index list --- sql/ha_ndbcluster.cc | 130 +++++++++++++++++++++------------------------------ sql/ha_ndbcluster.h | 7 ++- 2 files changed, 55 insertions(+), 82 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 2ba1bb04cc5..4ccf67beeb3 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -542,25 +542,30 @@ int ha_ndbcluster::get_metadata(const char *path) // All checks OK, lets use the table m_table= (void*)tab; - DBUG_RETURN(build_index_list()); + DBUG_RETURN(build_index_list(table, ILBP_OPEN)); } -int ha_ndbcluster::build_index_list0() + +int ha_ndbcluster::build_index_list(TABLE *tab, enum IBLP phase) { + int error= 0; char *name; const char *index_name; static const char* unique_suffix= "$unique"; uint i, name_len; - DBUG_ENTER("build_index_list0"); + KEY* key_info= tab->key_info; + const char **key_name= tab->keynames.type_names; + NdbDictionary::Dictionary *dict= m_ndb->getDictionary(); + DBUG_ENTER("build_index_list"); // Save information about all known indexes - for (i= 0; i < table->keys; i++) + for (i= 0; i < tab->keys; i++, key_info++, key_name++) { + index_name= *key_name; NDB_INDEX_TYPE idx_type= get_index_type_from_table(i); m_index[i].type= idx_type; if (idx_type == UNIQUE_ORDERED_INDEX || idx_type == UNIQUE_INDEX) { - index_name= get_index_name(i); name_len= strlen(index_name)+strlen(unique_suffix)+1; // Create name for unique index by appending "$unique"; if (!(name= my_malloc(name_len, MYF(MY_WME)))) @@ -570,23 +575,46 @@ int ha_ndbcluster::build_index_list0() DBUG_PRINT("info", ("Created unique index name: %s for index %d", name, i)); } - } - DBUG_RETURN(0); -} - -int ha_ndbcluster::build_index_list1() -{ - uint i; - NdbDictionary::Dictionary *dict= m_ndb->getDictionary(); - DBUG_ENTER("build_index_object_list1"); - // Add direct references to index objects - for (i= 0; i < table->keys; i++) - { - DBUG_PRINT("info", ("Trying to add handle to index %s", get_index_name(i))); + // Create secondary indexes if in create phase + if (phase == ILBP_CREATE) + { + DBUG_PRINT("info", ("Creating index %u: %s", i, index_name)); + + switch (m_index[i].type){ + + case PRIMARY_KEY_INDEX: + // Do nothing, already created + break; + case PRIMARY_KEY_ORDERED_INDEX: + error= create_ordered_index(index_name, key_info); + break; + case UNIQUE_ORDERED_INDEX: + if (!(error= create_ordered_index(index_name, key_info))) + error= create_unique_index(get_unique_index_name(i), key_info); + break; + case UNIQUE_INDEX: + error= create_unique_index(get_unique_index_name(i), key_info); + break; + case ORDERED_INDEX: + error= create_ordered_index(index_name, key_info); + break; + default: + DBUG_ASSERT(false); + break; + } + if (error) + { + DBUG_PRINT("error", ("Failed to create index %u", i)); + drop_table(); + break; + } + } + // Add handles to index objects + DBUG_PRINT("info", ("Trying to add handle to index %s", index_name)); if ((m_index[i].type != PRIMARY_KEY_INDEX) && (m_index[i].type != UNIQUE_INDEX)) { - const NDBINDEX *index= dict->getIndex(get_index_name(i), m_tabname); + const NDBINDEX *index= dict->getIndex(index_name, m_tabname); if (!index) DBUG_RETURN(1); m_index[i].index= (void *) index; } @@ -596,22 +624,12 @@ int ha_ndbcluster::build_index_list1() if (!index) DBUG_RETURN(1); m_index[i].unique_index= (void *) index; } - DBUG_PRINT("info", ("Added handle to index %s", get_index_name(i))); + DBUG_PRINT("info", ("Added handle to index %s", index_name)); } - DBUG_RETURN(0); + + DBUG_RETURN(error); } -int ha_ndbcluster::build_index_list() -{ - int res; - DBUG_ENTER("build_index_list"); - if ((res= build_index_list0())) - DBUG_RETURN(res); - if ((res= build_index_list1())) - DBUG_RETURN(res); - - DBUG_RETURN(0); -} /* Decode the type of an index from information @@ -2882,54 +2900,10 @@ int ha_ndbcluster::create(const char *name, } DBUG_PRINT("info", ("Table %s/%s created successfully", m_dbname, m_tabname)); - - if ((my_errno= build_index_list0())) - DBUG_RETURN(my_errno); - - // Create secondary indexes - KEY* key_info= form->key_info; - const char** key_name= key_names; - for (i= 0; i < form->keys; i++, key_info++, key_name++) - { - int error= 0; - DBUG_PRINT("info", ("Index %u: %s", i, *key_name)); - - switch (get_index_type_from_table(i)){ - - case PRIMARY_KEY_INDEX: - // Do nothing, already created - break; - case PRIMARY_KEY_ORDERED_INDEX: - error= create_ordered_index(*key_name, key_info); - break; - case UNIQUE_ORDERED_INDEX: - if (!(error= create_ordered_index(*key_name, key_info))) - error= create_unique_index(get_unique_index_name(i), key_info); - break; - case UNIQUE_INDEX: - error= create_unique_index(get_unique_index_name(i), key_info); - break; - case ORDERED_INDEX: - error= create_ordered_index(*key_name, key_info); - break; - default: - DBUG_ASSERT(false); - break; - } - if (error) - { - DBUG_PRINT("error", ("Failed to create index %u", i)); - drop_table(); - my_errno= error; - break; - } - } - - if (!(my_errno) && (my_errno= build_index_list1())) - DBUG_RETURN(my_errno); + // Create secondary indexes + my_errno= build_index_list(form, ILBP_CREATE); - DBUG_RETURN(my_errno); } diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 84c3d2092e8..d982ca446fe 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -155,10 +155,9 @@ class ha_ndbcluster: public handler int create_index(const char *name, KEY *key_info, bool unique); int create_ordered_index(const char *name, KEY *key_info); int create_unique_index(const char *name, KEY *key_info); - int initialize_autoincrement(const void* table); - int build_index_list0(); - int build_index_list1(); - int build_index_list(); + int initialize_autoincrement(const void *table); + enum IBLP {ILBP_CREATE = 0, ILBP_OPEN = 1}; // index_list_build_phase + int build_index_list(TABLE *tab, enum IBLP phase); int get_metadata(const char* path); void release_metadata(); const char* get_index_name(uint idx_no) const; -- cgit v1.2.1 From 8001a7db2b516069289db041bdac9cede64892ce Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 11:21:08 +0200 Subject: take dec. point into account in store_double_in_string --- sql/field.cc | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 33717d99583..1b5c688fe7a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3716,7 +3716,7 @@ static void store_double_in_string_field(Field_str *field, uint32 field_length, { bool use_scientific_notation=TRUE; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; - int length; + uint length; if (field_length < 32 && nr > 1) { if (field->ceiling == 0) @@ -3732,11 +3732,17 @@ static void store_double_in_string_field(Field_str *field, uint32 field_length, } use_scientific_notation= (field->ceiling < nr); } - length= sprintf(buff, "%-.*g", - use_scientific_notation ? max(0,field_length-5) : field_length, - nr); - DBUG_ASSERT(length <= field_length); - field->store(buff, (uint) length); + length= (uint)sprintf(buff, "%-.*g", + use_scientific_notation ? max(0,field_length-5) : field_length, + nr); + /* + +1 below is because "precision" in %g above means the + max. number of significant digits, not the output width. + Thus the width can be larger than number of significant digits by 1 + (for decimal point) + */ + DBUG_ASSERT(length <= field_length+1); + field->store(buff, min(length, field_length)); } void Field_string::store(double nr) -- cgit v1.2.1 From 8a5bb1a06cd3425ec5275ee2a78fa414bacb89e6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 11:51:06 +0200 Subject: Minor typo --- sql/ha_ndbcluster.cc | 2 +- sql/ha_ndbcluster.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 4ccf67beeb3..0545645b1fa 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -546,7 +546,7 @@ int ha_ndbcluster::get_metadata(const char *path) } -int ha_ndbcluster::build_index_list(TABLE *tab, enum IBLP phase) +int ha_ndbcluster::build_index_list(TABLE *tab, enum ILBP phase) { int error= 0; char *name; diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index d982ca446fe..7eb1b8dbefb 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -156,8 +156,8 @@ class ha_ndbcluster: public handler int create_ordered_index(const char *name, KEY *key_info); int create_unique_index(const char *name, KEY *key_info); int initialize_autoincrement(const void *table); - enum IBLP {ILBP_CREATE = 0, ILBP_OPEN = 1}; // index_list_build_phase - int build_index_list(TABLE *tab, enum IBLP phase); + enum ILBP {ILBP_CREATE = 0, ILBP_OPEN = 1}; // Index List Build Phase + int build_index_list(TABLE *tab, enum ILBP phase); int get_metadata(const char* path); void release_metadata(); const char* get_index_name(uint idx_no) const; -- cgit v1.2.1 From 7fbc796d4ad9681fa2381791f8c895be4cbd738b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 15:15:10 +0500 Subject: Bug#4521: unique key prefix interacts poorly with utf8. Fix for binary collations for MyISAM and HEAP BTREE. This patch also changes trailing spaces behaviour for binary collations. Binary collations now have PAD characteristic too. --- sql/field.h | 2 +- sql/ha_berkeley.cc | 6 ++++-- sql/item_cmpfunc.cc | 4 ++-- 3 files changed, 7 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/field.h b/sql/field.h index fe06cd96f1a..83c5a71f07f 100644 --- a/sql/field.h +++ b/sql/field.h @@ -357,7 +357,7 @@ public: uint size_of() const { return sizeof(*this); } CHARSET_INFO *charset(void) const { return field_charset; } void set_charset(CHARSET_INFO *charset) { field_charset=charset; } - bool binary() const { return field_charset->state & MY_CS_BINSORT ? 1 : 0; } + bool binary() const { return field_charset == &my_charset_bin; } uint32 max_length() { return field_length; } friend class create_field; }; diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 39ef6ca855a..7cd534d60b3 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -357,9 +357,11 @@ ulong ha_berkeley::index_flags(uint idx, uint part, bool all_parts) const case HA_KEYTYPE_VARTEXT: /* As BDB stores only one copy of equal strings, we can't use key read - on these + on these. Binary collations do support key read though. */ - flags&= ~HA_KEYREAD_ONLY; + if (!(table->key_info[idx].key_part[i].field->charset()->state + & MY_CS_BINSORT)) + flags&= ~HA_KEYREAD_ONLY; break; default: // Keep compiler happy break; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 23bdad1aae5..3c75dba42da 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -303,10 +303,10 @@ int Arg_comparator::set_compare_func(Item_bool_func2 *item, Item_result type) my_coll_agg_error((*a)->collation, (*b)->collation, owner->func_name()); return 1; } - if (my_binary_compare(cmp_collation.collation)) + if (cmp_collation.collation == &my_charset_bin) { /* - We are using binary collation, change to compare byte by byte, + We are using BLOB/BINARY/VARBINARY, change to compare byte by byte, without removing end space */ if (func == &Arg_comparator::compare_string) -- cgit v1.2.1 From 84779aef24cabafd26e8445fbe60c1d3a0c2b4e9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 15:36:05 +0500 Subject: addition to fixes about #4700, 4701 libmysqld/lib_sql.cc: Comment added sql/sql_prepare.cc: Necessary line added to emb_insert_params_with_log --- sql/sql_prepare.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 47cc461fac0..754da84f257 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -737,6 +737,7 @@ static bool emb_insert_params_withlog(Prepared_statement *stmt, String *query) else { uchar *buff= (uchar*)client_param->buffer; + param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, client_param->length ? *client_param->length : -- cgit v1.2.1 From de40ed916e4d4a70cee06250682e8a2c52d527a8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 15:38:12 +0500 Subject: Small tab's cleanup sql/sql_prepare.cc: tab changed with spaces --- sql/sql_prepare.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 754da84f257..b9f626ce8d4 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -696,7 +696,7 @@ static bool emb_insert_params(Prepared_statement *stmt, String *expanded_query) else { uchar *buff= (uchar*) client_param->buffer; - param->unsigned_flag= client_param->is_unsigned; + param->unsigned_flag= client_param->is_unsigned; param->set_param_func(param, &buff, client_param->length ? *client_param->length : -- cgit v1.2.1 From cc6d65b8d8227740aeba00a59e1de7c386967d52 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 16:07:18 +0500 Subject: Bug 4531: unique key prefix interacts poorly with utf8 Check HEAP+HASH, binary collation --- sql/ha_heap.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index a7f6cc45831..d7327362286 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -430,7 +430,7 @@ int ha_heap::create(const char *name, TABLE *table_arg, { if (!f_is_packed(flag) && f_packtype(flag) == (int) FIELD_TYPE_DECIMAL && - !(flag & FIELDFLAG_BINARY)) + !(field->charset() == &my_charset_bin)) seg->type= (int) HA_KEYTYPE_TEXT; else seg->type= (int) HA_KEYTYPE_BINARY; -- cgit v1.2.1 From 87bce8540c7c38cb88ce8743b8efcb0a51f53bfe Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 17:56:32 +0200 Subject: Bug #4466 Nothing in .err when mysql service ends because of malformed my.ini options mysqld.cc: Changed LOGLEVEL enum to loglevel mysql_priv.h, log.cc: Changed LOGLEVEL to loglevel. Removed startup_ from some of the DBUG_ENTER macros. Removed the print_msg_to_log function as it was unused. my_getopt.c, my_getopt.h: Renamed LOGLEVEL to loglevel to match coding standards include/my_getopt.h: Renamed LOGLEVEL to loglevel to match coding standards mysys/my_getopt.c: Renamed LOGLEVEL to loglevel to match coding standards sql/log.cc: Changed LOGLEVEL to loglevel. Removed startup_ from some of the DBUG_ENTER macros. Removed the print_msg_to_log function as it was unused. sql/mysql_priv.h: Changed LOGLEVEL to loglevel. Removed startup_ from some of the DBUG_ENTER macros. Removed the print_msg_to_log function as it was unused. sql/mysqld.cc: Changed LOGLEVEL enum to loglevel --- sql/log.cc | 45 +++++++++++++-------------------------------- sql/mysql_priv.h | 3 +-- sql/mysqld.cc | 2 +- 3 files changed, 15 insertions(+), 35 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index a487de250db..9743fdf8a37 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1716,13 +1716,13 @@ static bool test_if_number(register const char *str, } /* test_if_number */ -void print_buffer_to_file( enum LOGLEVEL level, const char *buffer ) +void print_buffer_to_file( enum loglevel level, const char *buffer ) { time_t skr; struct tm tm_tmp; struct tm *start; - DBUG_ENTER("startup_print_buffer_to_log"); + DBUG_ENTER("print_buffer_to_log"); VOID(pthread_mutex_lock(&LOCK_error_log)); @@ -1802,35 +1802,16 @@ bool flush_error_log() return result; } -/** - * prints a printf style message to the error log and, under NT, to the Windows event log. - * @param event_type type of even to log. - * @param timestamp true to add a timestamp to the entry, false otherwise. - * @param format The printf style format of the message - * @param ... values for the message - * @return void -*/ -void print_msg_to_log( LOGLEVEL level, const char *format, ... ) -{ - va_list args; - - DBUG_ENTER("startup_print_msg_to_log"); - - va_start( args, format ); - vprint_msg_to_log( level, format, args ); - va_end( args ); - - DBUG_VOID_RETURN; -} - #ifdef __NT__ -void print_buffer_to_nt_eventlog( enum LOGLEVEL level, char *buff, int buffLen ) +void print_buffer_to_nt_eventlog( enum loglevel level, char *buff, int buffLen ) { HANDLE event; char *buffptr; LPCSTR *buffmsgptr; + DBUG_ENTER( "print_buffer_to_nt_eventlog" ); + buffptr = buff; if (strlen(buff) > (uint)(buffLen-4)) { @@ -1885,11 +1866,11 @@ void print_buffer_to_nt_eventlog( enum LOGLEVEL level, char *buff, int buffLen ) RETURN VALUES void */ -void vprint_msg_to_log(enum LOGLEVEL level, const char *format, va_list args) +void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) { char buff[1024]; - DBUG_ENTER("startup_vprint_msg_to_log"); + DBUG_ENTER("vprint_msg_to_log"); my_vsnprintf( buff, sizeof(buff)-5, format, args ); @@ -1909,11 +1890,11 @@ void vprint_msg_to_log(enum LOGLEVEL level, const char *format, va_list args) void sql_print_error( const char *format, ... ) { - DBUG_ENTER( "startup_sql_print_error" ); + DBUG_ENTER( "sql_print_error" ); va_list args; va_start( args, format ); - print_msg_to_log( ERROR_LEVEL, format, args ); + vprint_msg_to_log( ERROR_LEVEL, format, args ); va_end( args ); DBUG_VOID_RETURN; @@ -1921,11 +1902,11 @@ void sql_print_error( const char *format, ... ) void sql_print_warning( const char *format, ... ) { - DBUG_ENTER( "startup_sql_print_warning" ); + DBUG_ENTER( "sql_print_warning" ); va_list args; va_start( args, format ); - print_msg_to_log( WARNING_LEVEL, format, args ); + vprint_msg_to_log( WARNING_LEVEL, format, args ); va_end( args ); DBUG_VOID_RETURN; @@ -1933,11 +1914,11 @@ void sql_print_warning( const char *format, ... ) void sql_print_information( const char *format, ... ) { - DBUG_ENTER( "startup_sql_print_information" ); + DBUG_ENTER( "sql_print_information" ); va_list args; va_start( args, format ); - print_msg_to_log( INFORMATION_LEVEL, format, args ); + vprint_msg_to_log( INFORMATION_LEVEL, format, args ); va_end( args ); DBUG_VOID_RETURN; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ed8b4bd2457..e86604df659 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -640,10 +640,9 @@ void key_unpack(String *to,TABLE *form,uint index); bool check_if_key_used(TABLE *table, uint idx, List &fields); void init_errmessage(void); -void vprint_msg_to_log( enum LOGLEVEL level, const char *format, va_list args ); -void print_msg_to_log( enum LOGLEVEL level, const char *format, ... ); void sql_perror(const char *message); +void vprint_msg_to_log( enum loglevel level, const char *format, va_list args ); void sql_print_error( const char *format, ... ); void sql_print_warning( const char *format, ...); void sql_print_information( const char *format, ...); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index d70f61c5c22..a27298c254c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5095,7 +5095,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } /* Initiates DEBUG - but no debugging here ! */ -void option_error_reporter( enum LOGLEVEL level, const char *format, ... ) +void option_error_reporter( enum loglevel level, const char *format, ... ) { va_list args; va_start( args, format ); -- cgit v1.2.1 From 4f8bbaeda02755a7a455b7bee5c5e45081a3e972 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 18:40:15 +0200 Subject: Bug #4769 - ft in subqueries --- sql/sql_select.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c56645e06b9..3a0ae219e81 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -729,6 +729,10 @@ JOIN::optimize() (select_lex->ftfunc_list->elements ? SELECT_NO_JOIN_CACHE : 0)); + /* Perform FULLTEXT search before all regular searches */ + if (!(select_options & SELECT_DESCRIBE)) + init_ftfuncs(thd, select_lex, test(order)); + /* is this simple IN subquery? */ @@ -784,7 +788,7 @@ JOIN::optimize() join_tab->info= "Using index; Using where"; else join_tab->info= "Using index"; - + DBUG_RETURN(unit->item-> change_engine(new subselect_indexsubquery_engine(thd, join_tab, @@ -849,8 +853,6 @@ JOIN::optimize() } having= 0; - /* Perform FULLTEXT search before all regular searches */ - init_ftfuncs(thd, select_lex, test(order)); /* Create a tmp table if distinct or if the sort is too complicated */ if (need_tmp) { @@ -858,7 +860,7 @@ JOIN::optimize() thd->proc_info="Creating tmp table"; init_items_ref_array(); - + tmp_table_param.hidden_field_count= (all_fields.elements - fields_list.elements); if (!(exec_tmp_table1 = -- cgit v1.2.1 From 0ed563e80180a848dbd8a3d062663ce14b479e11 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 20:48:00 +0200 Subject: Fixed symbol name problems that made build fail. include/mysql.h: Fixed symbol name change. include/mysql_com.h: Reverted parts of previous changeset (name changes) to make it build. libmysql/libmysql.c: Fixed symbol name change. sql/sql_parse.cc: Fixed symbol name change. --- sql/sql_parse.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 57e4022719e..5aa4a8de156 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1643,8 +1643,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in packet[0]. */ - enum enum_shutdown_level level= - (enum enum_shutdown_level) (uchar) packet[0]; + enum mysql_enum_shutdown_level level= + (enum mysql_enum_shutdown_level) (uchar) packet[0]; DBUG_PRINT("quit",("Got shutdown command for level %u", level)); if (level == SHUTDOWN_DEFAULT) level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable -- cgit v1.2.1 From 03a20c23b320bb28a13aa6dc69c9445ff414a144 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 23:22:16 +0300 Subject: ha_innodb.cc: innobase_mysql_tmpfile(): call dup() and my_close() on the file returned by create_temp_file() in order to avoid memory leak caused by my_open() being paired with close() sql/ha_innodb.cc: innobase_mysql_tmpfile(): call dup() and my_close() on the file returned by create_temp_file() in order to avoid memory leak caused by my_open() being paired with close() --- sql/ha_innodb.cc | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 22ddfe779d5..3d3aca9cfd5 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -31,6 +31,7 @@ have disables the InnoDB inlining in this file. */ #include #include #include +#include #define MAX_ULONG_BIT ((ulong) 1 << (sizeof(ulong)*8-1)) @@ -419,6 +420,7 @@ innobase_mysql_tmpfile(void) /* out: temporary file descriptor, or < 0 on error */ { char filename[FN_REFLEN]; + int fd2 = -1; File fd = create_temp_file(filename, NullS, "ib", #ifdef __WIN__ O_BINARY | O_TRUNC | O_SEQUENTIAL | @@ -426,12 +428,31 @@ innobase_mysql_tmpfile(void) #endif /* __WIN__ */ O_CREAT | O_EXCL | O_RDWR, MYF(MY_WME)); -#ifndef __WIN__ if (fd >= 0) { +#ifndef __WIN__ + /* On Windows, open files cannot be removed, but files can be + created with the O_TEMPORARY flag to the same effect + ("delete on close"). */ unlink(filename); - } #endif /* !__WIN__ */ - return(fd); + /* Copy the file descriptor, so that the additional resources + allocated by create_temp_file() can be freed by invoking + my_close(). + + Because the file descriptor returned by this function + will be passed to fdopen(), it will be closed by invoking + fclose(), which in turn will invoke close() instead of + my_close(). */ + fd2 = dup(fd); + if (fd2 < 0) { + DBUG_PRINT("error",("Got error %d on dup",fd2)); + my_errno=errno; + my_error(EE_OUT_OF_FILERESOURCES, + MYF(ME_BELL+ME_WAITTANG), filename, my_errno); + } + my_close(fd, MYF(MY_WME)); + } + return(fd2); } /************************************************************************* -- cgit v1.2.1 From 185fc2da944544e524a7c6b5bd8029d635cdbb0b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 22:40:31 +0200 Subject: This fixes a Windows build failure. How did this build on Linux? logging_ok: Logging to logging@openlogging.org accepted mysql_priv.h, my_time.h: Moved declaration of days_in_month array from mysql_priv.h to my_time.h to correct Windows build issues include/my_time.h: Moved declaration of days_in_month array from mysql_priv.h to my_time.h to correct Windows build issues sql/mysql_priv.h: Moved declaration of days_in_month array from mysql_priv.h to my_time.h to correct Windows build issues BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/mysql_priv.h | 1 - 1 file changed, 1 deletion(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9ada2fba164..b269f8bec3e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -827,7 +827,6 @@ extern Gt_creator gt_creator; extern Lt_creator lt_creator; extern Ge_creator ge_creator; extern Le_creator le_creator; -extern uchar days_in_month[]; extern char language[LIBLEN],reg_ext[FN_EXTLEN]; extern char glob_hostname[FN_REFLEN], mysql_home[FN_REFLEN]; extern char pidfile_name[FN_REFLEN], system_time_zone[30], *opt_init_file; -- cgit v1.2.1 From 432a0f36838f0c68d5db3087bf3331ff9df1460b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 23:10:33 +0200 Subject: less strict assert to take into account weird cases --- sql/field.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 1b5c688fe7a..71ec7545efc 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3733,15 +3733,17 @@ static void store_double_in_string_field(Field_str *field, uint32 field_length, use_scientific_notation= (field->ceiling < nr); } length= (uint)sprintf(buff, "%-.*g", - use_scientific_notation ? max(0,field_length-5) : field_length, + use_scientific_notation ? max(0,(int)field_length-5) : field_length, nr); /* +1 below is because "precision" in %g above means the max. number of significant digits, not the output width. Thus the width can be larger than number of significant digits by 1 (for decimal point) + the test for field_length < 5 is for extreme cases, + like inserting 500.0 in char(1) */ - DBUG_ASSERT(length <= field_length+1); + DBUG_ASSERT(field_length < 5 || length <= field_length+1); field->store(buff, min(length, field_length)); } -- cgit v1.2.1 From e7157aba3ab883135d32c285c70b4c326f44f870 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Aug 2004 23:24:35 +0200 Subject: (manual port from 4.0 - was needed) Fix for BUG#4971 "CREATE TABLE ... TYPE=HEAP SELECT ... stops slave (wrong DELETE in binlog)": replacing the no_log argument of mysql_create_table() by some safer method (temporarily setting OPTION_BIN_LOG to 0) which guarantees that even the automatic DELETE FROM heap_table does not get into the binlog when a not-yet-existing HEAP table is opened by mysql_create_table(). mysql-test/r/rpl_heap.result: result update mysql-test/t/rpl_heap.test: changing test to test a bug (but anyway, mysql-test-run --manager looks like not working in 4.1 currently, so this test is never run). sql/log.cc: new class Disable_binlog used to temporarily disable binlogging for one thread. sql/mysql_priv.h: removing argument no_log from mysql_create_table(); no_log was not perfect as some binlogging could still be done by open_unireg_entry() for a HEAP table. sql/sql_class.h: new class Disable_binlog used to temporarily disable binlogging for one thread. sql/sql_parse.cc: removing no_log arg from mysql_create_table() sql/sql_table.cc: removing no_log from mysql_create_table(); instead using new class Disable_binlog. Disabling binlogging in some cases, where the binlogging is done later by some other code (case of CREATE SELECT and ALTER). --- sql/log.cc | 14 ++++++++++++++ sql/mysql_priv.h | 2 +- sql/sql_class.h | 21 +++++++++++++++++++++ sql/sql_parse.cc | 2 +- sql/sql_table.cc | 31 +++++++++++++++++++++---------- 5 files changed, 58 insertions(+), 12 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index ac412f2de9a..bcac7267f8b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1877,6 +1877,20 @@ void MYSQL_LOG::set_max_size(ulong max_size_arg) } +Disable_binlog::Disable_binlog(THD *thd_arg) : + thd(thd_arg), + save_options(thd_arg->options) +{ + thd_arg->options&= ~OPTION_BIN_LOG; +}; + + +Disable_binlog::~Disable_binlog() +{ + thd->options= save_options; +} + + /* Check if a string is a valid number diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9ada2fba164..4b8a14474fa 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -518,7 +518,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, List &fields, List &keys, - bool tmp_table, bool no_log, uint select_field_count); + bool tmp_table, uint select_field_count); TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, const char *db, const char *name, List *extra_fields, diff --git a/sql/sql_class.h b/sql/sql_class.h index 59ac8ff0483..1fb2d5071f6 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1017,6 +1017,27 @@ public: #define SYSTEM_THREAD_SLAVE_IO 2 #define SYSTEM_THREAD_SLAVE_SQL 4 +/* + Disables binary logging for one thread, and resets it back to what it was + before being disabled. + Some functions (like the internal mysql_create_table() when it's called by + mysql_alter_table()) must NOT write to the binlog (binlogging is done at the + at a later stage of the command already, and must be, for locking reasons); + so we internally disable it temporarily by creating the Disable_binlog + object and reset the state by destroying the object (don't forget that! or + write code so that the object gets automatically destroyed when leaving a + function...). +*/ +class Disable_binlog { +private: + THD *thd; + ulong save_options; + ulong save_master_access; +public: + Disable_binlog(THD *thd_arg); + ~Disable_binlog(); +}; + /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 5aa4a8de156..41d7c471fe5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2379,7 +2379,7 @@ mysql_execute_command(THD *thd) res= mysql_create_table(thd,create_table->db, create_table->real_name, &lex->create_info, lex->create_list, - lex->key_list,0,0,0); // do logging + lex->key_list,0,0); } if (!res) send_ok(thd); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c82bff05412..9ff46f219b1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1090,7 +1090,6 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, keys List of keys to create tmp_table Set to 1 if this is an internal temporary table (From ALTER TABLE) - no_log Don't log the query to binary log. DESCRIPTION If one creates a temporary table, this is automaticly opened @@ -1108,7 +1107,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, int mysql_create_table(THD *thd,const char *db, const char *table_name, HA_CREATE_INFO *create_info, List &fields, - List &keys,bool tmp_table,bool no_log, + List &keys,bool tmp_table, uint select_field_count) { char path[FN_REFLEN]; @@ -1277,7 +1276,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, } thd->tmp_table_used= 1; } - if (!tmp_table && !no_log) + if (!tmp_table) { // Must be written before unlock mysql_update_log.write(thd,thd->query, thd->query_length); @@ -1352,6 +1351,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, TABLE *table; tmp_table.table_name=0; uint select_field_count= items->elements; + Disable_binlog disable_binlog(thd); DBUG_ENTER("create_table_from_items"); /* Add selected items to field list */ @@ -1382,9 +1382,17 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } /* create and lock table */ /* QQ: This should be done atomic ! */ + /* We don't log the statement, it will be logged later */ if (mysql_create_table(thd,db,name,create_info,*extra_fields, - *keys,0,1,select_field_count)) // no logging + *keys,0,select_field_count)) DBUG_RETURN(0); + /* + If this is a HEAP table, the automatic DELETE FROM which is written to the + binlog when a HEAP table is opened for the first time since startup, must + not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we + don't want to delete from it) 2) it would be written before the CREATE + TABLE, which is a wrong order. So we keep binary logging disabled. + */ if (!(table=open_table(thd,db,name,name,(bool*) 0))) { quick_rm_table(create_info->db_type,db,table_case_name(create_info,name)); @@ -1401,6 +1409,7 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } table->file->extra(HA_EXTRA_WRITE_CACHE); DBUG_RETURN(table); + /* Note that leaving the function resets binlogging properties */ } @@ -3008,12 +3017,14 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } else create_info->data_file_name=create_info->index_file_name=0; - - if ((error=mysql_create_table(thd, new_db, tmp_name, - create_info, - create_list,key_list,1,1,0))) // no logging - DBUG_RETURN(error); - + { + /* We don't log the statement, it will be logged later */ + Disable_binlog disable_binlog(thd); + if ((error=mysql_create_table(thd, new_db, tmp_name, + create_info, + create_list,key_list,1,0))) + DBUG_RETURN(error); + } if (table->tmp_table) new_table=open_table(thd,new_db,tmp_name,tmp_name,0); else -- cgit v1.2.1 From 560d8ea34209f977a72889989720394d232b0f1c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 00:01:00 +0200 Subject: sql_class.h: removing unneeded var left from 4.0 sql/sql_class.h: removing unneeded var left from 4.0 --- sql/sql_class.h | 1 - 1 file changed, 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_class.h b/sql/sql_class.h index 1fb2d5071f6..32adc462743 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1032,7 +1032,6 @@ class Disable_binlog { private: THD *thd; ulong save_options; - ulong save_master_access; public: Disable_binlog(THD *thd_arg); ~Disable_binlog(); -- cgit v1.2.1 From 20dab90aadf3174b92ecb270690a4dde6142e55c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 13:11:14 +0200 Subject: Fixed compiler warnings in sql/field.h. sql/field.h: Fixed compiler warnings. --- sql/field.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sql') diff --git a/sql/field.h b/sql/field.h index 83c5a71f07f..843961e64c3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -352,6 +352,7 @@ public: Item_result result_type () const { return STRING_RESULT; } uint decimals() const { return NOT_FIXED_DEC; } int store(double nr); + int store(longlong nr)=0; int store(const char *to,uint length,CHARSET_INFO *cs)=0; void make_field(Send_field *); uint size_of() const { return sizeof(*this); } @@ -908,6 +909,7 @@ public: void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); } int store(const char *to,uint length,CHARSET_INFO *charset); int store(longlong nr); + int store(double nr) { return Field_str::store(nr); } double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -953,6 +955,7 @@ public: uint32 key_length() const { return (uint32) field_length; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(longlong nr); + int store(double nr) { return Field_str::store(nr); } double val_real(void); longlong val_int(void); String *val_str(String*,String *); -- cgit v1.2.1 From f9c3cb5f2e764955890c9a4db8d791a47561d130 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 17:53:46 +0400 Subject: Fix for bug#4302 "ambiguos order by when renamed column is identical to another in result" When in find_item_in_list() we are looking for item we should take into account unaliased names of the fields but only if item with such aliased name is not found. Also we should ignore aliases when looking for fully specified field. mysql-test/r/order_by.result: Fixed wrong (non-standard) test results Added test case for bug #4302 Added tests for other ambiguos and potentially ambigous cases in order by clause mysql-test/t/order_by.test: Fixed wrong (non-standard) test results Added test case for bug #4302 Added tests for other ambiguos and potentially ambigous cases in order by clause sql/sql_select.cc: We should ignore only not_found_item errors when searching for item in find_order_in_list() to be able to catch ambiguities. --- sql/sql_base.cc | 123 +++++++++++++++++++++++++++++++++++++++++------------- sql/sql_select.cc | 9 +++- 2 files changed, 100 insertions(+), 32 deletions(-) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4efdd3edbcd..3513e9f1c92 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2101,10 +2101,12 @@ find_item_in_list(Item *find, List &items, uint *counter, find_item_error_report_type report_error) { List_iterator li(items); - Item **found=0,*item; + Item **found=0, **found_unaliased= 0, *item; const char *db_name=0; const char *field_name=0; const char *table_name=0; + bool found_unaliased_non_uniq= 0; + uint unaliased_counter; if (find->type() == Item::FIELD_ITEM || find->type() == Item::REF_ITEM) { field_name= ((Item_ident*) find)->field_name; @@ -2117,42 +2119,88 @@ find_item_in_list(Item *find, List &items, uint *counter, if (field_name && item->type() == Item::FIELD_ITEM) { Item_field *item_field= (Item_field*) item; + /* In case of group_concat() with ORDER BY condition in the QUERY item_field can be field of temporary table without item name (if this field created from expression argument of group_concat()), => we have to check presence of name before compare */ - if (item_field->name && - (!my_strcasecmp(system_charset_info, item_field->name, field_name) || - !my_strcasecmp(system_charset_info, - item_field->field_name, field_name))) + if (!item_field->name) + continue; + + if (table_name) { - if (!table_name) - { - if (found) - { - if ((*found)->eq(item,0)) - continue; // Same field twice (Access?) - if (report_error != IGNORE_ERRORS) - my_printf_error(ER_NON_UNIQ_ERROR,ER(ER_NON_UNIQ_ERROR),MYF(0), - find->full_name(), current_thd->where); - return (Item**) 0; - } - found= li.ref(); - *counter= i; - } - else - { - if (!strcmp(item_field->table_name,table_name) && - (!db_name || (db_name && item_field->db_name && - !strcmp(item_field->db_name, db_name)))) - { - found= li.ref(); - *counter= i; - break; - } - } + /* + If table name is specified we should find field 'field_name' in + table 'table_name'. According to SQL-standard we should ignore + aliases in this case. Note that we should prefer fields from the + select list over other fields from the tables participating in + this select in case of ambiguity. + + QQ: Why do we use simple strcmp for table name comparison here ? + */ + if (!my_strcasecmp(system_charset_info, item_field->field_name, + field_name) && + !strcmp(item_field->table_name, table_name) && + (!db_name || (item_field->db_name && + !strcmp(item_field->db_name, db_name)))) + { + if (found) + { + if ((*found)->eq(item, 0)) + continue; // Same field twice + if (report_error != IGNORE_ERRORS) + my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), + MYF(0), find->full_name(), current_thd->where); + return (Item**) 0; + } + found= li.ref(); + *counter= i; + } + } + else if (!my_strcasecmp(system_charset_info, item_field->name, + field_name)) + { + /* + If table name was not given we should scan through aliases + (or non-aliased fields) first. We are also checking unaliased + name of the field in then next else-if, to be able to find + instantly field (hidden by alias) if no suitable alias (or + non-aliased field) was found. + */ + if (found) + { + if ((*found)->eq(item, 0)) + continue; // Same field twice + if (report_error != IGNORE_ERRORS) + my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), + MYF(0), find->full_name(), current_thd->where); + return (Item**) 0; + } + found= li.ref(); + *counter= i; + } + else if (!my_strcasecmp(system_charset_info, item_field->field_name, + field_name)) + { + /* + We will use un-aliased field or react on such ambiguities only if + we won't be able to find aliased field. + Again if we have ambiguity with field outside of select list + we should prefer fields from select list. + */ + if (found_unaliased) + { + if ((*found_unaliased)->eq(item, 0)) + continue; // Same field twice + found_unaliased_non_uniq= 1; + } + else + { + found_unaliased= li.ref(); + unaliased_counter= i; + } } } else if (!table_name && (item->eq(find,0) || @@ -2165,6 +2213,21 @@ find_item_in_list(Item *find, List &items, uint *counter, break; } } + if (!found) + { + if (found_unaliased_non_uniq) + { + if (report_error != IGNORE_ERRORS) + my_printf_error(ER_NON_UNIQ_ERROR, ER(ER_NON_UNIQ_ERROR), MYF(0), + find->full_name(), current_thd->where); + return (Item **) 0; + } + if (found_unaliased) + { + found= found_unaliased; + *counter= unaliased_counter; + } + } if (found) return found; else if (report_error != REPORT_EXCEPT_NOT_FOUND) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f8bc6210a2f..d4cc263ac55 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7978,13 +7978,18 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, return 0; } uint counter; - Item **item= find_item_in_list(itemptr, fields, &counter, IGNORE_ERRORS); - if (item) + Item **item= find_item_in_list(itemptr, fields, &counter, + REPORT_EXCEPT_NOT_FOUND); + if (!item) + return 1; + + if (item != not_found_item) { order->item= ref_pointer_array + counter; order->in_field_list=1; return 0; } + order->in_field_list=0; Item *it= *order->item; /* -- cgit v1.2.1 From cd8054d4318077827bcf20e640af6fcddf1d9525 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 16:35:23 +0200 Subject: Making FLUSH TABLES WITH READ LOCK block COMMITs of existing transactions, in a deadlock-free manner. This splits locking the global read lock in two steps. This fixes a consequence of this bug, known as: BUG#4953 'mysqldump --master-data may report incorrect binlog position if using InnoDB' And a test. sql/handler.cc: making COMMIT wait if FLUSH TABLES WITH READ LOCK happened. sql/lock.cc: an additional stage so that FLUSH TABLES WITH READ LOCK blocks COMMIT: make_global_read_lock_block_commit(): taking the global read lock is TWO steps (2nd step is optional; without it, COMMIT of existing transactions will be allowed): lock_global_read_lock() THEN make_global_read_lock_block_commit(). sql/mysql_priv.h: new argument to wait_if_global_read_lock() sql/sql_class.h: THD::global_read_lock now an uint to reflect the 2 steps of global read lock (does not block COMMIT / does) sql/sql_db.cc: update for new prototype sql/sql_parse.cc: implementing the two steps of global read lock so that FLUSH TABLES WITH READ LOCK can block COMMIT without deadlocking with COMMITs. --- sql/handler.cc | 31 +++++++++++++++++++++++-------- sql/lock.cc | 54 +++++++++++++++++++++++++++++++++++++++++++++++------- sql/mysql_priv.h | 3 ++- sql/sql_class.h | 4 ++-- sql/sql_db.cc | 4 ++-- sql/sql_parse.cc | 6 +++++- 6 files changed, 81 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index a1e738583fd..9eb129fab45 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -342,17 +342,30 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) #ifdef USING_TRANSACTIONS if (opt_using_transactions) { - bool operation_done= 0; + bool operation_done= 0, need_start_waiters= 0; bool transaction_commited= 0; - - /* Update the binary log if we have cached some queries */ - if (trans == &thd->transaction.all && mysql_bin_log.is_open() && + /* If transaction has done some updates to tables */ + if (trans == &thd->transaction.all && my_b_tell(&thd->transaction.trans_log)) { - mysql_bin_log.write(thd, &thd->transaction.trans_log, 1); - reinit_io_cache(&thd->transaction.trans_log, - WRITE_CACHE, (my_off_t) 0, 0, 1); - thd->transaction.trans_log.end_of_file= max_binlog_cache_size; + if (error= wait_if_global_read_lock(thd, 0, 0)) + { + /* + Note that ROLLBACK [TO SAVEPOINT] does not have this test; it's + because ROLLBACK never updates data, so needn't wait on the lock. + */ + my_error(ER_ERROR_DURING_COMMIT, MYF(0), error); + error= 1; + } + else + need_start_waiters= 1; + if (mysql_bin_log.is_open()) + { + mysql_bin_log.write(thd, &thd->transaction.trans_log, 1); + reinit_io_cache(&thd->transaction.trans_log, + WRITE_CACHE, (my_off_t) 0, 0, 1); + thd->transaction.trans_log.end_of_file= max_binlog_cache_size; + } } #ifdef HAVE_BERKELEY_DB if (trans->bdb_tid) @@ -393,6 +406,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) statistic_increment(ha_commit_count,&LOCK_status); thd->transaction.cleanup(); } + if (need_start_waiters) + start_waiting_global_read_lock(thd); } #endif // using transactions DBUG_RETURN(error); diff --git a/sql/lock.cc b/sql/lock.cc index 9ea1ce96175..dd2b61b65d2 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -96,7 +96,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd,TABLE **tables,uint count) Someone has issued LOCK ALL TABLES FOR READ and we want a write lock Wait until the lock is gone */ - if (wait_if_global_read_lock(thd, 1)) + if (wait_if_global_read_lock(thd, 1, 1)) { my_free((gptr) sql_lock,MYF(0)); sql_lock=0; @@ -453,7 +453,7 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list) int error= -1; DBUG_ENTER("lock_and_wait_for_table_name"); - if (wait_if_global_read_lock(thd,0)) + if (wait_if_global_read_lock(thd, 0, 1)) DBUG_RETURN(1); VOID(pthread_mutex_lock(&LOCK_open)); if ((lock_retcode = lock_table_name(thd, table_list)) < 0) @@ -667,14 +667,23 @@ static void print_lock_error(int error) The global locks are handled through the global variables: global_read_lock + global_read_lock_blocks_commit waiting_for_read_lock protect_against_global_read_lock + + Taking the global read lock is TWO steps (2nd step is optional; without + it, COMMIT of existing transactions will be allowed): + lock_global_read_lock() THEN make_global_read_lock_block_commit(). ****************************************************************************/ volatile uint global_read_lock=0; +volatile uint global_read_lock_blocks_commit=0; static volatile uint protect_against_global_read_lock=0; static volatile uint waiting_for_read_lock=0; +#define GOT_GLOBAL_READ_LOCK 1 +#define MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT 2 + bool lock_global_read_lock(THD *thd) { DBUG_ENTER("lock_global_read_lock"); @@ -697,27 +706,40 @@ bool lock_global_read_lock(THD *thd) thd->exit_cond(old_message); DBUG_RETURN(1); } - thd->global_read_lock=1; + thd->global_read_lock= GOT_GLOBAL_READ_LOCK; global_read_lock++; thd->exit_cond(old_message); } + /* + We DON'T set global_read_lock_blocks_commit now, it will be set after + tables are flushed (as the present function serves for FLUSH TABLES WITH + READ LOCK only). Doing things in this order is necessary to avoid + deadlocks (we must allow COMMIT until all tables are closed; we should not + forbid it before, or we can have a 3-thread deadlock if 2 do SELECT FOR + UPDATE and one does FLUSH TABLES WITH READ LOCK). + */ DBUG_RETURN(0); } void unlock_global_read_lock(THD *thd) { uint tmp; - thd->global_read_lock=0; pthread_mutex_lock(&LOCK_open); tmp= --global_read_lock; + if (thd->global_read_lock == MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT) + --global_read_lock_blocks_commit; pthread_mutex_unlock(&LOCK_open); /* Send the signal outside the mutex to avoid a context switch */ if (!tmp) pthread_cond_broadcast(&COND_refresh); + thd->global_read_lock= 0; } +#define must_wait (global_read_lock && \ + (is_not_commit || \ + global_read_lock_blocks_commit)) -bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) +bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit) { const char *old_message; bool result= 0, need_exit_cond; @@ -725,7 +747,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) LINT_INIT(old_message); (void) pthread_mutex_lock(&LOCK_open); - if (need_exit_cond= (bool)global_read_lock) + if (need_exit_cond= must_wait) { if (thd->global_read_lock) // This thread had the read locks { @@ -735,7 +757,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh) } old_message=thd->enter_cond(&COND_refresh, &LOCK_open, "Waiting for release of readlock"); - while (global_read_lock && ! thd->killed && + while (must_wait && ! thd->killed && (!abort_on_refresh || thd->version == refresh_version)) (void) pthread_cond_wait(&COND_refresh,&LOCK_open); if (thd->killed) @@ -762,3 +784,21 @@ void start_waiting_global_read_lock(THD *thd) pthread_cond_broadcast(&COND_refresh); DBUG_VOID_RETURN; } + + +void make_global_read_lock_block_commit(THD *thd) +{ + /* + If we didn't succeed lock_global_read_lock(), or if we already suceeded + make_global_read_lock_block_commit(), do nothing. + */ + if (thd->global_read_lock != GOT_GLOBAL_READ_LOCK) + return; + pthread_mutex_lock(&LOCK_open); + /* increment this BEFORE waiting on cond (otherwise race cond) */ + global_read_lock_blocks_commit++; + while (protect_against_global_read_lock) + pthread_cond_wait(&COND_refresh, &LOCK_open); + pthread_mutex_unlock(&LOCK_open); + thd->global_read_lock= MADE_GLOBAL_READ_LOCK_BLOCK_COMMIT; +} diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ca4b8d2c2b9..f53e14878b0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -762,8 +762,9 @@ void mysql_lock_abort_for_thread(THD *thd, TABLE *table); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); bool lock_global_read_lock(THD *thd); void unlock_global_read_lock(THD *thd); -bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh); +bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit); void start_waiting_global_read_lock(THD *thd); +void make_global_read_lock_block_commit(THD *thd); /* Lock based on name */ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list); diff --git a/sql/sql_class.h b/sql/sql_class.h index 3c968c6a8ae..30947041b7d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -478,7 +478,7 @@ public: ulong rand_saved_seed1, rand_saved_seed2; long dbug_thread_id; pthread_t real_id; - uint current_tablenr,tmp_table,cond_count; + uint current_tablenr,tmp_table,cond_count,global_read_lock; uint server_status,open_options,system_thread; uint32 query_length; uint32 db_length; @@ -489,7 +489,7 @@ public: bool set_query_id,locked,count_cuted_fields,some_tables_deleted; bool no_errors, allow_sum_func, password, fatal_error; bool query_start_used,last_insert_id_used,insert_id_used,rand_used; - bool in_lock_tables,global_read_lock; + bool in_lock_tables; bool query_error, bootstrap, cleanup_done; bool safe_to_cache_query; bool volatile killed; diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 2ee725e7432..3d877403813 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -42,7 +42,7 @@ int mysql_create_db(THD *thd, char *db, uint create_options, bool silent) VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); // do not create database if another thread is holding read lock - if (wait_if_global_read_lock(thd,0)) + if (wait_if_global_read_lock(thd, 0, 1)) { error= -1; goto exit2; @@ -146,7 +146,7 @@ int mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); // do not drop database if another thread is holding read lock - if (wait_if_global_read_lock(thd,0)) + if (wait_if_global_read_lock(thd, 0, 1)) { error= -1; goto exit2; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7a5260a78f0..f4887c6a8e6 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3708,8 +3708,12 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) { if (lock_global_read_lock(thd)) return 1; + result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, + tables); + make_global_read_lock_block_commit(thd); } - result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables); + else + result=close_cached_tables(thd,(options & REFRESH_FAST) ? 0 : 1, tables); } if (options & REFRESH_HOSTS) hostname_cache_refresh(); -- cgit v1.2.1 From c6150949bf5b6bbfadc8cd568f7f3ad69a7dd84f Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 16:10:47 +0000 Subject: added switch to mysqld to specify connectstring --- sql/ha_ndbcluster.cc | 8 ++++++++ sql/ha_ndbcluster.h | 2 ++ sql/mysqld.cc | 12 +++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 0545645b1fa..2c066c8da1c 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -46,6 +46,9 @@ static const int max_transactions= 256; // Default value for prefetch of autoincrement values static const ha_rows autoincrement_prefetch= 32; +// connectstring to cluster if given by mysqld +const char *ndbcluster_connectstring = 0; + #define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8 @@ -3375,6 +3378,11 @@ int ndb_discover_tables() bool ndbcluster_init() { DBUG_ENTER("ndbcluster_init"); + // Set connectstring if specified + if (ndbcluster_connectstring != 0) { + DBUG_PRINT("connectstring", ("%s", ndbcluster_connectstring)); + Ndb::setConnectString(ndbcluster_connectstring); + } // Create a Ndb object to open the connection to NDB g_ndb= new Ndb("sys"); if (g_ndb->init() != 0) diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 7eb1b8dbefb..0d9c28723ce 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -37,6 +37,8 @@ class NdbScanOperation; class NdbIndexScanOperation; class NdbBlob; +// connectstring to cluster if given by mysqld +extern const char *ndbcluster_connectstring; typedef enum ndb_index_type { UNDEFINED_INDEX = 0, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 7050929d6ed..bf305b2a8c3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3893,7 +3893,7 @@ enum options_mysqld OPT_INNODB_FILE_PER_TABLE, OPT_CRASH_BINLOG_INNODB, OPT_INNODB_LOCKS_UNSAFE_FOR_BINLOG, OPT_SAFE_SHOW_DB, OPT_INNODB_SAFE_BINLOG, - OPT_INNODB, OPT_ISAM, OPT_NDBCLUSTER, OPT_SKIP_SAFEMALLOC, + OPT_INNODB, OPT_ISAM, OPT_NDBCLUSTER, OPT_NDB_CONNECTSTRING, OPT_SKIP_SAFEMALLOC, OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS, OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL, @@ -4318,6 +4318,11 @@ master-ssl", Disable with --skip-ndbcluster (will save memory).", (gptr*) &opt_ndbcluster, (gptr*) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, +#ifdef HAVE_NDBCLUSTER_DB + {"ndb-connectstring", OPT_NDB_CONNECTSTRING, "Connect string for ndbcluster.", + (gptr*) &ndbcluster_connectstring, (gptr*) &ndbcluster_connectstring, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"new", 'n', "Use very new possible 'unsafe' functions.", (gptr*) &global_system_variables.new_mode, (gptr*) &max_system_variables.new_mode, @@ -5997,6 +6002,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), have_ndbcluster=SHOW_OPTION_YES; else have_ndbcluster=SHOW_OPTION_DISABLED; +#endif + break; + case OPT_NDB_CONNECTSTRING: +#ifdef HAVE_NDBCLUSTER_DB + have_ndbcluster=SHOW_OPTION_YES; #endif break; case OPT_INNODB: -- cgit v1.2.1 From 91df160829a7e7699f2665716d860da069cd0f95 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 20:10:49 +0200 Subject: sql_select.cc: compilation failure fixed sql/sql_select.cc: why cannot I compare (type) to (const type) ????? --- sql/sql_select.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 908b28155c7..a5cd3dc4f87 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7999,7 +7999,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, if (!item) return 1; - if (item != not_found_item) + if (item != (Item **)not_found_item) { order->item= ref_pointer_array + counter; order->in_field_list=1; -- cgit v1.2.1 From 0745a2b783becf4b3ecb095cf8e43f67e333ba90 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 22:54:42 +0200 Subject: after merge fix myisam/Makefile.am: put zlib at the end (libtool adds the whole bunch of dependencies right after that) sql/Makefile.am: put zlib at the end (libtool adds the whole bunch of dependencies right after that) --- sql/Makefile.am | 3 +-- sql/handler.cc | 2 +- sql/sql_db.cc | 2 +- sql/sql_rename.cc | 2 +- sql/sql_table.cc | 2 +- 5 files changed, 5 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/Makefile.am b/sql/Makefile.am index ec4e729bedb..d951aae91e1 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -30,7 +30,6 @@ noinst_PROGRAMS = gen_lex_hash bin_PROGRAMS = mysql_tzinfo_to_sql gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ LDADD = @isam_libs@ \ - @ZLIB_LIBS@ \ $(top_builddir)/myisam/libmyisam.a \ $(top_builddir)/myisammrg/libmyisammrg.a \ $(top_builddir)/heap/libheap.a \ @@ -38,7 +37,7 @@ LDADD = @isam_libs@ \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/regex/libregex.a \ - $(top_builddir)/strings/libmystrings.a + $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @bdb_libs@ @innodb_libs@ @pstack_libs@ \ diff --git a/sql/handler.cc b/sql/handler.cc index 39a6296a525..119e29a6a03 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -476,7 +476,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) #ifdef USING_TRANSACTIONS if (opt_using_transactions) { - bool operation_done= 0; + bool transaction_commited= 0; bool operation_done= 0, need_start_waiters= 0; /* If transaction has done some updates to tables */ diff --git a/sql/sql_db.cc b/sql/sql_db.cc index f786e7476ac..cfc75e3be95 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -498,7 +498,7 @@ int mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) VOID(pthread_mutex_lock(&LOCK_mysql_create_db)); // do not alter database if another thread is holding read lock - if ((error=wait_if_global_read_lock(thd,0))) + if ((error=wait_if_global_read_lock(thd,0,1))) goto exit2; /* Check directory */ diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index d2b575c0838..afaf2ed0923 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -48,7 +48,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(1); } - if (wait_if_global_read_lock(thd,0)) + if (wait_if_global_read_lock(thd,0,1)) DBUG_RETURN(1); VOID(pthread_mutex_lock(&LOCK_open)); if (lock_table_names(thd, table_list)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9ff46f219b1..b0b92178198 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1206,7 +1206,7 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name, my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); DBUG_RETURN(-1); } - if (wait_if_global_read_lock(thd, 0)) + if (wait_if_global_read_lock(thd, 0, 1)) DBUG_RETURN(error); VOID(pthread_mutex_lock(&LOCK_open)); if (!tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) -- cgit v1.2.1 From 095b686c09f5c143abbfb99839c1d1e2810a5a35 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 21 Aug 2004 02:02:46 +0400 Subject: Fix for bug#4912 "mysqld crashs in case a statement is executed a second time". The bug was caused by incompatibility of negations elimination algorithm and PS: during first statement execute a subtree with negation was replaced with equivalent subtree without NOTs. The problem was that although this transformation was permanent, items of the new subtree were created in execute-local memory. The patch adds means to check if it is the first execute of a prepared statement, and if this is the case, to allocate items in memory of the prepared statement. The implementation: - backports Item_arena from 5.0 - adds Item_arena::is_stmt_prepare(), Item_arena::is_first_stmt_execute(). - deletes THD::allocate_temporary_pool_for_ps_preparing(), THD::free_temporary_pool_for_ps_preparing(); they were redundant. and adds a few invariants: - thd->free_list never contains junk (= freed items) - thd->current_arena is never null. If there is no prepared statement, it points at the thd. The rest of the patch contains mainly mechanical changes and cleanups. mysql-test/r/ps.result: Test results updated (test case for Bug#4912) mysql-test/t/ps.test: A test case for Bug#4912 "mysqld crashs in case a statement is executed a second time" sql/item_cmpfunc.cc: current_statement -> current_arena sql/item_subselect.cc: Statement -> Item_arena, current_statement -> current_arena sql/item_subselect.h: Item_subselect does not need to save thd->current_statement. sql/item_sum.cc: Statement -> Item_arena sql/item_sum.h: Statement -> Item_arena sql/mysql_priv.h: Statement -> Item_arena sql/sql_base.cc: current_statement -> current_arena sql/sql_class.cc: - Item_arena - convenient set_n_backup_statement, restore_backup_statement (nice idea, Sanja) sql/sql_class.h: - Item_arena: backport from 5.0 - allocate_temporary_pool_for_ps_preparing, free_temporary_pool_for_ps_preparing removed. sql/sql_derived.cc: current_statement -> current_arena sql/sql_lex.cc: current_statement -> current_arena sql/sql_parse.cc: Deploy invariant that thd->free_list never contains junk items (backport from 5.0). sql/sql_prepare.cc: - backporting Item_arena - no need to allocate_temporary_pool_for_ps_preparing(). sql/sql_select.cc: Fix for bug#4912 "mysqld crashs in case a statement is executed a second time": if this is the first execute of a prepared statement, negation elimination is done in memory of the prepared statement. sql/sql_union.cc: Backporting Item_arena from 5.0. --- sql/item_cmpfunc.cc | 4 +- sql/item_subselect.cc | 50 ++++++++-------- sql/item_subselect.h | 2 - sql/item_sum.cc | 20 +++---- sql/item_sum.h | 4 +- sql/mysql_priv.h | 2 +- sql/sql_base.cc | 43 +++++++------- sql/sql_class.cc | 78 ++++++++++++++++++++----- sql/sql_class.h | 128 +++++++++++++++++++--------------------- sql/sql_derived.cc | 2 +- sql/sql_lex.cc | 4 +- sql/sql_parse.cc | 3 + sql/sql_prepare.cc | 158 ++++++++++++++++++++++---------------------------- sql/sql_select.cc | 46 ++++++++++----- sql/sql_union.cc | 15 +++-- 15 files changed, 298 insertions(+), 261 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 23bdad1aae5..75dbbecf187 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -589,10 +589,8 @@ bool Item_in_optimizer::fix_left(THD *thd, /* If it is preparation PS only then we do not know values of parameters => cant't get there values and do not need that values. - - TODO: during merge with 5.0 it should be changed on !thd->only_prepare() */ - if (!thd->current_statement) + if (! thd->current_arena->is_stmt_prepare()) cache->store(args[0]); if (cache->cols() == 1) { diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 8c4dae92ddc..68bc144d518 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -125,7 +125,6 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) { DBUG_ASSERT(fixed == 0); engine->set_thd((thd= thd_param)); - stmt= thd->current_statement; char const *save_where= thd->where; int res; @@ -306,7 +305,10 @@ Item_singlerow_subselect::select_transformer(JOIN *join) return RES_OK; SELECT_LEX *select_lex= join->select_lex; - Statement backup; + + /* Juggle with current arena only if we're in prepared statement prepare */ + Item_arena *arena= join->thd->current_arena; + Item_arena backup; if (!select_lex->master_unit()->first_select()->next_select() && !select_lex->table_list.elements && @@ -341,8 +343,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join) if (join->conds || join->having) { Item *cond; - if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); if (!join->having) cond= join->conds; @@ -355,15 +357,15 @@ Item_singlerow_subselect::select_transformer(JOIN *join) new Item_null()))) goto err; } - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); return RES_REDUCE; } return RES_OK; err: - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); return RES_ERROR; } @@ -640,11 +642,11 @@ Item_in_subselect::single_value_transformer(JOIN *join, } SELECT_LEX *select_lex= join->select_lex; - Statement backup; + Item_arena *arena= join->thd->current_arena, backup; thd->where= "scalar IN/ALL/ANY subquery"; - if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); if (select_lex->item_list.elements > 1) { @@ -857,21 +859,21 @@ Item_in_subselect::single_value_transformer(JOIN *join, push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SELECT_REDUCED, warn_buff); } - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(RES_REDUCE); } } } ok: - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(RES_OK); err: - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(RES_ERROR); } @@ -885,12 +887,12 @@ Item_in_subselect::row_value_transformer(JOIN *join) { DBUG_RETURN(RES_OK); } - Statement backup; + Item_arena *arena= join->thd->current_arena, backup; Item *item= 0; thd->where= "row IN/ALL/ANY subquery"; - if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); SELECT_LEX *select_lex= join->select_lex; @@ -974,13 +976,13 @@ Item_in_subselect::row_value_transformer(JOIN *join) if (join->conds->fix_fields(thd, join->tables_list, 0)) goto err; } - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(RES_OK); err: - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(RES_ERROR); } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 6b8b8b0b3a7..1ce3144f660 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -36,8 +36,6 @@ class Item_subselect :public Item_result_field protected: /* thread handler, will be assigned in fix_fields only */ THD *thd; - /* prepared statement, or 0 */ - Statement *stmt; /* substitution instead of subselect in case of optimization */ Item *substitution; /* unit of subquery */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index c256055d5bb..cbb4cd41046 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -64,28 +64,28 @@ Item_sum::Item_sum(THD *thd, Item_sum *item): /* - Save copy of arguments if we are prepare prepared statement + Save copy of arguments if we prepare prepared statement (arguments can be rewritten in get_tmp_table_item()) SYNOPSIS - Item_sum::save_args_for_prepared_statements() + Item_sum::save_args_for_prepared_statement() thd - thread handler RETURN 0 - OK 1 - Error */ -bool Item_sum::save_args_for_prepared_statements(THD *thd) +bool Item_sum::save_args_for_prepared_statement(THD *thd) { - if (thd->current_statement) - return save_args(thd->current_statement); + if (thd->current_arena->is_stmt_prepare()) + return save_args(thd->current_arena); return 0; } -bool Item_sum::save_args(Statement* stmt) +bool Item_sum::save_args(Item_arena* arena) { - if (!(args_copy= (Item**) stmt->alloc(sizeof(Item*)*arg_count))) + if (!(args_copy= (Item**) arena->alloc(sizeof(Item*)*arg_count))) return 1; memcpy(args_copy, args, sizeof(Item*)*arg_count); return 0; @@ -214,7 +214,7 @@ Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { DBUG_ASSERT(fixed == 0); - if (save_args_for_prepared_statements(thd)) + if (save_args_for_prepared_statement(thd)) return 1; if (!thd->allow_sum_func) @@ -248,7 +248,7 @@ Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { DBUG_ASSERT(fixed == 0); - if (save_args_for_prepared_statements(thd)) + if (save_args_for_prepared_statement(thd)) return 1; Item *item= args[0]; @@ -1947,7 +1947,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { DBUG_ASSERT(fixed == 0); - if (save_args_for_prepared_statements(thd)) + if (save_args_for_prepared_statement(thd)) return 1; uint i; /* for loop variable */ diff --git a/sql/item_sum.h b/sql/item_sum.h index fcace9e322a..5081d592654 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -92,8 +92,8 @@ public: virtual bool setup(THD *thd) {return 0;} virtual void make_unique() {} Item *get_tmp_table_item(THD *thd); - bool save_args_for_prepared_statements(THD *); - bool save_args(Statement* stmt); + bool save_args_for_prepared_statement(THD *); + bool save_args(Item_arena *arena); bool walk (Item_processor processor, byte *argument); }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 9ada2fba164..b7c19ad2c06 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -295,7 +295,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); struct st_table; class THD; -class Statement; +class Item_arena; /* Struct to handle simple linked lists */ diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4efdd3edbcd..eed7012966d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2188,14 +2188,15 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, { if (!wild_num) return 0; - Statement *stmt= thd->current_statement, backup; + Item_arena *arena= thd->current_arena, backup; /* If we are in preparing prepared statement phase then we have change temporary mem_root to statement mem root to save changes of SELECT list */ - if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); + reg2 Item *item; List_iterator it(fields); while ( wild_num && (item= it++)) @@ -2219,8 +2220,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, else if (insert_fields(thd,tables,((Item_field*) item)->db_name, ((Item_field*) item)->table_name, &it)) { - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); return (-1); } if (sum_func_list) @@ -2235,8 +2236,8 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, wild_num--; } } - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); return 0; } @@ -2449,7 +2450,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) { table_map not_null_tables= 0; - Statement *stmt= thd->current_statement, backup; + Item_arena *arena= thd->current_arena, backup; DBUG_ENTER("setup_conds"); thd->set_query_id=1; @@ -2488,12 +2489,12 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) !(specialflag & SPECIAL_NO_NEW_FUNC))) { table->outer_join= 0; - if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); *conds= and_conds(*conds, table->on_expr); table->on_expr=0; - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); if ((*conds) && !(*conds)->fixed && (*conds)->fix_fields(thd, tables, conds)) DBUG_RETURN(1); @@ -2501,8 +2502,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) } if (table->natural_join) { - if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); /* Make a join of all fields with have the same name */ TABLE *t1= table->table; TABLE *t2= table->natural_join->table; @@ -2543,8 +2544,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) { *conds= and_conds(*conds, cond_and); // fix_fields() should be made with temporary memory pool - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); if (*conds && !(*conds)->fixed) { if ((*conds)->fix_fields(thd, tables, conds)) @@ -2555,8 +2556,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) { table->on_expr= and_conds(table->on_expr, cond_and); // fix_fields() should be made with temporary memory pool - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); if (table->on_expr && !table->on_expr->fixed) { if (table->on_expr->fix_fields(thd, tables, &table->on_expr)) @@ -2567,7 +2568,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) } } - if (stmt) + if (arena->is_stmt_prepare()) { /* We are in prepared statement preparation code => we should store @@ -2580,8 +2581,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) DBUG_RETURN(test(thd->net.report_error)); err: - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(1); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 73a180078cf..23fef44c964 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -155,7 +155,7 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), current_statement(0), is_fatal_error(0), +THD::THD():user_time(0), current_arena(this), is_fatal_error(0), last_insert_id_used(0), insert_id_used(0), rand_used(0), time_zone_used(0), in_lock_tables(0), global_read_lock(0), bootstrap(0) @@ -1301,23 +1301,59 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) } +Item_arena::Item_arena(THD* thd) + :free_list(0), + state(INITIALIZED) +{ + init_sql_alloc(&mem_root, + thd->variables.query_alloc_block_size, + thd->variables.query_prealloc_size); +} + + +/* This constructor is called when Item_arena is a subobject of THD */ + +Item_arena::Item_arena() + :free_list(0), + state(CONVENTIONAL_EXECUTION) +{ + clear_alloc_root(&mem_root); +} + + +Item_arena::Item_arena(bool init_mem_root) + :free_list(0), + state(INITIALIZED) +{ + if (init_mem_root) + clear_alloc_root(&mem_root); +} + +Item_arena::Type Item_arena::type() const +{ + DBUG_ASSERT("Item_arena::type()" == "abstract"); + return STATEMENT; +} + + +Item_arena::~Item_arena() +{} + + /* Statement functions */ Statement::Statement(THD *thd) - :id(++thd->statement_id_counter), + :Item_arena(thd), + id(++thd->statement_id_counter), set_query_id(1), allow_sum_func(0), lex(&main_lex), query(0), - query_length(0), - free_list(0) + query_length(0) { name.str= NULL; - init_sql_alloc(&mem_root, - thd->variables.query_alloc_block_size, - thd->variables.query_prealloc_size); } /* @@ -1332,14 +1368,12 @@ Statement::Statement() allow_sum_func(0), /* initialized later */ lex(&main_lex), query(0), /* these two are set */ - query_length(0), /* in alloc_query() */ - free_list(0) + query_length(0) /* in alloc_query() */ { - bzero((char *) &mem_root, sizeof(mem_root)); } -Statement::Type Statement::type() const +Item_arena::Type Statement::type() const { return STATEMENT; } @@ -1356,14 +1390,29 @@ void Statement::set_statement(Statement *stmt) } -void Statement::set_n_backup_item_arena(Statement *set, Statement *backup) +void +Statement::set_n_backup_statement(Statement *stmt, Statement *backup) +{ + backup->set_statement(this); + set_statement(stmt); +} + + +void Statement::restore_backup_statement(Statement *stmt, Statement *backup) +{ + stmt->set_statement(this); + set_statement(backup); +} + + +void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup) { backup->set_item_arena(this); set_item_arena(set); } -void Statement::restore_backup_item_arena(Statement *set, Statement *backup) +void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup) { set->set_item_arena(this); set_item_arena(backup); @@ -1371,10 +1420,11 @@ void Statement::restore_backup_item_arena(Statement *set, Statement *backup) init_alloc_root(&backup->mem_root, 0, 0); } -void Statement::set_item_arena(Statement *set) +void Item_arena::set_item_arena(Item_arena *set) { mem_root= set->mem_root; free_list= set->free_list; + state= set->state; } Statement::~Statement() diff --git a/sql/sql_class.h b/sql/sql_class.h index 59ac8ff0483..61b8a8281da 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -418,6 +418,61 @@ struct system_variables void free_tmp_table(THD *thd, TABLE *entry); +class Item_arena +{ +public: + /* + 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; + static const int INITIALIZED= 0, PREPARED= 1, EXECUTED= 3, + CONVENTIONAL_EXECUTION= 2, ERROR= -1; + int state; + + /* We build without RTTI, so dynamic_cast can't be used. */ + enum Type + { + STATEMENT, PREPARED_STATEMENT, STORED_PROCEDURE + }; + + Item_arena(THD *thd); + Item_arena(); + Item_arena(bool init_mem_root); + virtual Type type() const; + virtual ~Item_arena(); + + inline bool is_stmt_prepare() const { return state < PREPARED; } + inline bool is_first_stmt_execute() const { return state == PREPARED; } + inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); } + inline gptr calloc(unsigned int size) + { + gptr ptr; + if ((ptr=alloc_root(&mem_root,size))) + bzero((char*) ptr,size); + return ptr; + } + inline char *strdup(const char *str) + { return strdup_root(&mem_root,str); } + inline char *strmake(const char *str, uint size) + { return strmake_root(&mem_root,str,size); } + inline char *memdup(const char *str, uint size) + { return memdup_root(&mem_root,str,size); } + inline char *memdup_w_gap(const char *str, uint size, uint gap) + { + gptr ptr; + if ((ptr=alloc_root(&mem_root,size+gap))) + memcpy(ptr,str,size); + return ptr; + } + + void set_n_backup_item_arena(Item_arena *set, Item_arena *backup); + void restore_backup_item_arena(Item_arena *set, Item_arena *backup); + void set_item_arena(Item_arena *set); +}; + + /* State of a single command executed against this connection. One connection can contain a lot of simultaneously running statements, @@ -432,7 +487,7 @@ void free_tmp_table(THD *thd, TABLE *entry); be used explicitly. */ -class Statement +class Statement: public Item_arena { Statement(const Statement &rhs); /* not implemented: */ Statement &operator=(const Statement &rhs); /* non-copyable */ @@ -474,20 +529,8 @@ public: */ 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; public: - /* We build without RTTI, so dynamic_cast can't be used. */ - enum Type - { - STATEMENT, - PREPARED_STATEMENT - }; /* This constructor is called when statement is a subobject of THD: @@ -500,34 +543,10 @@ public: /* Assign execution context (note: not all members) of given stmt to self */ void set_statement(Statement *stmt); + void set_n_backup_statement(Statement *stmt, Statement *backup); + void restore_backup_statement(Statement *stmt, Statement *backup); /* return class type */ virtual Type type() const; - - inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); } - inline gptr calloc(unsigned int size) - { - gptr ptr; - if ((ptr=alloc_root(&mem_root,size))) - bzero((char*) ptr,size); - return ptr; - } - inline char *strdup(const char *str) - { return strdup_root(&mem_root,str); } - inline char *strmake(const char *str, uint size) - { return strmake_root(&mem_root,str,size); } - inline char *memdup(const char *str, uint size) - { return memdup_root(&mem_root,str,size); } - inline char *memdup_w_gap(const char *str, uint size, uint gap) - { - gptr ptr; - if ((ptr=alloc_root(&mem_root,size+gap))) - memcpy(ptr,str,size); - return ptr; - } - - void set_n_backup_item_arena(Statement *set, Statement *backup); - void restore_backup_item_arena(Statement *set, Statement *backup); - void set_item_arena(Statement *set); }; @@ -760,9 +779,9 @@ public: Vio* active_vio; #endif /* - Current prepared Statement if there one, or 0 + Current prepared Item_arena if there one, or 0 */ - Statement *current_statement; + Item_arena *current_arena; /* next_insert_id is set on SET INSERT_ID= #. This is used as the next generated auto_increment value in handler.cc @@ -983,33 +1002,6 @@ public: } inline CHARSET_INFO *charset() { return variables.character_set_client; } void update_charset(); - - inline void allocate_temporary_memory_pool_for_ps_preparing() - { - DBUG_ASSERT(current_statement!=0); - /* - We do not want to have in PS memory all that junk, - which will be created by preparation => substitute memory - from original thread pool. - - We know that PS memory pool is now copied to THD, we move it back - to allow some code use it. - */ - current_statement->set_item_arena(this); - init_sql_alloc(&mem_root, - variables.query_alloc_block_size, - variables.query_prealloc_size); - free_list= 0; - } - inline void free_temporary_memory_pool_for_ps_preparing() - { - DBUG_ASSERT(current_statement!=0); - cleanup_items(current_statement->free_list); - free_items(free_list); - close_thread_tables(this); // to close derived tables - free_root(&mem_root, MYF(0)); - set_item_arena(current_statement); - } }; /* Flags for the THD::system_thread (bitmap) variable */ diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 01459d3fc7a..30b06e91082 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -151,7 +151,7 @@ static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, if it is preparation PS only then we do not need real data and we can skip execution (and parameters is not defined, too) */ - if (!thd->current_statement) + if (! thd->current_arena->is_stmt_prepare()) { if (is_union) { diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 2b6a307092c..be1b7c3377e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1527,9 +1527,9 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) We have to create array in prepared statement memory if it is prepared statement */ - Statement *stmt= thd->current_statement ? thd->current_statement : thd; + Item_arena *arena= thd->current_arena; return (ref_pointer_array= - (Item **)stmt->alloc(sizeof(Item*) * + (Item **)arena->alloc(sizeof(Item*) * (item_list.elements + select_n_having_items + order_group_num)* 5)) == 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 57e4022719e..7c275aa6e6f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1543,6 +1543,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, break; mysqld_list_fields(thd,&table_list,fields); free_items(thd->free_list); + thd->free_list= 0; break; } #endif @@ -4047,6 +4048,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) } thd->proc_info="freeing items"; free_items(thd->free_list); /* Free strings used by items */ + thd->free_list= 0; lex_end(lex); } DBUG_VOID_RETURN; @@ -4073,6 +4075,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) error= 1; /* Ignore question */ free_items(thd->free_list); /* Free strings used by items */ + thd->free_list= 0; lex_end(lex); return error; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index db904d24bf7..57bb96946ff 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -88,7 +88,6 @@ public: uint param_count; uint last_errno; char last_error[MYSQL_ERRMSG_SIZE]; - bool get_longdata_error; #ifndef EMBEDDED_LIBRARY bool (*set_params)(Prepared_statement *st, uchar *data, uchar *data_end, uchar *read_pos, String *expanded_query); @@ -102,7 +101,7 @@ public: Prepared_statement(THD *thd_arg); virtual ~Prepared_statement(); void setup_set_params(); - virtual Statement::Type type() const; + virtual Item_arena::Type type() const; }; static void execute_stmt(THD *thd, Prepared_statement *stmt, @@ -133,7 +132,7 @@ find_prepared_statement(THD *thd, ulong id, const char *where, { Statement *stmt= thd->stmt_map.find(id); - if (stmt == 0 || stmt->type() != Statement::PREPARED_STATEMENT) + if (stmt == 0 || stmt->type() != Item_arena::PREPARED_STATEMENT) { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), 22, llstr(id, llbuf), where); @@ -894,10 +893,8 @@ static int mysql_test_insert(Prepared_statement *stmt, open temporary memory pool for temporary data allocated by derived tables & preparation procedure */ - thd->allocate_temporary_memory_pool_for_ps_preparing(); if (open_and_lock_tables(thd, table_list)) { - thd->free_temporary_memory_pool_for_ps_preparing(); DBUG_RETURN(-1); } @@ -932,7 +929,6 @@ static int mysql_test_insert(Prepared_statement *stmt, res= 0; error: lex->unit.cleanup(); - thd->free_temporary_memory_pool_for_ps_preparing(); DBUG_RETURN(res); } @@ -961,12 +957,6 @@ static int mysql_test_update(Prepared_statement *stmt, if ((res= update_precheck(thd, table_list))) DBUG_RETURN(res); - /* - open temporary memory pool for temporary data allocated by derived - tables & preparation procedure - */ - thd->allocate_temporary_memory_pool_for_ps_preparing(); - if (open_and_lock_tables(thd, table_list)) res= -1; else @@ -986,7 +976,6 @@ static int mysql_test_update(Prepared_statement *stmt, } stmt->lex->unit.cleanup(); } - thd->free_temporary_memory_pool_for_ps_preparing(); /* TODO: here we should send types of placeholders to the client. */ DBUG_RETURN(res); } @@ -1016,12 +1005,6 @@ static int mysql_test_delete(Prepared_statement *stmt, if ((res= delete_precheck(thd, table_list))) DBUG_RETURN(res); - /* - open temporary memory pool for temporary data allocated by derived - tables & preparation procedure - */ - thd->allocate_temporary_memory_pool_for_ps_preparing(); - if (open_and_lock_tables(thd, table_list)) res= -1; else @@ -1029,7 +1012,6 @@ static int mysql_test_delete(Prepared_statement *stmt, res= mysql_prepare_delete(thd, table_list, &lex->select_lex.where); lex->unit.cleanup(); } - thd->free_temporary_memory_pool_for_ps_preparing(); /* TODO: here we should send types of placeholders to the client. */ DBUG_RETURN(res); } @@ -1071,11 +1053,6 @@ static int mysql_test_select(Prepared_statement *stmt, DBUG_RETURN(1); #endif - /* - open temporary memory pool for temporary data allocated by derived - tables & preparation procedure - */ - thd->allocate_temporary_memory_pool_for_ps_preparing(); if (open_and_lock_tables(thd, tables)) { send_error(thd); @@ -1090,33 +1067,30 @@ static int mysql_test_select(Prepared_statement *stmt, send_error(thd); goto err_prep; } - if (lex->describe) - { - if (!text_protocol && send_prep_stmt(stmt, 0)) - goto err_prep; - unit->cleanup(); - } - else + if (!text_protocol) { - if (!text_protocol) + if (lex->describe) + { + if (send_prep_stmt(stmt, 0)) + goto err_prep; + } + else { if (send_prep_stmt(stmt, lex->select_lex.item_list.elements) || - thd->protocol_simple.send_fields(&lex->select_lex.item_list, 0) + thd->protocol_simple.send_fields(&lex->select_lex.item_list, 0) #ifndef EMBEDDED_LIBRARY || net_flush(&thd->net) #endif ) goto err_prep; } - unit->cleanup(); } - thd->free_temporary_memory_pool_for_ps_preparing(); + unit->cleanup(); DBUG_RETURN(0); err_prep: unit->cleanup(); err: - thd->free_temporary_memory_pool_for_ps_preparing(); DBUG_RETURN(1); } @@ -1145,19 +1119,13 @@ static int mysql_test_do_fields(Prepared_statement *stmt, int res= 0; if (tables && (res= check_table_access(thd, SELECT_ACL, tables, 0))) DBUG_RETURN(res); - /* - open temporary memory pool for temporary data allocated by derived - tables & preparation procedure - */ - thd->allocate_temporary_memory_pool_for_ps_preparing(); + if (tables && (res= open_and_lock_tables(thd, tables))) { - thd->free_temporary_memory_pool_for_ps_preparing(); DBUG_RETURN(res); } res= setup_fields(thd, 0, 0, *values, 0, 0, 0); stmt->lex->unit.cleanup(); - thd->free_temporary_memory_pool_for_ps_preparing(); if (res) DBUG_RETURN(-1); DBUG_RETURN(0); @@ -1190,11 +1158,7 @@ static int mysql_test_set_fields(Prepared_statement *stmt, if (tables && (res= check_table_access(thd, SELECT_ACL, tables, 0))) DBUG_RETURN(res); - /* - open temporary memory pool for temporary data allocated by derived - tables & preparation procedure - */ - thd->allocate_temporary_memory_pool_for_ps_preparing(); + if (tables && (res= open_and_lock_tables(thd, tables))) goto error; while ((var= it++)) @@ -1208,7 +1172,6 @@ static int mysql_test_set_fields(Prepared_statement *stmt, } error: stmt->lex->unit.cleanup(); - thd->free_temporary_memory_pool_for_ps_preparing(); DBUG_RETURN(res); } @@ -1233,11 +1196,7 @@ static int select_like_statement_test(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; int res= 0; - /* - open temporary memory pool for temporary data allocated by derived - tables & preparation procedure - */ - thd->allocate_temporary_memory_pool_for_ps_preparing(); + if (tables && (res= open_and_lock_tables(thd, tables))) goto end; @@ -1250,7 +1209,6 @@ static int select_like_statement_test(Prepared_statement *stmt, } end: lex->unit.cleanup(); - thd->free_temporary_memory_pool_for_ps_preparing(); DBUG_RETURN(res); } @@ -1594,17 +1552,13 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, DBUG_RETURN(1); } - thd->stmt_backup.set_statement(thd); - thd->stmt_backup.set_item_arena(thd); - thd->set_statement(stmt); - thd->set_item_arena(stmt); + thd->set_n_backup_statement(stmt, &thd->stmt_backup); + thd->set_n_backup_item_arena(stmt, &thd->stmt_backup); if (alloc_query(thd, packet, packet_length)) { - stmt->set_statement(thd); - stmt->set_item_arena(thd); - thd->set_statement(&thd->stmt_backup); - thd->set_item_arena(&thd->stmt_backup); + thd->restore_backup_statement(stmt, &thd->stmt_backup); + thd->restore_backup_item_arena(stmt, &thd->stmt_backup); /* Statement map deletes statement on erase */ thd->stmt_map.erase(stmt); send_error(thd, ER_OUT_OF_RESOURCES); @@ -1613,24 +1567,36 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, mysql_log.write(thd, COM_PREPARE, "%s", packet); - thd->current_statement= stmt; + thd->current_arena= stmt; mysql_init_query(thd, (uchar *) thd->query, thd->query_length); lex= thd->lex; lex->safe_to_cache_query= 0; error= yyparse((void *)thd) || thd->is_fatal_error || - init_param_array(stmt) || - send_prepare_results(stmt, test(name)); + init_param_array(stmt); + /* + While doing context analysis of the query (in send_prepare_results) we + allocate a lot of additional memory: for open tables, JOINs, derived + tables, etc. Let's save a snapshot of current parse tree to the + statement and restore original THD. In cases when some tree + transformation can be reused on execute, we set again thd->mem_root from + stmt->mem_root (see setup_wild for one place where we do that). + */ + thd->restore_backup_item_arena(stmt, &thd->stmt_backup); + + if (!error) + error= send_prepare_results(stmt, test(name)); /* restore to WAIT_PRIOR: QUERY_PRIOR is set inside alloc_query */ if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),WAIT_PRIOR); lex_end(lex); - stmt->set_statement(thd); - stmt->set_item_arena(thd); - thd->set_statement(&thd->stmt_backup); - thd->set_item_arena(&thd->stmt_backup); - thd->current_statement= 0; + thd->restore_backup_statement(stmt, &thd->stmt_backup); + cleanup_items(stmt->free_list); + close_thread_tables(thd); + free_items(thd->free_list); + thd->free_list= 0; + thd->current_arena= thd; if (error) { @@ -1651,7 +1617,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, { sl->prep_where= sl->where; } - + stmt->state= Prepared_statement::PREPARED; } DBUG_RETURN(!stmt); @@ -1765,7 +1731,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) DBUG_PRINT("exec_query:", ("%s", stmt->query)); /* Check if we got an error when sending long data */ - if (stmt->get_longdata_error) + if (stmt->state == Item_arena::ERROR) { send_error(thd, stmt->last_errno, stmt->last_error); DBUG_VOID_RETURN; @@ -1789,6 +1755,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) if (stmt->param_count && stmt->set_params_data(stmt, &expanded_query)) goto set_params_data_err; #endif + DBUG_ASSERT(thd->free_list == NULL); thd->protocol= &thd->protocol_prep; // Switch to binary protocol execute_stmt(thd, stmt, &expanded_query, true); thd->protocol= &thd->protocol_simple; // Use normal protocol @@ -1832,9 +1799,9 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) DBUG_VOID_RETURN; } - thd->free_list= NULL; - thd->stmt_backup.set_statement(thd); - thd->set_statement(stmt); + DBUG_ASSERT(thd->free_list == NULL); + + thd->set_n_backup_statement(stmt, &thd->stmt_backup); if (stmt->set_params_from_vars(stmt, thd->stmt_backup.lex->prepared_stmt_params, &expanded_query)) @@ -1866,11 +1833,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, { DBUG_ENTER("execute_stmt"); if (set_context) - { - thd->free_list= NULL; - thd->stmt_backup.set_statement(thd); - thd->set_statement(stmt); - } + thd->set_n_backup_statement(stmt, &thd->stmt_backup); reset_stmt_for_execute(stmt); if (expanded_query->length() && @@ -1880,6 +1843,13 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, my_error(ER_OUTOFMEMORY, 0, expanded_query->length()); DBUG_VOID_RETURN; } + /* + At first execution of prepared statement we will perform logical + transformations of the query tree (i.e. negations elimination). + This should be done permanently on the parse tree of this statement. + */ + if (stmt->state == Item_arena::PREPARED) + thd->current_arena= stmt; if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); @@ -1890,6 +1860,12 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, /* Free Items that were created during this execution of the PS. */ free_items(thd->free_list); + thd->free_list= 0; + if (stmt->state == Item_arena::PREPARED) + { + thd->current_arena= thd; + stmt->state= Item_arena::EXECUTED; + } cleanup_items(stmt->free_list); reset_stmt_params(stmt); close_thread_tables(thd); // to close derived tables @@ -1927,7 +1903,7 @@ void mysql_stmt_reset(THD *thd, char *packet) SEND_ERROR))) DBUG_VOID_RETURN; - stmt->get_longdata_error= 0; + stmt->state= Item_arena::PREPARED; /* Clear parameters from data which could be set by @@ -2015,7 +1991,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param_number >= stmt->param_count) { /* Error will be sent in execute call */ - stmt->get_longdata_error= 1; + stmt->state= Item_arena::ERROR; stmt->last_errno= ER_WRONG_ARGUMENTS; sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "mysql_stmt_send_long_data"); @@ -2026,10 +2002,15 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) param= stmt->param_array[param_number]; #ifndef EMBEDDED_LIBRARY - param->set_longdata(packet, (ulong) (packet_end - packet)); + if (param->set_longdata(packet, (ulong) (packet_end - packet))) #else - param->set_longdata(thd->extra_data, thd->extra_length); + if (param->set_longdata(thd->extra_data, thd->extra_length)) #endif + { + stmt->state= Item_arena::ERROR; + stmt->last_errno= ER_OUTOFMEMORY; + sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0); + } DBUG_VOID_RETURN; } @@ -2039,8 +2020,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg) thd(thd_arg), param_array(0), param_count(0), - last_errno(0), - get_longdata_error(0) + last_errno(0) { *last_error= '\0'; } @@ -2074,7 +2054,7 @@ Prepared_statement::~Prepared_statement() } -Statement::Type Prepared_statement::type() const +Item_arena::Type Prepared_statement::type() const { return PREPARED_STATEMENT; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index c56645e06b9..2478ec0eb7b 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4377,25 +4377,39 @@ COND *eliminate_not_funcs(THD *thd, COND *cond) static COND * optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) { + SELECT_LEX *select= thd->lex->current_select; DBUG_ENTER("optimize_cond"); - if (!conds) + if (conds) + { + DBUG_EXECUTE("where", print_where(conds, "original");); + /* Eliminate NOT operators; in case of PS/SP do it once */ + if (thd->current_arena->is_first_stmt_execute()) + { + Item_arena *arena= thd->current_arena, backup; + thd->set_n_backup_item_arena(arena, &backup); + conds= eliminate_not_funcs(thd, conds); + select->prep_where= conds->copy_andor_structure(thd); + thd->restore_backup_item_arena(arena, &backup); + } + else + conds= eliminate_not_funcs(thd, conds); + DBUG_EXECUTE("where", print_where(conds, "after negation elimination");); + + /* change field = field to field = const for each found field = const */ + propagate_cond_constants((I_List *) 0, conds, conds); + /* + Remove all instances of item == item + Remove all and-levels where CONST item != CONST item + */ + DBUG_EXECUTE("where", print_where(conds, "after const change");); + conds= remove_eq_conds(thd, conds, cond_value); + DBUG_EXECUTE("info", print_where(conds, "after remove");); + } + else { *cond_value= Item::COND_TRUE; - DBUG_RETURN(conds); - } - DBUG_EXECUTE("where",print_where(conds,"original");); - /* eliminate NOT operators */ - conds= eliminate_not_funcs(thd, conds); - DBUG_EXECUTE("where", print_where(conds, "after negation elimination");); - /* change field = field to field = const for each found field = const */ - propagate_cond_constants((I_List *) 0,conds,conds); - /* - Remove all instances of item == item - Remove all and-levels where CONST item != CONST item - */ - DBUG_EXECUTE("where",print_where(conds,"after const change");); - conds= remove_eq_conds(thd, conds, cond_value) ; - DBUG_EXECUTE("info",print_where(conds,"after remove");); + select->prep_where= 0; + } DBUG_RETURN(conds); } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 70c05489f82..1e8c6576dec 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -287,24 +287,23 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, thd_arg->lex->current_select= lex_select_save; if (!item_list.elements) { - Statement *stmt= thd->current_statement; - Statement backup; - if (stmt) - thd->set_n_backup_item_arena(stmt, &backup); + Item_arena *arena= thd->current_arena, backup; + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); Field **field; for (field= table->field; *field; field++) { Item_field *item= new Item_field(*field); if (!item || item_list.push_back(item)) { - if (stmt) - thd->restore_backup_item_arena(stmt, &backup); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(-1); } } - if (stmt) + if (arena->is_stmt_prepare()) { - thd->restore_backup_item_arena(stmt, &backup); + thd->restore_backup_item_arena(arena, &backup); /* prepare fake select to initialize it correctly */ ulong options_tmp= init_prepare_fake_select_lex(thd); -- cgit v1.2.1 From 2eb954a27a6aa6bf0f4e9c480dc8a633649595f1 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 21 Aug 2004 05:07:32 +0200 Subject: Bug #4629 Crash after SLAVE STOP, if the IO thread is in special state. client.c: Added call to clear_slave_vio inside end_server only when under Windows with repliaction slave.cc: Added clear_slave_vio function for clearing active vio on THD under Windows replication sql/slave.cc: Added clear_slave_vio function for clearing active vio on THD under Windows replication sql-common/client.c: Added call to clear_slave_vio inside end_server only when under Windows with repliaction --- sql/slave.cc | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'sql') diff --git a/sql/slave.cc b/sql/slave.cc index 7fb7fbdade4..51421533a5b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -4383,4 +4383,26 @@ template class I_List_iterator; template class I_List_iterator; #endif + +#ifdef __WIN__ +extern "C" void clear_slave_vio( MYSQL* mysql ) +{ + if (active_mi->mysql == mysql) + active_mi->io_thd->clear_active_vio(); + /* TODO: use code like below when multi-master is in place */ + /* LIST *cur = &master_list; + if (((MASTER_INFO*)cur->data)->mysql == mysql) + { + MASTER_INFO *mi = (MASTER_INFO*)cur->data; + mi->io_thd->clear_active_vio(); + return; + } + else + cur = cur->next;*/ +} +#endif + + + + #endif /* HAVE_REPLICATION */ -- cgit v1.2.1 From c1fd20bb5ed75b4d6df24703e0b26a488eac4a3b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Aug 2004 23:48:30 -0700 Subject: null.test, null.result: Added test case for bug #4256. join_outer.result: Fixed bug #4256. item_cmpfunc.h: Fixed inconsistency of values of used_tables_cache and const_item_cache for Item_func_isnull objects. This inconsistency caused bug #4256. sql/item_cmpfunc.h: Fixed inconsistency of values of used_tables_cache and const_item_cache for Item_func_isnull objects. This inconsistency caused bug #4256. mysql-test/r/join_outer.result: Fixed bug #4256. mysql-test/r/null.result: Added test case for bug #4256. mysql-test/t/null.test: Added test case for bug #4256. --- sql/item_cmpfunc.h | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index a0bcd864d4b..236ebb8d28b 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -469,6 +469,7 @@ public: if (!args[0]->maybe_null) { used_tables_cache= 0; /* is always false */ + const_item_cache= 1; cached_value= (longlong) 0; } else -- cgit v1.2.1 From ac4c0538529c0bf351d116b0b9d2c58c7fc3bc35 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Aug 2004 00:06:19 +0500 Subject: Proposed fix for bug #5003 (subselect with MIN() and LIKE crashes server) We have next problem here: active_index is wrong in the subselect's handler on the second val_int() call. Optimizer sees that we can use index-read for that kind of condition, and matching_cond() (sql/opt_sum.cc) doesn't. I suspect, proper solution is to add appropriate code to the matching_cond() but now just added missed initialization. mysql-test/r/subselect.result: Appropriate test result mysql-test/t/subselect.test: Test case added sql/records.cc: index's initialization added --- sql/records.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sql') diff --git a/sql/records.cc b/sql/records.cc index 94634d30759..5a969ef9c20 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -101,6 +101,9 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, else if (select && select->quick) { DBUG_PRINT("info",("using rr_quick")); + + if (!table->file->inited) + table->file->ha_index_init(select->quick->index); info->read_record=rr_quick; } else if (table->sort.record_pointers) -- cgit v1.2.1 From dcf98760aedfebd631e786d2d23fd28fcfea77d9 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 22 Aug 2004 14:23:52 +0200 Subject: check for mysql_bin_log.is_open() before my_b_tell(&thd->transaction.trans_log in ha_commit_trans - why it didn't crash earlier ? mysql-test/r/null.result: after merge fix --- sql/handler.cc | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/handler.cc b/sql/handler.cc index 119e29a6a03..15f30b25eb8 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -472,7 +472,7 @@ int ha_release_temporary_latches(THD *thd) int ha_commit_trans(THD *thd, THD_TRANS* trans) { int error=0; - DBUG_ENTER("ha_commit"); + DBUG_ENTER("ha_commit_trans"); #ifdef USING_TRANSACTIONS if (opt_using_transactions) { @@ -480,8 +480,8 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) bool operation_done= 0, need_start_waiters= 0; /* If transaction has done some updates to tables */ - if (trans == &thd->transaction.all && - my_b_tell(&thd->transaction.trans_log)) + if (trans == &thd->transaction.all && mysql_bin_log.is_open() && + my_b_tell(&thd->transaction.trans_log)) { if (error= wait_if_global_read_lock(thd, 0, 0)) { @@ -576,7 +576,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) int ha_rollback_trans(THD *thd, THD_TRANS *trans) { int error=0; - DBUG_ENTER("ha_rollback"); + DBUG_ENTER("ha_rollback_trans"); #ifdef USING_TRANSACTIONS if (opt_using_transactions) { @@ -587,7 +587,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) if ((error=ndbcluster_rollback(thd, trans->ndb_tid))) { if (error == -1) - my_error(ER_ERROR_DURING_ROLLBACK, MYF(0)); + my_error(ER_ERROR_DURING_ROLLBACK, MYF(0)); error=1; } trans->ndb_tid = 0; @@ -768,12 +768,12 @@ bool ha_flush_logs() { bool result=0; #ifdef HAVE_BERKELEY_DB - if ((have_berkeley_db == SHOW_OPTION_YES) && + if ((have_berkeley_db == SHOW_OPTION_YES) && berkeley_flush_logs()) result=1; #endif #ifdef HAVE_INNOBASE_DB - if ((have_innodb == SHOW_OPTION_YES) && + if ((have_innodb == SHOW_OPTION_YES) && innobase_flush_logs()) result=1; #endif @@ -868,7 +868,7 @@ my_off_t ha_get_ptr(byte *ptr, uint pack_length) int handler::ha_open(const char *name, int mode, int test_if_locked) { int error; - DBUG_ENTER("handler::open"); + DBUG_ENTER("handler::ha_open"); DBUG_PRINT("enter",("name: %s db_type: %d db_stat: %d mode: %d lock_test: %d", name, table->db_type, table->db_stat, mode, test_if_locked)); @@ -967,7 +967,7 @@ void handler::update_auto_increment() { longlong nr; THD *thd; - DBUG_ENTER("update_auto_increment"); + DBUG_ENTER("handler::update_auto_increment"); if (table->next_number_field->val_int() != 0 || table->auto_increment_field_not_null && current_thd->variables.sql_mode & MODE_NO_AUTO_VALUE_ON_ZERO) @@ -1025,7 +1025,7 @@ longlong handler::get_auto_increment() void handler::print_error(int error, myf errflag) { - DBUG_ENTER("print_error"); + DBUG_ENTER("handler::print_error"); DBUG_PRINT("enter",("error: %d",error)); int textno=ER_GET_ERRNO; @@ -1164,7 +1164,7 @@ bool handler::get_error_message(int error, String* buf) uint handler::get_dup_key(int error) { - DBUG_ENTER("get_dup_key"); + DBUG_ENTER("handler::get_dup_key"); table->file->errkey = (uint) -1; if (error == HA_ERR_FOUND_DUPP_KEY || error == HA_ERR_FOUND_DUPP_UNIQUE) info(HA_STATUS_ERRKEY | HA_STATUS_NO_LOCK); -- cgit v1.2.1 From 34c8e46dc35d03751fde16efd2ce3c70192827b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 12:31:56 +0400 Subject: Fix for bug#5088: * When executing EXPLAIN, do the same as for the query: convert join type to JT_CONST if keyuse array covers all key parts and all of them are constants. * In remove_const, don't remove conditions that depend on some-const-table and current-table. mysql-test/r/join_outer.result: Testcase for bug#5088 mysql-test/t/join_outer.test: Testcase for bug#5088 --- sql/sql_select.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fdea963b3ca..8830b2b2d17 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3215,6 +3215,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, store_key **ref_key= j->ref.key_copy; byte *key_buff=j->ref.key_buff, *null_ref_key= 0; + bool keyuse_uses_no_tables= true; if (ftkey) { j->ref.items[0]=((Item_func*)(keyuse->val))->key_item(); @@ -3234,6 +3235,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, uint maybe_null= test(keyinfo->key_part[i].null_bit); j->ref.items[i]=keyuse->val; // Save for cond removal + keyuse_uses_no_tables= keyuse_uses_no_tables & !keyuse->used_tables; if (!keyuse->used_tables && !(join->select_options & SELECT_DESCRIBE)) { // Compare against constant @@ -3273,7 +3275,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF; j->ref.null_ref_key= null_ref_key; } - else if (ref_key == j->ref.key_copy) + else if (keyuse_uses_no_tables) { /* This happen if we are using a constant expression in the ON part @@ -4062,7 +4064,7 @@ remove_const(JOIN *join,ORDER *first_order, COND *cond, bool *simple_order) } if ((ref=order_tables & (not_const_tables ^ first_table))) { - if (only_eq_ref_tables(join,first_order,ref)) + if (!(order_tables & first_table) && only_eq_ref_tables(join,first_order,ref)) { DBUG_PRINT("info",("removing: %s", order->item[0]->full_name())); continue; -- cgit v1.2.1 From 355004e0d66fa3f2ce363269ad0560ea84789745 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 08:42:31 +0000 Subject: stylistic fixes --- sql/ha_ndbcluster.cc | 5 +++-- sql/mysqld.cc | 18 +++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 2c066c8da1c..cc6b9016bfb 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -47,7 +47,7 @@ static const int max_transactions= 256; static const ha_rows autoincrement_prefetch= 32; // connectstring to cluster if given by mysqld -const char *ndbcluster_connectstring = 0; +const char *ndbcluster_connectstring= 0; #define NDB_HIDDEN_PRIMARY_KEY_LENGTH 8 @@ -3379,7 +3379,8 @@ bool ndbcluster_init() { DBUG_ENTER("ndbcluster_init"); // Set connectstring if specified - if (ndbcluster_connectstring != 0) { + if (ndbcluster_connectstring != 0) + { DBUG_PRINT("connectstring", ("%s", ndbcluster_connectstring)); Ndb::setConnectString(ndbcluster_connectstring); } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9c72a38bd49..c95c9f5e79f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5977,15 +5977,15 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } case OPT_BDB_SHARED: berkeley_init_flags&= ~(DB_PRIVATE); - berkeley_shared_data=1; + berkeley_shared_data= 1; break; #endif /* HAVE_BERKELEY_DB */ case OPT_BDB: #ifdef HAVE_BERKELEY_DB if (opt_bdb) - have_berkeley_db=SHOW_OPTION_YES; + have_berkeley_db= SHOW_OPTION_YES; else - have_berkeley_db=SHOW_OPTION_DISABLED; + have_berkeley_db= SHOW_OPTION_DISABLED; #endif break; case OPT_ISAM: @@ -5999,27 +5999,27 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case OPT_NDBCLUSTER: #ifdef HAVE_NDBCLUSTER_DB if (opt_ndbcluster) - have_ndbcluster=SHOW_OPTION_YES; + have_ndbcluster= SHOW_OPTION_YES; else - have_ndbcluster=SHOW_OPTION_DISABLED; + have_ndbcluster= SHOW_OPTION_DISABLED; #endif break; case OPT_NDB_CONNECTSTRING: #ifdef HAVE_NDBCLUSTER_DB - have_ndbcluster=SHOW_OPTION_YES; + have_ndbcluster= SHOW_OPTION_YES; #endif break; case OPT_INNODB: #ifdef HAVE_INNOBASE_DB if (opt_innodb) - have_innodb=SHOW_OPTION_YES; + have_innodb= SHOW_OPTION_YES; else - have_innodb=SHOW_OPTION_DISABLED; + have_innodb= SHOW_OPTION_DISABLED; #endif break; case OPT_INNODB_DATA_FILE_PATH: #ifdef HAVE_INNOBASE_DB - innobase_data_file_path=argument; + innobase_data_file_path= argument; #endif break; #ifdef HAVE_INNOBASE_DB -- cgit v1.2.1 From e66e0c1a04b78c899c9a6a0218a215023ec5bfa0 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 10:53:53 +0200 Subject: better for for bug#4767 --- sql/item_sum.cc | 3 --- sql/sql_select.cc | 23 ++++++++++++++--------- 2 files changed, 14 insertions(+), 12 deletions(-) (limited to 'sql') diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 3aacf7605c6..cbb4cd41046 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -159,10 +159,7 @@ Item *Item_sum::get_tmp_table_item(THD *thd) if (!arg->const_item()) { if (arg->type() == Item::FIELD_ITEM) - { - arg->maybe_null= result_field_tmp->maybe_null(); ((Item_field*) arg)->field= result_field_tmp++; - } else sum_item->args[i]= new Item_field(result_field_tmp++); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fdea963b3ca..4ee3fa234e3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4740,7 +4740,7 @@ static Field* create_tmp_field_from_item(THD *thd, copy_func If set and item is a function, store copy of item in this array from_field if field will be created using other field as example, - pointer example field will be written here + pointer example field will be written here group 1 if we are going to do a relative group by on result modify_item 1 if item->result_field should point to new item. This is relevent for how fill_record() is going to @@ -4749,7 +4749,7 @@ static Field* create_tmp_field_from_item(THD *thd, the record in the original table. If modify_item is 0 then fill_record() will update the temporary table - + RETURN 0 on error new_created field @@ -4773,13 +4773,13 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type, return new Field_double(item_sum->max_length,maybe_null, item->name, table, item_sum->decimals); case Item_sum::VARIANCE_FUNC: /* Place for sum & count */ - case Item_sum::STD_FUNC: + case Item_sum::STD_FUNC: if (group) return new Field_string(sizeof(double)*2+sizeof(longlong), 0, item->name,table,&my_charset_bin); else return new Field_double(item_sum->max_length, maybe_null, - item->name,table,item_sum->decimals); + item->name,table,item_sum->decimals); case Item_sum::UNIQUE_USERS_FUNC: return new Field_long(9,maybe_null,item->name,table,1); default: @@ -4887,7 +4887,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, else // if we run out of slots or we are not using tempool sprintf(path,"%s%s%lx_%lx_%x",mysql_tmpdir,tmp_file_prefix,current_pid, thd->thread_id, thd->tmp_table++); - + if (lower_case_table_names) my_casedn_str(files_charset_info, path); @@ -5003,16 +5003,21 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List &fields, tmp_from_field++; *(reg_field++)= new_field; reclength+=new_field->pack_length(); - if (!(new_field->flags & NOT_NULL_FLAG)) - null_count++; if (new_field->flags & BLOB_FLAG) { *blob_field++= new_field; blob_count++; } ((Item_sum*) item)->args[i]= new Item_field(new_field); - if (((Item_sum*) item)->arg_count == 1) - ((Item_sum*) item)->result_field= new_field; + if (!(new_field->flags & NOT_NULL_FLAG)) + { + null_count++; + /* + new_field->maybe_null() is still false, it will be + changed below. But we have to setup Item_field correctly + */ + ((Item_sum*) item)->args[i]->maybe_null=1; + } } } } -- cgit v1.2.1 From b6d9222da3c2b0f6ec33efa6e16359b1630bad4a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 09:15:42 +0000 Subject: small ndb switch fix --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c95c9f5e79f..3a1c66a52f3 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6004,11 +6004,11 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), have_ndbcluster= SHOW_OPTION_DISABLED; #endif break; - case OPT_NDB_CONNECTSTRING: #ifdef HAVE_NDBCLUSTER_DB + case OPT_NDB_CONNECTSTRING: have_ndbcluster= SHOW_OPTION_YES; -#endif break; +#endif case OPT_INNODB: #ifdef HAVE_INNOBASE_DB if (opt_innodb) -- cgit v1.2.1 From f7d0dfd9e8966a6c4c885ade872273dddd36e228 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 13:46:51 +0300 Subject: Changed %lx -> 0x%lx (for easier comparison of debug files) Cosmetic cleanups Don't call 'delete_elements' on copy_funcs as this causes elements to be freed twice mysys/hash.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/list.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/mf_iocache.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/mf_keycache.c: Changed %lx -> 0x%lx (for easier comparison of debug files) Changed debug messages to be more consistent with other mysys files. mysys/mf_keycaches.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_alloc.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_fopen.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_fstream.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_getwd.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_lib.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_lwrite.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_malloc.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_pread.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_read.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_realloc.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/my_write.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/safemalloc.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/thr_alarm.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/thr_lock.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/thr_mutex.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/tree.c: Changed %lx -> 0x%lx (for easier comparison of debug files) mysys/typelib.c: Changed %lx -> 0x%lx (for easier comparison of debug files) sql/examples/ha_archive.cc: Changed to return error number for some functions (instead of -1) Updated function comments & some other minor cleanups Ensure that free_share() and gzclose() are always called Use 'TRUE' and 'FALSE' instead of 'true' and 'false' Removed some compiler warnings sql/examples/ha_archive.h: Fixed to use new prototypes for records_in_range sql/sql_select.cc: Don't call 'delete_elements' on copy_funcs --- sql/examples/ha_archive.cc | 125 +++++++++++++++++++++++++++++---------------- sql/examples/ha_archive.h | 8 ++- sql/sql_select.cc | 6 ++- 3 files changed, 89 insertions(+), 50 deletions(-) (limited to 'sql') diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc index 9b439087259..c004330932c 100644 --- a/sql/examples/ha_archive.cc +++ b/sql/examples/ha_archive.cc @@ -192,7 +192,7 @@ static int free_share(ARCHIVE_SHARE *share) thr_lock_delete(&share->lock); pthread_mutex_destroy(&share->mutex); if (gzclose(share->archive_write) == Z_ERRNO) - rc= -1; + rc= 1; my_free((gptr) share, MYF(0)); } pthread_mutex_unlock(&archive_mutex); @@ -226,7 +226,7 @@ int ha_archive::open(const char *name, int mode, uint test_if_locked) if ((archive= gzopen(share->data_file_name, "rb")) == NULL) { (void)free_share(share); //We void since we already have an error - DBUG_RETURN(-1); + DBUG_RETURN(errno ? errno : -1); } DBUG_RETURN(0); @@ -234,56 +234,91 @@ int ha_archive::open(const char *name, int mode, uint test_if_locked) /* - Closes the file. We first close this storage engines file handle to the - archive and then remove our reference count to the table (and possibly - free it as well). - */ + Closes the file. + + SYNOPSIS + close(); + + IMPLEMENTATION: + + We first close this storage engines file handle to the archive and + then remove our reference count to the table (and possibly free it + as well). + + RETURN + 0 ok + 1 Error +*/ + int ha_archive::close(void) { + int rc= 0; DBUG_ENTER("ha_archive::close"); - DBUG_RETURN(((gzclose(archive) == Z_ERRNO || free_share(share)) ? -1 : 0)); + + /* First close stream */ + if (gzclose(archive) == Z_ERRNO) + rc= 1; + /* then also close share */ + rc|= free_share(share); + + DBUG_RETURN(rc); } /* - We create our data file here. The format is pretty simple. The first bytes in - any file are the version number. Currently we do nothing with this, but in - the future this gives us the ability to figure out version if we change the - format at all. After the version we starting writing our rows. Unlike other - storage engines we do not "pack" our data. Since we are about to do a general - compression, packing would just be a waste of CPU time. If the table has blobs - they are written after the row in the order of creation. + We create our data file here. The format is pretty simple. The first + bytes in any file are the version number. Currently we do nothing + with this, but in the future this gives us the ability to figure out + version if we change the format at all. After the version we + starting writing our rows. Unlike other storage engines we do not + "pack" our data. Since we are about to do a general compression, + packing would just be a waste of CPU time. If the table has blobs + they are written after the row in the order of creation. + So to read a row we: Read the version Read the record and copy it into buf Loop through any blobs and read them - */ -int ha_archive::create(const char *name, TABLE *table_arg, HA_CREATE_INFO *create_info) +*/ + +int ha_archive::create(const char *name, TABLE *table_arg, + HA_CREATE_INFO *create_info) { File create_file; char name_buff[FN_REFLEN]; size_t written; + int error; DBUG_ENTER("ha_archive::create"); - if ((create_file= my_create(fn_format(name_buff,name,"",ARZ,MY_REPLACE_EXT|MY_UNPACK_FILENAME),0, - O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) - DBUG_RETURN(-1); + if ((create_file= my_create(fn_format(name_buff,name,"",ARZ, + MY_REPLACE_EXT|MY_UNPACK_FILENAME),0, + O_RDWR | O_TRUNC,MYF(MY_WME))) < 0) + { + error= my_errno; + goto err; + } if ((archive= gzdopen(create_file, "ab")) == NULL) { + error= errno; delete_table(name); - DBUG_RETURN(-1); + goto err; } version= ARCHIVE_VERSION; written= gzwrite(archive, &version, sizeof(version)); - if (written != sizeof(version) || gzclose(archive)) + if (gzclose(archive) || written != sizeof(version)) { + error= errno; delete_table(name); - DBUG_RETURN(-1); + goto err; } - DBUG_RETURN(0); + +err: + /* Return error number, if we got one */ + DBUG_RETURN(error ? error : -1); } + /* Look at ha_archive::open() for an explanation of the row format. Here we just write out the row. @@ -298,9 +333,9 @@ int ha_archive::write_row(byte * buf) if (table->timestamp_default_now) update_timestamp(buf+table->timestamp_default_now-1); written= gzwrite(share->archive_write, buf, table->reclength); - share->dirty= true; + share->dirty= TRUE; if (written != table->reclength) - DBUG_RETURN(-1); + DBUG_RETURN(errno ? errno : -1); for (Field_blob **field=table->blob_field ; *field ; field++) { @@ -310,7 +345,7 @@ int ha_archive::write_row(byte * buf) (*field)->get_ptr(&ptr); written= gzwrite(share->archive_write, ptr, (unsigned)size); if (written != size) - DBUG_RETURN(-1); + DBUG_RETURN(errno ? errno : -1); } DBUG_RETURN(0); @@ -322,6 +357,7 @@ int ha_archive::write_row(byte * buf) that it is a table scan we rewind the file to the beginning, otherwise we assume the position will be set. */ + int ha_archive::rnd_init(bool scan) { DBUG_ENTER("ha_archive::rnd_init"); @@ -339,10 +375,10 @@ int ha_archive::rnd_init(bool scan) If dirty, we lock, and then reset/flush the data. I found that just calling gzflush() doesn't always work. */ - if (share->dirty == true) + if (share->dirty == TRUE) { pthread_mutex_lock(&share->mutex); - if (share->dirty == true) + if (share->dirty == TRUE) { /* I was having problems with OSX, but it worked for 10.3 so I am wrapping this with and ifdef */ #ifdef BROKEN_GZFLUSH @@ -350,12 +386,12 @@ int ha_archive::rnd_init(bool scan) if ((share->archive_write= gzopen(share->data_file_name, "ab")) == NULL) { pthread_mutex_unlock(&share->mutex); - DBUG_RETURN(-1); + DBUG_RETURN(errno ? errno : -1); } #else gzflush(share->archive_write, Z_SYNC_FLUSH); #endif - share->dirty= false; + share->dirty= FALSE; } pthread_mutex_unlock(&share->mutex); } @@ -367,8 +403,8 @@ int ha_archive::rnd_init(bool scan) if (scan) { read= gzread(archive, &version, sizeof(version)); - if (read == 0 || read != sizeof(version)) - DBUG_RETURN(-1); + if (read != sizeof(version)) + DBUG_RETURN(errno ? errno : -1); } DBUG_RETURN(0); @@ -393,7 +429,7 @@ int ha_archive::get_row(byte *buf) DBUG_RETURN(HA_ERR_END_OF_FILE); /* If the record is the wrong size, the file is probably damaged */ - if (read != table->reclength) + if ((ulong) read != table->reclength) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); /* Calculate blob length, we use this for our buffer */ @@ -409,7 +445,7 @@ int ha_archive::get_row(byte *buf) { size_t size= (*field)->get_length(); read= gzread(archive, last, size); - if (read == 0 || read != size) + if ((size_t) read != size) DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); (*field)->set_ptr(size, last); last += size; @@ -417,19 +453,21 @@ int ha_archive::get_row(byte *buf) DBUG_RETURN(0); } + /* Called during ORDER BY. Its position is either from being called sequentially or by having had ha_archive::rnd_pos() called before it is called. */ + int ha_archive::rnd_next(byte *buf) { - DBUG_ENTER("ha_archive::rnd_next"); int rc; + DBUG_ENTER("ha_archive::rnd_next"); statistic_increment(ha_read_rnd_next_count,&LOCK_status); current_position= gztell(archive); rc= get_row(buf); - if (!(HA_ERR_END_OF_FILE == rc)) + if (rc != HA_ERR_END_OF_FILE) records++; DBUG_RETURN(rc); @@ -450,10 +488,12 @@ void ha_archive::position(const byte *record) /* - This is called after a table scan for each row if the results of the scan need - to be ordered. It will take *pos and use it to move the cursor in the file so - that the next row that is called is the correctly ordered row. + This is called after a table scan for each row if the results of the + scan need to be ordered. It will take *pos and use it to move the + cursor in the file so that the next row that is called is the + correctly ordered row. */ + int ha_archive::rnd_pos(byte * buf, byte *pos) { DBUG_ENTER("ha_archive::rnd_pos"); @@ -568,11 +608,8 @@ THR_LOCK_DATA **ha_archive::store_lock(THD *thd, return to; } -ha_rows ha_archive::records_in_range(int inx, - const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag) +ha_rows ha_archive::records_in_range(uint inx, key_range *min_key, + key_range *max_key) { DBUG_ENTER("ha_archive::records_in_range "); DBUG_RETURN(records); // HA_ERR_WRONG_COMMAND diff --git a/sql/examples/ha_archive.h b/sql/examples/ha_archive.h index 2fab80f0598..f08353a5d6c 100644 --- a/sql/examples/ha_archive.h +++ b/sql/examples/ha_archive.h @@ -86,7 +86,8 @@ public: */ virtual double scan_time() { return (double) (records) / 20.0+10; } /* The next method will never be called */ - virtual double read_time(ha_rows rows) { return (double) rows / 20.0+1; } + virtual double read_time(uint index, uint ranges, ha_rows rows) + { return (double) rows / 20.0+1; } int open(const char *name, int mode, uint test_if_locked); int close(void); int write_row(byte * buf); @@ -109,10 +110,7 @@ public: int extra(enum ha_extra_function operation); int reset(void); int external_lock(THD *thd, int lock_type); - ha_rows records_in_range(int inx, const byte *start_key,uint start_key_len, - enum ha_rkey_function start_search_flag, - const byte *end_key,uint end_key_len, - enum ha_rkey_function end_search_flag); + ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 657853c98ba..d532a189ab6 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3911,7 +3911,11 @@ JOIN::join_free(bool full) if (full) { group_fields.delete_elements(); - tmp_table_param.copy_funcs.delete_elements(); + /* + We can't call delete_elements() on copy_funcs as this will cause + problems in free_elements() as some of the elements are then deleted. + */ + tmp_table_param.copy_funcs.empty(); tmp_table_param.cleanup(); } DBUG_VOID_RETURN; -- cgit v1.2.1 From b7e4463dacb38d73492b3b039daf335a7fb0f76d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 15:29:55 +0200 Subject: Fixed: BUG#5135: cannot turn on log_warnings with SET in 4.1 (and 4.0) mysql-test/r/variables.result: Test case for BUG#5135, check that setting log_warnings actually works. mysql-test/t/variables.test: Test case for BUG#5135, check that setting log_warnings actually works. sql/mysqld.cc: Set a max value for log_warnings, so se can set it to something other than 0. --- sql/mysqld.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index e4d60fc9e7c..e20251adac4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3959,11 +3959,11 @@ replicating a LOAD DATA INFILE command", 0, 0, 0, 0}, {"log-warnings", 'W', "Log some not critical warnings to the log file", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ~0L, 0, 0, 0}, {"warnings", 'W', "Deprecated ; Use --log-warnings instead", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ~0L, 0, 0, 0}, { "back_log", OPT_BACK_LOG, "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.", -- cgit v1.2.1 From e9c25d9336c8d1266254df5f795366e7d280de85 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 16:15:57 +0200 Subject: Fix for BUG#5033 "When using temporary tables truncate does NOT reset the auto_increment counter" (ok'd by CTO to fix it in 4.0). Fix to make mysql-test-run work with all Valgrind versions. mysql-test/mysql-test-run.sh: fixing mysql-test-run.sh so that it works indifferently with Valgrind 1.x, 2.x (versions <= 2.0.0 refuse --tool option; versions >=2.1.2 require it; 2.1.0 accepts it). I hope the shell code is portable enough; anyway Valgrind only runs on Linux... I tested it with 2.0.0, 2.1.0, 2.1.2. mysql-test/r/truncate.result: result update mysql-test/t/truncate.test: testing if TRUNCATE resets autoinc counter for temp tables (BUG#5033); testing difference with DELETE FROM. sql/sql_delete.cc: in mysql_truncate(), always reset the autoinc counter, as manual says (even if it's a temp table, which was BUG#5033). --- sql/sql_delete.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b568166a766..555e63b9e32 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -545,15 +545,13 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) int error; DBUG_ENTER("mysql_truncate"); + bzero((char*) &create_info,sizeof(create_info)); /* If it is a temporary table, close and regenerate it */ if (!dont_send_ok && (table_ptr=find_temporary_table(thd,table_list->db, table_list->real_name))) { TABLE *table= *table_ptr; - HA_CREATE_INFO create_info; table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); - bzero((char*) &create_info,sizeof(create_info)); - create_info.auto_increment_value= table->file->auto_increment_value; db_type table_type=table->db_type; strmov(path,table->path); @@ -596,7 +594,6 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) DBUG_RETURN(-1); } - bzero((char*) &create_info,sizeof(create_info)); *fn_ext(path)=0; // Remove the .frm extension error= ha_create_table(path,&create_info,1) ? -1 : 0; query_cache_invalidate3(thd, table_list, 0); -- cgit v1.2.1 From 8522f83038f1021374a565e70ab842511d4dae97 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 15:12:38 +0000 Subject: reverted default setting of --ndbcluster if --ndb-connectstring is given --- sql/mysqld.cc | 5 ----- 1 file changed, 5 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3a1c66a52f3..8dfca2bb684 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -6004,11 +6004,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), have_ndbcluster= SHOW_OPTION_DISABLED; #endif break; -#ifdef HAVE_NDBCLUSTER_DB - case OPT_NDB_CONNECTSTRING: - have_ndbcluster= SHOW_OPTION_YES; - break; -#endif case OPT_INNODB: #ifdef HAVE_INNOBASE_DB if (opt_innodb) -- cgit v1.2.1 From c3c483e0918aaba7925a86a53018fd4cb5e03a82 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 20:12:39 +0500 Subject: Bug#4594: column index make = failed for gbk, but like works Fix for HEAP+HASH prefix keys. --- sql/key.cc | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/key.cc b/sql/key.cc index 9425a368669..b1f4c9533a9 100644 --- a/sql/key.cc +++ b/sql/key.cc @@ -211,10 +211,17 @@ bool key_cmp_if_same(TABLE *table,const byte *key,uint idx,uint key_length) if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+ FIELDFLAG_PACK))) { - if (my_strnncoll(key_part->field->charset(), - (const uchar*) key, length, - (const uchar*) table->record[0]+key_part->offset, - length)) + CHARSET_INFO *cs= key_part->field->charset(); + uint char_length= key_part->length / cs->mbmaxlen; + const byte *pos= table->record[0] + key_part->offset; + if (length > char_length) + { + char_length= my_charpos(cs, pos, pos + length, char_length); + set_if_smaller(char_length, length); + } + if (cs->coll->strnncollsp(cs, + (const uchar*) key, length, + (const uchar*) pos, char_length)) return 1; } else if (memcmp(key,table->record[0]+key_part->offset,length)) -- cgit v1.2.1 From 6d9046c6e7cbb691eb3a9e96003b9fcff6be7e28 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 19:13:47 +0400 Subject: Fix for bug #5134: WHERE x = 'bar' AND x LIKE BINARY 'bar' returns wrong results --- sql/sql_select.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 882f345a1ca..cf5e8a75f85 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3371,7 +3371,10 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, Item *right_item= func->arguments()[1]; Item_func::Functype functype= func->functype(); - if (right_item->eq(field,0) && left_item != value) + if (right_item->eq(field,0) && left_item != value && + (left_item->result_type() != STRING_RESULT || + value->result_type() != STRING_RESULT || + left_item->binary == value->binary)) { Item *tmp=value->new_item(); if (tmp) @@ -3390,7 +3393,10 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, func->arguments()[1]->result_type())); } } - else if (left_item->eq(field,0) && right_item != value) + else if (left_item->eq(field,0) && right_item != value && + (right_item->result_type() != STRING_RESULT || + value->result_type() != STRING_RESULT || + right_item->binary == value->binary)) { Item *tmp=value->new_item(); if (tmp) -- cgit v1.2.1 From 21fa12734fa53d5cfea11cc9d5d306274790b7e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 20:17:14 +0400 Subject: Fix for bug #5134: WHERE x = 'bar' AND x LIKE BINARY 'bar' returns wrong results(for 4.1 tree) mysql-test/r/binary.result: Fix for bug #5134: WHERE x = 'bar' AND x LIKE BINARY 'bar' returns wrong results mysql-test/t/binary.test: Fix for bug #5134: WHERE x = 'bar' AND x LIKE BINARY 'bar' returns wrong results sql/sql_select.cc: Fix for bug #5134: WHERE x = 'bar' AND x LIKE BINARY 'bar' returns wrong results --- sql/sql_select.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 70fec408753..ca17f246929 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4186,7 +4186,10 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, Item *right_item= func->arguments()[1]; Item_func::Functype functype= func->functype(); - if (right_item->eq(field,0) && left_item != value) + if (right_item->eq(field,0) && left_item != value && + (left_item->result_type() != STRING_RESULT || + value->result_type() != STRING_RESULT || + left_item->collation.collation == value->collation.collation)) { Item *tmp=value->new_item(); if (tmp) @@ -4204,7 +4207,10 @@ change_cond_ref_to_const(I_List *save_list,Item *and_father, func->set_cmp_func(); } } - else if (left_item->eq(field,0) && right_item != value) + else if (left_item->eq(field,0) && right_item != value && + (right_item->result_type() != STRING_RESULT || + value->result_type() != STRING_RESULT || + right_item->collation.collation == value->collation.collation)) { Item *tmp=value->new_item(); if (tmp) -- cgit v1.2.1 From e0a12e898c1645b450c69503d481ab1f92d1e012 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 18:55:12 +0200 Subject: Bug #4629 Crash after SLAVE STOP, if the IO thread is in special state. client.c: Removed call to clear_slave_vio in end_server(). Removed header declaration of clear_slave_vio slave.cc: Removed clear_slave_vio function and added calls to thd->clear_active_vio before each call to end_server() sql/slave.cc: Removed clear_slave_vio function and added calls to thd->clear_active_vio before each call to end_server() sql-common/client.c: Removed call to clear_slave_vio in end_server(). Removed header declaration of clear_slave_vio --- sql/slave.cc | 27 ++++++--------------------- 1 file changed, 6 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/slave.cc b/sql/slave.cc index 51421533a5b..cb37a798037 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -3056,6 +3056,9 @@ dump"); } thd->proc_info= "Waiting to reconnect after a failed binlog dump request"; +#ifdef SIGNAL_WITH_VIO_CLOSE + thd->clear_active_vio(); +#endif end_server(mysql); /* First time retry immediately, assuming that we can recover @@ -3129,6 +3132,9 @@ max_allowed_packet", goto err; } thd->proc_info = "Waiting to reconnect after a failed master event read"; +#ifdef SIGNAL_WITH_VIO_CLOSE + thd->clear_active_vio(); +#endif end_server(mysql); if (retry_count++) { @@ -4384,25 +4390,4 @@ template class I_List_iterator; #endif -#ifdef __WIN__ -extern "C" void clear_slave_vio( MYSQL* mysql ) -{ - if (active_mi->mysql == mysql) - active_mi->io_thd->clear_active_vio(); - /* TODO: use code like below when multi-master is in place */ - /* LIST *cur = &master_list; - if (((MASTER_INFO*)cur->data)->mysql == mysql) - { - MASTER_INFO *mi = (MASTER_INFO*)cur->data; - mi->io_thd->clear_active_vio(); - return; - } - else - cur = cur->next;*/ -} -#endif - - - - #endif /* HAVE_REPLICATION */ -- cgit v1.2.1 From 3bb0223e7e819dc77801b459fd242cdb72f79f07 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 14:30:55 -0500 Subject: mysqld.cc: System variable names use underscores, not dashes. Alphabetize variables in option struct for help message. (will wait for okay to push) sql/mysqld.cc: System variable names use underscores, not dashes. Alphabetize variables in option struct for help message. --- sql/mysqld.cc | 216 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 108 insertions(+), 108 deletions(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8dfca2bb684..9b40768f0da 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4562,6 +4562,10 @@ replicating a LOAD DATA INFILE command.", "The buffer that is allocated to cache index and rows for BDB tables.", (gptr*) &berkeley_cache_size, (gptr*) &berkeley_cache_size, 0, GET_ULONG, REQUIRED_ARG, KEY_CACHE_SIZE, 20*1024, (long) ~0, 0, IO_SIZE, 0}, + /* QQ: The following should be removed soon! (bdb_max_lock preferred) */ + {"bdb_lock_max", OPT_BDB_MAX_LOCK, "Synonym for bdb_max_lock.", + (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, + REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0}, {"bdb_log_buffer_size", OPT_BDB_LOG_BUFFER_SIZE, "The buffer that is allocated to cache index and rows for BDB tables.", (gptr*) &berkeley_log_buffer_size, (gptr*) &berkeley_log_buffer_size, 0, @@ -4570,15 +4574,16 @@ replicating a LOAD DATA INFILE command.", "The maximum number of locks you can have active on a BDB table.", (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0}, - /* QQ: The following should be removed soon! */ - {"bdb_lock_max", OPT_BDB_MAX_LOCK, "Synonym for bdb_max_lock.", - (gptr*) &berkeley_max_lock, (gptr*) &berkeley_max_lock, 0, GET_ULONG, - REQUIRED_ARG, 10000, 0, (long) ~0, 0, 1, 0}, #endif /* HAVE_BERKELEY_DB */ {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE, "The size of the cache to hold the SQL statements for the binary log during a transaction. If you often use big, multi-statement transactions you can increase this to get more performance.", (gptr*) &binlog_cache_size, (gptr*) &binlog_cache_size, 0, GET_ULONG, REQUIRED_ARG, 32*1024L, IO_SIZE, ~0L, 0, IO_SIZE, 0}, + {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE, + "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!", + (gptr*) &global_system_variables.bulk_insert_buff_size, + (gptr*) &max_system_variables.bulk_insert_buff_size, + 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ~0L, 0, 1, 0}, {"connect_timeout", OPT_CONNECT_TIMEOUT, "The number of seconds the mysqld server is waiting for a connect packet before responding with 'Bad handshake'.", (gptr*) &connect_timeout, (gptr*) &connect_timeout, @@ -4589,18 +4594,38 @@ replicating a LOAD DATA INFILE command.", (gptr*) &opt_crash_binlog_innodb, (gptr*) &opt_crash_binlog_innodb, 0, GET_UINT, REQUIRED_ARG, 0, 0, ~(uint)0, 0, 1, 0}, #endif - {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT, - "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.", - (gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0, - GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + { "date_format", OPT_DATE_FORMAT, + "The DATE format (For future).", + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE], + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "datetime_format", OPT_DATETIME_FORMAT, + "The DATETIME/TIMESTAMP format (for future).", + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME], + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { "default_week_format", OPT_DEFAULT_WEEK_FORMAT, + "The default week format used by WEEK() functions.", + (gptr*) &global_system_variables.default_week_format, + (gptr*) &max_system_variables.default_week_format, + 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0}, {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT, "After inserting delayed_insert_limit rows, the INSERT DELAYED handler will check if there are any SELECT statements pending. If so, it allows these to execute before continuing.", (gptr*) &delayed_insert_limit, (gptr*) &delayed_insert_limit, 0, GET_ULONG, REQUIRED_ARG, DELAYED_LIMIT, 1, ~0L, 0, 1, 0}, + {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT, + "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.", + (gptr*) &delayed_insert_timeout, (gptr*) &delayed_insert_timeout, 0, + GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE, "What size queue (in rows) should be allocated for handling INSERT DELAYED. If the queue becomes full, any client that does INSERT DELAYED will wait until there is room in the queue again.", (gptr*) &delayed_queue_size, (gptr*) &delayed_queue_size, 0, GET_ULONG, REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ~0L, 0, 1, 0}, + {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS, + "Binary logs will be rotated after expire-log-days days ", + (gptr*) &expire_logs_days, + (gptr*) &expire_logs_days, 0, GET_ULONG, + REQUIRED_ARG, 0, 0, 99, 0, 1, 0}, { "flush_time", OPT_FLUSH_TIME, "A dedicated thread is created to flush all tables at the given interval.", (gptr*) &flush_time, (gptr*) &flush_time, 0, GET_ULONG, REQUIRED_ARG, @@ -4609,14 +4634,14 @@ replicating a LOAD DATA INFILE command.", "List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE)", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - { "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_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_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0}, + { "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_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, @@ -4631,48 +4656,52 @@ replicating a LOAD DATA INFILE command.", (gptr*) &max_system_variables.group_concat_max_len, 0, GET_ULONG, REQUIRED_ARG, 1024, 4, (long) ~0, 0, 1, 0}, #ifdef HAVE_INNOBASE_DB - {"innodb_mirrored_log_groups", OPT_INNODB_MIRRORED_LOG_GROUPS, - "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.", - (gptr*) &innobase_mirrored_log_groups, - (gptr*) &innobase_mirrored_log_groups, 0, GET_LONG, REQUIRED_ARG, 1, 1, 10, - 0, 1, 0}, - {"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP, - "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.", - (gptr*) &innobase_log_files_in_group, (gptr*) &innobase_log_files_in_group, - 0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0}, - {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE, - "Size of each log file in a log group in megabytes.", - (gptr*) &innobase_log_file_size, (gptr*) &innobase_log_file_size, 0, - GET_LONG, REQUIRED_ARG, 5*1024*1024L, 1*1024*1024L, ~0L, 0, 1024*1024L, 0}, - {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE, - "The size of the buffer which InnoDB uses to write log to the log files on disk.", - (gptr*) &innobase_log_buffer_size, (gptr*) &innobase_log_buffer_size, 0, - GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, ~0L, 0, 1024, 0}, - {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE, - "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", - (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0, - GET_LONG, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, ~0L, 0, 1024*1024L, 0}, - {"innodb_buffer_pool_awe_mem_mb", OPT_INNODB_BUFFER_POOL_AWE_MEM_MB, - "If Windows AWE is used, the size of InnoDB buffer pool allocated from the AWE memory.", - (gptr*) &innobase_buffer_pool_awe_mem_mb, (gptr*) &innobase_buffer_pool_awe_mem_mb, 0, - GET_LONG, REQUIRED_ARG, 0, 0, 63000, 0, 1, 0}, {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE, "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.", (gptr*) &innobase_additional_mem_pool_size, (gptr*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG, 1*1024*1024L, 512*1024L, ~0L, 0, 1024, 0}, + {"innodb_buffer_pool_awe_mem_mb", OPT_INNODB_BUFFER_POOL_AWE_MEM_MB, + "If Windows AWE is used, the size of InnoDB buffer pool allocated from the AWE memory.", + (gptr*) &innobase_buffer_pool_awe_mem_mb, (gptr*) &innobase_buffer_pool_awe_mem_mb, 0, + GET_LONG, REQUIRED_ARG, 0, 0, 63000, 0, 1, 0}, + {"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE, + "The size of the memory buffer InnoDB uses to cache data and indexes of its tables.", + (gptr*) &innobase_buffer_pool_size, (gptr*) &innobase_buffer_pool_size, 0, + GET_LONG, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, ~0L, 0, 1024*1024L, 0}, {"innodb_file_io_threads", OPT_INNODB_FILE_IO_THREADS, "Number of file I/O threads in InnoDB.", (gptr*) &innobase_file_io_threads, (gptr*) &innobase_file_io_threads, 0, GET_LONG, REQUIRED_ARG, 4, 4, 64, 0, 1, 0}, - {"innodb_open_files", OPT_INNODB_OPEN_FILES, - "How many files at the maximum InnoDB keeps open at the same time.", - (gptr*) &innobase_open_files, (gptr*) &innobase_open_files, 0, - GET_LONG, REQUIRED_ARG, 300L, 10L, ~0L, 0, 1L, 0}, + {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY, + "Helps to save your data in case the disk image of the database becomes corrupt.", + (gptr*) &innobase_force_recovery, (gptr*) &innobase_force_recovery, 0, + GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0}, {"innodb_lock_wait_timeout", OPT_INNODB_LOCK_WAIT_TIMEOUT, "Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back.", (gptr*) &innobase_lock_wait_timeout, (gptr*) &innobase_lock_wait_timeout, 0, GET_LONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0}, + {"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE, + "The size of the buffer which InnoDB uses to write log to the log files on disk.", + (gptr*) &innobase_log_buffer_size, (gptr*) &innobase_log_buffer_size, 0, + GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, ~0L, 0, 1024, 0}, + {"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE, + "Size of each log file in a log group in megabytes.", + (gptr*) &innobase_log_file_size, (gptr*) &innobase_log_file_size, 0, + GET_LONG, REQUIRED_ARG, 5*1024*1024L, 1*1024*1024L, ~0L, 0, 1024*1024L, 0}, + {"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP, + "Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here.", + (gptr*) &innobase_log_files_in_group, (gptr*) &innobase_log_files_in_group, + 0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0}, + {"innodb_mirrored_log_groups", OPT_INNODB_MIRRORED_LOG_GROUPS, + "Number of identical copies of log groups we keep for the database. Currently this should be set to 1.", + (gptr*) &innobase_mirrored_log_groups, + (gptr*) &innobase_mirrored_log_groups, 0, GET_LONG, REQUIRED_ARG, 1, 1, 10, + 0, 1, 0}, + {"innodb_open_files", OPT_INNODB_OPEN_FILES, + "How many files at the maximum InnoDB keeps open at the same time.", + (gptr*) &innobase_open_files, (gptr*) &innobase_open_files, 0, + GET_LONG, REQUIRED_ARG, 300L, 10L, ~0L, 0, 1L, 0}, #ifdef HAVE_REPLICATION /* Disabled for the 4.1.3 release. Disabling just this paragraph of code is @@ -4697,10 +4726,6 @@ replicating a LOAD DATA INFILE command.", "Helps in performance tuning in heavily concurrent environments.", (gptr*) &innobase_thread_concurrency, (gptr*) &innobase_thread_concurrency, 0, GET_LONG, REQUIRED_ARG, 8, 1, 1000, 0, 1, 0}, - {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY, - "Helps to save your data in case the disk image of the database becomes corrupt.", - (gptr*) &innobase_force_recovery, (gptr*) &innobase_force_recovery, 0, - GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0}, #endif /* HAVE_INNOBASE_DB */ {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT, "The number of seconds the server waits for activity on an interactive connection before closing it.", @@ -4720,6 +4745,12 @@ replicating a LOAD DATA INFILE command.", 0, (GET_ULL | GET_ASK_ADDR), REQUIRED_ARG, KEY_CACHE_SIZE, MALLOC_OVERHEAD, (long) ~0, MALLOC_OVERHEAD, IO_SIZE, 0}, + {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD, + "This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache", + (gptr*) &dflt_key_cache_var.param_age_threshold, + (gptr*) 0, + 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, + 300, 100, ~0L, 0, 100, 0}, {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE, "The default size of key cache blocks", (gptr*) &dflt_key_cache_var.param_block_size, @@ -4732,12 +4763,6 @@ replicating a LOAD DATA INFILE command.", (gptr*) 0, 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0}, - {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD, - "This characterizes the number of hits a hot block has to be untouched until it is considered aged enough to be downgraded to a warm block. This specifies the percentage ratio of that number of hits to the total number of blocks in key cache", - (gptr*) &dflt_key_cache_var.param_age_threshold, - (gptr*) 0, - 0, (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, - 300, 100, ~0L, 0, 100, 0}, {"long_query_time", OPT_LONG_QUERY_TIME, "Log all queries that have taken more than long_query_time seconds to execute to file.", (gptr*) &global_system_variables.long_query_time, @@ -4768,14 +4793,14 @@ value. Will also apply to relay logs if max_relay_log_size is 0. \ The minimum value for this variable is 4096.", (gptr*) &max_binlog_size, (gptr*) &max_binlog_size, 0, GET_ULONG, REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0}, - {"max_connections", OPT_MAX_CONNECTIONS, - "The number of simultaneous clients allowed.", (gptr*) &max_connections, - (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, - 0}, {"max_connect_errors", OPT_MAX_CONNECT_ERRORS, "If there is more than this number of interrupted connections from a host this host will be blocked from further connections.", (gptr*) &max_connect_errors, (gptr*) &max_connect_errors, 0, GET_ULONG, REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ~0L, 0, 1, 0}, + {"max_connections", OPT_MAX_CONNECTIONS, + "The number of simultaneous clients allowed.", (gptr*) &max_connections, + (gptr*) &max_connections, 0, GET_ULONG, REQUIRED_ARG, 100, 1, 16384, 0, 1, + 0}, {"max_delayed_threads", OPT_MAX_DELAYED_THREADS, "Don't start more than this number of threads to handle INSERT DELAYED statements. If set to zero, which means INSERT DELAYED is not used.", (gptr*) &global_system_variables.max_insert_delayed_threads, @@ -4828,11 +4853,6 @@ The minimum value for this variable is 4096.", "After this many write locks, allow some read locks to run in between.", (gptr*) &max_write_lock_count, (gptr*) &max_write_lock_count, 0, GET_ULONG, REQUIRED_ARG, ~0L, 1, ~0L, 0, 1, 0}, - {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE, - "Size of tree cache used in bulk insert optimisation. Note that this is a limit per thread!", - (gptr*) &global_system_variables.bulk_insert_buff_size, - (gptr*) &max_system_variables.bulk_insert_buff_size, - 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ~0L, 0, 1, 0}, {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE, "Block size to be used for MyISAM index pages.", (gptr*) &opt_myisam_block_size, @@ -4871,16 +4891,16 @@ The minimum value for this variable is 4096.", (gptr*) &global_system_variables.net_buffer_length, (gptr*) &max_system_variables.net_buffer_length, 0, GET_ULONG, REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0}, - {"net_retry_count", OPT_NET_RETRY_COUNT, - "If a read on a communication port is interrupted, retry this many times before giving up.", - (gptr*) &global_system_variables.net_retry_count, - (gptr*) &max_system_variables.net_retry_count,0, - GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0}, {"net_read_timeout", OPT_NET_READ_TIMEOUT, "Number of seconds to wait for more data from a connection before aborting the read.", (gptr*) &global_system_variables.net_read_timeout, (gptr*) &max_system_variables.net_read_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, + {"net_retry_count", OPT_NET_RETRY_COUNT, + "If a read on a communication port is interrupted, retry this many times before giving up.", + (gptr*) &global_system_variables.net_retry_count, + (gptr*) &max_system_variables.net_retry_count,0, + GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ~0L, 0, 1, 0}, {"net_write_timeout", OPT_NET_WRITE_TIMEOUT, "Number of seconds to wait for a block to be written to a connection before aborting the write.", (gptr*) &global_system_variables.net_write_timeout, @@ -4932,11 +4952,21 @@ The minimum value for this variable is 4096.", (gptr*) &global_system_variables.query_prealloc_size, (gptr*) &max_system_variables.query_prealloc_size, 0, GET_ULONG, REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, 1024, ~0L, 0, 1024, 0}, + {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE, + "Allocation block size for storing ranges during optimization", + (gptr*) &global_system_variables.range_alloc_block_size, + (gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG, + REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, {"read_buffer_size", OPT_RECORD_BUFFER, "Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value.", (gptr*) &global_system_variables.read_buff_size, (gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0}, + {"read_only", OPT_READONLY, + "Make all tables readonly, with the exception for replication (slave) threads and users with the SUPER privilege", + (gptr*) &opt_readonly, + (gptr*) &opt_readonly, + 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER, "When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks. If not set, then it's set to the value of record_buffer.", (gptr*) &global_system_variables.read_rnd_buff_size, @@ -4969,16 +4999,6 @@ The minimum value for this variable is 4096.", (gptr*) &slave_net_timeout, (gptr*) &slave_net_timeout, 0, GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, #endif /* HAVE_REPLICATION */ - {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE, - "Allocation block size for storing ranges during optimization", - (gptr*) &global_system_variables.range_alloc_block_size, - (gptr*) &max_system_variables.range_alloc_block_size, 0, GET_ULONG, - REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, 1024, ~0L, 0, 1024, 0}, - {"read-only", OPT_READONLY, - "Make all tables readonly, with the exception for replication (slave) threads and users with the SUPER privilege", - (gptr*) &opt_readonly, - (gptr*) &opt_readonly, - 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0}, {"slow_launch_time", OPT_SLOW_LAUNCH_TIME, "If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented.", (gptr*) &slow_launch_time, (gptr*) &slow_launch_time, 0, GET_ULONG, @@ -5008,23 +5028,28 @@ The minimum value for this variable is 4096.", "The number of open tables for all threads.", (gptr*) &table_cache_size, (gptr*) &table_cache_size, 0, GET_ULONG, REQUIRED_ARG, 64, 1, 512*1024L, 0, 1, 0}, - {"thread_concurrency", OPT_THREAD_CONCURRENCY, - "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.", - (gptr*) &concurrency, (gptr*) &concurrency, 0, GET_ULONG, REQUIRED_ARG, - DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0}, {"thread_cache_size", OPT_THREAD_CACHE_SIZE, "How many threads we should keep in a cache for reuse.", (gptr*) &thread_cache_size, (gptr*) &thread_cache_size, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 16384, 0, 1, 0}, + {"thread_concurrency", OPT_THREAD_CONCURRENCY, + "Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.", + (gptr*) &concurrency, (gptr*) &concurrency, 0, GET_ULONG, REQUIRED_ARG, + DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0}, + {"thread_stack", OPT_THREAD_STACK, + "The stack size for each thread.", (gptr*) &thread_stack, + (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, + 1024L*128L, ~0L, 0, 1024, 0}, + { "time_format", OPT_TIME_FORMAT, + "The TIME format (for future).", + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], + (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"tmp_table_size", OPT_TMP_TABLE_SIZE, "If an in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM table.", (gptr*) &global_system_variables.tmp_table_size, (gptr*) &max_system_variables.tmp_table_size, 0, GET_ULONG, REQUIRED_ARG, 32*1024*1024L, 1024, ~0L, 0, 1, 0}, - {"thread_stack", OPT_THREAD_STACK, - "The stack size for each thread.", (gptr*) &thread_stack, - (gptr*) &thread_stack, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK, - 1024L*128L, ~0L, 0, 1024, 0}, {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE, "Allocation block size for transactions to be stored in binary log", (gptr*) &global_system_variables.trans_alloc_block_size, @@ -5041,31 +5066,6 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT), 0, 1, 0}, - {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS, - "Binary logs will be rotated after expire-log-days days ", - (gptr*) &expire_logs_days, - (gptr*) &expire_logs_days, 0, GET_ULONG, - REQUIRED_ARG, 0, 0, 99, 0, 1, 0}, - { "default-week-format", OPT_DEFAULT_WEEK_FORMAT, - "The default week format used by WEEK() functions.", - (gptr*) &global_system_variables.default_week_format, - (gptr*) &max_system_variables.default_week_format, - 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0}, - { "date-format", OPT_DATE_FORMAT, - "The DATE format (For future).", - (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE], - (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATE], - 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - { "datetime-format", OPT_DATETIME_FORMAT, - "The DATETIME/TIMESTAMP format (for future).", - (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME], - (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME], - 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - { "time-format", OPT_TIME_FORMAT, - "The TIME format (for future).", - (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], - (gptr*) &opt_date_time_formats[MYSQL_TIMESTAMP_TIME], - 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; -- cgit v1.2.1 From 13f7338a3f09195be66fd7868d474126c51b708d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Aug 2004 22:31:01 +0300 Subject: after review fixes: allowed parsing of table fields inside aggregate functions added new tests of fields resolving in grouping mysql-test/r/func_gconcat.result: allowed parsing of table fields inside aggregate functions mysql-test/r/subselect.result: added new tests of fields resolving in grouping mysql-test/t/func_gconcat.test: allowed parsing of table fields inside aggregate functions mysql-test/t/subselect.test: added new tests of fields resolving in grouping sql/item_subselect.cc: allowed parsing of table fields inside aggregate functions --- sql/item_subselect.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 395c5589dec..8d140efac5f 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -70,7 +70,14 @@ void Item_subselect::init(st_select_lex *select_lex, } else { - parsing_place= unit->outer_select()->parsing_place; + SELECT_LEX *outer_select= unit->outer_select(); + /* + do not take into account expression inside aggregate functions because + they can access original table fields + */ + parsing_place= (outer_select->in_sum_expr ? + NO_MATTER : + outer_select->parsing_place); if (select_lex->next_select()) engine= new subselect_union_engine(unit, result, this); else -- cgit v1.2.1 From 7d4ad390e04068a04e056ca5e98df60c1e75c7f6 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 01:08:48 +0300 Subject: Fixed uninitialized variable Fixed error messages sql/share/czech/errmsg.txt: Fixed error message to us long sql/share/danish/errmsg.txt: Fixed error message to us long sql/share/dutch/errmsg.txt: Fixed error message to us long sql/share/english/errmsg.txt: Fixed error message to us long sql/share/estonian/errmsg.txt: Fixed error message to us long sql/share/french/errmsg.txt: Fixed error message to us long sql/share/german/errmsg.txt: Fixed error message to us long sql/share/greek/errmsg.txt: Fixed error message to us long sql/share/hungarian/errmsg.txt: Fixed error message to us long sql/share/italian/errmsg.txt: Fixed error message to us long sql/share/japanese/errmsg.txt: Fixed error message to us long sql/share/korean/errmsg.txt: Fixed error message to us long sql/share/norwegian-ny/errmsg.txt: Fixed error message to us long sql/share/norwegian/errmsg.txt: Fixed error message to us long sql/share/polish/errmsg.txt: Fixed error message to us long sql/share/portuguese/errmsg.txt: Fixed error message to us long sql/share/romanian/errmsg.txt: Fixed error message to us long sql/share/russian/errmsg.txt: Fixed error message to us long sql/share/serbian/errmsg.txt: Fixed error message to us long sql/share/slovak/errmsg.txt: Fixed error message to us long sql/share/spanish/errmsg.txt: Fixed error message to us long sql/share/swedish/errmsg.txt: Fixed error message to us long sql/share/ukrainian/errmsg.txt: Fixed error message to us long sql/sql_table.cc: Fixed uninitialized variable --- sql/share/czech/errmsg.txt | 2 +- sql/share/danish/errmsg.txt | 2 +- sql/share/dutch/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 2 +- sql/share/estonian/errmsg.txt | 2 +- sql/share/french/errmsg.txt | 2 +- sql/share/german/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/errmsg.txt | 2 +- sql/share/italian/errmsg.txt | 2 +- sql/share/japanese/errmsg.txt | 2 +- sql/share/korean/errmsg.txt | 2 +- sql/share/norwegian-ny/errmsg.txt | 2 +- sql/share/norwegian/errmsg.txt | 2 +- sql/share/polish/errmsg.txt | 2 +- sql/share/portuguese/errmsg.txt | 2 +- sql/share/romanian/errmsg.txt | 2 +- sql/share/russian/errmsg.txt | 2 +- sql/share/serbian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- sql/share/spanish/errmsg.txt | 2 +- sql/share/swedish/errmsg.txt | 2 +- sql/share/ukrainian/errmsg.txt | 2 +- sql/sql_table.cc | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) (limited to 'sql') diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 772e3e387d6..ee75210d4fe 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -313,4 +313,4 @@ character-set=latin2 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 91fdb82fe59..408f86b0445 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -307,4 +307,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 41678ae67aa..95af6aaa01f 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -315,4 +315,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index c34bf1c0403..5ad23b92a5a 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -304,4 +304,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index d3bb306f00a..36e0b8409e9 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -309,4 +309,4 @@ character-set=latin7 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 49a1065a5ca..3bd6835908e 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -304,4 +304,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 56e6454ab29..bf5a36a887a 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -316,4 +316,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index dd83db9907c..9703bad11a1 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -304,4 +304,4 @@ character-set=greek "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 23c6cffbcb8..1f71086ff69 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -306,4 +306,4 @@ character-set=latin2 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 1ae152fff8f..21158fcb567 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -304,4 +304,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index fbdd63f1ede..3a6dd644d8b 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -306,4 +306,4 @@ character-set=ujis "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 6e98cd61541..356f0a63540 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -304,4 +304,4 @@ character-set=euckr "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 517c041a355..b5564cb264e 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -306,4 +306,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index b5cf4a7df19..fcea45b06ac 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -306,4 +306,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index be152eed9b2..2a18e4de020 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -308,4 +308,4 @@ character-set=latin2 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 729883c7a79..6ba0fbca014 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -305,4 +305,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index c1f3abc9c3d..50b2b36c959 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -308,4 +308,4 @@ character-set=latin2 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index ecc8fc6e408..d8641d1dd14 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -306,4 +306,4 @@ character-set=koi8r "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index a4c8ea3713a..a8cde5a56b1 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -310,4 +310,4 @@ character-set=cp1250 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index b616db6235c..42ef7f62076 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -312,4 +312,4 @@ character-set=latin2 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 0231e83fbec..b82712be350 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -306,4 +306,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index a227de3b991..78620b28a2f 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -304,4 +304,4 @@ character-set=latin1 "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index f68e709471c..6d07eb1a656 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -309,4 +309,4 @@ character-set=koi8u "Unknown or incorrect time zone: '%-.64s'", "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", -"Result of %s() was larger than max_allowed_packet (%d) - truncated" +"Result of %s() was larger than max_allowed_packet (%ld) - truncated" diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b0b92178198..03777daa9b0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3281,7 +3281,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ha_rows *deleted) { int error; - Copy_field *copy,*copy_end, *next_field; + Copy_field *copy,*copy_end, *next_field= 0; ulong found_count,delete_count; THD *thd= current_thd; uint length; -- cgit v1.2.1 From d261072f7cdb44869ab8de39fd7a67f0c5122ab5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 14:44:15 +0400 Subject: Fix to compile with msvc: converted static const int Item_arena::* to enum members, undefine ERROR include/config-win.h: Undefine ERROR #defined by WINGDI sql/sql_class.cc: Fix to compile with msvc: converted static const int Item_arena::* to enum members sql/sql_class.h: Fix to compile with msvc: converted static const int Item_arena::* to enum members sql/sql_prepare.cc: Fix to compile with msvc: converted static const int Item_arena::* to enum members --- sql/sql_class.cc | 6 +++--- sql/sql_class.h | 12 ++++++++---- sql/sql_prepare.cc | 18 +++++++++--------- 3 files changed, 20 insertions(+), 16 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 23fef44c964..ff7dc805119 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1303,7 +1303,7 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) Item_arena::Item_arena(THD* thd) :free_list(0), - state(INITIALIZED) + state((int)INITIALIZED) { init_sql_alloc(&mem_root, thd->variables.query_alloc_block_size, @@ -1315,7 +1315,7 @@ Item_arena::Item_arena(THD* thd) Item_arena::Item_arena() :free_list(0), - state(CONVENTIONAL_EXECUTION) + state((int)CONVENTIONAL_EXECUTION) { clear_alloc_root(&mem_root); } @@ -1323,7 +1323,7 @@ Item_arena::Item_arena() Item_arena::Item_arena(bool init_mem_root) :free_list(0), - state(INITIALIZED) + state((int)INITIALIZED) { if (init_mem_root) clear_alloc_root(&mem_root); diff --git a/sql/sql_class.h b/sql/sql_class.h index 83fdb4c7d76..713609b3d32 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -427,8 +427,12 @@ public: */ Item *free_list; MEM_ROOT mem_root; - static const int INITIALIZED= 0, PREPARED= 1, EXECUTED= 3, - CONVENTIONAL_EXECUTION= 2, ERROR= -1; + enum + { + INITIALIZED= 0, PREPARED= 1, EXECUTED= 3, CONVENTIONAL_EXECUTION= 2, + ERROR= -1 + }; + int state; /* We build without RTTI, so dynamic_cast can't be used. */ @@ -443,8 +447,8 @@ public: virtual Type type() const; virtual ~Item_arena(); - inline bool is_stmt_prepare() const { return state < PREPARED; } - inline bool is_first_stmt_execute() const { return state == PREPARED; } + inline bool is_stmt_prepare() const { return state < (int)PREPARED; } + inline bool is_first_stmt_execute() const { return state == (int)PREPARED; } inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); } inline gptr calloc(unsigned int size) { diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 850d41a030b..94b6ab103da 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -132,7 +132,7 @@ find_prepared_statement(THD *thd, ulong id, const char *where, { Statement *stmt= thd->stmt_map.find(id); - if (stmt == 0 || stmt->type() != Item_arena::PREPARED_STATEMENT) + if (stmt == 0 || stmt->type() != (int)Item_arena::PREPARED_STATEMENT) { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), 22, llstr(id, llbuf), where); @@ -1619,7 +1619,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, { sl->prep_where= sl->where; } - stmt->state= Prepared_statement::PREPARED; + stmt->state= (int)Prepared_statement::PREPARED; } DBUG_RETURN(!stmt); @@ -1733,7 +1733,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) DBUG_PRINT("exec_query:", ("%s", stmt->query)); /* Check if we got an error when sending long data */ - if (stmt->state == Item_arena::ERROR) + if (stmt->state == (int)Item_arena::ERROR) { send_error(thd, stmt->last_errno, stmt->last_error); DBUG_VOID_RETURN; @@ -1850,7 +1850,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, transformations of the query tree (i.e. negations elimination). This should be done permanently on the parse tree of this statement. */ - if (stmt->state == Item_arena::PREPARED) + if (stmt->state == (int)Item_arena::PREPARED) thd->current_arena= stmt; if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1863,10 +1863,10 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, /* Free Items that were created during this execution of the PS. */ free_items(thd->free_list); thd->free_list= 0; - if (stmt->state == Item_arena::PREPARED) + if (stmt->state == (int)Item_arena::PREPARED) { thd->current_arena= thd; - stmt->state= Item_arena::EXECUTED; + stmt->state= (int)Item_arena::EXECUTED; } cleanup_items(stmt->free_list); reset_stmt_params(stmt); @@ -1905,7 +1905,7 @@ void mysql_stmt_reset(THD *thd, char *packet) SEND_ERROR))) DBUG_VOID_RETURN; - stmt->state= Item_arena::PREPARED; + stmt->state= (int)Item_arena::PREPARED; /* Clear parameters from data which could be set by @@ -1993,7 +1993,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param_number >= stmt->param_count) { /* Error will be sent in execute call */ - stmt->state= Item_arena::ERROR; + stmt->state= (int)Item_arena::ERROR; stmt->last_errno= ER_WRONG_ARGUMENTS; sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "mysql_stmt_send_long_data"); @@ -2009,7 +2009,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param->set_longdata(thd->extra_data, thd->extra_length)) #endif { - stmt->state= Item_arena::ERROR; + stmt->state= (int)Item_arena::ERROR; stmt->last_errno= ER_OUTOFMEMORY; sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0); } -- cgit v1.2.1 From b758a6d142a3c2a96c6744c9cf28e444180caa19 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 17:29:08 +0400 Subject: Fix for bug #4340: find_in_set is case insensitive even on binary operators(2nd version) mysql-test/r/func_set.result: Fix for bug #4340: find_in_set is case insensitive even on binary operators mysql-test/t/func_set.test: Fix for bug #4340: find_in_set is case insensitive even on binary operators sql/item_func.cc: Fix for bug #4340: find_in_set is case insensitive even on binary operators --- sql/item_func.cc | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index 237db890abb..334be48dc9a 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1071,6 +1071,7 @@ static const char separator=','; longlong Item_func_find_in_set::val_int() { + bool binary_cmp= args[0]->binary || args[1]->binary; if (enum_value) { ulonglong tmp=(ulonglong) args[1]->val_int(); @@ -1103,12 +1104,25 @@ longlong Item_func_find_in_set::val_int() do { const char *pos= f_pos; - while (pos != f_end) + if (binary_cmp) { - if (toupper(*str) != toupper(*pos)) - goto not_found; - str++; - pos++; + while (pos != f_end) + { + if (*str != *pos) + goto not_found; + str++; + pos++; + } + } + else + { + while (pos != f_end) + { + if (toupper(*str) != toupper(*pos)) + goto not_found; + str++; + pos++; + } } if (str == real_end || str[0] == separator) return (longlong) position; -- cgit v1.2.1 From b033e3dfbb9d15e40887cde9914f99a41b304cad Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 15:32:57 +0200 Subject: BDB: Bug#4531: unique key prefix interacts poorly with utf8, Bug#4594 column index make = failed for gbk myisam/mi_key.c: cleanup --- sql/field.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- sql/field.h | 2 ++ 2 files changed, 47 insertions(+), 8 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 96f4fa8fd86..f1d1227ace8 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4382,7 +4382,7 @@ void Field_string::sql_type(String &res) const (field_length > 3 && (table->db_options_in_use & HA_OPTION_PACK_RECORD) ? - (has_charset() ? "varchar" : "varbinary") : + (has_charset() ? "varchar" : "varbinary") : (has_charset() ? "char" : "binary")), (int) field_length / charset()->mbmaxlen); res.length(length); @@ -4401,6 +4401,24 @@ char *Field_string::pack(char *to, const char *from, uint max_length) } +char *Field_string::pack_key(char *to, const char *from, uint max_length) +{ + const char *end=from+min(field_length,max_length); + int length; + while (end > from && end[-1] == ' ') + end--; + length= end-from; + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + if (length > char_length) + char_length= my_charpos(field_charset, from, end, char_length); + set_if_smaller(length, char_length); + *to= (uchar)length; + memcpy(to+1, from, length); + return to+1+length; +} + + const char *Field_string::unpack(char *to, const char *from) { uint length= (uint) (uchar) *from++; @@ -4564,6 +4582,24 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length) } +char *Field_varstring::pack_key(char *to, const char *from, uint max_length) +{ + uint length=uint2korr(from); + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + from+=HA_KEY_BLOB_LENGTH; + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); + *to++= (char) (length & 255); + if (max_length > 255) + *to++= (char) (length >> 8); + if (length) + memcpy(to, from, length); + return to+length; +} + + const char *Field_varstring::unpack(char *to, const char *from) { uint length; @@ -5139,16 +5175,17 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length) char *save=ptr; ptr=(char*) from; uint32 length=get_length(); // Length of from string - if (length > max_length) - length=max_length; + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + if (length) + get_ptr((char**) &from); + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); *to++= (uchar) length; if (max_length > 255) // 2 byte length *to++= (uchar) (length >> 8); - if (length) - { - get_ptr((char**) &from); - memcpy(to, from, length); - } + memcpy(to, from, length); ptr=save; // Restore org row pointer return to+length; } diff --git a/sql/field.h b/sql/field.h index 843961e64c3..eaf90ddc0ff 100644 --- a/sql/field.h +++ b/sql/field.h @@ -917,6 +917,7 @@ public: void sort_string(char *buff,uint length); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + char *pack_key(char *to, const char *from, uint max_length); const char *unpack(char* to, const char *from); int pack_cmp(const char *a,const char *b,uint key_length); int pack_cmp(const char *b,uint key_length); @@ -965,6 +966,7 @@ public: void set_key_image(char *buff,uint length, CHARSET_INFO *cs); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + char *pack_key(char *to, const char *from, uint max_length); const char *unpack(char* to, const char *from); int pack_cmp(const char *a, const char *b, uint key_length); int pack_cmp(const char *b, uint key_length); -- cgit v1.2.1 From 20f24a422bd8ff8747c2e75c03b9f207875ad880 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 18:00:45 +0300 Subject: Portablity fixes & simple optimizations sql/ha_ndbcluster.cc: Added missing cast sql/item.cc: Portability fix (for windows) sql/lock.cc: Cleanup + more comments sql/sql_class.cc: Portability fix + more comments sql/sql_select.cc: Portability fix sql/sql_table.cc: Simpler handling of auto_increment in ALTER TABLE --- sql/ha_ndbcluster.cc | 3 ++- sql/item.cc | 2 +- sql/lock.cc | 8 ++++++-- sql/sql_class.cc | 19 ++++++++++++------- sql/sql_select.cc | 2 +- sql/sql_table.cc | 14 +++++++++----- 6 files changed, 31 insertions(+), 17 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index cc6b9016bfb..1a11f0d3073 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1423,7 +1423,8 @@ int ha_ndbcluster::write_row(byte *record) { Uint64 next_val= (Uint64) table->next_number_field->val_int() + 1; DBUG_PRINT("info", - ("Trying to set next auto increment value to %u", next_val)); + ("Trying to set next auto increment value to %lu", + (ulong) next_val)); if (m_ndb->setAutoIncrementValue((NDBTAB *) m_table, next_val, true)) DBUG_PRINT("info", ("Setting next auto increment value to %u", next_val)); diff --git a/sql/item.cc b/sql/item.cc index 11d618748b3..2c98aad2074 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -919,7 +919,7 @@ double Item_param::val() This works for example when user says SELECT ?+0.0 and supplies time value for the placeholder. */ - return (double) TIME_to_ulonglong(&value.time); + return ulonglong2double(TIME_to_ulonglong(&value.time)); case NULL_VALUE: return 0.0; default: diff --git a/sql/lock.cc b/sql/lock.cc index fa199ce7454..fab0a61e506 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -787,7 +787,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commi LINT_INIT(old_message); (void) pthread_mutex_lock(&LOCK_open); - if (need_exit_cond= must_wait) + if ((need_exit_cond= must_wait)) { if (thd->global_read_lock) // This thread had the read locks { @@ -805,7 +805,11 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commi } if (!abort_on_refresh && !result) protect_against_global_read_lock++; - if (unlikely(need_exit_cond)) // global read locks are rare + /* + The following is only true in case of a global read locks (which is rare) + and if old_message is set + */ + if (unlikely(need_exit_cond)) thd->exit_cond(old_message); else pthread_mutex_unlock(&LOCK_open); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 23fef44c964..e49cfecba9d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -155,11 +155,13 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), current_arena(this), is_fatal_error(0), - last_insert_id_used(0), - insert_id_used(0), rand_used(0), time_zone_used(0), - in_lock_tables(0), global_read_lock(0), bootstrap(0) +THD::THD() + :user_time(0), global_read_lock(0), is_fatal_error(0), + last_insert_id_used(0), + insert_id_used(0), rand_used(0), time_zone_used(0), + in_lock_tables(0), bootstrap(0) { + current_arena= this; host= user= priv_user= db= ip=0; host_or_ip= "connecting host"; locked=some_tables_deleted=no_errors=password= 0; @@ -439,10 +441,13 @@ void THD::awake(bool prepare_to_die) it is the true value but maybe current_mutex is not yet non-zero (we're in the middle of enter_cond() and there is a "memory order inversion"). So we test the mutex too to not lock 0. + Note that there is a small chance we fail to kill. If victim has locked - current_mutex, and hasn't entered enter_cond(), then we don't know it's - going to wait on cond. Then victim goes into its cond "forever" (until - we issue a second KILL). True we have set its thd->killed but it may not + current_mutex, but hasn't yet entered enter_cond() (which means that + current_cond and current_mutex are 0), then the victim will not get + a signal and it may wait "forever" on the cond (until + we issue a second KILL or the status it's waiting for happens). + It's true that we have set its thd->killed but it may not see it immediately and so may have time to reach the cond_wait(). */ if (mysys_var->current_cond && mysys_var->current_mutex) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 279a56b9e58..630a520066a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -8014,7 +8014,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, Item *itemptr=*order->item; if (itemptr->type() == Item::INT_ITEM) { /* Order by position */ - uint count= itemptr->val_int(); + uint count= (uint) itemptr->val_int(); if (!count || count > fields.elements) { my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 03777daa9b0..408f3408346 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3281,7 +3281,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, ha_rows *deleted) { int error; - Copy_field *copy,*copy_end, *next_field= 0; + Copy_field *copy,*copy_end; ulong found_count,delete_count; THD *thd= current_thd; uint length; @@ -3291,6 +3291,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, List fields; List all_fields; ha_rows examined_rows; + bool auto_increment_field_copied= 0; DBUG_ENTER("copy_data_between_tables"); if (!(copy= new Copy_field[to->fields])) @@ -3309,7 +3310,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, if (def->field) { if (*ptr == to->next_number_field) - next_field= copy_end; + auto_increment_field_copied= TRUE; (copy_end++)->set(*ptr,def->field,0); } @@ -3368,11 +3369,14 @@ copy_data_between_tables(TABLE *from,TABLE *to, } thd->row_count++; if (to->next_number_field) - to->next_number_field->reset(); - for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++) { - if (copy_ptr == next_field) + if (auto_increment_field_copied) to->auto_increment_field_not_null= TRUE; + else + to->next_number_field->reset(); + } + for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++) + { copy_ptr->do_copy(copy_ptr); } if ((error=to->file->write_row((byte*) to->record[0]))) -- cgit v1.2.1 From 49bd559eb8f041de97e4ef55f280f3806d1b6c42 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 20:17:11 +0400 Subject: Fix for Bug#5034 "prepared "select 1 into @arg15", second execute crashes server": we were deleting lex->result after each execute, but prepared statements assumed that it's left intact. The fix adds cleanup() method to select_result hierarchy, so that result objects can be reused. Plus we now need to delete result objects more wisely. mysql-test/r/ps.result: Test results fixed: test case for bug#5034 mysql-test/t/ps.test: A test case for bug#5034, few followups sql/sql_class.cc: - fix warning in THD::THD - implementation of cleanup() for select_result hierarchy - select_export::send_eof was identical to select_dump::send_eof: moved to the base class select_to_file. - Statement::end_statement() to end lex, free items, and delete possible select_result sql/sql_class.h: - select_result::cleanup() declaration - sql/sql_insert.cc: - implementation of select_insert::cleanup(): currently we always create a new instance of select_insert/ select_create on each execute. sql/sql_lex.cc: - with more complicated logic of freeing lex->result it's easier to have it non-zero only if it points to a valid result. sql/sql_lex.h: Now st_lex::st_lex is not empty. sql/sql_parse.cc: mysql_execute_command(): - delete select_result *result only if it was created in this function. - use end_statement() to cleanup lex and thd in the end of each statement. - no need to save THD::lock if this is explain. This save apparently left from times when derived tables were materialized here, not in open_and_lock_tables. sql/sql_prepare.cc: - call result->cleanup() in reset_stmt_for_execute - now Statement is responsible for freeing its lex->result. sql/sql_select.cc: handle_select(): - don't delete result, it might be needed for next executions - result is never null --- sql/sql_class.cc | 84 ++++++++++++++++++++++++++++++++++++------------------ sql/sql_class.h | 22 ++++++++++++-- sql/sql_insert.cc | 7 +++++ sql/sql_lex.cc | 5 ++++ sql/sql_lex.h | 2 +- sql/sql_parse.cc | 59 +++++++++++++++++--------------------- sql/sql_prepare.cc | 8 ++++-- sql/sql_select.cc | 10 ++----- 8 files changed, 123 insertions(+), 74 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 23fef44c964..07df83b78e7 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -155,10 +155,10 @@ bool foreign_key_prefix(Key *a, Key *b) ** Thread specific functions ****************************************************************************/ -THD::THD():user_time(0), current_arena(this), is_fatal_error(0), - last_insert_id_used(0), +THD::THD():user_time(0), current_arena(this), global_read_lock(0), + is_fatal_error(0), last_insert_id_used(0), insert_id_used(0), rand_used(0), time_zone_used(0), - in_lock_tables(0), global_read_lock(0), bootstrap(0) + in_lock_tables(0), bootstrap(0) { host= user= priv_user= db= ip=0; host_or_ip= "connecting host"; @@ -703,6 +703,12 @@ void select_result::send_error(uint errcode,const char *err) ::send_error(thd, errcode, err); } + +void select_result::cleanup() +{ + /* do nothing */ +} + static String default_line_term("\n",default_charset_info); static String default_escaped("\\",default_charset_info); static String default_field_term("\t",default_charset_info); @@ -808,6 +814,32 @@ void select_to_file::send_error(uint errcode,const char *err) } +bool select_to_file::send_eof() +{ + int error= test(end_io_cache(&cache)); + if (my_close(file,MYF(MY_WME))) + error= 1; + if (!error) + ::send_ok(thd,row_count); + file= -1; + return error; +} + + +void select_to_file::cleanup() +{ + /* In case of error send_eof() may be not called: close the file here. */ + if (file >= 0) + { + (void) end_io_cache(&cache); + (void) my_close(file,MYF(0)); + file= -1; + } + path[0]= '\0'; + row_count= 0; +} + + select_to_file::~select_to_file() { if (file >= 0) @@ -1058,18 +1090,6 @@ err: } -bool select_export::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - /*************************************************************************** ** Dump of select to a binary file ***************************************************************************/ @@ -1123,18 +1143,6 @@ err: } -bool select_dump::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - select_subselect::select_subselect(Item_subselect *item_arg) { item= item_arg; @@ -1301,6 +1309,13 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) } +void select_dumpvar::cleanup() +{ + vars.empty(); + row_count=0; +} + + Item_arena::Item_arena(THD* thd) :free_list(0), state(INITIALIZED) @@ -1405,6 +1420,21 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup) } +void Statement::end_statement() +{ + /* Cleanup SQL processing state to resuse this statement in next query. */ + lex_end(lex); + delete lex->result; + lex->result= 0; + free_items(free_list); + free_list= 0; + /* + Don't free mem_root, as mem_root is freed in the end of dispatch_command + (once for any command). + */ +} + + void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup) { backup->set_item_arena(this); diff --git a/sql/sql_class.h b/sql/sql_class.h index 83fdb4c7d76..c18bf969ab9 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -547,6 +547,12 @@ public: void restore_backup_statement(Statement *stmt, Statement *backup); /* return class type */ virtual Type type() const; + + /* + Cleanup statement parse state (parse tree, lex) after execution of + a non-prepared SQL statement. + */ + void end_statement(); }; @@ -1029,10 +1035,13 @@ public: ~Disable_binlog(); }; + /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) + XXX: We never call destructor for objects of this class. */ + class sql_exchange :public Sql_alloc { public: @@ -1042,7 +1051,6 @@ public: bool dumpfile; ulong skip_lines; sql_exchange(char *name,bool dumpfile_flag); - ~sql_exchange() {} }; #include "log_event.h" @@ -1073,6 +1081,11 @@ public: virtual void send_error(uint errcode,const char *err); virtual bool send_eof()=0; virtual void abort() {} + /* + Cleanup instance of this class for next execution of a prepared + statement/stored procedure. + */ + virtual void cleanup(); }; @@ -1099,6 +1112,8 @@ public: ~select_to_file(); bool send_fields(List &list, uint flag) { return 0; } void send_error(uint errcode,const char *err); + bool send_eof(); + void cleanup(); }; @@ -1111,7 +1126,6 @@ public: ~select_export(); int prepare(List &list, SELECT_LEX_UNIT *u); bool send_data(List &items); - bool send_eof(); }; @@ -1120,7 +1134,6 @@ public: select_dump(sql_exchange *ex) :select_to_file(ex) {} int prepare(List &list, SELECT_LEX_UNIT *u); bool send_data(List &items); - bool send_eof(); }; @@ -1145,6 +1158,8 @@ class select_insert :public select_result { bool send_data(List &items); void send_error(uint errcode,const char *err); bool send_eof(); + /* not implemented: select_insert is never re-used in prepared statements */ + void cleanup(); }; @@ -1445,4 +1460,5 @@ public: bool send_fields(List &list, uint flag) {return 0;} bool send_data(List &items); bool send_eof(); + void cleanup(); }; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 406bff6d273..4cbd11c6a15 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1465,6 +1465,13 @@ select_insert::prepare(List &values, SELECT_LEX_UNIT *u) DBUG_RETURN(0); } + +void select_insert::cleanup() +{ + /* select_insert/select_create are never re-used in prepared statement */ + DBUG_ASSERT(0); +} + select_insert::~select_insert() { if (table) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index be1b7c3377e..d83c5ba5778 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1653,6 +1653,11 @@ void st_select_lex::print_limit(THD *thd, String *str) } +st_lex::st_lex() + :result(0) +{} + + /* Unlink first table from global table list and first table from outer select list (lex->select_lex) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 053c85166f6..9c7918a400f 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -639,7 +639,7 @@ typedef struct st_lex list of those tables after they are opened. */ TABLE_LIST *time_zone_tables_used; - st_lex() {} + st_lex(); inline void uncacheable(uint8 cause) { safe_to_cache_query= 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 66eebba74c9..f9e979d1fdf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1967,8 +1967,6 @@ mysql_execute_command(THD *thd) else thd->send_explain_fields(result); res= mysql_explain_union(thd, &thd->lex->unit, result); - MYSQL_LOCK *save_lock= thd->lock; - thd->lock= (MYSQL_LOCK *)0; if (lex->describe & DESCRIBE_EXTENDED) { char buff[1024]; @@ -1980,20 +1978,19 @@ mysql_execute_command(THD *thd) ER_YES, str.ptr()); } result->send_eof(); - thd->lock= save_lock; + delete result; } else { - if (!result) + if (!result && !(result= new select_send())) { - if (!(result=new select_send())) - { - res= -1; - break; - } + res= -1; + break; } query_cache_store_query(thd, tables); - res=handle_select(thd, lex, result); + res= handle_select(thd, lex, result); + if (result != lex->result) + delete result; } } break; @@ -2708,23 +2705,24 @@ unsent_create_error: } - if (!(res=open_and_lock_tables(thd, tables))) + if (!(res= open_and_lock_tables(thd, tables)) && + (result= new select_insert(tables->table, &lex->field_list, + lex->duplicates))) { - if ((result=new select_insert(tables->table,&lex->field_list, - lex->duplicates))) - /* Skip first table, which is the table we are inserting in */ - lex->select_lex.table_list.first= (byte*) first_local_table->next; - /* - insert/replace from SELECT give its SELECT_LEX for SELECT, - and item_list belong to SELECT - */ - lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; - res=handle_select(thd,lex,result); - /* revert changes for SP */ - lex->select_lex.table_list.first= (byte*) first_local_table; - lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + /* Skip first table, which is the table we are inserting in */ + lex->select_lex.table_list.first= (byte*) first_local_table->next; + /* + insert/replace from SELECT give its SELECT_LEX for SELECT, + and item_list belong to SELECT + */ + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + res= handle_select(thd, lex, result); + /* revert changes for SP */ + lex->select_lex.table_list.first= (byte*) first_local_table; + lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + delete result; if (thd->net.report_error) - res= -1; + res= -1; } else res= -1; @@ -3904,8 +3902,8 @@ mysql_init_select(LEX *lex) select_lex->select_limit= HA_POS_ERROR; if (select_lex == &lex->select_lex) { + DBUG_ASSERT(lex->result == 0); lex->exchange= 0; - lex->result= 0; lex->proc_list.first= 0; } } @@ -4047,9 +4045,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) query_cache_abort(&thd->net); } thd->proc_info="freeing items"; - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; - lex_end(lex); + thd->end_statement(); } DBUG_VOID_RETURN; } @@ -4074,10 +4070,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) if (!yyparse((void*) thd) && ! thd->is_fatal_error && all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) error= 1; /* Ignore question */ - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; - lex_end(lex); - + thd->end_statement(); return error; } #endif diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 850d41a030b..6d494b83535 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1630,7 +1630,8 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, static void reset_stmt_for_execute(Prepared_statement *stmt) { THD *thd= stmt->thd; - SELECT_LEX *sl= stmt->lex->all_selects_list; + LEX *lex= stmt->lex; + SELECT_LEX *sl= lex->all_selects_list; for (; sl; sl= sl->next_select_in_list()) { @@ -1678,7 +1679,9 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) unit->reinit_exec_mechanism(); } } - stmt->lex->current_select= &stmt->lex->select_lex; + lex->current_select= &lex->select_lex; + if (lex->result) + lex->result->cleanup(); } @@ -2053,6 +2056,7 @@ void Prepared_statement::setup_set_params() Prepared_statement::~Prepared_statement() { free_items(free_list); + delete lex->result; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index fdea963b3ca..34ee7139d71 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -199,16 +199,10 @@ int handle_select(THD *thd, LEX *lex, select_result *result) res= 1; if (res) { - if (result) - { - result->send_error(0, NullS); - result->abort(); - } - else - send_error(thd, 0, NullS); + result->send_error(0, NullS); + result->abort(); res= 1; // Error sent to client } - delete result; DBUG_RETURN(res); } -- cgit v1.2.1 From f5ce37d7fec7443542d4d6d7ee0a224c525ce877 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 20:18:59 +0400 Subject: Fix for bug #4340: find_in_set is case insensitive even on binary operators(for 4.1) --- sql/item_func.cc | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/item_func.cc b/sql/item_func.cc index c90a70a6bb6..adcba34d56b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1435,30 +1435,43 @@ longlong Item_func_find_in_set::val_int() int diff; if ((diff=buffer->length() - find->length()) >= 0) { - const char *f_pos=find->ptr(); - const char *f_end=f_pos+find->length(); - const char *str=buffer->ptr(); - const char *end=str+diff+1; - const char *real_end=str+buffer->length(); - uint position=1; - do + my_wc_t wc; + CHARSET_INFO *cs= cmp_collation.collation; + const char *str_begin= buffer->ptr(); + const char *str_end= buffer->ptr(); + const char *real_end= str_end+buffer->length(); + const uchar *find_str= (const uchar *) find->ptr(); + uint find_str_len= find->length(); + int position= 0; + while (1) { - const char *pos= f_pos; - while (pos != f_end) + int symbol_len; + if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, + (uchar*) real_end)) > 0) { - if (my_toupper(cmp_collation.collation,*str) != - my_toupper(cmp_collation.collation,*pos)) - goto not_found; - str++; - pos++; + const char *substr_end= str_end + symbol_len; + bool is_last_item= (substr_end == real_end); + if (wc == (my_wc_t) separator || is_last_item) + { + position++; + if (is_last_item) + str_end= substr_end; + if (!my_strnncoll(cs, (const uchar *) str_begin, + str_end - str_begin, + find_str, find_str_len)) + return (longlong) position; + else + str_begin= substr_end; + } + str_end= substr_end; } - if (str == real_end || str[0] == separator) - return (longlong) position; - not_found: - while (str < end && str[0] != separator) - str++; - position++; - } while (++str <= end); + else if (str_end - str_begin == 0 && + find_str_len == 0 && + wc == (my_wc_t) separator) + return (longlong) ++position; + else + return (longlong) 0; + } } return 0; } -- cgit v1.2.1 From 44a75553840b4ecb0be4e89eafb267d1d005dc72 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 18:20:27 +0200 Subject: followup --- sql/field.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index f1d1227ace8..bbb91fc534d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4403,16 +4403,14 @@ char *Field_string::pack(char *to, const char *from, uint max_length) char *Field_string::pack_key(char *to, const char *from, uint max_length) { - const char *end=from+min(field_length,max_length); - int length; - while (end > from && end[-1] == ' ') - end--; - length= end-from; + int length=min(field_length,max_length); uint char_length= (field_charset->mbmaxlen > 1) ? max_length/field_charset->mbmaxlen : max_length; if (length > char_length) - char_length= my_charpos(field_charset, from, end, char_length); + char_length= my_charpos(field_charset, from, from+length, char_length); set_if_smaller(length, char_length); + while (length && from[length-1] == ' ') + length--; *to= (uchar)length; memcpy(to+1, from, length); return to+1+length; -- cgit v1.2.1 From 9d3009eaeab17e3695f7d7184089714ebd95bd20 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 22:45:32 +0500 Subject: Fix for bug #4815 (embedded server calculates wrong places for outfiles) In some places in mysqld behaviour depends on system working directory It works badly in libmysqld because user can set it in the way he needs. I think we should explicitly insert mysql_real_data_home value in paths in these places sql/sql_class.cc: here we concat mysql_real_data_home and thd->db to be the prefix sql/sql_load.cc: it's better to build the prefix from mysql_real_data_home also i think it's better always to call my_load_path to not to depend of current system working directory --- sql/sql_class.cc | 13 +++++++++++-- sql/sql_load.cc | 16 +++------------- 2 files changed, 14 insertions(+), 15 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index aecb2ef6522..80b9d6e20bf 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -854,12 +854,21 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, { File file; uint option= MY_UNPACK_FILENAME; + char buff[FN_REFLEN]; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS option|= MY_REPLACE_DIR; // Force use of db directory #endif - (void) fn_format(path, exchange->file_name, thd->db ? thd->db : "", "", - option); + + char *cnt= strmake(buff, mysql_real_data_home, FN_REFLEN); + *cnt= FN_LIBCHAR; + cnt++; + cnt= strmake(cnt, thd->db ? thd->db : "", FN_REFLEN - (cnt-buff)); + *cnt= FN_LIBCHAR; + cnt++; + *cnt= 0; + + (void) fn_format(path, exchange->file_name, buff, "", option); if (!access(path, F_OK)) { my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 8442d03c1d9..1f4905837f0 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -180,7 +180,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ex->file_name+=dirname_length(ex->file_name); #endif if (!dirname_length(ex->file_name) && - strlen(ex->file_name)+strlen(mysql_data_home)+strlen(tdb)+3 < + strlen(ex->file_name)+strlen(mysql_real_data_home)+strlen(tdb)+3 < FN_REFLEN) { (void) sprintf(name,"%s/%s/%s",mysql_data_home,tdb,ex->file_name); @@ -188,18 +188,8 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, } else { -#ifdef EMBEDDED_LIBRARY - char *chk_name= ex->file_name; - while ((*chk_name == ' ') || (*chk_name == 't')) - chk_name++; - if (*chk_name == FN_CURLIB) - { - sprintf(name, "%s%s", mysql_data_home, ex->file_name); - unpack_filename(name, name); - } - else -#endif /*EMBEDDED_LIBRARY*/ - unpack_filename(name,ex->file_name); + my_load_path(name, ex->file_name, mysql_real_data_home); + unpack_filename(name, name); #if !defined(__WIN__) && !defined(OS2) && ! defined(__NETWARE__) MY_STAT stat_info; if (!my_stat(name,&stat_info,MYF(MY_WME))) -- cgit v1.2.1 From 340d40a77c87009d83fe360ca00bd5ef0f7b8792 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Aug 2004 23:13:32 +0200 Subject: Cleaned up rnd_init --- sql/ha_ndbcluster.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1a11f0d3073..80b8c21fa0c 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2013,10 +2013,12 @@ int ha_ndbcluster::rnd_init(bool scan) DBUG_ENTER("rnd_init"); DBUG_PRINT("enter", ("scan: %d", scan)); // Check if scan is to be restarted - if (cursor && scan) + if (cursor) + { + if (!scan) + DBUG_RETURN(1); cursor->restart(); - else - DBUG_RETURN(1); + } index_init(table->primary_key); DBUG_RETURN(0); } -- cgit v1.2.1 From ca59bf47466bb50148315bb82af23db11aaab003 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Aug 2004 15:12:31 +0200 Subject: Bug #4792 lower_case_table_names does not resolve db.tbl.column in SELECT list sql_base.cc: Added code to lowercase database name in insert_fields when lower_case_table_names=1. This fixes bug# 4792 sql/sql_base.cc: Added code to lowercase database name in insert_fields when lower_case_table_names=1. This fixes bug# 4792 --- sql/sql_base.cc | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 7b1b3cc1b7a..26ce394ec37 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2062,9 +2062,20 @@ bool insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, const char *table_name, List_iterator *it) { + char name_buff[NAME_LEN+1]; uint found; DBUG_ENTER("insert_fields"); + + if (db_name && lower_case_table_names) + { + /* convert database to lower case for comparison */ + strmake( name_buff, db_name, sizeof(name_buff)-1 ); + casedn_str( name_buff ); + db_name = name_buff; + } + + found=0; for (; tables ; tables=tables->next) { -- cgit v1.2.1 From 8ed5952a86b75f3c68faf3c039a59fbde51209f8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Aug 2004 00:37:25 +0300 Subject: Remove default argument to mysql_truncate() Update to new valgrind mysql-test/mysql-test-run.sh: Update for new valgrind sql/mysql_priv.h: Remove default argument to mysql_truncate() sql/sql_parse.cc: Remove default argument to mysql_truncate() --- sql/mysql_priv.h | 2 +- sql/sql_parse.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2e893ead407..3fba75d7140 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -477,7 +477,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table,List &fields, void kill_delayed_threads(void); int mysql_delete(THD *thd, TABLE_LIST *table, COND *conds, ORDER *order, ha_rows rows, ulong options); -int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok=0); +int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok); TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update); TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias, bool *refresh); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1f0af05a460..7b0924ff108 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2046,7 +2046,7 @@ mysql_execute_command(void) send_error(&thd->net,ER_LOCK_OR_ACTIVE_TRANSACTION,NullS); goto error; } - res=mysql_truncate(thd,tables); + res=mysql_truncate(thd, tables, 0); break; case SQLCOM_DELETE: { -- cgit v1.2.1 From 42771f9877c17050a230cdaf8a26afc5d077a712 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Aug 2004 16:31:37 +0500 Subject: "SELECT BINARY x" now means "SELECT CAST(x AS BINARY)". --- sql/sql_yacc.yy | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9cc39fe5104..4eca7359023 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2745,8 +2745,7 @@ simple_expr: | ASCII_SYM '(' expr ')' { $$= new Item_func_ascii($3); } | BINARY expr %prec NEG { - $$= new Item_func_set_collation($2,new Item_string(binary_keyword, - 6, &my_charset_latin1)); + $$= create_func_cast($2, ITEM_CAST_CHAR, -1, &my_charset_bin); } | CAST_SYM '(' expr AS cast_type ')' { -- cgit v1.2.1 From 45f49c60cd124315e2d70905f3a01d6f738123f6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Aug 2004 16:51:26 +0500 Subject: A fix (Bug#5219: Cannot use '||' with MBRContains(..)). --- sql/opt_range.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'sql') diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 40e3ffebe56..02947e58a9e 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1302,14 +1302,14 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) if (*key2 && !(*key2)->simple_key()) flag|=CLONE_KEY2_MAYBE; *key1=key_and(*key1,*key2,flag); - if ((*key1)->type == SEL_ARG::IMPOSSIBLE) + if (*key1 && (*key1)->type == SEL_ARG::IMPOSSIBLE) { tree1->type= SEL_TREE::IMPOSSIBLE; - break; - } #ifdef EXTRA_DEBUG - (*key1)->test_use_count(*key1); + (*key1)->test_use_count(*key1); #endif + break; + } } } DBUG_RETURN(tree1); @@ -1401,6 +1401,12 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) return key2; if (!key2) return key1; + if ((key1->min_flag | key2->min_flag) & GEOM_FLAG) + { + key1->free_tree(); + key2->free_tree(); + return 0; // Can't optimize this + } if (key1->part != key2->part) { if (key1->part > key2->part) @@ -1538,7 +1544,8 @@ key_or(SEL_ARG *key1,SEL_ARG *key2) key1->use_count--; key2->use_count--; - if (key1->part != key2->part) + if (key1->part != key2->part || + (key1->min_flag | key2->min_flag) & GEOM_FLAG) { key1->free_tree(); key2->free_tree(); -- cgit v1.2.1 From 11612dd3b428b24b5a47a257ae5f01b03e688e59 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Aug 2004 17:43:08 +0500 Subject: Should check for GEOM_FLAG later because keyX may be partly initialized (min_flag is not set). --- sql/opt_range.cc | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'sql') diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 02947e58a9e..f11ed31950a 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1401,12 +1401,6 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) return key2; if (!key2) return key1; - if ((key1->min_flag | key2->min_flag) & GEOM_FLAG) - { - key1->free_tree(); - key2->free_tree(); - return 0; // Can't optimize this - } if (key1->part != key2->part) { if (key1->part > key2->part) @@ -1462,6 +1456,13 @@ key_and(SEL_ARG *key1,SEL_ARG *key2,uint clone_flag) return key1; } + if ((key1->min_flag | key2->min_flag) & GEOM_FLAG) + { + key1->free_tree(); + key2->free_tree(); + return 0; // Can't optimize this + } + key1->use_count--; key2->use_count--; SEL_ARG *e1=key1->first(), *e2=key2->first(), *new_tree=0; -- cgit v1.2.1 From 44b2807e4bb2383525c3abfd9ad896114dec0796 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Aug 2004 18:26:38 +0300 Subject: Portability fixes Fixed bug in end space handle for WHERE text_column="constant" heap/hp_hash.c: Optimzations (no change of logic) libmysql/libmysql.c: Added missing casts (portability fix) myisam/mi_key.c: Changed macro to take arguments and not depend on local variables Simple indentation fixes ? mysql-test/r/connect.result: Added test for setting empty password mysql-test/r/create_select_tmp.result: TYPE -> ENGINE mysql-test/r/ctype_utf8.result: Combine drop's mysql-test/r/endspace.result: Added more tests to test end space behaviour mysql-test/r/having.result: Added missing DROP TABLE mysql-test/r/type_blob.result: Added more tests to ensure that fix for BLOB usage is correct mysql-test/r/type_timestamp.result: Add test from 4.0 mysql-test/t/connect.test: Added test for setting empty password mysql-test/t/create_select_tmp.test: TYPE -> ENGINE mysql-test/t/ctype_utf8.test: Combine drop's mysql-test/t/endspace.test: Added more tests to test end space behaviour mysql-test/t/having.test: Added missing DROP TABLE mysql-test/t/type_blob.test: Added more tests to ensure that fix for BLOB usage is correct mysql-test/t/type_timestamp.test: Add test from 4.0 sql/field.cc: Removed not used variable Portability fix (cast) Simplified Field_str::double() Simple indentation cleanups sql/field.h: Removed not needed class variable sql/item_cmpfunc.cc: Indentation fix sql/item_strfunc.cc: Use on stack variable for Item_str_func::val() instead of str_value. This makes it safe to use str_value inside the Item's val function. Cleaned up LEFT() usage, thanks to the above change sql/item_sum.cc: Indentation cleanups sql/protocol.cc: Added missing cast sql/sql_acl.cc: Indentatin cleanups. Added missing cast Simple optimization of get_sort() sql/sql_select.cc: Don't use 'ref' to search on text field that is not of type BINARY (use 'range' instead). The reson is that for 'ref' we use 'index_next_same' to read the next possible row. For text fields, rows in a ref may not come in order, like for 'x', 'x\t' 'x ' (stored in this order) which causes a search for 'column='x ' to fail sql/tztime.cc: Simple cleanup strings/ctype-bin.c: Comment fixes strings/ctype-mb.c: Changed variable names for arguments --- sql/field.cc | 38 ++++++++++++++------------------------ sql/field.h | 3 +-- sql/item_cmpfunc.cc | 4 ++-- sql/item_strfunc.cc | 21 +++++++++++---------- sql/item_sum.cc | 8 ++++---- sql/protocol.cc | 2 +- sql/sql_acl.cc | 10 ++++------ sql/sql_select.cc | 51 ++++++++++++++++++++++++++++++--------------------- sql/tztime.cc | 11 ++++++----- 9 files changed, 73 insertions(+), 75 deletions(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index bbb91fc534d..5356fbc773a 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1753,7 +1753,7 @@ void Field_medium::sql_type(String &res) const int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { long tmp; - int error= 0, cuted_fields= 0; + int error= 0; char *end; tmp= cs->cset->scan(cs, from, from+len, MY_SEQ_SPACES); @@ -1781,7 +1781,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) #if SIZEOF_LONG > 4 if (unsigned_flag) { - if (tmp > UINT_MAX32) + if ((ulong) tmp > UINT_MAX32) { tmp= UINT_MAX32; error= 1; @@ -4277,27 +4277,17 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) int Field_str::store(double nr) { - bool use_scientific_notation=TRUE; char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; uint length; - if (field_length < 32 && nr > 1) // TODO: negative numbers - { - if (ceiling == 0) - { - static double e[]= {1e1, 1e2, 1e4, 1e8, 1e16 }; - double p= 1; - for (int i= sizeof(e)/sizeof(e[0]), j= 1<>= 1 ) - { - if (field_length & j) - p*= e[i]; - } - ceiling= p-1; - } - use_scientific_notation= (ceiling < nr); - } - length= (uint)sprintf(buff, "%-.*g", - use_scientific_notation ? max(0,(int)field_length-5) : field_length, - nr); + bool use_scientific_notation= TRUE; + use_scientific_notation= TRUE; +if (field_length < 32 && fabs(nr) < log_10[field_length]-1) + use_scientific_notation= FALSE; + length= (uint) my_sprintf(buff, (buff, "%-.*g", + (use_scientific_notation ? + max(0, (int)field_length-5) : + field_length), + nr)); /* +1 below is because "precision" in %g above means the max. number of significant digits, not the output width. @@ -4310,6 +4300,7 @@ int Field_str::store(double nr) return store((const char *)buff, min(length, field_length), charset()); } + int Field_string::store(longlong nr) { char buff[64]; @@ -4403,9 +4394,8 @@ char *Field_string::pack(char *to, const char *from, uint max_length) char *Field_string::pack_key(char *to, const char *from, uint max_length) { - int length=min(field_length,max_length); - uint char_length= (field_charset->mbmaxlen > 1) ? - max_length/field_charset->mbmaxlen : max_length; + uint length= min(field_length,max_length); + uint char_length= max_length/field_charset->mbmaxlen; if (length > char_length) char_length= my_charpos(field_charset, from, from+length, char_length); set_if_smaller(length, char_length); diff --git a/sql/field.h b/sql/field.h index eaf90ddc0ff..9cce7b9541b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -336,14 +336,13 @@ public: class Field_str :public Field { protected: CHARSET_INFO *field_charset; - double ceiling; // for ::store(double nr) public: Field_str(char *ptr_arg,uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, utype unireg_check_arg, const char *field_name_arg, struct st_table *table_arg,CHARSET_INFO *charset) :Field(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, - unireg_check_arg, field_name_arg, table_arg), ceiling(0.0) + unireg_check_arg, field_name_arg, table_arg) { field_charset=charset; if (charset->state & MY_CS_BINSORT) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 5ad4cf92959..bf7813eb9ba 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1732,8 +1732,8 @@ bool Item_func_in::nulls_in_row() static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y) { return cs->coll->strnncollsp(cs, - (unsigned char *) x->ptr(),x->length(), - (unsigned char *) y->ptr(),y->length()); + (uchar *) x->ptr(),x->length(), + (uchar *) y->ptr(),y->length()); } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index ecfeff02cac..fac73a1a759 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -39,7 +39,8 @@ C_MODE_END String my_empty_string("",default_charset_info); -static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, const char *fname) +static void my_coll_agg_error(DTCollation &c1, DTCollation &c2, + const char *fname) { my_error(ER_CANT_AGGREGATE_2COLLATIONS,MYF(0), c1.collation->name,c1.derivation_name(), @@ -62,8 +63,9 @@ double Item_str_func::val() { DBUG_ASSERT(fixed == 1); int err; - String *res; - res=val_str(&str_value); + char buff[64]; + String *res, tmp(buff,sizeof(buff), &my_charset_bin); + res= val_str(&tmp); return res ? my_strntod(res->charset(), (char*) res->ptr(),res->length(), NULL, &err) : 0.0; } @@ -72,8 +74,9 @@ longlong Item_str_func::val_int() { DBUG_ASSERT(fixed == 1); int err; - String *res; - res=val_str(&str_value); + char buff[22]; + String *res, tmp(buff,sizeof(buff), &my_charset_bin); + res= val_str(&tmp); return (res ? my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL, &err) : @@ -986,10 +989,7 @@ String *Item_func_left::val_str(String *str) if (res->length() <= (uint) length || res->length() <= (char_pos= res->charpos(length))) return res; - if (&str_value == res) - str_value.length(char_pos); - else - str_value.set(*res, 0, char_pos); + str_value.set(*res, 0, char_pos); return &str_value; } @@ -2200,7 +2200,8 @@ String *Item_func_conv_charset::val_str(String *str) null_value=1; return 0; } - null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(),conv_charset); + null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(), + conv_charset); return null_value ? 0 : &str_value; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index cbb4cd41046..0ec8baf97bb 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1945,13 +1945,12 @@ void Item_func_group_concat::reset_field() bool Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { + uint i; /* for loop variable */ DBUG_ASSERT(fixed == 0); if (save_args_for_prepared_statement(thd)) return 1; - uint i; /* for loop variable */ - if (!thd->allow_sum_func) { my_error(ER_INVALID_GROUP_FUNC_USE,MYF(0)); @@ -1971,7 +1970,7 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1)) return 1; if (i < arg_count_field) - maybe_null |= args[i]->maybe_null; + maybe_null|= args[i]->maybe_null; } result_field= 0; @@ -2048,7 +2047,8 @@ bool Item_func_group_concat::setup(THD *thd) of a record instead of a pointer of one. */ if (!(table=create_tmp_table(thd, tmp_table_param, all_fields, - (ORDER*) 0, 0, TRUE,select_lex->options | thd->options, + (ORDER*) 0, 0, TRUE, + select_lex->options | thd->options, HA_POS_ERROR,(char *) ""))) DBUG_RETURN(1); table->file->extra(HA_EXTRA_NO_ROWS); diff --git a/sql/protocol.cc b/sql/protocol.cc index 7c4b09ac3e3..da2a285fffc 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -200,7 +200,7 @@ net_printf(THD *thd, uint errcode, ...) 2+SQLSTATE_LENGTH+1 : 2) : 0); #ifndef EMBEDDED_LIBRARY text_pos=(char*) net->buff + head_length + offset + 1; - length=(char*)net->buff_end-text_pos; + length= (uint) ((char*)net->buff_end - text_pos); #else length=sizeof(text_pos)-1; #endif diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index f60897bf62b..fd3d27099ed 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -551,21 +551,19 @@ static ulong get_sort(uint count,...) uint chars= 0; uint wild_pos= 0; /* first wildcard position */ - if (start= str) + if ((start= str)) { for (; *str ; str++) { if (*str == wild_many || *str == wild_one || *str == wild_prefix) { - wild_pos= str - start + 1; + wild_pos= (uint) (str - start) + 1; break; } - else - chars++; + chars= 128; // Marker that chars existed } } - sort= (sort << 8) + (wild_pos ? (wild_pos > 127 ? 127 : wild_pos) : - (chars ? 128 : 0)); + sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars); } va_end(args); return sort; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 6fdc1c2bfc3..4ca8008c518 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -833,7 +833,8 @@ JOIN::optimize() ((group_list && const_tables != tables && (!simple_group || !test_if_skip_sort_order(&join_tab[const_tables], group_list, - unit->select_limit_cnt, 0))) || select_distinct) && + unit->select_limit_cnt, 0))) || + select_distinct) && tmp_table_param.quick_group && !procedure) { need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort @@ -2163,22 +2164,32 @@ add_key_field(KEY_FIELD **key_fields,uint and_level, COND *cond, number. cmp_type() is checked to allow compare of dates to numbers. eq_func is NEVER true when num_values > 1 */ - if (!eq_func || - field->result_type() == STRING_RESULT && - (*value)->result_type() != STRING_RESULT && - field->cmp_type() != (*value)->result_type()) - return; - - /* - We can't use indexes if the effective collation - of the operation differ from the field collation. - */ - if (field->result_type() == STRING_RESULT && - (*value)->result_type() == STRING_RESULT && - field->cmp_type() == STRING_RESULT && - ((Field_str*)field)->charset() != cond->compare_collation()) - return; + if (!eq_func) + return; + if (field->result_type() == STRING_RESULT) + { + if ((*value)->result_type() != STRING_RESULT) + { + if (field->cmp_type() != (*value)->result_type()) + return; + } + else + { + /* + We can't use indexes if the effective collation + of the operation differ from the field collation. + We can also not used index on a text column, as the column may + contain 'x' 'x\t' 'x ' and 'read_next_same' will stop after + 'x' when searching for WHERE col='x ' + */ + if (field->cmp_type() == STRING_RESULT && + (((Field_str*)field)->charset() != cond->compare_collation() || + ((*value)->type() != Item::NULL_ITEM && + (field->flags & BLOB_FLAG) && !field->binary()))) + return; + } + } } } DBUG_ASSERT(num_values == 1); @@ -5564,9 +5575,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param, table->file->info(HA_STATUS_VARIABLE); /* update table->file->records */ new_table.file->start_bulk_insert(table->file->records); #else - /* - HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it explicitly. - */ + /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */ new_table.file->extra(HA_EXTRA_WRITE_CACHE); #endif @@ -7234,9 +7243,9 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit, keys.merge(table->used_keys); /* - We are adding here also the index speified in FORCE INDEX clause, + We are adding here also the index specified in FORCE INDEX clause, if any. - This is to allow users to use index in ORDER BY. + This is to allow users to use index in ORDER BY. */ if (table->force_index) keys.merge(table->keys_in_use_for_query); diff --git a/sql/tztime.cc b/sql/tztime.cc index 757272d332f..610f75f1643 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -2158,20 +2158,21 @@ my_tz_find(const String * name, TABLE_LIST *tz_tables) if (!(result_tz= new (&tz_storage) Time_zone_offset(offset)) || my_hash_insert(&offset_tzs, (const byte *) result_tz)) { + result_tz= 0; sql_print_error("Fatal error: Out of memory " "while setting new time zone"); - result_tz= 0; } } - } else { + } + else + { + result_tz= 0; if ((tmp_tzname= (TZ_NAMES_ENTRY *)hash_search(&tz_names, (const byte *)name->ptr(), name->length()))) result_tz= tmp_tzname->tz; - else if(time_zone_tables_exist) + else if (time_zone_tables_exist) result_tz= tz_load_from_open_tables(name, tz_tables); - else - result_tz= 0; } VOID(pthread_mutex_unlock(&tz_LOCK)); -- cgit v1.2.1 From 82257f94f411b678da753b3ccb7e883621189eb1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Aug 2004 18:22:22 +0200 Subject: after merge sql/item_row.cc: ds20 compat fix --- sql/item_row.cc | 3 ++- sql/log.cc | 38 +++++++++++++++++++------------------- sql/sql_base.cc | 4 ++-- 3 files changed, 23 insertions(+), 22 deletions(-) (limited to 'sql') diff --git a/sql/item_row.cc b/sql/item_row.cc index c7e4bc0acf4..f6623e80734 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -66,7 +66,8 @@ bool Item_row::fix_fields(THD *thd, TABLE_LIST *tabl, Item **ref) // we can't assign 'item' before, because fix_fields() can change arg Item *item= *arg; used_tables_cache |= item->used_tables(); - if (const_item_cache&= item->const_item() && !with_null) + const_item_cache&= item->const_item() && !with_null; + if (const_item_cache) { if (item->cols() > 1) with_null|= item->null_inside(); diff --git a/sql/log.cc b/sql/log.cc index 870242eac31..f4ec5d9c731 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1,15 +1,15 @@ /* Copyright (C) 2000-2003 MySQL AB - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ @@ -43,31 +43,31 @@ static bool test_if_number(const char *str, #ifdef __NT__ static int eventSource = 0; -void setupWindowsEventSource() +void setupWindowsEventSource() { if (eventSource) return; eventSource = 1; - HKEY hRegKey = NULL; + HKEY hRegKey = NULL; DWORD dwError = 0; TCHAR szPath[ MAX_PATH ]; - + // Create the event source registry key - dwError = RegCreateKey(HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\MySQL", + dwError = RegCreateKey(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\MySQL", &hRegKey); // Name of the PE module that contains the message resource GetModuleFileName(NULL, szPath, MAX_PATH); // Register EventMessageFile - dwError = RegSetValueEx(hRegKey, "EventMessageFile", 0, REG_EXPAND_SZ, - (PBYTE) szPath, strlen(szPath)+1); - + dwError = RegSetValueEx(hRegKey, "EventMessageFile", 0, REG_EXPAND_SZ, + (PBYTE) szPath, strlen(szPath)+1); + // Register supported event types - DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; - dwError = RegSetValueEx(hRegKey, "TypesSupported", 0, REG_DWORD, + DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; + dwError = RegSetValueEx(hRegKey, "TypesSupported", 0, REG_DWORD, (LPBYTE) &dwTypes, sizeof dwTypes); RegCloseKey(hRegKey); @@ -2200,6 +2200,8 @@ void MYSQL_LOG::report_pos_in_innodb() my_b_tell(&log_file)); } #endif + DBUG_VOID_RETURN; +} #ifdef __NT__ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, int buffLen) @@ -2241,7 +2243,6 @@ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, int buffLen) if (buffptr != buff) delete[] buffptr; - DBUG_VOID_RETURN; } #endif @@ -2253,7 +2254,7 @@ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, int buffLen) vprint_msg_to_log() event_type Type of event to write (Error, Warning, or Info) format Printf style format of message - args va_list list of arguments for the message + args va_list list of arguments for the message NOTE @@ -2267,7 +2268,6 @@ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, int buffLen) void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) { char buff[1024]; - DBUG_ENTER("vprint_msg_to_log"); my_vsnprintf(buff, sizeof(buff)-5, format, args); @@ -2286,7 +2286,7 @@ void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) } -void sql_print_error(const char *format, ...) +void sql_print_error(const char *format, ...) { DBUG_ENTER("sql_print_error"); @@ -2298,7 +2298,7 @@ void sql_print_error(const char *format, ...) DBUG_VOID_RETURN; } -void sql_print_warning(const char *format, ...) +void sql_print_warning(const char *format, ...) { DBUG_ENTER("sql_print_warning"); @@ -2310,7 +2310,7 @@ void sql_print_warning(const char *format, ...) DBUG_VOID_RETURN; } -void sql_print_information(const char *format, ...) +void sql_print_information(const char *format, ...) { DBUG_ENTER("sql_print_information"); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 255f04d853b..ea7b4521247 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2449,8 +2449,8 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, if (db_name && lower_case_table_names) { /* convert database to lower case for comparison */ - strmake( name_buff, db_name, sizeof(name_buff)-1 ); - casedn_str( name_buff ); + strmake(name_buff, db_name, sizeof(name_buff)-1); + my_casedn_str(system_charset_info,name_buff); db_name = name_buff; } -- cgit v1.2.1 From dd714c9a1b6f7e98e4e9b3397a4b84144fb4e181 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Aug 2004 10:54:57 +0500 Subject: win1251.conf: Wrong UPPER/LOWER translation for Cyrillic letter tse was fixed. bug#5110 sql/share/charsets/win1251.conf: Wrong UPPER/LOWER translation for Cyrillic letter tse was fixed. bug#5110 BitKeeper/etc/logging_ok: Logging to logging@openlogging.org accepted --- sql/share/charsets/win1251.conf | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/share/charsets/win1251.conf b/sql/share/charsets/win1251.conf index a5ccc3190ad..e05568323b4 100644 --- a/sql/share/charsets/win1251.conf +++ b/sql/share/charsets/win1251.conf @@ -41,7 +41,7 @@ A0 A1 A2 A3 A4 A5 A6 A7 B8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF - F0 F1 F2 F3 F4 F5 F5 F7 F8 F9 FA FB FC FD FE FF + F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF @@ -59,7 +59,7 @@ A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 B7 A8 B9 BA BB BC BD BE BF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF - D0 D1 D2 D3 D4 D5 D5 D7 D8 D9 DA DB DC DD DE DF + D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF -- cgit v1.2.1 From 14f96b2f6059471cb2f1addb94ecfdcdb09bf071 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Aug 2004 12:09:28 +0500 Subject: table.cc: Bug #4558 Escape handling error for ENUM values in SJIS encoding sql/table.cc: Bug #4558 Escape handling error for ENUM values in SJIS encoding --- sql/table.cc | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/table.cc b/sql/table.cc index 7e6338a3f3f..898ed4bca3d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -993,8 +993,26 @@ ulong next_io_size(register ulong pos) void append_unescaped(String *res,const char *pos) { - for (; *pos ; pos++) +#ifdef USE_MB + const char *end= pos + strlen(pos); +#endif + + for (; *pos ; ) { +#ifdef USE_MB + /* + Note, there is no needs to propagate this code into 4.1. + */ + uint mblen; + if (use_mb(default_charset_info) && + (mblen= my_ismbchar(default_charset_info, pos, end))) + { + res->append(pos, mblen); + pos+= mblen; + continue; + } +#endif + switch (*pos) { case 0: /* Must be escaped for 'mysql' */ res->append('\\'); @@ -1020,6 +1038,7 @@ void append_unescaped(String *res,const char *pos) res->append(*pos); break; } + pos++; } } -- cgit v1.2.1 From bf268802916d85f7fa4cb832a409e20ab404effa Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Aug 2004 16:43:01 +0500 Subject: A fix (Bug #5232: CREATE TABLE ... SELECT can deadlock itself). --- sql/sql_parse.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'sql') diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 14fc748c288..e95c52f1e48 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1655,6 +1655,19 @@ mysql_execute_command(void) net_printf(&thd->net,ER_INSERT_TABLE_USED,tables->real_name); DBUG_VOID_RETURN; } + if (lex->create_info.used_fields & HA_CREATE_USED_UNION) + { + TABLE_LIST *tab; + for (tab= tables; tab; tab= tab->next) + { + if (check_dup(tables->db, tab->real_name, + (TABLE_LIST*)lex->create_info.merge_list.first)) + { + net_printf(&thd->net, ER_INSERT_TABLE_USED, tab->real_name); + DBUG_VOID_RETURN; + } + } + } if (tables->next) { TABLE_LIST *table; -- cgit v1.2.1 From f71662695d424aad8f0de3af3044cabc7da72c88 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Aug 2004 20:48:19 +0500 Subject: Bug#2451 ALTER doesn't result in an error on CHARACTER SET and COLLATION conflict --- 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_yacc.yy | 67 +++++++++++++++++++++++++++++---------- 24 files changed, 73 insertions(+), 17 deletions(-) (limited to 'sql') diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index ee75210d4fe..9769ec1a55d 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -314,3 +314,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 408f86b0445..31715354101 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -308,3 +308,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 95af6aaa01f..06e47e006f5 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -316,3 +316,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index 5ad23b92a5a..a2e74460380 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 36e0b8409e9..df29f08e752 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -310,3 +310,4 @@ character-set=latin7 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 3bd6835908e..f0435278440 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index bf5a36a887a..af11e09f2f6 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -317,3 +317,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 9703bad11a1..7c921beba75 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -305,3 +305,4 @@ character-set=greek "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 1f71086ff69..e961b72a38e 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 21158fcb567..02c719fd7c0 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 3a6dd644d8b..9674f690183 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -307,3 +307,4 @@ character-set=ujis "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 356f0a63540..417d9976b7c 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -305,3 +305,4 @@ character-set=euckr "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index b5564cb264e..ae0b307439d 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index fcea45b06ac..246333af497 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 2a18e4de020..417757b2aea 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -309,3 +309,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 6ba0fbca014..344860280cb 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -306,3 +306,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 50b2b36c959..6b64d103e61 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -309,3 +309,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index d8641d1dd14..642b792a24f 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -307,3 +307,4 @@ character-set=koi8r "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index a8cde5a56b1..8c8bc6e9729 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -311,3 +311,4 @@ character-set=cp1250 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 42ef7f62076..23814b2cbc2 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -313,3 +313,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index b82712be350..113157858ad 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -307,3 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 78620b28a2f..8b43ea8ed0e 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -305,3 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 6d07eb1a656..4c762bf5313 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -310,3 +310,4 @@ character-set=koi8u "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" +"Conflicting declarations: '%s' and '%s'" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4eca7359023..1c057e03a11 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1049,7 +1049,10 @@ create: lex->col_list.empty(); } | CREATE DATABASE opt_if_not_exists ident - { Lex->create_info.default_table_charset=NULL; } + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + } opt_create_database_options { LEX *lex=Lex; @@ -1136,11 +1139,8 @@ create_database_options: | create_database_options create_database_option {}; create_database_option: - opt_default COLLATE_SYM collation_name_or_default - { Lex->create_info.default_table_charset=$3; } - | opt_default charset charset_name_or_default - { Lex->create_info.default_table_charset=$3; } - ; + default_collation {} + | default_charset {}; opt_table_options: /* empty */ { $$= 0; } @@ -1200,21 +1200,49 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } - | opt_default charset opt_equal charset_name_or_default - { - Lex->create_info.default_table_charset= $4; - Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; - } - | opt_default COLLATE_SYM opt_equal collation_name_or_default - { - Lex->create_info.default_table_charset= $4; - Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; - } + | default_charset + | default_collation | INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; } | INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; }; +default_charset: + opt_default charset opt_equal charset_name_or_default + { + HA_CREATE_INFO *cinfo= &Lex->create_info; + if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !my_charset_same(cinfo->default_table_charset,$4)) + { + char cs1[32]; + char cs2[32]; + my_snprintf(cs1, sizeof(cs1), "CHARACTER SET %s", + cinfo->default_table_charset->csname); + my_snprintf(cs2, sizeof(cs2), "CHARACTER SET %s", $4->csname); + net_printf(YYTHD, ER_CONFLICTING_DECLARATIONS, cs1, cs2); + YYABORT; + } + Lex->create_info.default_table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + }; + +default_collation: + opt_default COLLATE_SYM opt_equal collation_name_or_default + { + HA_CREATE_INFO *cinfo= &Lex->create_info; + if ((cinfo->used_fields & HA_CREATE_USED_DEFAULT_CHARSET) && + cinfo->default_table_charset && $4 && + !my_charset_same(cinfo->default_table_charset,$4)) + { + net_printf(YYTHD,ER_COLLATION_CHARSET_MISMATCH, + $4->name, cinfo->default_table_charset->csname); + YYABORT; + } + Lex->create_info.default_table_charset= $4; + Lex->create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET; + }; + storage_engines: ident_or_text { @@ -1824,7 +1852,12 @@ alter: } alter_list {} - | ALTER DATABASE ident opt_create_database_options + | ALTER DATABASE ident + { + Lex->create_info.default_table_charset= NULL; + Lex->create_info.used_fields= 0; + } + opt_create_database_options { LEX *lex=Lex; lex->sql_command=SQLCOM_ALTER_DB; -- cgit v1.2.1 From 434d385ac17f2bfb553c112b5e19491d0bb0f876 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Aug 2004 21:17:29 +0500 Subject: Compile all charset conversion tables if --with-extra-charsets=all or --with-extra-charsets=complex is given. --- sql/convert.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sql') diff --git a/sql/convert.cc b/sql/convert.cc index e4ae13d1e07..f84c80a6121 100644 --- a/sql/convert.cc +++ b/sql/convert.cc @@ -20,6 +20,9 @@ ** Some of the tables are hidden behind IFDEF to reduce some space. ** One can enable them by removing the // characters from the next comment ** One must also give a name to each mapping that one wants to use... +** +** All tables are activated if --with-extra-charsets=all or +** --with-extra-charsets=complex was given to configure. */ /* #define DEFINE_ALL_CHARACTER_SETS */ -- cgit v1.2.1 From db15b91915bb57914e11f226c0130467dd4dcfdd Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Aug 2004 00:49:54 +0300 Subject: Code style fixes. Initialize LOG_error_log before get_options to not use an uninitalized mutex in case of an error from handle_options() mysql-test/r/lowercase_table.result: Changed foo database -> mysqltest More test cases mysql-test/t/lowercase_table.test: Changed foo database -> mysqltest More test cases mysys/my_getopt.c: Fix new code to use MySQL indentation style sql/log.cc: Change to use MySQL indentation style and naming conventions Remove usage of strlen() and strcat() sql/mysqld.cc: Initialize LOG_error_log before get_options to not use an uninitalized mutex in case of an error from handle_options() sql/sql_base.cc: Added comment sql/table.cc: Added #if MYSQL_VERSION_ID < 40100 to ensure code is merged correctly --- sql/log.cc | 171 +++++++++++++++++++++++++++++--------------------------- sql/mysqld.cc | 20 ++++--- sql/sql_base.cc | 13 +++-- sql/table.cc | 5 +- 4 files changed, 111 insertions(+), 98 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index db7b80eb4f7..e9dd2e4a69b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -43,37 +43,41 @@ static bool test_if_number(const char *str, #ifdef __NT__ static int eventSource = 0; -void setupWindowsEventSource() -{ - if (eventSource) return; - eventSource = 1; - HKEY hRegKey = NULL; - DWORD dwError = 0; - TCHAR szPath[ MAX_PATH ]; +void setup_windows_event_source() +{ + HKEY hRegKey= NULL; + DWORD dwError= 0; + TCHAR szPath[MAX_PATH]; + DWORD dwTypes; - // Create the event source registry key - dwError = RegCreateKey( HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\MySQL", - &hRegKey ); + if (eventSource) // Ensure that we are only called once + return; + eventSource= 1; - // Name of the PE module that contains the message resource - GetModuleFileName( NULL, szPath, MAX_PATH ); + // Create the event source registry key + dwError= RegCreateKey(HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\MySQL", + &hRegKey); - // Register EventMessageFile - dwError = RegSetValueEx( hRegKey, "EventMessageFile", 0, REG_EXPAND_SZ, - (PBYTE) szPath, strlen(szPath)+1 ); + /* Name of the PE module that contains the message resource */ + GetModuleFileName(NULL, szPath, MAX_PATH); + + / Register EventMessageFile */ + dwError = RegSetValueEx(hRegKey, "EventMessageFile", 0, REG_EXPAND_SZ, + (PBYTE) szPath, strlen(szPath)+1); - // Register supported event types - DWORD dwTypes = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; - dwError = RegSetValueEx( hRegKey, "TypesSupported", 0, REG_DWORD, - (LPBYTE) &dwTypes, sizeof dwTypes ); + /* Register supported event types */ + dwTypes= (EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | + EVENTLOG_INFORMATION_TYPE); + dwError= RegSetValueEx(hRegKey, "TypesSupported", 0, REG_DWORD, + (LPBYTE) &dwTypes, sizeof dwTypes); - RegCloseKey( hRegKey ); + RegCloseKey(hRegKey); } -#endif +#endif /* __NT__ */ /**************************************************************************** @@ -1732,33 +1736,33 @@ static bool test_if_number(register const char *str, } /* test_if_number */ -void print_buffer_to_file( enum loglevel level, const char *buffer ) +void print_buffer_to_file(enum loglevel level, const char *buffer) { time_t skr; struct tm tm_tmp; struct tm *start; - - DBUG_ENTER("print_buffer_to_log"); + DBUG_ENTER("print_buffer_to_file"); + DBUG_PRINT("enter",("buffer: %s", buffer)); VOID(pthread_mutex_lock(&LOCK_error_log)); skr=time(NULL); localtime_r(&skr, &tm_tmp); start=&tm_tmp; - fprintf( stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", start->tm_year % 100, start->tm_mon+1, start->tm_mday, start->tm_hour, start->tm_min, start->tm_sec, - level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? "WARNING" : "INFORMATION", - buffer ); + (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? + "WARNING" : "INFORMATION"), + buffer); fflush(stderr); VOID(pthread_mutex_unlock(&LOCK_error_log)); - DBUG_VOID_RETURN; } @@ -1772,6 +1776,7 @@ void sql_perror(const char *message) #endif } + bool flush_error_log() { bool result=0; @@ -1820,122 +1825,124 @@ bool flush_error_log() #ifdef __NT__ -void print_buffer_to_nt_eventlog( enum loglevel level, char *buff, int buffLen ) +void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, + uint length, int buffLen) { HANDLE event; char *buffptr; LPCSTR *buffmsgptr; + DBUG_ENTER("print_buffer_to_nt_eventlog"); - DBUG_ENTER( "print_buffer_to_nt_eventlog" ); - - buffptr = buff; - if (strlen(buff) > (uint)(buffLen-4)) + buffptr= buff; + if (length > (uint)(buffLen-4)) { - char *newBuff = new char[ strlen(buff) + 4 ]; - strcpy( newBuff, buff ); - buffptr = newBuff; + char *newBuff= new char[length + 4]; + strcpy(newBuff, buff); + buffptr= newBuff; } - strcat( buffptr, "\r\n\r\n" ); - buffmsgptr = (LPCSTR*)&buffptr; + strmov(buffptr+length, "\r\n\r\n"); + buffmsgptr= (LPCSTR*) &buffptr; // Keep windows happy - setupWindowsEventSource(); - if (event = RegisterEventSource(NULL,"MySQL")) + setup_windows_event_source(); + if ((event= RegisterEventSource(NULL,"MySQL"))) { - switch (level){ + switch (level) { case ERROR_LEVEL: - ReportEvent(event, EVENTLOG_ERROR_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + ReportEvent(event, EVENTLOG_ERROR_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, + buffmsgptr, NULL); break; case WARNING_LEVEL: - ReportEvent(event, EVENTLOG_WARNING_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + ReportEvent(event, EVENTLOG_WARNING_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, + buffmsgptr, NULL); break; case INFORMATION_LEVEL: - ReportEvent(event, EVENTLOG_INFORMATION_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, buffmsgptr, NULL); + ReportEvent(event, EVENTLOG_INFORMATION_TYPE, 0, MSG_DEFAULT, NULL, 1, + 0, buffmsgptr, NULL); break; } DeregisterEventSource(event); } - // if we created a string buffer, then delete it - if ( buffptr != buff ) + /* if we created a string buffer, then delete it */ + if (buffptr != buff) delete[] buffptr; - DBUG_VOID_RETURN; } -#endif +#endif /* __NT__ */ + /* - Prints a printf style message to the error log and, under NT, to the Windows event log. + Prints a printf style message to the error log and, under NT, to the + Windows event log. SYNOPSIS vprint_msg_to_log() - event_type Type of event to write (Error, Warning, or Info) - format Printf style format of message - args va_list list of arguments for the message + event_type Type of event to write (Error, Warning, or Info) + format Printf style format of message + args va_list list of arguments for the message NOTE IMPLEMENTATION - This function prints the message into a buffer and then sends that buffer to other - functions to write that message to other logging sources. + This function prints the message into a buffer and then sends that buffer + to other functions to write that message to other logging sources. RETURN VALUES void */ + void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) { char buff[1024]; - + uint length; DBUG_ENTER("vprint_msg_to_log"); - my_vsnprintf( buff, sizeof(buff)-5, format, args ); - - print_buffer_to_file( level, buff ); - -#ifndef DBUG_OFF - DBUG_PRINT("error",("%s",buff)); -#endif + length= my_vsnprintf(buff, sizeof(buff)-5, format, args); + print_buffer_to_file(level, buff); #ifdef __NT__ - print_buffer_to_nt_eventlog( level, buff, sizeof(buff) ); + print_buffer_to_nt_eventlog(level, buff, length, sizeof(buff)); #endif DBUG_VOID_RETURN; } -void sql_print_error( const char *format, ... ) +void sql_print_error(const char *format, ...) { - DBUG_ENTER( "sql_print_error" ); - va_list args; - va_start( args, format ); - vprint_msg_to_log( ERROR_LEVEL, format, args ); - va_end( args ); + DBUG_ENTER("sql_print_error"); + + va_start(args, format); + vprint_msg_to_log(ERROR_LEVEL, format, args); + va_end(args); DBUG_VOID_RETURN; } -void sql_print_warning( const char *format, ... ) -{ - DBUG_ENTER( "sql_print_warning" ); +void sql_print_warning(const char *format, ...) +{ va_list args; - va_start( args, format ); - vprint_msg_to_log( WARNING_LEVEL, format, args ); - va_end( args ); + DBUG_ENTER("sql_print_warning"); + + va_start(args, format); + vprint_msg_to_log(WARNING_LEVEL, format, args); + va_end(args); DBUG_VOID_RETURN; } -void sql_print_information( const char *format, ... ) -{ - DBUG_ENTER( "sql_print_information" ); +void sql_print_information(const char *format, ...) +{ va_list args; - va_start( args, format ); - vprint_msg_to_log( INFORMATION_LEVEL, format, args ); - va_end( args ); + DBUG_ENTER("sql_print_information"); + + va_start(args, format); + vprint_msg_to_log(INFORMATION_LEVEL, format, args); + va_end(args); DBUG_VOID_RETURN; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8b10627b323..1068c5ec9a1 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2247,6 +2247,10 @@ int main(int argc, char **argv) if (!opt_mysql_tmpdir || !opt_mysql_tmpdir[0]) opt_mysql_tmpdir=(char*) P_tmpdir; /* purecov: inspected */ + /* needed by get_options */ + + (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST); + set_options(); get_options(argc,argv); set_server_version(); @@ -2263,7 +2267,6 @@ int main(int argc, char **argv) (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW); @@ -5100,21 +5103,24 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } return 0; } - /* Initiates DEBUG - but no debugging here ! */ -void option_error_reporter( enum loglevel level, const char *format, ... ) + +void option_error_reporter(enum loglevel level, const char *format, ...) { va_list args; - va_start( args, format ); - vprint_msg_to_log( level, format, args ); - va_end( args ); + va_start(args, format); + vprint_msg_to_log(level, format, args); + va_end(args); } + /* Initiates DEBUG - but no debugging here ! */ + static void get_options(int argc,char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, option_error_reporter ))) + if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, + option_error_reporter))) exit(ho_error); #if defined(HAVE_BROKEN_REALPATH) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 26ce394ec37..8fd7273fd78 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2066,13 +2066,16 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, uint found; DBUG_ENTER("insert_fields"); - if (db_name && lower_case_table_names) { - /* convert database to lower case for comparison */ - strmake( name_buff, db_name, sizeof(name_buff)-1 ); - casedn_str( name_buff ); - db_name = name_buff; + /* + convert database to lower case for comparison + We can't do this in Item_field as this would change the + 'name' of the item which may be used in the select list + */ + strmake(name_buff, db_name, sizeof(name_buff)-1); + casedn_str(name_buff); + db_name= name_buff; } diff --git a/sql/table.cc b/sql/table.cc index 898ed4bca3d..573fa11a4c4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -999,10 +999,7 @@ void append_unescaped(String *res,const char *pos) for (; *pos ; ) { -#ifdef USE_MB - /* - Note, there is no needs to propagate this code into 4.1. - */ +#if defined(USE_MB) && MYSQL_VERSION_ID < 40100 uint mblen; if (use_mb(default_charset_info) && (mblen= my_ismbchar(default_charset_info, pos, end))) -- cgit v1.2.1 From ebf4ce0501486f5eba7b69fe77fb1c49bbd22763 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 28 Aug 2004 13:07:47 -0500 Subject: Minor edits to error messsage. --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 74f130e6784..11397736555 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2687,7 +2687,7 @@ static void handle_connections_methods() (!have_tcpip || opt_disable_networking) && !opt_enable_shared_memory) { - sql_print_error("TCP/IP,--shared-memory or --named-pipe should be configured on NT OS"); + sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS"); unireg_abort(1); // Will not return } #endif -- cgit v1.2.1 From 4014c093e2ababc8436f83ef2b3f4c946a13795d Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Aug 2004 14:13:51 +0200 Subject: Fix for BUG#4500 "set character set replicates incorrectly" We must not reset the charset in slave after each statement, otherwise the SET CHARACTER SET is cancelled immediately. Instead, we write a SET CHARACTER SET DEFAULT to the master's binlog when needed (like we already do for SET FOREIGN_KEY_CHECKS); such writing is not necessary in 4.1 (in 4.1 the bug does not exist, as the SET ONE_SHOT syntax is used). I have written a test and it works, but I'm not pushing the test as it requires building with all charsets. I have noticed differences between what is inserted in the master's table in 4.0 and 4.1, and alerted Bar. sql/log.cc: When SET CHARACTER SET has been used, we must reset the charset after the writing the statement, in the binlog. In 4.1, this resetting is already achieved by the SET ONE_SHOT syntax. sql/log_event.cc: In slave, we must not simply reset the charset after each statement: if we do this, the charset gets immediately after executing the SET CHARACTER SET! (BUG#4500). --- sql/log.cc | 22 +++++++++++++++++----- sql/log_event.cc | 2 -- 2 files changed, 17 insertions(+), 7 deletions(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index db7b80eb4f7..9927bfe8d17 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -1208,12 +1208,24 @@ bool MYSQL_LOG::write(Log_event* event_info) /* Write log events to reset the 'run environment' of the SQL command */ - if (thd && thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) + if (thd) { - Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0); - e.set_log_pos(this); - if (e.write(file)) - goto err; + if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS) + { + Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0); + e.set_log_pos(this); + if (e.write(file)) + goto err; + } +#if MYSQL_VERSION_ID < 40100 + if (thd->variables.convert_set) + { + Query_log_event e(thd, "SET CHARACTER SET DEFAULT", 25, 0); + e.set_log_pos(this); + if (e.write(file)) + goto err; + } +#endif } /* diff --git a/sql/log_event.cc b/sql/log_event.cc index 3e1544adf14..5526795c9d1 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1932,8 +1932,6 @@ end: thd->query= 0; // just to be sure thd->query_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); - // assume no convert for next query unless set explictly - thd->variables.convert_set = 0; close_thread_tables(thd); free_root(&thd->mem_root,MYF(MY_KEEP_PREALLOC)); return (thd->query_error ? thd->query_error : Log_event::exec_event(rli)); -- cgit v1.2.1 From 02d3c022814a524a7af8cb2abe0573bb1613ff5d Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Aug 2004 19:44:28 +0400 Subject: Fix for BUG#5242: Made SQL Syntax Prepared Statement names case-insensitive. mysql-test/r/ps.result: Testcase for BUG#5242 mysql-test/t/ps.test: Testcase for BUG#5242 --- sql/sql_class.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 26e2cebb909..c7d8e81d11b 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1503,7 +1503,7 @@ Statement_map::Statement_map() : hash_init(&st_hash, default_charset_info, START_STMT_HASH_SIZE, 0, 0, get_statement_id_as_hash_key, delete_statement_as_hash_key, MYF(0)); - hash_init(&names_hash, &my_charset_bin, START_NAME_HASH_SIZE, 0, 0, + hash_init(&names_hash, system_charset_info, START_NAME_HASH_SIZE, 0, 0, (hash_get_key) get_stmt_name_hash_key, NULL,MYF(0)); } -- cgit v1.2.1 From f45c482aa9a546ca6ad0f258aa0a8358522f5c2f Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 29 Aug 2004 23:14:46 +0300 Subject: NOT elimination moved in parsing (suggested by Monty) sql/item_cmpfunc.cc: NOT elimination moved in parsing (we do not need fix fields in it and PS processing) sql/item_cmpfunc.h: NOT elimination moved in parsing (we do not need fix fields in it and PS processing) sql/sql_select.cc: NOT elimination moved in parsing (we do not need fix fields in it and PS processing) sql/sql_yacc.yy: NOT elimination moved in parsing --- sql/item_cmpfunc.cc | 33 --------------------------------- sql/item_cmpfunc.h | 2 +- sql/sql_select.cc | 13 ------------- sql/sql_yacc.yy | 12 ++++++++++-- 4 files changed, 11 insertions(+), 49 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index bf7813eb9ba..de37e858bac 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2030,15 +2030,6 @@ void Item_cond::neg_arguments(THD *thd) { if (!(new_item= new Item_func_not(item))) return; // Fatal OEM error - /* - We can use 0 as tables list because Item_func_not do not use it - on fix_fields and its arguments are already fixed. - - We do not check results of fix_fields, because there are not way - to return error in this functions interface, thd->net.report_error - will be checked on upper level call. - */ - new_item->fix_fields(thd, 0, &new_item); } VOID(li.replace(new_item)); } @@ -2734,18 +2725,6 @@ Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */ Item *Item_bool_rowready_func2::neg_transformer(THD *thd) { Item *item= negated_item(); - if (item) - { - /* - We can use 0 as tables list because Item_func* family do not use it - on fix_fields and its arguments are already fixed. - - We do not check results of fix_fields, because there are not way - to return error in this functions interface, thd->net.report_error - will be checked on upper level call. - */ - item->fix_fields(thd, 0, &item); - } return item; } @@ -2754,9 +2733,6 @@ Item *Item_bool_rowready_func2::neg_transformer(THD *thd) Item *Item_func_isnull::neg_transformer(THD *thd) { Item *item= new Item_func_isnotnull(args[0]); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } @@ -2765,9 +2741,6 @@ Item *Item_func_isnull::neg_transformer(THD *thd) Item *Item_func_isnotnull::neg_transformer(THD *thd) { Item *item= new Item_func_isnull(args[0]); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } @@ -2777,9 +2750,6 @@ Item *Item_cond_and::neg_transformer(THD *thd) /* NOT(a AND b AND ...) -> */ { neg_arguments(thd); Item *item= new Item_cond_or(list); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } @@ -2789,9 +2759,6 @@ Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */ { neg_arguments(thd); Item *item= new Item_cond_and(list); - // see comment before fix_fields in Item_bool_rowready_func2::neg_transformer - if (item) - item->fix_fields(thd, 0, &item); return item; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 4f2dcb6a412..c3551b35d63 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -274,7 +274,7 @@ public: enum Functype rev_functype() const { return EQUAL_FUNC; } cond_result eq_cmp_result() const { return COND_TRUE; } const char *func_name() const { return "<=>"; } - Item* neg_transformer(THD *thd) { return 0; } + Item *neg_transformer(THD *thd) { return 0; } }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4ca8008c518..701d2597d3d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4401,19 +4401,6 @@ optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) if (conds) { DBUG_EXECUTE("where", print_where(conds, "original");); - /* Eliminate NOT operators; in case of PS/SP do it once */ - if (thd->current_arena->is_first_stmt_execute()) - { - Item_arena *arena= thd->current_arena, backup; - thd->set_n_backup_item_arena(arena, &backup); - conds= eliminate_not_funcs(thd, conds); - select->prep_where= conds->copy_andor_structure(thd); - thd->restore_backup_item_arena(arena, &backup); - } - else - conds= eliminate_not_funcs(thd, conds); - DBUG_EXECUTE("where", print_where(conds, "after negation elimination");); - /* change field = field to field = const for each found field = const */ propagate_cond_constants((I_List *) 0, conds, conds); /* diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1c057e03a11..afb55463ad1 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2755,8 +2755,16 @@ simple_expr: | '+' expr %prec NEG { $$= $2; } | '-' expr %prec NEG { $$= new Item_func_neg($2); } | '~' expr %prec NEG { $$= new Item_func_bit_neg($2); } - | NOT expr %prec NEG { $$= new Item_func_not($2); } - | '!' expr %prec NEG { $$= new Item_func_not($2); } + | NOT expr %prec NEG + { + if (($$= $2->neg_transformer(YYTHD)) == 0) + $$= new Item_func_not($2); + } + | '!' expr %prec NEG + { + if (($$= $2->neg_transformer(YYTHD)) == 0) + $$= new Item_func_not($2); + } | '(' expr ')' { $$= $2; } | '(' expr ',' expr_list ')' { -- cgit v1.2.1 From 877503f5af17808a36c44a84566f6fe9ab55bce3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Aug 2004 00:50:39 +0200 Subject: log.cc: Fixed missing * in comment in setup_windows_event_source sql/log.cc: Fixed missing * in comment in setup_windows_event_source --- sql/log.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/log.cc b/sql/log.cc index aa45e2f77ee..55ef2e72960 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -63,7 +63,7 @@ void setup_windows_event_source() /* Name of the PE module that contains the message resource */ GetModuleFileName(NULL, szPath, MAX_PATH); - / Register EventMessageFile */ + /* Register EventMessageFile */ dwError = RegSetValueEx(hRegKey, "EventMessageFile", 0, REG_EXPAND_SZ, (PBYTE) szPath, strlen(szPath)+1); -- cgit v1.2.1 From d8f416a26c1c69b1a1a7130b0d31a7e92b825408 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Aug 2004 08:37:36 +0200 Subject: bug in my_strnncoll_utf8 (and friends) fixed cleanups better, charset-dependent, ft_max_len_for_sort value myisam/ftdefs.h: better ft_max_len_for_sort value myisam/mi_check.c: better, charset-dependent, ft_max_len_for_sort value myisam/myisamchk.c: unused value from enum removed myisam/sort.c: cleanup sql/mysql_priv.h: cleanup sql/mysqld.cc: cleanup sql/sql_acl.cc: cleanup sql/tztime.cc: cleanup strings/ctype-utf8.c: bug in my_strnncoll_utf8 (and friends) fixed --- sql/mysql_priv.h | 8 +++--- sql/mysqld.cc | 80 ++++++++++++++++++++++++++++---------------------------- sql/sql_acl.cc | 6 ++--- sql/tztime.cc | 26 +++++++++--------- 4 files changed, 59 insertions(+), 61 deletions(-) (limited to 'sql') diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1949ecf26dc..dcc39f30c69 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -783,10 +783,10 @@ int key_cmp(KEY_PART_INFO *key_part, const byte *key, uint key_length); bool init_errmessage(void); void sql_perror(const char *message); -void vprint_msg_to_log( enum loglevel level, const char *format, va_list args ); -void sql_print_error( const char *format, ... ); -void sql_print_warning( const char *format, ...); -void sql_print_information( const char *format, ...); +void vprint_msg_to_log(enum loglevel level, const char *format, va_list args); +void sql_print_error(const char *format, ...); +void sql_print_warning(const char *format, ...); +void sql_print_information(const char *format, ...); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 74f130e6784..a0f78396666 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -762,7 +762,7 @@ void kill_mysql(void) abort_loop=1; if (pthread_create(&tmp,&connection_attrib, kill_server_thread, (void*) 0)) - sql_print_error("Error: Can't create thread to kill server"); + sql_print_error("Can't create thread to kill server"); } #endif DBUG_VOID_RETURN; @@ -791,7 +791,7 @@ static void __cdecl kill_server(int sig_ptr) abort_loop=1; // This should be set signal(sig,SIG_IGN); if (sig == MYSQL_KILL_SIGNAL || sig == 0) - sql_print_error(ER(ER_NORMAL_SHUTDOWN),my_progname); + sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname); else sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */ @@ -806,7 +806,7 @@ static void __cdecl kill_server(int sig_ptr) #ifdef __NETWARE__ pthread_join(select_thread, NULL); // wait for main thread #endif /* __NETWARE__ */ - + pthread_exit(0); /* purecov: deadcode */ #endif /* EMBEDDED_LIBRARY */ @@ -834,7 +834,7 @@ extern "C" sig_handler print_signal_warning(int sig) if (!DBUG_IN_USE) { if (global_system_variables.log_warnings) - sql_print_error("Warning: Got signal %d from thread %d", + sql_print_warning("Got signal %d from thread %d", sig,my_thread_id()); } #ifdef DONT_REMEMBER_SIGNAL @@ -961,7 +961,7 @@ void clean_up(bool print_message) #endif if (print_message && errmesg) - sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname); + sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname); #if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist @@ -1062,8 +1062,8 @@ static void set_user(const char *user) struct passwd *user_info= getpwnam(user); if ((!user_info || user_id != user_info->pw_uid) && global_system_variables.log_warnings) - fprintf(stderr, - "Warning: One can only use the --user switch if running as root\n"); + sql_print_warning( + "One can only use the --user switch if running as root\n"); } return; } @@ -1183,7 +1183,7 @@ static void server_init(void) if (listen(ip_sock,(int) back_log) < 0) { sql_perror("Can't start server: listen() on TCP/IP port"); - sql_print_error("Error: listen() on TCP/IP failed with error %d", + sql_print_error("listen() on TCP/IP failed with error %d", socket_errno); unireg_abort(1); } @@ -1278,7 +1278,7 @@ static void server_init(void) (void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */ #endif if (listen(unix_sock,(int) back_log) < 0) - sql_print_error("Warning: listen() on Unix socket failed with error %d", + sql_print_warning("listen() on Unix socket failed with error %d", socket_errno); } #endif @@ -1870,7 +1870,7 @@ static void init_signals(void) struct rlimit rl; rl.rlim_cur = rl.rlim_max = RLIM_INFINITY; if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings) - sql_print_error("Warning: setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); + sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals"); } #endif (void) sigemptyset(&set); @@ -2024,7 +2024,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) case SIGQUIT: case SIGKILL: #ifdef EXTRA_DEBUG - sql_print_error("Got signal %d to shutdown mysqld",sig); + sql_print_information("Got signal %d to shutdown mysqld",sig); #endif DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop)); if (!abort_loop) @@ -2036,7 +2036,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR); if (pthread_create(&tmp,&connection_attrib, kill_server_thread, (void*) sig)) - sql_print_error("Error: Can't create thread to kill server"); + sql_print_error("Can't create thread to kill server"); #else kill_server((void*) sig); // MIT THREAD has a alarm thread #endif @@ -2060,7 +2060,7 @@ extern "C" void *signal_hand(void *arg __attribute__((unused))) #endif default: #ifdef EXTRA_DEBUG - sql_print_error("Warning: Got signal: %d error: %d",sig,error); /* purecov: tested */ + sql_print_warning("Got signal: %d error: %d",sig,error); /* purecov: tested */ #endif break; /* purecov: tested */ } @@ -2339,11 +2339,11 @@ static int init_common_variables(const char *conf_file_name, int argc, ("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", files, max_connections, table_cache_size)); if (global_system_variables.log_warnings) - sql_print_error("Warning: Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", + sql_print_warning("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld", files, max_connections, table_cache_size); } else if (global_system_variables.log_warnings) - sql_print_error("Warning: Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); + sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files); } open_files_limit= files; } @@ -2523,8 +2523,8 @@ static int init_server_components() } else if (opt_log_slave_updates) { - sql_print_error("\ -Warning: you need to use --log-bin to make --log-slave-updates work. \ + sql_print_warning("\ +you need to use --log-bin to make --log-slave-updates work. \ Now disabling --log-slave-updates."); } @@ -2532,7 +2532,7 @@ Now disabling --log-slave-updates."); if (opt_log_slave_updates && replicate_same_server_id) { sql_print_error("\ -Error: using --replicate-same-server-id in conjunction with \ +using --replicate-same-server-id in conjunction with \ --log-slave-updates is impossible, it would lead to infinite loops in this \ server."); unireg_abort(1); @@ -2561,12 +2561,12 @@ server."); if (opt_innodb_safe_binlog) { if (have_innodb != SHOW_OPTION_YES) - sql_print_error("Warning: --innodb-safe-binlog is meaningful only if " + sql_print_warning("--innodb-safe-binlog is meaningful only if " "the InnoDB storage engine is enabled in the server."); #ifdef HAVE_INNOBASE_DB if (innobase_flush_log_at_trx_commit != 1) { - sql_print_error("Warning: --innodb-safe-binlog is meaningful only if " + sql_print_warning("--innodb-safe-binlog is meaningful only if " "innodb_flush_log_at_trx_commit is 1; now setting it " "to 1."); innobase_flush_log_at_trx_commit= 1; @@ -2578,14 +2578,14 @@ server."); good (especially "littlesync", and on Windows... see srv/srv0start.c). */ - sql_print_error("Warning: --innodb-safe-binlog requires that " + sql_print_warning("--innodb-safe-binlog requires that " "the innodb_flush_method actually synchronizes the " "InnoDB log to disk; it is your responsibility " "to verify that the method you chose does it."); } if (sync_binlog_period != 1) { - sql_print_error("Warning: --innodb-safe-binlog is meaningful only if " + sql_print_warning("--innodb-safe-binlog is meaningful only if " "the global sync_binlog variable is 1; now setting it " "to 1."); sync_binlog_period= 1; @@ -2624,7 +2624,7 @@ server."); if (mlockall(MCL_CURRENT)) { if (global_system_variables.log_warnings) - sql_print_error("Warning: Failed to lock memory. Errno: %d\n",errno); + sql_print_warning("Failed to lock memory. Errno: %d\n",errno); locked_in_memory= 0; } } @@ -2650,7 +2650,7 @@ static void create_maintenance_thread() { pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_manager,0)) - sql_print_error("Warning: Can't create thread to manage maintenance"); + sql_print_warning("Can't create thread to manage maintenance"); } } @@ -2662,7 +2662,7 @@ static void create_shutdown_thread() hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) - sql_print_error("Warning: Can't create thread to handle shutdown requests"); + sql_print_warning("Can't create thread to handle shutdown requests"); // On "Stop Service" we have to do regular shutdown Service.SetShutdownEvent(hEventShutdown); @@ -2671,7 +2671,7 @@ static void create_shutdown_thread() pthread_cond_init(&eventShutdown, NULL); pthread_t hThread; if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0)) - sql_print_error("Warning: Can't create thread to handle shutdown requests"); + sql_print_warning("Can't create thread to handle shutdown requests"); #endif #endif // EMBEDDED_LIBRARY } @@ -2702,7 +2702,7 @@ static void handle_connections_methods() if (pthread_create(&hThread,&connection_attrib, handle_connections_namedpipes, 0)) { - sql_print_error("Warning: Can't create thread to handle named pipes"); + sql_print_warning("Can't create thread to handle named pipes"); handler_count--; } } @@ -2713,7 +2713,7 @@ static void handle_connections_methods() if (pthread_create(&hThread,&connection_attrib, handle_connections_sockets, 0)) { - sql_print_error("Warning: Can't create thread to handle TCP/IP"); + sql_print_warning("Can't create thread to handle TCP/IP"); handler_count--; } } @@ -2724,7 +2724,7 @@ static void handle_connections_methods() if (pthread_create(&hThread,&connection_attrib, handle_connections_shared_memory, 0)) { - sql_print_error("Warning: Can't create thread to handle shared memory"); + sql_print_warning("Can't create thread to handle shared memory"); handler_count--; } } @@ -2784,7 +2784,7 @@ int main(int argc, char **argv) if (stack_size && stack_size < thread_stack) { if (global_system_variables.log_warnings) - sql_print_error("Warning: Asked for %ld thread stack, but got %ld", + sql_print_warning("Asked for %ld thread stack, but got %ld", thread_stack, stack_size); thread_stack= stack_size; } @@ -2807,8 +2807,8 @@ int main(int argc, char **argv) if (lower_case_table_names_used) { if (global_system_variables.log_warnings) - sql_print_error("\ -Warning: You have forced lower_case_table_names to 0 through a command-line \ + sql_print_warning("\ +You have forced lower_case_table_names to 0 through a command-line \ option, even though your file system '%s' is case insensitive. This means \ that you can corrupt a MyISAM table by accessing it with different cases. \ You should consider changing lower_case_table_names to 1 or 2", @@ -2817,7 +2817,7 @@ You should consider changing lower_case_table_names to 1 or 2", else { if (global_system_variables.log_warnings) - sql_print_error("Warning: Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); + sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home); lower_case_table_names= 2; } } @@ -2850,14 +2850,14 @@ You should consider changing lower_case_table_names to 1 or 2", #ifdef EXTRA_DEBUG switch (server_id) { case 1: - sql_print_error("\ -Warning: You have enabled the binary log, but you haven't set server-id to \ + sql_print_warning("\ +You have enabled the binary log, but you haven't set server-id to \ a non-zero value: we force server id to 1; updates will be logged to the \ binary log, but connections from slaves will not be accepted."); break; case 2: - sql_print_error("\ -Warning: You should set server-id to a non-0 value if master_host is set; \ + sql_print_warning("\ +You should set server-id to a non-0 value if master_host is set; \ we force server id to 2, but this MySQL server will not act as a slave."); break; } @@ -3197,7 +3197,7 @@ static int bootstrap(FILE *file) if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap, (void*) thd)) { - sql_print_error("Warning: Can't create thread to handle bootstrap"); + sql_print_warning("Can't create thread to handle bootstrap"); DBUG_RETURN(-1); } /* Wait for thread to die */ @@ -5606,7 +5606,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), if (!mysqld_user || !strcmp(mysqld_user, argument)) mysqld_user= argument; else - fprintf(stderr, "Warning: Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user); + sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user); break; case 'L': strmake(language, argument, sizeof(language)-1); @@ -6391,7 +6391,7 @@ static int test_if_case_insensitive(const char *dir_name) (void) my_delete(buff2, MYF(0)); if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0) { - sql_print_error("Warning: Can't create test file %s", buff); + sql_print_warning("Can't create test file %s", buff); DBUG_RETURN(-1); } my_close(file, MYF(0)); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fd3d27099ed..9c6853187f6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -251,9 +251,9 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) { global_system_variables.old_passwords= 1; pthread_mutex_unlock(&LOCK_global_system_variables); - sql_print_error("mysql.user table is not updated to new password format; " - "Disabling new password usage until " - "mysql_fix_privilege_tables is run"); + sql_print_warning("mysql.user table is not updated to new password format; " + "Disabling new password usage until " + "mysql_fix_privilege_tables is run"); } thd->variables.old_passwords= 1; } diff --git a/sql/tztime.cc b/sql/tztime.cc index 610f75f1643..af9af530fec 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1560,8 +1560,8 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) if (open_tables(thd, tables_buff, &counter) || lock_tables(thd, tables_buff, counter)) { - sql_print_error("Warning: Can't open and lock time zone table: %s " - "trying to live without them", thd->net.last_error); + sql_print_warning("Can't open and lock time zone table: %s " + "trying to live without them", thd->net.last_error); /* We will try emulate that everything is ok */ return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; @@ -1740,8 +1740,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (!(alloc_buff= alloc_root(&tz_storage, sizeof(TIME_ZONE_INFO) + tz_name->length() + 1))) { - sql_print_error("Error: Out of memory while loading time zone " - "description"); + sql_print_error("Out of memory while loading time zone description"); return 0; } tz_info= (TIME_ZONE_INFO *)alloc_buff; @@ -1757,7 +1756,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) Let us find out time zone id by its name (there is only one index and it is specifically for this purpose). */ - table= tz_tables->table; + table= tz_tables->table; tz_tables= tz_tables->next; table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); /* @@ -1770,7 +1769,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { - sql_print_error("Error: Can't find description of time zone."); + sql_print_error("Can't find description of time zone."); goto end; } @@ -1783,7 +1782,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) understand whenever this timezone uses leap seconds (again we are using the only index in this table). */ - table= tz_tables->table; + table= tz_tables->table; tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); @@ -1791,7 +1790,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { - sql_print_error("Error: Can't find description of time zone."); + sql_print_error("Can't find description of time zone."); goto end; } @@ -1810,7 +1809,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) only for our time zone guess what are we doing? Right - using special index. */ - table= tz_tables->table; + table= tz_tables->table; tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); @@ -1948,8 +1947,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) #endif sizeof(TRAN_TYPE_INFO) * tz_info->typecnt))) { - sql_print_error("Error: Out of memory while loading time zone " - "description"); + sql_print_error("Out of memory while loading time zone description"); goto end; } @@ -1974,12 +1972,12 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ if (tz_info->typecnt < 1) { - sql_print_error("Error: loading time zone without transition types"); + sql_print_error("loading time zone without transition types"); goto end; } if (prepare_tz_info(tz_info, &tz_storage)) { - sql_print_error("Error: Unable to build mktime map for time zone"); + sql_print_error("Unable to build mktime map for time zone"); goto end; } @@ -1991,7 +1989,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) &my_charset_latin1), my_hash_insert(&tz_names, (const byte *)tmp_tzname))) { - sql_print_error("Error: Out of memory while loading time zone"); + sql_print_error("Out of memory while loading time zone"); goto end; } -- cgit v1.2.1 From 4e2f80b4572f808017ef1dab276841b2a6384613 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Aug 2004 10:13:13 +0200 Subject: typo fixed --- sql/field.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/field.cc b/sql/field.cc index 71ec7545efc..394d53238c2 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2341,7 +2341,7 @@ String *Field_double::val_str(String *val_buffer, else { #ifdef HAVE_FCONVERT - char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE], + char buff[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE]; char *pos= buff; int decpt,sign,tmp_dec=dec; -- cgit v1.2.1 From c52a30b5dfc80341567a2e286c554fc35964cae9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 10:19:10 +0200 Subject: Enabled HA_NULL_IN_KEY support --- sql/ha_ndbcluster.cc | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 80b8c21fa0c..424dc132370 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1075,11 +1075,13 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, const key_range *key, int bound) { - uint i, tot_len; + uint key_len, key_store_len, tot_len, key_tot_len; byte *key_ptr; KEY* key_info= table->key_info + active_index; KEY_PART_INFO* key_part= key_info->key_part; KEY_PART_INFO* end= key_part+key_info->key_parts; + Field* field; + bool key_nullable, key_null; DBUG_ENTER("set_bounds"); DBUG_PRINT("enter", ("bound: %d", bound)); @@ -1089,29 +1091,37 @@ int ha_ndbcluster::set_bounds(NdbIndexScanOperation *op, // Set bounds using key data tot_len= 0; - key_ptr= (byte *) key->key; + key_ptr= (byte *) key->key; + key_tot_len= key->length; for (; key_part != end; key_part++) { - Field* field= key_part->field; - uint32 field_len= field->pack_length(); - tot_len+= field_len; + field= key_part->field; + key_len= key_part->length; + key_store_len= key_part->store_length; + key_nullable= (bool) key_part->null_bit; + key_null= (field->maybe_null() && *key_ptr); + tot_len+= key_store_len; const char* bounds[]= {"LE", "LT", "GE", "GT", "EQ"}; DBUG_ASSERT(bound >= 0 && bound <= 4); - DBUG_PRINT("info", ("Set Bound%s on %s", + DBUG_PRINT("info", ("Set Bound%s on %s %s %s %s", bounds[bound], - field->field_name)); - DBUG_DUMP("key", (char*)key_ptr, field_len); + field->field_name, + key_nullable ? "NULLABLE" : "", + key_null ? "NULL":"")); + DBUG_PRINT("info", ("Total length %ds", tot_len)); + + DBUG_DUMP("key", (char*) key_ptr, key_store_len); if (op->setBound(field->field_name, bound, - field->is_null() ? 0 : key_ptr, - field->is_null() ? 0 : field_len) != 0) + key_null ? 0 : (key_nullable ? key_ptr + 1 : key_ptr), + key_null ? 0 : key_len) != 0) ERR_RETURN(op->getNdbError()); - key_ptr+= field_len; - - if (tot_len >= key->length) + key_ptr+= key_store_len; + + if (tot_len >= key_tot_len) break; /* @@ -3104,7 +3114,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_ndb(NULL), m_table(NULL), m_table_flags(HA_REC_NOT_IN_SEQ | - //HA_NULL_IN_KEY | + HA_NULL_IN_KEY | HA_NOT_EXACT_COUNT | HA_NO_PREFIX_CHAR_KEYS), m_use_write(false), -- cgit v1.2.1 From c62dd0d409c76fe676e76467675512c275e8da09 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 14:07:02 +0400 Subject: Change Item_arena::state to enum --- sql/sql_class.cc | 6 +++--- sql/sql_class.h | 8 ++++---- sql/sql_prepare.cc | 18 +++++++++--------- 3 files changed, 16 insertions(+), 16 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 26e2cebb909..79c28d94127 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1323,7 +1323,7 @@ void select_dumpvar::cleanup() Item_arena::Item_arena(THD* thd) :free_list(0), - state((int)INITIALIZED) + state(INITIALIZED) { init_sql_alloc(&mem_root, thd->variables.query_alloc_block_size, @@ -1335,7 +1335,7 @@ Item_arena::Item_arena(THD* thd) Item_arena::Item_arena() :free_list(0), - state((int)CONVENTIONAL_EXECUTION) + state(CONVENTIONAL_EXECUTION) { clear_alloc_root(&mem_root); } @@ -1343,7 +1343,7 @@ Item_arena::Item_arena() Item_arena::Item_arena(bool init_mem_root) :free_list(0), - state((int)INITIALIZED) + state(INITIALIZED) { if (init_mem_root) clear_alloc_root(&mem_root); diff --git a/sql/sql_class.h b/sql/sql_class.h index 198e06bb3bd..a8035cffd96 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -427,13 +427,13 @@ public: */ Item *free_list; MEM_ROOT mem_root; - enum + enum enum_state { INITIALIZED= 0, PREPARED= 1, EXECUTED= 3, CONVENTIONAL_EXECUTION= 2, ERROR= -1 }; - int state; + enum_state state; /* We build without RTTI, so dynamic_cast can't be used. */ enum Type @@ -447,8 +447,8 @@ public: virtual Type type() const; virtual ~Item_arena(); - inline bool is_stmt_prepare() const { return state < (int)PREPARED; } - inline bool is_first_stmt_execute() const { return state == (int)PREPARED; } + inline bool is_stmt_prepare() const { return (int)state < (int)PREPARED; } + inline bool is_first_stmt_execute() const { return state == PREPARED; } inline gptr alloc(unsigned int size) { return alloc_root(&mem_root,size); } inline gptr calloc(unsigned int size) { diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index baff7bd604d..708ca3a516f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -132,7 +132,7 @@ find_prepared_statement(THD *thd, ulong id, const char *where, { Statement *stmt= thd->stmt_map.find(id); - if (stmt == 0 || stmt->type() != (int)Item_arena::PREPARED_STATEMENT) + if (stmt == 0 || stmt->type() != Item_arena::PREPARED_STATEMENT) { char llbuf[22]; my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), 22, llstr(id, llbuf), where); @@ -1619,7 +1619,7 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, { sl->prep_where= sl->where; } - stmt->state= (int)Prepared_statement::PREPARED; + stmt->state= Item_arena::PREPARED; } DBUG_RETURN(!stmt); @@ -1736,7 +1736,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) DBUG_PRINT("exec_query:", ("%s", stmt->query)); /* Check if we got an error when sending long data */ - if (stmt->state == (int)Item_arena::ERROR) + if (stmt->state == Item_arena::ERROR) { send_error(thd, stmt->last_errno, stmt->last_error); DBUG_VOID_RETURN; @@ -1853,7 +1853,7 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, transformations of the query tree (i.e. negations elimination). This should be done permanently on the parse tree of this statement. */ - if (stmt->state == (int)Item_arena::PREPARED) + if (stmt->state == Item_arena::PREPARED) thd->current_arena= stmt; if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -1866,10 +1866,10 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, /* Free Items that were created during this execution of the PS. */ free_items(thd->free_list); thd->free_list= 0; - if (stmt->state == (int)Item_arena::PREPARED) + if (stmt->state == Item_arena::PREPARED) { thd->current_arena= thd; - stmt->state= (int)Item_arena::EXECUTED; + stmt->state= Item_arena::EXECUTED; } cleanup_items(stmt->free_list); reset_stmt_params(stmt); @@ -1908,7 +1908,7 @@ void mysql_stmt_reset(THD *thd, char *packet) SEND_ERROR))) DBUG_VOID_RETURN; - stmt->state= (int)Item_arena::PREPARED; + stmt->state= Item_arena::PREPARED; /* Clear parameters from data which could be set by @@ -1996,7 +1996,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param_number >= stmt->param_count) { /* Error will be sent in execute call */ - stmt->state= (int)Item_arena::ERROR; + stmt->state= Item_arena::ERROR; stmt->last_errno= ER_WRONG_ARGUMENTS; sprintf(stmt->last_error, ER(ER_WRONG_ARGUMENTS), "mysql_stmt_send_long_data"); @@ -2012,7 +2012,7 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) if (param->set_longdata(thd->extra_data, thd->extra_length)) #endif { - stmt->state= (int)Item_arena::ERROR; + stmt->state= Item_arena::ERROR; stmt->last_errno= ER_OUTOFMEMORY; sprintf(stmt->last_error, ER(ER_OUTOFMEMORY), 0); } -- cgit v1.2.1 From 851e3cabb0faec154c2daee82505d4275e9386de Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 12:07:48 +0200 Subject: Fix for bug#5312 Ndb Cluster returns wrong error code for duplicate key at insert --- sql/ha_ndbcluster.cc | 17 ++++++++++++++--- sql/ha_ndbcluster.h | 1 + 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 424dc132370..815aed13ce3 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -144,6 +144,7 @@ static int ndb_to_mysql_error(const NdbError *err) int ha_ndbcluster::ndb_err(NdbConnection *trans) { + int res; const NdbError err= trans->getNdbError(); if (!err.code) return 0; // Don't log things to DBUG log if no error @@ -161,7 +162,13 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans) default: break; } - DBUG_RETURN(ndb_to_mysql_error(&err)); + res= ndb_to_mysql_error(&err); + DBUG_PRINT("info", ("transformed ndbcluster error %d to mysql error %d", + err.code, res)); + if (res == HA_ERR_FOUND_DUPP_KEY) + dupkey= table->primary_key; + + DBUG_RETURN(res); } @@ -2167,7 +2174,10 @@ void ha_ndbcluster::info(uint flag) if (flag & HA_STATUS_VARIABLE) DBUG_PRINT("info", ("HA_STATUS_VARIABLE")); if (flag & HA_STATUS_ERRKEY) + { DBUG_PRINT("info", ("HA_STATUS_ERRKEY")); + errkey= dupkey; + } if (flag & HA_STATUS_AUTO) DBUG_PRINT("info", ("HA_STATUS_AUTO")); DBUG_VOID_RETURN; @@ -2621,7 +2631,7 @@ int ndbcluster_commit(THD *thd, void *ndb_transaction) const NdbOperation *error_op= trans->getNdbErrorOperation(); ERR_PRINT(err); res= ndb_to_mysql_error(&err); - if (res != -1) + if (res != -1) ndbcluster_print_error(res, error_op); } ndb->closeTransaction(trans); @@ -3126,7 +3136,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): ops_pending(0), skip_auto_increment(true), blobs_buffer(0), - blobs_buffer_size(0) + blobs_buffer_size(0), + dupkey((uint) -1) { int i; diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 0d9c28723ce..c49a6078e7a 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -237,6 +237,7 @@ class ha_ndbcluster: public handler // memory for blobs in one tuple char *blobs_buffer; uint32 blobs_buffer_size; + uint dupkey; }; bool ndbcluster_init(void); -- cgit v1.2.1 From 07f5a44bc0a525c99394536a436cc85fb00fc337 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 14:35:04 +0300 Subject: Review of new pushed code (Indentation fixes and simple optimizations) Use 'mysqltest' as test database instead of test_$1 or test1,test2 to not accidently delete an important database Safety fix for mailformed MERGE files Build-tools/mysql-copyright: Print correct file name in case of errors Fixed indentation include/config-win.h: Removed unnecessary #ifdef myisammrg/myrg_open.c: Don't give a core if merge file contains INSERT_METHOD first (not legal but better safe than sorry) Don't set struct variables to zero that are already zero Indentation fixes mysql-test/r/create.result: Use 'mysqltest' as test database mysql-test/r/ndb_basic.result: Use 'mysqltest' as test database mysql-test/r/ndb_blob.result: Use 'mysqltest' as test database mysql-test/r/ndb_transaction.result: Use 'mysqltest' as test database mysql-test/r/ps_1general.result: Use 'mysqltest' as test database mysql-test/r/rpl_charset.result: Use 'mysqltest' as test database mysql-test/r/rpl_delete_all.result: Use 'mysqltest' as test database mysql-test/r/show_check.result: Use 'mysqltest' as test database mysql-test/t/create.test: Use 'mysqltest' as test database mysql-test/t/ndb_basic.test: Use 'mysqltest' as test database mysql-test/t/ndb_blob.test: Use 'mysqltest' as test database mysql-test/t/ndb_transaction.test: Use 'mysqltest' as test database mysql-test/t/ps_1general.test: Use 'mysqltest' as test database mysql-test/t/rpl_charset.test: Use 'mysqltest' as test database mysql-test/t/rpl_delete_all.test: Use 'mysqltest' as test database mysql-test/t/show_check.test: Use 'mysqltest' as test database sql/field.h: Mark functions that should be deleted as soon as we have a new prototype for store(longlong) sql/lock.cc: Indentation fix sql/sql_base.cc: Better comment. Break find_item_in_list in case of perfect match sql/sql_prepare.cc: Simple optimization sql/sql_select.cc: Portability fix --- sql/field.h | 4 ++-- sql/lock.cc | 3 ++- sql/sql_base.cc | 11 ++++++++--- sql/sql_prepare.cc | 7 +++---- sql/sql_select.cc | 4 ++-- 5 files changed, 17 insertions(+), 12 deletions(-) (limited to 'sql') diff --git a/sql/field.h b/sql/field.h index 9cce7b9541b..e12dd60c13b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -908,7 +908,7 @@ public: void reset(void) { charset()->cset->fill(charset(),ptr,field_length,' '); } int store(const char *to,uint length,CHARSET_INFO *charset); int store(longlong nr); - int store(double nr) { return Field_str::store(nr); } + int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */ double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -955,7 +955,7 @@ public: uint32 key_length() const { return (uint32) field_length; } int store(const char *to,uint length,CHARSET_INFO *charset); int store(longlong nr); - int store(double nr) { return Field_str::store(nr); } + int store(double nr) { return Field_str::store(nr); } /* QQ: To be deleted */ double val_real(void); longlong val_int(void); String *val_str(String*,String *); diff --git a/sql/lock.cc b/sql/lock.cc index fab0a61e506..215059b8a46 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -779,7 +779,8 @@ void unlock_global_read_lock(THD *thd) (is_not_commit || \ global_read_lock_blocks_commit)) -bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit) +bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, + bool is_not_commit) { const char *old_message; bool result= 0, need_exit_cond; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index dede280325d..92364b23461 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2138,7 +2138,10 @@ find_item_in_list(Item *find, List &items, uint *counter, select list over other fields from the tables participating in this select in case of ambiguity. - QQ: Why do we use simple strcmp for table name comparison here ? + We use strcmp for table names and database names as these may be + case sensitive. + In cases where they are not case sensitive, they are always in lower + case. */ if (!my_strcasecmp(system_charset_info, item_field->field_name, field_name) && @@ -2157,10 +2160,12 @@ find_item_in_list(Item *find, List &items, uint *counter, } found= li.ref(); *counter= i; + if (db_name) + break; // Perfect match } } else if (!my_strcasecmp(system_charset_info, item_field->name, - field_name)) + field_name)) { /* If table name was not given we should scan through aliases @@ -2230,7 +2235,7 @@ find_item_in_list(Item *find, List &items, uint *counter, } if (found) return found; - else if (report_error != REPORT_EXCEPT_NOT_FOUND) + if (report_error != REPORT_EXCEPT_NOT_FOUND) { if (report_error == REPORT_ALL_ERRORS) my_printf_error(ER_BAD_FIELD_ERROR, ER(ER_BAD_FIELD_ERROR), MYF(0), diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index baff7bd604d..4b9f4162aff 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1041,7 +1041,7 @@ static int mysql_test_select(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX_UNIT *unit= &lex->unit; - + int result= 1; DBUG_ENTER("mysql_test_select"); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -1087,13 +1087,12 @@ static int mysql_test_select(Prepared_statement *stmt, goto err_prep; } } - unit->cleanup(); - DBUG_RETURN(0); + result= 0; // ok err_prep: unit->cleanup(); err: - DBUG_RETURN(1); + DBUG_RETURN(result); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 4ca8008c518..59c587d876f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3220,7 +3220,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, store_key **ref_key= j->ref.key_copy; byte *key_buff=j->ref.key_buff, *null_ref_key= 0; - bool keyuse_uses_no_tables= true; + bool keyuse_uses_no_tables= TRUE; if (ftkey) { j->ref.items[0]=((Item_func*)(keyuse->val))->key_item(); @@ -3240,7 +3240,7 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, uint maybe_null= test(keyinfo->key_part[i].null_bit); j->ref.items[i]=keyuse->val; // Save for cond removal - keyuse_uses_no_tables= keyuse_uses_no_tables & !keyuse->used_tables; + keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables; if (!keyuse->used_tables && !(join->select_options & SELECT_DESCRIBE)) { // Compare against constant -- cgit v1.2.1 From e9c594e6d4fcb33bafc9896c2223dad56b1fbb00 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 18:53:27 +0500 Subject: Better easier to call error message format. --- sql/share/czech/errmsg.txt | 2 +- sql/share/danish/errmsg.txt | 2 +- sql/share/dutch/errmsg.txt | 2 +- sql/share/english/errmsg.txt | 2 +- sql/share/estonian/errmsg.txt | 2 +- sql/share/french/errmsg.txt | 2 +- sql/share/german/errmsg.txt | 2 +- sql/share/greek/errmsg.txt | 2 +- sql/share/hungarian/errmsg.txt | 2 +- sql/share/italian/errmsg.txt | 2 +- sql/share/japanese/errmsg.txt | 2 +- sql/share/korean/errmsg.txt | 2 +- sql/share/norwegian-ny/errmsg.txt | 2 +- sql/share/norwegian/errmsg.txt | 2 +- sql/share/polish/errmsg.txt | 2 +- sql/share/portuguese/errmsg.txt | 2 +- sql/share/romanian/errmsg.txt | 2 +- sql/share/russian/errmsg.txt | 2 +- sql/share/serbian/errmsg.txt | 2 +- sql/share/slovak/errmsg.txt | 2 +- sql/share/spanish/errmsg.txt | 2 +- sql/share/swedish/errmsg.txt | 2 +- sql/share/ukrainian/errmsg.txt | 2 +- sql/sql_yacc.yy | 9 +++------ 24 files changed, 26 insertions(+), 29 deletions(-) (limited to 'sql') diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index 9769ec1a55d..047db57c86c 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -314,4 +314,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 31715354101..168cddec81d 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -308,4 +308,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 06e47e006f5..32d8a2ba168 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -316,4 +316,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index a2e74460380..3303cd0666a 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -305,4 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index df29f08e752..cdfb5e9d170 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -310,4 +310,4 @@ character-set=latin7 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index f0435278440..72c2381dc70 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -305,4 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index af11e09f2f6..0818895dacb 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -317,4 +317,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 7c921beba75..4ee82d91566 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -305,4 +305,4 @@ character-set=greek "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index e961b72a38e..6be3add430e 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -307,4 +307,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 02c719fd7c0..fd2d33c5e2e 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -305,4 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 9674f690183..7ebce1cf662 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -307,4 +307,4 @@ character-set=ujis "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 417d9976b7c..f389feb7e40 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -305,4 +305,4 @@ character-set=euckr "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index ae0b307439d..088adb43c96 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -307,4 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 246333af497..0e92867a201 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -307,4 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index 417757b2aea..c61db27cd58 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -309,4 +309,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 344860280cb..66b3d9a516b 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -306,4 +306,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 6b64d103e61..43c669cb4f9 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -309,4 +309,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 642b792a24f..311cfd35cb5 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -307,4 +307,4 @@ character-set=koi8r "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/serbian/errmsg.txt b/sql/share/serbian/errmsg.txt index 8c8bc6e9729..45b56c8269c 100644 --- a/sql/share/serbian/errmsg.txt +++ b/sql/share/serbian/errmsg.txt @@ -311,4 +311,4 @@ character-set=cp1250 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 23814b2cbc2..e45858805db 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -313,4 +313,4 @@ character-set=latin2 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 113157858ad..9a3296cb405 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -307,4 +307,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 8b43ea8ed0e..85271f81b2b 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -305,4 +305,4 @@ character-set=latin1 "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 4c762bf5313..87789018185 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -310,4 +310,4 @@ character-set=koi8u "Invalid TIMESTAMP value in column '%s' at row %ld", "Invalid %s character string: '%.64s'", "Result of %s() was larger than max_allowed_packet (%ld) - truncated" -"Conflicting declarations: '%s' and '%s'" +"Conflicting declarations: '%s%s' and '%s%s'" diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 1c057e03a11..7194cc72c04 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1215,12 +1215,9 @@ default_charset: cinfo->default_table_charset && $4 && !my_charset_same(cinfo->default_table_charset,$4)) { - char cs1[32]; - char cs2[32]; - my_snprintf(cs1, sizeof(cs1), "CHARACTER SET %s", - cinfo->default_table_charset->csname); - my_snprintf(cs2, sizeof(cs2), "CHARACTER SET %s", $4->csname); - net_printf(YYTHD, ER_CONFLICTING_DECLARATIONS, cs1, cs2); + net_printf(YYTHD, ER_CONFLICTING_DECLARATIONS, + "CHARACTER SET ", cinfo->default_table_charset->csname, + "CHARACTER SET ", $4->csname); YYABORT; } Lex->create_info.default_table_charset= $4; -- cgit v1.2.1 From c9394a0f0da951a24f72598f00d82e27fcc55684 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 21:27:58 +0500 Subject: Added global my_getopt_error_reporter function pointer which is used in the handle_options() function (instead of using additional handle_option() parameter). The default value of the my_getopt_error_reporter is default_reporter(). One can set it to other functions if case of need. client/mysql.cc: Removed extra handle_optins()'s parameter. client/mysqladmin.c: Removed extra handle_optins()'s parameter. client/mysqlbinlog.cc: Removed extra handle_optins()'s parameter. client/mysqlcheck.c: Removed extra handle_optins()'s parameter. client/mysqldump.c: Removed extra handle_optins()'s parameter. client/mysqlimport.c: Removed extra handle_optins()'s parameter. client/mysqlmanager-pwgen.c: Removed extra handle_optins()'s parameter. client/mysqlmanagerc.c: Removed extra handle_optins()'s parameter. client/mysqlshow.c: Removed extra handle_optins()'s parameter. client/mysqltest.c: Removed extra handle_optins()'s parameter. extra/my_print_defaults.c: Removed extra handle_optins()'s parameter. extra/mysql_install.c: Removed extra handle_optins()'s parameter. extra/mysql_waitpid.c: Removed extra handle_optins()'s parameter. extra/perror.c: Removed extra handle_optins()'s parameter. extra/resolve_stack_dump.c: Removed extra handle_optins()'s parameter. extra/resolveip.c: Removed extra handle_optins()'s parameter. include/my_getopt.h: Removed extra handle_optins()'s parameter. isam/isamchk.c: Removed extra handle_optins()'s parameter. isam/pack_isam.c: Removed extra handle_optins()'s parameter. myisam/mi_test1.c: Removed extra handle_optins()'s parameter. myisam/myisam_ftdump.c: Removed extra handle_optins()'s parameter. myisam/myisamchk.c: Removed extra handle_optins()'s parameter. myisam/myisampack.c: Removed extra handle_optins()'s parameter. sql/gen_lex_hash.cc: Removed extra handle_optins()'s parameter. sql/mysqld.cc: Removed extra handle_optins()'s parameter. tools/mysqlmanager.c: Removed extra handle_optins()'s parameter. --- sql/gen_lex_hash.cc | 2 +- sql/mysqld.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 72ab1184533..1e78aa35195 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -384,7 +384,7 @@ static int get_options(int argc, char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, 0))) + if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option))) exit(ho_error); if (argc >= 1) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1068c5ec9a1..1e682e16d1f 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5119,8 +5119,8 @@ static void get_options(int argc,char **argv) { int ho_error; - if ((ho_error=handle_options(&argc, &argv, my_long_options, get_one_option, - option_error_reporter))) + my_getopt_error_reporter= option_error_reporter; + if ((ho_error= handle_options(&argc, &argv, my_long_options, get_one_option))) exit(ho_error); #if defined(HAVE_BROKEN_REALPATH) -- cgit v1.2.1 From 1dc52f07633b6a0f81b7b0cb8e1a5b438a39dce5 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Aug 2004 21:10:57 +0300 Subject: after review patch mysql-test/r/negation_elimination.result: new tests of negation elimination mysql-test/t/negation_elimination.test: new tests of negation elimination sql/item.h: test of boolean functions added sql/item_cmpfunc.cc: NOT subtree is already checked, so wee need to return just argument sql/item_cmpfunc.h: test of boolean functions added sql/mysql_priv.h: 'place' to detect WHERE clause sql/sql_parse.cc: function for creation negated expression sql/sql_select.cc: removed unused function sql/sql_select.h: removed unused function sql/sql_yacc.yy: 'place' to detect WHERE clause --- sql/item.h | 4 ++-- sql/item_cmpfunc.cc | 5 +---- sql/item_cmpfunc.h | 3 +++ sql/mysql_priv.h | 4 +++- sql/sql_parse.cc | 36 +++++++++++++++++++++++++++++++++++ sql/sql_select.cc | 54 ----------------------------------------------------- sql/sql_select.h | 1 - sql/sql_yacc.yy | 20 ++++++++++++-------- 8 files changed, 57 insertions(+), 70 deletions(-) (limited to 'sql') diff --git a/sql/item.h b/sql/item.h index 6900fa11b90..742cf934381 100644 --- a/sql/item.h +++ b/sql/item.h @@ -239,6 +239,7 @@ public: virtual void top_level_item() {} virtual void set_result_field(Field *field) {} virtual bool is_result_field() { return 0; } + virtual bool is_bool_func() { return 0; } virtual void save_in_result_field(bool no_conversions) {} virtual void no_rows_in_result() {} virtual Item *copy_or_same(THD *thd) { return this; } @@ -268,8 +269,7 @@ public: virtual void bring_value() {} Field *tmp_table_field_from_field_type(TABLE *table); - - /* Used in sql_select.cc:eliminate_not_funcs() */ + virtual Item *neg_transformer(THD *thd) { return NULL; } void delete_self() { diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index de37e858bac..53ec17fd59d 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2707,9 +2707,6 @@ longlong Item_cond_xor::val_int() IS NULL(a) -> IS NOT NULL(a) IS NOT NULL(a) -> IS NULL(a) - NOTE - This method is used in the eliminate_not_funcs() function. - RETURN New item or NULL if we cannot apply NOT transformation (see Item::neg_transformer()). @@ -2718,7 +2715,7 @@ longlong Item_cond_xor::val_int() Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */ { // We should apply negation elimination to the argument of the NOT function - return eliminate_not_funcs(thd, args[0]); + return args[0]; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index c3551b35d63..f1a2b11aaa8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -89,6 +89,7 @@ public: Item_bool_func(Item *a) :Item_int_func(a) {} Item_bool_func(Item *a,Item *b) :Item_int_func(a,b) {} Item_bool_func(THD *thd, Item_bool_func *item) :Item_int_func(thd, item) {} + bool is_bool_func() { return 1; } void fix_length_and_dec() { decimals=0; max_length=1; } }; @@ -201,6 +202,7 @@ public: bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } void print(String *str) { Item_func::print_op(str); } bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } + bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp.cmp_collation.collation; } friend class Arg_comparator; @@ -748,6 +750,7 @@ class Item_func_in :public Item_int_func enum Functype functype() const { return IN_FUNC; } const char *func_name() const { return " IN "; } bool nulls_in_row(); + bool is_bool_func() { return 1; } CHARSET_INFO *compare_collation() { return cmp_collation.collation; } }; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 1949ecf26dc..a9ee6b4b691 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -297,7 +297,8 @@ enum enum_parsing_place { NO_MATTER, IN_HAVING, - SELECT_LIST + SELECT_LIST, + IN_WHERE }; struct st_table; @@ -376,6 +377,7 @@ int delete_precheck(THD *thd, TABLE_LIST *tables); int insert_precheck(THD *thd, TABLE_LIST *tables, bool update); int create_table_precheck(THD *thd, TABLE_LIST *tables, TABLE_LIST *create_table); +Item *negate_expression(THD *thd, Item *expr); #include "sql_class.h" #include "opt_range.h" diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 3cb356d42c8..79a011b9501 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -5401,3 +5401,39 @@ int create_table_precheck(THD *thd, TABLE_LIST *tables, check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0)) ? 1 : 0); } + + +/* + negate given expression + + SYNOPSIS + negate_expression() + thd therad handler + expr expression for negation + + RETURN + negated expression +*/ + +Item *negate_expression(THD *thd, Item *expr) +{ + Item *negated; + if (expr->type() == Item::FUNC_ITEM && + ((Item_func *) expr)->functype() == Item_func::NOT_FUNC) + { + /* it is NOT(NOT( ... )) */ + Item *arg= ((Item_func *) expr)->arguments()[0]; + enum_parsing_place place= thd->lex->current_select->parsing_place; + if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING) + return arg; + /* + if it is not boolean function then we have to emulate value of + not(not(a)), it will be a != 0 + */ + return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1)); + } + + if ((negated= expr->neg_transformer(thd)) != 0) + return negated; + return new Item_func_not(expr); +} diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 701d2597d3d..72e169c77af 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4339,60 +4339,6 @@ propagate_cond_constants(I_List *save_list,COND *and_father, } -/* - Eliminate NOT functions from the condition tree. - - SYNPOSIS - eliminate_not_funcs() - thd thread handler - cond condition tree - - DESCRIPTION - Eliminate NOT functions from the condition tree where it's possible. - Recursively traverse condition tree to find all NOT functions. - Call neg_transformer() method for negated arguments. - - NOTE - If neg_transformer() returned a new condition we call fix_fields(). - We don't delete any items as it's not needed. They will be deleted - later at once. - - RETURN - New condition tree -*/ - -COND *eliminate_not_funcs(THD *thd, COND *cond) -{ - if (!cond) - return cond; - if (cond->type() == Item::COND_ITEM) /* OR or AND */ - { - List_iterator li(*((Item_cond*) cond)->argument_list()); - Item *item; - while ((item= li++)) - { - Item *new_item= eliminate_not_funcs(thd, item); - if (item != new_item) - VOID(li.replace(new_item)); /* replace item with a new condition */ - } - } - else if (cond->type() == Item::FUNC_ITEM && /* 'NOT' operation? */ - ((Item_func*) cond)->functype() == Item_func::NOT_FUNC) - { - COND *new_cond= ((Item_func*) cond)->arguments()[0]->neg_transformer(thd); - if (new_cond) - { - /* - Here we can delete the NOT function. Something like: delete cond; - But we don't need to do it. All items will be deleted later at once. - */ - cond= new_cond; - } - } - return cond; -} - - static COND * optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value) { diff --git a/sql/sql_select.h b/sql/sql_select.h index 8aca43484d2..34eaa7e272d 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -438,4 +438,3 @@ bool cp_buffer_from_ref(TABLE_REF *ref); bool error_if_full_join(JOIN *join); int report_error(TABLE *table, int error); int safe_index_read(JOIN_TAB *tab); -COND *eliminate_not_funcs(THD *thd, COND *cond); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index afb55463ad1..fa772a9cf11 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2757,13 +2757,11 @@ simple_expr: | '~' expr %prec NEG { $$= new Item_func_bit_neg($2); } | NOT expr %prec NEG { - if (($$= $2->neg_transformer(YYTHD)) == 0) - $$= new Item_func_not($2); + $$= negate_expression(YYTHD, $2); } | '!' expr %prec NEG { - if (($$= $2->neg_transformer(YYTHD)) == 0) - $$= new Item_func_not($2); + $$= negate_expression(YYTHD, $2); } | '(' expr ')' { $$= $2; } | '(' expr ',' expr_list ')' @@ -3606,11 +3604,17 @@ opt_all: where_clause: /* empty */ { Select->where= 0; } - | WHERE expr + | WHERE + { + Select->parsing_place= IN_WHERE; + } + expr { - Select->where= $2; - if ($2) - $2->top_level_item(); + SELECT_LEX *select= Select; + select->where= $3; + select->parsing_place= NO_MATTER; + if ($3) + $3->top_level_item(); } ; -- cgit v1.2.1 From 705d50660de96fd7d20d585348ace0d2eb512baf Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Sep 2004 13:56:33 +0500 Subject: Move collation aggregation with superset conversion code from Item_bool_func2 into DTCollation to make it reusable for other types of items. --- sql/item.cc | 30 ++++++++++++++++++++++++++++-- sql/item.h | 12 +++++++++--- sql/item_cmpfunc.cc | 24 ++++++++---------------- 3 files changed, 45 insertions(+), 21 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 2c98aad2074..e9ef3b6a763 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -265,8 +265,9 @@ CHARSET_INFO *Item::default_charset() return current_thd->variables.collation_connection; } -bool DTCollation::aggregate(DTCollation &dt) +bool DTCollation::aggregate(DTCollation &dt, bool superset_conversion) { + nagg++; if (!my_charset_same(collation, dt.collation)) { /* @@ -280,15 +281,39 @@ bool DTCollation::aggregate(DTCollation &dt) if (derivation <= dt.derivation) ; // Do nothing else - set(dt); + { + set(dt); + strong= nagg; + } } else if (dt.collation == &my_charset_bin) { if (dt.derivation <= derivation) + { set(dt); + strong= nagg; + } else ; // Do nothing } + else if (superset_conversion) + { + if (derivation < dt.derivation && + collation->state & MY_CS_UNICODE) + ; // Do nothing + else if (dt.derivation < derivation && + dt.collation->state & MY_CS_UNICODE) + { + set(dt); + strong= nagg; + } + else + { + // Cannot convert to superset + set(0, DERIVATION_NONE); + return 1; + } + } else { set(0, DERIVATION_NONE); @@ -302,6 +327,7 @@ bool DTCollation::aggregate(DTCollation &dt) else if (dt.derivation < derivation) { set(dt); + strong= nagg; } else { diff --git a/sql/item.h b/sql/item.h index 742cf934381..23c5c844f21 100644 --- a/sql/item.h +++ b/sql/item.h @@ -41,16 +41,22 @@ class DTCollation { public: CHARSET_INFO *collation; enum Derivation derivation; + uint nagg; // Total number of aggregated collations. + uint strong; // Number of the strongest collation. DTCollation() { collation= &my_charset_bin; derivation= DERIVATION_NONE; + nagg= 0; + strong= 0; } DTCollation(CHARSET_INFO *collation_arg, Derivation derivation_arg) { collation= collation_arg; derivation= derivation_arg; + nagg= 0; + strong= 0; } void set(DTCollation &dt) { @@ -66,9 +72,9 @@ public: { collation= collation_arg; } void set(Derivation derivation_arg) { derivation= derivation_arg; } - bool aggregate(DTCollation &dt); - bool set(DTCollation &dt1, DTCollation &dt2) - { set(dt1); return aggregate(dt2); } + bool aggregate(DTCollation &dt, bool superset_conversion= FALSE); + bool set(DTCollation &dt1, DTCollation &dt2, bool superset_conversion= FALSE) + { set(dt1); return aggregate(dt2, superset_conversion); } const char *derivation_name() const { switch(derivation) diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 53ec17fd59d..f91bc5c4bc5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -188,25 +188,17 @@ void Item_bool_func2::fix_length_and_dec() { uint strong= 0; uint weak= 0; + DTCollation coll; - if ((args[0]->collation.derivation < args[1]->collation.derivation) && - !my_charset_same(args[0]->collation.collation, - args[1]->collation.collation) && - (args[0]->collation.collation->state & MY_CS_UNICODE)) - { - weak= 1; - } - else if ((args[1]->collation.derivation < args[0]->collation.derivation) && - !my_charset_same(args[0]->collation.collation, - args[1]->collation.collation) && - (args[1]->collation.collation->state & MY_CS_UNICODE)) - { - strong= 1; - } - - if (strong || weak) + if (args[0]->result_type() == STRING_RESULT && + args[1]->result_type() == STRING_RESULT && + !my_charset_same(args[0]->collation.collation, + args[1]->collation.collation) && + !coll.set(args[0]->collation, args[1]->collation, TRUE)) { Item* conv= 0; + strong= coll.strong; + weak= strong ? 0 : 1; if (args[weak]->type() == STRING_ITEM) { String tmp, cstr; -- cgit v1.2.1 From 94ecacdb97b97c74aae3eeb29965b80be28ac020 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Sep 2004 15:39:15 +0500 Subject: Allow IN to convert arguments into Unicode in some cases. --- sql/item_cmpfunc.cc | 54 +++++++++++++++++++++++++++++++++++++++++++++++++---- sql/item_func.cc | 12 ++++++++---- sql/item_func.h | 7 +++++-- 3 files changed, 63 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f91bc5c4bc5..4ddb648399a 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1735,12 +1735,58 @@ void Item_func_in::fix_length_and_dec() uint const_itm= 1; agg_cmp_type(&cmp_type, args, arg_count); - if ((cmp_type == STRING_RESULT) && - (agg_arg_collations_for_comparison(cmp_collation, args, arg_count))) - return; - + for (arg=args+1, arg_end=args+arg_count; arg != arg_end ; arg++) const_itm&= arg[0]->const_item(); + + + if (cmp_type == STRING_RESULT) + { + /* + We allow consts character set conversion for + + item IN (const1, const2, const3, ...) + + if item is in a superset for all arguments, + and if it is a stong side according to coercibility rules. + + TODO: add covnersion for non-constant IN values + via creating Item_func_conv_charset(). + */ + + if (agg_arg_collations_for_comparison(cmp_collation, + args, arg_count, TRUE)) + return; + if ((!my_charset_same(args[0]->collation.collation, + cmp_collation.collation) || !const_itm)) + { + if (agg_arg_collations_for_comparison(cmp_collation, + args, arg_count, FALSE)) + return; + } + else + { + /* + Conversion is possible: + All IN arguments are constants. + */ + for (arg= args+1, arg_end= args+arg_count; arg < arg_end; arg++) + { + if (!my_charset_same(cmp_collation.collation, + arg[0]->collation.collation)) + { + Item_string *conv; + String tmp, cstr, *ostr= arg[0]->val_str(&tmp); + cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), + cmp_collation.collation); + conv= new Item_string(cstr.ptr(),cstr.length(), cstr.charset(), + arg[0]->collation.derivation); + conv->str_value.copy(); + arg[0]= conv; + } + } + } + } /* Row item with NULLs inside can return NULL or FALSE => diff --git a/sql/item_func.cc b/sql/item_func.cc index adcba34d56b..ef845bb8266 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -75,13 +75,16 @@ static void my_coll_agg_error(Item** args, uint count, const char *fname) } -bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count) +bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count, + bool allow_superset_conversion) { uint i; + c.nagg= 0; + c.strong= 0; c.set(av[0]->collation); for (i= 1; i < count; i++) { - if (c.aggregate(av[i]->collation)) + if (c.aggregate(av[i]->collation, allow_superset_conversion)) { my_coll_agg_error(av, count, func_name()); return TRUE; @@ -92,9 +95,10 @@ bool Item_func::agg_arg_collations(DTCollation &c, Item **av, uint count) bool Item_func::agg_arg_collations_for_comparison(DTCollation &c, - Item **av, uint count) + Item **av, uint count, + bool allow_superset_conv) { - if (agg_arg_collations(c, av, count)) + if (agg_arg_collations(c, av, count, allow_superset_conv)) return TRUE; if (c.derivation == DERIVATION_NONE) diff --git a/sql/item_func.h b/sql/item_func.h index eaa0a044fd6..d45f7244e55 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -140,8 +140,11 @@ public: Field *tmp_table_field(TABLE *t_arg); Item *get_tmp_table_item(THD *thd); - bool agg_arg_collations(DTCollation &c, Item **items, uint nitems); - bool agg_arg_collations_for_comparison(DTCollation &c, Item **items, uint nitems); + bool agg_arg_collations(DTCollation &c, Item **items, uint nitems, + bool allow_superset_conversion= FALSE); + bool agg_arg_collations_for_comparison(DTCollation &c, + Item **items, uint nitems, + bool allow_superset_comversion= FALSE); bool walk(Item_processor processor, byte *arg); }; -- cgit v1.2.1 From 06959e0e66ab4640e9e7eea3354c8888ae7acc73 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Sep 2004 16:41:09 +0300 Subject: ha_innodb.cc: If ALTER TABLE ... DROP FOREIGN KEY ... fails because of a wrong constraint name, return a table handler error number 150 instead of 152; the value 152 was misleading, as it referred to '152 = Cannot delete a parent row', whereas '150 = Foreign key constraint is incorrectly formed' is less misleading sql/ha_innodb.cc: If ALTER TABLE ... DROP FOREIGN KEY ... fails because of a wrong constraint name, return a table handler error number 150 instead of 152; the value 152 was misleading, as it referred to '152 = Cannot delete a parent row', whereas '150 = Foreign key constraint is incorrectly formed' is less misleading --- sql/ha_innodb.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 3d3aca9cfd5..1572e22d6f7 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -285,8 +285,9 @@ convert_error_code_to_mysql( } else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) { - return(HA_ERR_ROW_IS_REFERENCED); - + return(HA_ERR_CANNOT_ADD_FOREIGN); /* TODO: This is a bit + misleading, a new MySQL error + code should be introduced */ } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) { return(HA_ERR_CRASHED); -- cgit v1.2.1 From d21aae95646db530315fbefc34da13421334394f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Sep 2004 16:04:01 +0200 Subject: - removed swedish errmsg.OLD BitKeeper/deleted/.del-errmsg.OLD~de59ad17392012d: Delete: sql/share/swedish/errmsg.OLD --- sql/share/swedish/errmsg.OLD | 221 ------------------------------------------- 1 file changed, 221 deletions(-) delete mode 100644 sql/share/swedish/errmsg.OLD (limited to 'sql') diff --git a/sql/share/swedish/errmsg.OLD b/sql/share/swedish/errmsg.OLD deleted file mode 100644 index 3dd14c8b613..00000000000 --- a/sql/share/swedish/errmsg.OLD +++ /dev/null @@ -1,221 +0,0 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ - -"hashchk", -"isamchk", -"NO", -"YES", -"Kan inte skapa filen: '%-.64s' (Felkod: %d)", -"Kan inte skapa tabellen: '%-.64s' (Felkod: %d)", -"Kan inte skapa databasen '%-.64s'. (Felkod: %d)", -"Databasen '%-.64s' existerar redan", -"Kan inte radera databasen '%-.64s'. Databasen finns inte", -"Fel vid radering av databasen (Kan inte radera '%-.64s'. Felkod: %d)", -"Fel vid radering av databasen (Kan inte radera biblioteket '%-.64s'. Felkod: %d)", -"Kan inte radera filen: '%-.64s' (Felkod: %d)", -"Hittar inte posten i systemregistret", -"Kan inte läsa filinformationen (stat) från '%-.64s' (Felkod: %d)", -"Kan inte inte läsa aktivt bibliotek. (Felkod: %d)", -"Kan inte låsa filen. (Felkod: %d)", -"Kan inte använda: '%-.64s'. (Felkod: %d)", -"Hittar inte filen: '%-.64s'. (Felkod: %d)", -"Kan inte läsa från bibliotek '%-.64s'. (Felkod: %d)", -"Kan inte byta till: '%-.64s'. (Felkod: %d)", -"Posten har förändrats sedan den lästes i register '%-.64s'", -"Disken är full (%s). Väntar tills det finns ledigt utrymme....", -"Kan inte skriva, dubbel söknyckel i register '%-.64s'", -"Fick fel vid stängning av '%-.64s' (Felkod: %d)", -"Fick fel vid läsning av '%-.64s' (Felkod %d)", -"Kan inte byta namn från '%-.64s' till '%-.64s' (Felkod: %d)", -"Fick fel vid skrivning till '%-.64s' (Felkod %d)", -"'%-.64s' är låst mot användning", -"Sorteringen avbruten", -"Formulär '%-.64s' finns inte i '%-.64s'", -"Fick felkod %d från databashanteraren", -"Registrets databas har inte denna facilitet", -"Hittar inte posten", -"Felaktig fil: '%-.64s'", -"Fatalt fel vid hantering av register '%-.64s'. Kör en reparation", -"Gammal nyckelfil '%-.64s'; Reparera registret", -"'%-.64s' är skyddad mot förändring", -"Oväntat slut på minnet, starta om programmet och försök på nytt (Behövde %d bytes)", -"Sorteringsbufferten räcker inte till. Kontrollera startparametrarna", -"Oväntat filslut vid läsning från '%-.64s' (Felkod: %d)", -"För många anslutningar", -"Fick slut på minnet. Kontrollera ifall mysqld eller någon annan process använder allt tillgängligt minne. Ifall inte, försök använda 'ulimit' eller allokera mera swap", -"Kan inte hitta 'hostname' för din adress", -"Fel vid initiering av kommunikationen med klienten", -"Användare '%-.32s@%-.64s' är ej berättigad att använda databasen %-.64s", -"Användare '%-.32s@%-.64s' är ej berättigad att logga in (Använder lösen: %s)", -"Ingen databas i användning", -"Okänt commando", -"Kolumn '%-.64s' får inte vara NULL", -"Okänd database '%-.64s'", -"Tabellen '%-.64s' finns redan", -"Okänd tabell '%-.64s'", -"Kolumn: '%-.64s' i %s är inte unik", -"Servern går nu ned", -"Okänd kolumn '%-.64s' i %s", -"'%-.64s' finns inte i GROUP BY", -"Kan inte använda GROUP BY med '%-.64s'", -"Kommandot har både sum functions och enkla funktioner", -"Antalet kolumner motsvarar inte antalet värden", -"Kolumn namn '%-.64s' är för långt", -"Kolumn namn '%-64s finns flera gånger", -"Nyckel namn '%-.64s' finns flera gånger", -"Dubbel nyckel '%-.64s' för nyckel: %d", -"Felaktigt kolumn typ för kolumn: '%-.64s'", -"%s nära '%-.64s' på rad %d", -"Frågan var tom", -"Icke unikt tabell/alias: '%-.64s'", -"Ogiltigt DEFAULT värde för '%-.64s'", -"Flera PRIMARY KEY använda", -"För många nycklar använda. Man får ha högst %d nycklar", -"För många nyckel delar använda. Man får ha högst %d nyckeldelar", -"För lång nyckel. Högsta tillåtna nyckellängd är %d", -"Nyckel kolumn '%-.64s' finns inte", -"En BLOB '%-.64s' kan inte vara nyckel med den använda tabellen typen", -"För stor kolumnlängd angiven för '%-.64s' (max= %d). Använd en BLOB instället", -"Det får finnas endast ett AUTO_INCREMENT fält och detta måste vara en nyckel", -"%s: klar att ta emot klienter\n", -"%s: Normal avslutning\n", -"%s: Fick signal %d. Avslutar!\n", -"%s: Avslutning klar\n", -"%s: Stänger av tråd %ld användare: '%-.64s'\n", -"Kan inte skapa IP socket", -"Tabellen '%-.64s' har inget index som motsvarar det angivna i CREATE INDEX. Skapa om tabellen", -"Fält separatorerna är inte emotsägande eller för långa. Kontrollera mot manualen", -"Man kan inte använda fast radlängd med blobs. Använd 'fields terminated by'." -"Textfilen '%' måste finnas i databas biblioteket eller vara läsbar för alla", -"Filen '%-.64s' existerar redan", -"Rader: %ld Bortagna: %ld Dubletter: %ld Varningar: %ld", -"Rader: %ld Dubletter: %ld", -"Felaktig delnyckel. Nyckeldelen är inte en sträng eller den angivna längden är längre än kolumnlängden", -"Man kan inte radera alla fält med ALTER TABLE. Använd DROP TABLE istället", -"Kan inte ta bort '%-.64s'. Kontrollera att fältet/nyckel finns", -"Rader: %ld Dubletter: %ld Varningar: %ld", -"INSERT table '%-.64s' får inte finnas i FROM tabell-listan", -"Finns inget thread med id %lu", -"Du är inte ägare till thread %lu", -"Inga tabeller angivna", -"För många alternativ till kolumn %s för SET", -"Kan inte generera ett unikt filnamn %s.(1-999)\n", -"Tabell '%-.64s' kan inte uppdateras emedan den är låst för läsning", -"Tabell '%-.64s' är inte låst med LOCK TABLES", -"BLOB fält '%-.64s' kan inte ha ett DEFAULT värde" -"Felaktigt databas namn '%-.64s'", -"Felaktigt tabell namn '%-.64s'", -"Den angivna frågan skulle troligen ta mycket long tid! Kontrollar din WHERE och använd SET OPTION SQL_BIG_SELECTS=1 ifall du vill hantera stora joins", -"Oidentifierat fel", -"Okänd procedur: %s", -"Felaktigt antal parametrar till procedur %s", -"Felaktiga parametrar till procedur %s", -"Okänd tabell '%-.64s' i '%-.64s'", -"Fält '%-.64s' är redan använt", -"Felaktig användning av SQL grupp function", -"Tabell '%-.64s' har en extension som inte finns i denna version av MySQL", -"Tabeller måste ha minst 1 kolumn", -"Tabellen '%-.64s' är full", -"Okänt karaktärset: '%-.64s'", -"För många tabeller. MySQL can ha högst %d tabeller i en och samma join" -"För många fält", -"För stor total rad längd. Den högst tillåtna rad-längden, förutom BLOBs, är %d. Ändra några av dina fält till BLOB", -"Tråd-stacken tog slut: Har använt %ld av %ld bytes. Använd 'mysqld -O thread_stack=#' ifall du behöver en större stack", -"Felaktigt referens i OUTER JOIN. Kontrollera ON uttrycket", -"Kolumn '%-.32s' är använd med UNIQUE eller INDEX men är inte definerad med NOT NULL", -"Kan inte ladda funktionen '%-.64s'", -"Kan inte initialisera funktionen '%-.64s'; '%-.80s'", -"Man får inte ange sökväg för dynamiska bibliotek", -"Funktionen '%-.64s' finns redan", -"Kan inte öppna det dynamiska biblioteket '%-.64s' (Felkod: %d %s)", -"Hittar inte funktionen '%-.64s' in det dynamiska biblioteket", -"Funktionen '%-.64s' är inte definierad", -"Denna dator '%-.64s' är blockerad pga många felaktig paket. Gör 'mysqladmin flush-hosts' för att ta bort alla blockeringarna", -"Denna dator '%-.64s' har inte privileger att använda denna MySQL server", -"Du använder MySQL som en anonym användare och som sådan får du inte ändra ditt lösenord", -"För att ändra lösenord för andra måste du ha rättigheter att uppdatera mysql databasen", -"Hittade inte användaren i 'user' tabellen", -"Rader: %ld Uppdaterade: %ld Varningar: %ld", -"Kan inte skapa en ny tråd (errno %d)" -"Antalet kolumner motsvarar inte antalet värden på rad: %ld", -"Kunde inte stänga och öppna tabell: '%-.64s', -"Felaktig använding av NULL", -"Fix fel '%-.64s' från REGEXP", -"Man får ha både GROUP kolumner (MIN(),MAX(),COUNT()...) och fält i en fråga om man inte har en GROUP BY del", -"Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s'", -"%-.16s ej tillåtet för '%-.32s@%-.64s' för tabell '%-.64s'", -"%-.16s ej tillåtet för '%-.32s@%-.64s'\n för kolumn '%-.64s' i tabell '%-.64s'", -"Felaktigt GRANT privilegium använt", -"Felaktigt maskinnamn eller användarnamn använt med GRANT", -"Det finns ingen tabell som heter '%-64s.%s'" -"Det finns inget privilegium definierat för användare '%-.32s' på '%-.64s' för tabell '%-.64s'", -"Du kan inte använda detta kommando med denna MySQL version", -"Du har något fel i din syntax", -"DELAYED INSERT tråden kunde inte låsa tabell '%-.64s'", -"Det finns redan 'max_delayed_threads' trådar i använding", -"Avbröt länken för tråd %ld till db: '%-.64s' användare: '%-.64s' (%s)", -"Kommunkationspaketet är större än 'max_allowed_packet'", -"Fick läsfel från klienten vid läsning från 'PIPE'", -"Fick fatalt fel från 'fcntl()'", -"Kommunikationspaketen kom i fel ordning", -"Kunde inte packa up kommunikationspaketet", -"Fick ett fel vid läsning från klienten", -"Fick 'timeout' vid läsning från klienten", -"Fick ett fel vid skrivning till klienten", -"Fick 'timeout' vid skrivning till klienten", -"Resultat strängen är längre än max_allowed_packet", -"Den använda tabell typen kan inte hantera BLOB/TEXT kolumner", -"Den använda tabell typen kan inte hantera AUTO_INCREMENT kolumner", -"INSERT DELAYED kan inte användas med tabell '%-.64s', emedan den är låst med LOCK TABLES", -"Felaktigt column namn '%-.100s'", -"Den använda tabell typen kan inte indexera kolumn '%-.64s'", -"Tabellerna i MERGE tabellen är inte identiskt definierade", -"Kan inte skriva till tabell '%-.64s'; UNIQUE test", -"Du har inte angett en nyckel längd för BLOB '%-.64s'", -"Alla delar av en PRIMARY KEY måste vara NOT NULL; Om du vill ha en nyckel med NULL, använd UNIQUE istället", -"Resultet bestod av mera än en rad", -"Denna tabell typ kräver en PRIMARY KEY", -"Denna version av MySQL är inte kompilerad med RAID", -"Du använder 'säker uppdaterings mod' och försökte uppdatera en table utan en WHERE sats som använder sig av en nyckel", -"Nyckel '%-.64s' finns inte in tabell '%-.64s'", -"Kan inte öppna tabellen", -"Tabellhanteraren för denna tabell kan inte göra check/repair", -"Du får inte utföra detta kommando i en transaktion", -"Fick fel %d vid COMMIT", -"Fick fel %d vid ROLLBACK", -"Fick fel %d vid FLUSH_LOGS", -"Fick fel %d vid CHECKPOINT", -"Avbröt länken för tråd %ld till db: '%-.64s' användare: '%-.32s' Host: '%-.64s' (%.-64s)", -"Tabellhanteraren klarar inte en binär kopiering av tabellen", -"Binärloggen stängdes medan vi gjorde FLUSH MASTER", -"Failed rebuilding the index of dumped table '%-.64s'", -"Fick en master: '%-.64s'", -"Fick nätverksfel vid läsning från master", -"Fick nätverksfel vid skrivning till master", -"Hittar inte ett FULLTEXT index i kolumnlistan", -"Kan inte exekvera kommandot emedan du har en låst tabell eller an aktiv transaktion", -"Okänd system variabel '%-.64'", -"Tabell '%-.64s' är crashad och bör repareras med REPAIR TABLE", -"Tabell '%-.64s' är crashad och senast (automatiska?) reparation misslyckades", -"Warning: Några icke transaktionella tabeller kunde inte återställas vid ROLLBACK", -"Transaktionen krävde mera än 'max_binlog_cache_size' minne. Utöka denna mysqld variabel och försök på nytt", -"Denna operation kan inte göras under replikering; Gör SLAVE STOP först", -"Denna operation kan endast göras under replikering; Konfigurera slaven och gör SLAVE START", -"Servern är inte konfigurerade som en replikations slav. Ändra konfigurationsfilen eller gör CHANGE MASTER TO", -"Kunde inte initializera replications-strukturerna. Kontrollera privilegerna för 'master.info'", -"Kunde inte starta en tråd för replikering", -"Användare '%-.64s' har redan 'max_user_connections' aktiva inloggningar", -"Man kan endast använda konstant-uttryck med SET", -"Fick inte ett lås i tid", -"Antal lås överskrider antalet reserverade lås", -"Updaterings-lås kan inte göras när man använder READ UNCOMMITTED", -"DROP DATABASE är inte tillåtet när man har ett globalt läs-lås", -"CREATE DATABASE är inte tillåtet när man har ett globalt läs-lås", -"Felaktiga argument till %s", -"%-.32s@%-.64s har inte rättigheter att skapa nya användare", -"Fick fel vid anslutning till master: %-.128s", -"Fick fel vid utförande av command på mastern: %-.128s", -"Fick fel vid utförande av %s: %-.128s", -"Felaktig använding av %s and %s", -"SELECT kommandona har olika antal kolumner" -"Kan inte utföra kommandot emedan du har ett READ lås", -- cgit v1.2.1 From 240812bdef994012bcc541f9f5ff8b272b093ed8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Sep 2004 14:02:11 -0300 Subject: Fix for bug #5302 --- sql/mysqld.cc | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1e682e16d1f..8236e5d9842 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2669,6 +2669,13 @@ server."); pthread_mutex_unlock(&LOCK_thread_count); } #else +#ifdef __WIN__ + if ( !have_tcpip || opt_disable_networking) + { + sql_print_error("Without TCP/IP or use of --skip-networking results in no available interfaces"); + unireg_abort(1); + } +#endif handle_connections_sockets(0); #ifdef EXTRA_DEBUG2 sql_print_error("Exiting main thread"); -- cgit v1.2.1 From 0ceb4ddc9f9212a1f9caf6b2179c59158677a91f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 1 Sep 2004 21:32:24 +0300 Subject: fixed typo in group_concat printing (BUG#5161) mysql-test/r/func_gconcat.result: fixed typo sql/item_sum.cc: fixed typo --- sql/item_sum.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 0ec8baf97bb..79c1be57625 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2157,7 +2157,7 @@ void Item_func_group_concat::print(String *str) (*order[i]->item)->print(str); } } - str->append(" seperator \'", 12); + str->append(" separator \'", 12); str->append(*separator); str->append("\')", 2); } -- cgit v1.2.1 From ac55058d78b353504d96f9d2965fb57e2cd81d9b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Sep 2004 01:17:28 -0300 Subject: Fix for bug #5302 --- sql/mysqld.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8236e5d9842..670e6a5a63e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2672,7 +2672,7 @@ server."); #ifdef __WIN__ if ( !have_tcpip || opt_disable_networking) { - sql_print_error("Without TCP/IP or use of --skip-networking results in no available interfaces"); + sql_print_error("TCP/IP unavailable or disabled with --skip-networking; no available interfaces"); unireg_abort(1); } #endif -- cgit v1.2.1 From 848414cf11bb77fe20b583eece29bccb0d25338d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Sep 2004 11:10:26 +0500 Subject: Addition to the fix for #4815 sql/sql_class.cc: Code simplified with strxnmov --- sql/sql_class.cc | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) (limited to 'sql') diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 80b9d6e20bf..b6b9a316cc6 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -854,21 +854,13 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, { File file; uint option= MY_UNPACK_FILENAME; - char buff[FN_REFLEN]; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS option|= MY_REPLACE_DIR; // Force use of db directory #endif - char *cnt= strmake(buff, mysql_real_data_home, FN_REFLEN); - *cnt= FN_LIBCHAR; - cnt++; - cnt= strmake(cnt, thd->db ? thd->db : "", FN_REFLEN - (cnt-buff)); - *cnt= FN_LIBCHAR; - cnt++; - *cnt= 0; - - (void) fn_format(path, exchange->file_name, buff, "", option); + strxnmov(path, FN_REFLEN, mysql_real_data_home, thd->db ? thd->db : ""); + (void) fn_format(path, exchange->file_name, path, "", option); if (!access(path, F_OK)) { my_error(ER_FILE_EXISTS_ERROR, MYF(0), exchange->file_name); -- cgit v1.2.1 From 762bee96d2be00d45d53cf9434383b325ce54f79 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Sep 2004 16:57:26 +0300 Subject: After merge fixes mysql-test/mysql-test-run.sh: Export MASTER_MYSOCK (used in some tests) mysql-test/t/alter_table.test: Use MASTER_MYSOCK instead of master.sock --- sql/sql_base.cc | 2 +- sql/table.cc | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 921e1c1ec42..ac5008717e6 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2458,7 +2458,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, 'name' of the item which may be used in the select list */ strmake(name_buff, db_name, sizeof(name_buff)-1); - my_casedn_str(name_buff); + my_casedn_str(files_charset_info, name_buff); db_name= name_buff; } diff --git a/sql/table.cc b/sql/table.cc index eb3e0e8d1a7..8b018d61e5a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1120,7 +1120,6 @@ void append_unescaped(String *res, const char *pos, uint length) res->append(*pos); break; } - pos++; } res->append('\''); } -- cgit v1.2.1 From 0c58737ad6700e844ab38cc2b1154509f0c236db Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Sep 2004 20:16:01 +0400 Subject: A fix and test case for Bug#4231 "Wrong result with MYSQL_TIME parameters": when unpacking binary time recieved from client, handle the case when length is 0: it means all MYSQL_TIME members are zero. include/my_time.h: Declaration for set_zero_time: a tiny piece of code, which I see no reason to not reuse. libmysql/libmysql.c: set_zero_time implementation is now shared between client and server. sql-common/my_time.c: set_zero_time implementation added. sql/sql_prepare.cc: A fix for Bug#4231 "Wrong result with MYSQL_TIME parameters": when unpacking binary time recieved from client, handle the case when length is 0: it means all MYSQL_TIME members are zero. tests/client_test.c: Test case for bug#4231 "Wrong result with MYSQL_TIME parameters" --- sql/sql_prepare.cc | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) (limited to 'sql') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 708ca3a516f..25b6434c184 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -329,15 +329,22 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len) } #ifndef EMBEDDED_LIBRARY + +/* + Read date/time/datetime parameter values from network (binary + protocol). See writing counterparts of these functions in + libmysql.c (store_param_{time,date,datetime}). +*/ + static void set_param_time(Item_param *param, uchar **pos, ulong len) { - ulong length; - uint day; + MYSQL_TIME tm; + ulong length= get_param_length(pos, len); - if ((length= get_param_length(pos, len)) >= 8) + if (length >= 8) { uchar *to= *pos; - TIME tm; + uint day; tm.neg= (bool) to[0]; day= (uint) sint4korr(to+1); @@ -359,21 +366,22 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len) tm.second= 59; } tm.day= tm.year= tm.month= 0; - - param->set_time(&tm, MYSQL_TIMESTAMP_TIME, - MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } + else + set_zero_time(&tm); + param->set_time(&tm, MYSQL_TIMESTAMP_TIME, + MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; } static void set_param_datetime(Item_param *param, uchar **pos, ulong len) { - uint length; + MYSQL_TIME tm; + ulong length= get_param_length(pos, len); - if ((length= get_param_length(pos, len)) >= 4) + if (length >= 4) { uchar *to= *pos; - TIME tm; tm.neg= 0; tm.year= (uint) sint2korr(to); @@ -394,21 +402,22 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len) tm.hour= tm.minute= tm.second= 0; tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0; - - param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME, - MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } + else + set_zero_time(&tm); + param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME, + MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; } static void set_param_date(Item_param *param, uchar **pos, ulong len) { - ulong length; - - if ((length= get_param_length(pos, len)) >= 4) + MYSQL_TIME tm; + ulong length= get_param_length(pos, len); + + if (length >= 4) { uchar *to= *pos; - TIME tm; /* Note, that though ranges of hour, minute and second are not checked here we rely on them being < 256: otherwise @@ -421,10 +430,11 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) tm.hour= tm.minute= tm.second= 0; tm.second_part= 0; tm.neg= 0; - - param->set_time(&tm, MYSQL_TIMESTAMP_DATE, - MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } + else + set_zero_time(&tm); + param->set_time(&tm, MYSQL_TIMESTAMP_DATE, + MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; } -- cgit v1.2.1 From b871ea386c706a63bb53876d143d06e4109b4169 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Sep 2004 18:12:05 -0500 Subject: errmsg.txt: Add GPL comment sql/share/czech/errmsg.txt: Add GPL comment sql/share/danish/errmsg.txt: Add GPL comment sql/share/dutch/errmsg.txt: Add GPL comment sql/share/english/errmsg.txt: Add GPL comment sql/share/estonian/errmsg.txt: Add GPL comment sql/share/french/errmsg.txt: Add GPL comment sql/share/german/errmsg.txt: Add GPL comment sql/share/greek/errmsg.txt: Add GPL comment sql/share/hungarian/errmsg.txt: Add GPL comment sql/share/italian/errmsg.txt: Add GPL comment sql/share/japanese/errmsg.txt: Add GPL comment sql/share/korean/errmsg.txt: Add GPL comment sql/share/norwegian-ny/errmsg.txt: Add GPL comment sql/share/norwegian/errmsg.txt: Add GPL comment sql/share/polish/errmsg.txt: Add GPL comment sql/share/portuguese/errmsg.txt: Add GPL comment sql/share/romanian/errmsg.txt: Add GPL comment sql/share/russian/errmsg.txt: Add GPL comment sql/share/slovak/errmsg.txt: Add GPL comment sql/share/spanish/errmsg.txt: Add GPL comment sql/share/swedish/errmsg.txt: Add GPL comment sql/share/ukrainian/errmsg.txt: Add GPL comment --- sql/share/czech/errmsg.txt | 16 ++++++++++++++++ sql/share/danish/errmsg.txt | 17 +++++++++++++++-- sql/share/dutch/errmsg.txt | 18 ++++++++++++++++-- sql/share/english/errmsg.txt | 17 +++++++++++++++-- sql/share/estonian/errmsg.txt | 19 ++++++++++++++++--- sql/share/french/errmsg.txt | 17 +++++++++++++++-- sql/share/german/errmsg.txt | 18 ++++++++++++++++-- sql/share/greek/errmsg.txt | 17 +++++++++++++++-- sql/share/hungarian/errmsg.txt | 20 ++++++++++++++++++-- sql/share/italian/errmsg.txt | 17 +++++++++++++++-- sql/share/japanese/errmsg.txt | 19 +++++++++++++++++-- sql/share/korean/errmsg.txt | 17 +++++++++++++++-- sql/share/norwegian-ny/errmsg.txt | 17 +++++++++++++++-- sql/share/norwegian/errmsg.txt | 17 +++++++++++++++-- sql/share/polish/errmsg.txt | 18 ++++++++++++++++-- sql/share/portuguese/errmsg.txt | 19 +++++++++++++++++-- sql/share/romanian/errmsg.txt | 18 ++++++++++++++++-- sql/share/russian/errmsg.txt | 20 ++++++++++++++++++-- sql/share/slovak/errmsg.txt | 17 +++++++++++++++-- sql/share/spanish/errmsg.txt | 19 +++++++++++++++++-- sql/share/swedish/errmsg.txt | 17 +++++++++++++++-- sql/share/ukrainian/errmsg.txt | 20 +++++++++++++++++--- 22 files changed, 350 insertions(+), 44 deletions(-) (limited to 'sql') diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index b6737df91e1..88ecaed386b 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -1,3 +1,19 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* Modifikoval Petr -B©najdr, snajdr@pvt.net, snajdr@cpress.cz v.0.01 ISO LATIN-8852-2 diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index ba50c78e92c..6210bf7788c 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Knud Riishøjgård knudriis@post.tele.dk 99 && Carsten H. Pedersen, carsten.pedersen@bitbybit.dk oct. 1999 / aug. 2001. */ diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 1b9c1025e69..c3607f4cd0f 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -1,6 +1,20 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind +/* Copyright (C) 2003 MySQL AB + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Dutch error messages (share/dutch/errmsg.txt) 2001-08-02 - Arjen Lentz (agl@bitbike.com) Completed earlier partial translation; worked on consistency and spelling. diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index edbf2357ff8..796751210dc 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ "hashchk", "isamchk", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 8ec5d4b29f0..8157a33836e 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -1,9 +1,22 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* - Copyright Abandoned 1997 MySQL AB - This file is public domain and comes with NO WARRANTY of any kind Esialgne tõlge: Tõnu Samuel (tonu@spam.ee) Parandanud ja täiendanud: Indrek Siitan (tfr@mysql.com) - */ "hashchk", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 3c5c827aa62..3c88ccc0378 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ "hashchk", "isamchk", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index 3960dcc2122..91f3f91a464 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -1,6 +1,20 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind +/* Copyright (C) 2003 MySQL AB + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Dirk Munzinger (dmun@4t2.com) Version: 07.06.2001 */ diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index 3e9a68f2b4b..aff7f8ba3c2 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ "hashchk", "isamchk", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 9da878981b0..60dc3204bb4 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -1,7 +1,23 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Translated by Feher Peter. Forditotta Feher Peter (feherp@mail.matav.hu) 1998 Updated May, 2000 - This file is public domain and comes with NO WARRANTY of any kind */ +*/ "hashchk", "isamchk", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 30dff93ebef..c51c69cf298 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ "hashchk", "isamchk", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 7e267261a2e..fb604923e4e 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -1,5 +1,20 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* 3.22.10-beta euc-japanese (ujis) text */ diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 1ad5432f4db..764cbb78740 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This È­ÀÏ is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ "hashchk", "isamchk", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index 234a53b53fb..424530ecf87 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Roy-Magne Mo rmo@www.hivolda.no 97 */ diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index e582786dc6e..73314ea647b 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Roy-Magne Mo rmo@www.hivolda.no 97 */ diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index a4d11046ea4..f24a54ec8e8 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -1,6 +1,20 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind +/* Copyright (C) 2003 MySQL AB + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Changed by Jaroslaw Lewandowski Charset ISO-8859-2 */ diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index 14c14270dc0..2810ac134b1 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -1,6 +1,21 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + /* Updated by Thiago Delgado Pinto - thiagodp@ieg.com.br - 06.07.2002 */ + "hashchk", "isamchk", "NÃO", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 8d2decdf23f..552b532c0a2 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -1,6 +1,20 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind +/* Copyright (C) 2003 MySQL AB + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Translated into Romanian by Stefan Saroiu e-mail: tzoompy@cs.washington.edu */ diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index 42845b57d76..172ee97c883 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -1,6 +1,22 @@ -/* Copyright 2003 MySQL AB; +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Translation done in 2003 by Egor Egorov; Ensita.NET, http://www.ensita.net/ - This file is public domain and comes with NO WARRANTY of any kind */ +*/ /* charset: KOI8-R */ "hashchk", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index 52ed69a238d..8467fad5b11 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* Translated from both E n g l i s h & C z e c h error messages diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 2ed3c19b68e..4ab76a64ca7 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -1,5 +1,20 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* Traduccion por Miguel Angel Fernandez Roiz -- LoboCom Sistemas, s.l. From June 28, 2001 translated by Miguel Solorzano miguel@mysql.com */ "hashchk", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 4fd05875b43..352a226ef23 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -1,5 +1,18 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - This file is public domain and comes with NO WARRANTY of any kind */ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ "hashchk", "isamchk", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 6036f4be2d5..188523ecf45 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -1,6 +1,20 @@ -/* Copyright Abandoned 1997 TCX DataKonsult AB & Monty Program KB & Detron HB - * This ÆÁÊÌ is public domain and comes with NO WARRANTY of any kind - * +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +/* * Ukrainian translation by Roman Festchook * Encoding: KOI8-U * Version: 13/09/2001 mysql-3.23.41 -- cgit v1.2.1 From 1b51f98e477c6f85ae3f4b82e41c5bc337de127c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 02:25:27 +0300 Subject: Remove extra '/' after mysql_real_data_home Add missing parameter to strxnmov() that caused some INTO OUTFILE commands to core dump mysql-test/mysql-test-run.sh: Ensure that clients used the supplied --socket argument mysql-test/r/lowercase_table.result: Remove tables used in other tests that may affect this one mysql-test/r/rename.result: Remove tables used in other tests that may affect this one mysql-test/t/lowercase_table.test: Remove tables used in other tests that may affect this one mysql-test/t/rename.test: Remove tables used in other tests that may affect this one sql/item_cmpfunc.cc: Remove not relevant comment sql/sql_class.cc: Add missing parameter to strxnmov() that caused some INTO OUTFILE commands to core dump sql/sql_load.cc: Remove extra '/' after mysql_real_data_home sql/sql_table.cc: Remove extra '/' after mysql_real_data_home --- sql/item_cmpfunc.cc | 1 - sql/sql_class.cc | 3 ++- sql/sql_load.cc | 2 +- sql/sql_table.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 4ddb648399a..f473d242b07 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2752,7 +2752,6 @@ longlong Item_cond_xor::val_int() Item *Item_func_not::neg_transformer(THD *thd) /* NOT(x) -> x */ { - // We should apply negation elimination to the argument of the NOT function return args[0]; } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 36b1b89f6bf..b103ee29095 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -891,7 +891,8 @@ static File create_file(THD *thd, char *path, sql_exchange *exchange, option|= MY_REPLACE_DIR; // Force use of db directory #endif - strxnmov(path, FN_REFLEN, mysql_real_data_home, thd->db ? thd->db : ""); + strxnmov(path, FN_REFLEN, mysql_real_data_home, thd->db ? thd->db : "", + NullS); (void) fn_format(path, exchange->file_name, path, "", option); if (!access(path, F_OK)) { diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 1f4905837f0..1ad9a6aa952 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -183,7 +183,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, strlen(ex->file_name)+strlen(mysql_real_data_home)+strlen(tdb)+3 < FN_REFLEN) { - (void) sprintf(name,"%s/%s/%s",mysql_data_home,tdb,ex->file_name); + (void) sprintf(name,"%s%s/%s",mysql_real_data_home,tdb,ex->file_name); unpack_filename(name,name); /* Convert to system format */ } else diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 408f3408346..58e3bc1d9ac 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1579,7 +1579,7 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, reg_ext)) DBUG_RETURN(-1); // protect buffer overflow - my_snprintf(dst_path, sizeof(dst_path), "%s/%s/%s", + my_snprintf(dst_path, sizeof(dst_path), "%s%s/%s", mysql_real_data_home, db, table_name); if (lock_and_wait_for_table_name(thd,table)) -- cgit v1.2.1 From 8838c971fa6ced3a8cb90c154bc5b9e0ec4bfba5 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 19:59:29 +0500 Subject: A fix (Bug #4980: union statement with () union () order by produces wrong explain). --- sql/sql_union.cc | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'sql') diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 8088737c0de..f79ff7967db 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -148,6 +148,10 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) { ha_rows records_at_start; lex->select=sl; +#if MYSQL_VERSION_ID < 40100 + if (describe && sl->linkage == NOT_A_SELECT) + break; // Skip extra item in case of 'explain' +#endif /* Don't use offset for the last union if there is no braces */ if (sl != lex_sl) { -- cgit v1.2.1 From 0d34c63536031ee2e104ec8cb94e5a1a3dd68ab4 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 10:56:55 -0500 Subject: sql_yacc.yy: Allow FROM or IN in SHOW KEYS, as in other SHOW statements. sql/sql_yacc.yy: Allow FROM or IN in SHOW KEYS, as in other SHOW statements. --- sql/sql_yacc.yy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sql') diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 2199a0c8be5..6b073db2e36 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -2917,7 +2917,7 @@ show_param: lex->select->select_limit= lex->thd->variables.select_limit; lex->select->offset_limit= 0L; } limit_clause - | keys_or_index FROM table_ident opt_db + | keys_or_index from_or_in table_ident opt_db { Lex->sql_command= SQLCOM_SHOW_KEYS; if ($4) -- cgit v1.2.1 From 14c4d0d72ee38960182cfd013d1f5f3fc9a73393 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 3 Sep 2004 23:28:49 +0400 Subject: A fix for bug#4368 '"like" fails in PreparedStatement, crashes server': the bug occurs when arguments of LIKE function are in differentcharacter sets. If these character sets are compatible, we create an item-converter. In prepared mode, this item needs to be created in memory of current prepared statement. mysql-test/r/ps.result: Test for Bug#4368 added. mysql-test/t/ps.test: A test case for bug#4368 '"like" fails in PreparedStatement, crashes server'. --- sql/item_cmpfunc.cc | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f473d242b07..85b22d1eddd 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -211,9 +211,20 @@ void Item_bool_func2::fix_length_and_dec() } else { - conv= new Item_func_conv_charset(args[weak],args[strong]->collation.collation); + THD *thd= current_thd; + /* + In case we're in statement prepare, create conversion item + in its memory: it will be reused on each execute. + */ + Item_arena *arena= thd->current_arena, backup; + if (arena->is_stmt_prepare()) + thd->set_n_backup_item_arena(arena, &backup); + conv= new Item_func_conv_charset(args[weak], + args[strong]->collation.collation); + if (arena->is_stmt_prepare()) + thd->restore_backup_item_arena(arena, &backup); conv->collation.set(args[weak]->collation.derivation); - conv->fix_fields(current_thd, 0, &conv); + conv->fix_fields(thd, 0, &conv); } args[weak]= conv ? conv : args[weak]; } -- cgit v1.2.1 From 1bf3ce01c48f980c183a8b88afdc0440a26da36d Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Sep 2004 11:42:18 +0200 Subject: Fixed BUG#5258: Stored procedure modified date is 0000-00-00. Althought techically not a but (as it's functioning as designed), it was decided that the design should be changed. Some users have a problem with dates being '0000-00-00' and the SQL standard specifies that the modification date should be the same as the creation date at creation. mysql-test/r/sp.result: New test case for BUG#5258. mysql-test/t/sp.test: New test case for BUG#5258. sql/sp.cc: Set the modification time at creation too. --- sql/sp.cc | 1 + 1 file changed, 1 insertion(+) (limited to 'sql') diff --git a/sql/sp.cc b/sql/sp.cc index cd52cff90a3..41d07bb9d40 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -371,6 +371,7 @@ db_create_routine(THD *thd, int type, sp_head *sp) table->field[MYSQL_PROC_FIELD_DEFINER]-> store(definer, (uint)strlen(definer), system_charset_info); ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_CREATED])->set_time(); + ((Field_timestamp *)table->field[MYSQL_PROC_FIELD_MODIFIED])->set_time(); table->field[MYSQL_PROC_FIELD_SQL_MODE]-> store((longlong)thd->variables.sql_mode); if (sp->m_chistics->comment.str) -- cgit v1.2.1 From c92b5349701ba68fa7ab97abf14933de8d6352fe Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Sep 2004 14:23:14 +0200 Subject: Fixed BUG#5000: SPs can be created with no default database. Easy to prevent crash, but the question was how to treat this case? We ended up implementing the "global" SPs (i.e. with no associated db), which were planned but left unresolved when SPs moved into dbs. So now things like "call .p()" work too. mysql-test/r/sp-error.result: New test case for BUG#5000, and "global" SPs in general. mysql-test/t/sp-error.test: New test case for BUG#5000, and "global" SPs in general. sql/sp.cc: Prevent crash when the new db is null. sql/sp_head.cc: Don't set the db part of the name to thd->db, we have already set it correctly in the provided name struct. Also, don't attempt to change "no-db" when executing an SP. sql/sql_yacc.yy: Added support for the "global SP" syntax, e.g ".p()". --- sql/sp.cc | 2 ++ sql/sp_head.cc | 12 ++++-------- sql/sql_yacc.yy | 19 ++++++++++++++++++- 3 files changed, 24 insertions(+), 9 deletions(-) (limited to 'sql') diff --git a/sql/sp.cc b/sql/sp.cc index 41d07bb9d40..6475b64eb18 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1054,6 +1054,8 @@ sp_use_new_db(THD *thd, char *newdb, char *olddb, uint olddblen, DBUG_ENTER("sp_use_new_db"); DBUG_PRINT("enter", ("newdb: %s", newdb)); + if (! newdb) + newdb= (char *)""; if (thd->db && thd->db[0]) { if (my_strcasecmp(system_charset_info, thd->db, newdb) == 0) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 4bb06fd8172..5222f8e6fbe 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -296,16 +296,11 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name) name->m_db.length, name->m_db.str, name->m_name.length, name->m_name.str)); /* We have to copy strings to get them into the right memroot */ + m_db.length= name->m_db.length; if (name->m_db.length == 0) - { - m_db.length= (thd->db ? strlen(thd->db) : 0); - m_db.str= strmake_root(root, (thd->db ? thd->db : ""), m_db.length); - } + m_db.str= NULL; else - { - m_db.length= name->m_db.length; m_db.str= strmake_root(root, name->m_db.str, name->m_db.length); - } m_name.length= name->m_name.length; m_name.str= strmake_root(root, name->m_name.str, name->m_name.length); @@ -453,7 +448,8 @@ sp_head::execute(THD *thd) #endif dbchanged= FALSE; - if ((ret= sp_use_new_db(thd, m_db.str, olddb, sizeof(olddb), 0, &dbchanged))) + if (m_db.length && + (ret= sp_use_new_db(thd, m_db.str, olddb, sizeof(olddb), 0, &dbchanged))) goto done; if ((ctx= thd->spcont)) diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ba3a36f2c34..17cc3b7d12c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1207,7 +1207,12 @@ create: ; sp_name: - IDENT_sys '.' IDENT_sys + '.' IDENT_sys + { + $$= new sp_name($2); + $$->init_qname(YYTHD); + } + | IDENT_sys '.' IDENT_sys { $$= new sp_name($1, $3); $$->init_qname(YYTHD); @@ -4312,6 +4317,18 @@ simple_expr: { $$= new Item_func_round($3,$5,1); } | TRUE_SYM { $$= new Item_int((char*) "TRUE",1,1); } + | '.' ident '(' udf_expr_list ')' + { + LEX *lex= Lex; + sp_name *name= new sp_name($2); + + name->init_qname(YYTHD); + sp_add_fun_to_lex(Lex, name); + if ($4) + $$= new Item_func_sp(name, *$4); + else + $$= new Item_func_sp(name); + } | ident '.' ident '(' udf_expr_list ')' { LEX *lex= Lex; -- cgit v1.2.1 From 33efc9677d6f6a68d3dba69f4c036856ac4af5fe Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Sep 2004 06:59:26 +0300 Subject: After merge fixes of merge with 4.1 that included the new arena code. Fixed (together with Guilhem) bugs in mysqlbinlog regarding --offset Prefix addresses with 0x for easier comparisons of debug logs Fixed problem where MySQL choosed index-read even if there would be a much better range on the same index This fix changed some 'index' queries to 'range' queries in the test suite Don't create 'dummy' WHERE clause for trivial WHERE clauses where we can remove the WHERE clause. This fix removed of a lot of 'Using where' notes in the test suite. Give NOTE instead of WARNING if table/function doesn't exists when using DROP IF EXISTS Give NOTE instead of WARNING for safe field-type conversions Makefile.am: Don't automaticly update files from bk client/mysqlbinlog.cc: Merge with 4.1 (+ apply bug fixes for --offset and --start-position) include/my_sys.h: Faster clear_alloc_root() mysql-test/r/bdb.result: Updated results after merge mysql-test/r/create.result: Updated results after merge mysql-test/r/func_group.result: Updated results after merge mysql-test/r/func_if.result: Updated results after merge mysql-test/r/heap_btree.result: Updated results after merge mysql-test/r/index_merge.result: Updated results after merge mysql-test/r/index_merge_ror.result: Updated results after merge mysql-test/r/innodb.result: Updated results after merge mysql-test/r/join_outer.result: Updated results after merge mysql-test/r/mysqlbinlog2.result: Updated results after merge mysql-test/r/negation_elimination.result: Updated results after merge mysql-test/r/null.result: Updated results after merge Added more tests mysql-test/r/null_key.result: Updated results after merge Added more tests mysql-test/r/order_by.result: Updated results after merge mysql-test/r/range.result: Updated results after merge Added more tests mysql-test/r/rpl_charset.result: Updated results after merge mysql-test/r/sp-error.result: Updated results after merge mysql-test/r/sp.result: Updated results after merge Added delete of some stored procedures in an attempt to be able to re-run test even if it aborts in the middle mysql-test/r/type_blob.result: Updated results after merge (Some warnings are now notes) mysql-test/r/user_var.result: Updated results after merge Added more tests mysql-test/r/variables.result: Updated results after merge mysql-test/r/view.result: Updated results after merge mysql-test/t/mysqlbinlog2.test: Updated tests to use new positions mysql-test/t/null.test: More tests mysql-test/t/null_key.test: More tests mysql-test/t/range.test: More tests mysql-test/t/rpl_charset.test: Avoid big diffs in the future if tests changes mysql-test/t/sp-error.test: Updated error numbers mysql-test/t/sp-security.test: Updated error numbers mysql-test/t/sp.test: Updated results after merge Added delete of some stored procedures in an attempt to be able to re-run test even if it aborts in the middle mysql-test/t/user_var.test: More tests mysql-test/t/view.test: Updated error numbers mysys/my_alloc.c: Write into debug log the address of the allocated area sql/ha_isam.cc: Prefix addresses with 0x for easier comparisons of debug logs sql/ha_myisam.cc: Prefix addresses with 0x for easier comparisons of debug logs sql/ha_ndbcluster.cc: Add missing enum to switch sql/handler.cc: remove compiler warning sql/item.cc: More debugging Simple cleanup sql/item.h: Move Item::cleanup() to item.cc sql/item_cmpfunc.cc: Fix arena code sql/item_subselect.cc: After merge fixes sql/item_subselect.h: After merge fixes sql/item_sum.cc: Updated comment sql/log_event.cc: Remove wrong test sql/mysql_priv.h: Indentation fixes sql/mysqld.cc: After merge fixes Added 0x to pointers in debug log sql/opt_range.cc: Fixed problem where MySQL choosed index-read even if there would be a much better range on the same index This fix changed some 'index' queries to 'range' queries in the test suite sql/set_var.cc: Indentation fixes sql/sp_head.cc: Set state to INITIALIZED to make SP work with new arena code sql/sql_base.cc: After merge fixes sql/sql_class.cc: More debugging Use clear_alloc_root() instead of init_alloc_root() as the former is faster sql/sql_class.h: New method 'only_prepare()' sql/sql_lex.cc: After merge fixes sql/sql_lex.h: After merge fixes sql/sql_parse.cc: Fix for timezone tables. (The old way to add timezone tables to global list in 'create_total_list' doesn't work anymore) Give NOTE instead of WARNING if table/function doesn't exists when using DROP IF EXISTS sql/sql_prepare.cc: After merge fixes sql/sql_select.cc: Don't create 'dummy' WHERE clause for trivial WHERE clauses where we can remove the WHERE clause. This fix removed of a lot of 'Using where' notes in the test suite sql/sql_table.cc: Give NOTE instead of WARNING if table/function doesn't exists when using DROP IF EXISTS sql/sql_union.cc: After merge fix sql/sql_view.cc: After merge fix sql/table.cc: After merge fix sql/tztime.cc: Update timezone table handling to use new table lists structure sql/tztime.h: Update timezone table handling to use new table lists structure sql/unireg.cc: Use 0x before pointers --- sql/ha_isam.cc | 2 +- sql/ha_myisam.cc | 2 +- sql/ha_ndbcluster.cc | 2 ++ sql/handler.cc | 2 +- sql/item.cc | 15 ++++++++++++--- sql/item.h | 8 +------- sql/item_cmpfunc.cc | 10 +++------- sql/item_subselect.cc | 3 +-- sql/item_subselect.h | 2 -- sql/item_sum.cc | 2 +- sql/log_event.cc | 11 ++++++----- sql/mysql_priv.h | 3 ++- sql/mysqld.cc | 10 +++++++--- sql/opt_range.cc | 22 ++++++++++++++++------ sql/set_var.cc | 2 +- sql/sp_head.cc | 8 +++++--- sql/sql_base.cc | 27 ++++++++++---------------- sql/sql_class.cc | 4 +++- sql/sql_class.h | 4 ++++ sql/sql_lex.cc | 11 +++-------- sql/sql_lex.h | 2 +- sql/sql_parse.cc | 26 ++++++++++++++++++++------ sql/sql_prepare.cc | 11 +++++------ sql/sql_select.cc | 52 ++++++++++++++++++++++++++++++++------------------- sql/sql_table.cc | 2 +- sql/sql_union.cc | 5 +++-- sql/sql_view.cc | 8 +++++--- sql/table.cc | 9 +++++---- sql/tztime.cc | 49 +++++++++++++++++++++++++++++++----------------- sql/tztime.h | 2 +- sql/unireg.cc | 2 +- 31 files changed, 187 insertions(+), 131 deletions(-) (limited to 'sql') diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 85ab25a31d9..2fd75462329 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -330,7 +330,7 @@ int ha_isam::create(const char *name, register TABLE *form, } } } - DBUG_PRINT("loop",("found: %lx recpos: %d minpos: %d length: %d", + DBUG_PRINT("loop",("found: 0x%lx recpos: %d minpos: %d length: %d", found,recpos,minpos,length)); if (recpos != minpos) { // Reserved space (Null bits?) diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 89288d6059f..4a6f2c556bf 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -1435,7 +1435,7 @@ int ha_myisam::create(const char *name, register TABLE *table_arg, } } } - DBUG_PRINT("loop",("found: %lx recpos: %d minpos: %d length: %d", + DBUG_PRINT("loop",("found: 0x%lx recpos: %d minpos: %d length: %d", found,recpos,minpos,length)); if (recpos != minpos) { // Reserved space (Null bits?) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 815aed13ce3..09cb0c0f02d 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2297,6 +2297,8 @@ int ha_ndbcluster::extra(enum ha_extra_function operation) break; case HA_EXTRA_CHANGE_KEY_TO_DUP: DBUG_PRINT("info", ("HA_EXTRA_CHANGE_KEY_TO_DUP")); + case HA_EXTRA_KEYREAD_PRESERVE_FIELDS: + DBUG_PRINT("info", ("HA_EXTRA_KEYREAD_PRESERVE_FIELDS")); break; } diff --git a/sql/handler.cc b/sql/handler.cc index 640c4f3710d..e7e1c807306 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -483,7 +483,7 @@ int ha_commit_trans(THD *thd, THD_TRANS* trans) if (trans == &thd->transaction.all && mysql_bin_log.is_open() && my_b_tell(&thd->transaction.trans_log)) { - if (error= wait_if_global_read_lock(thd, 0, 0)) + if ((error= wait_if_global_read_lock(thd, 0, 0))) { /* Note that ROLLBACK [TO SAVEPOINT] does not have this test; it's diff --git a/sql/item.cc b/sql/item.cc index ecbe2d22fa4..5fa6b2400df 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -105,6 +105,15 @@ void Item::print_item_w_name(String *str) } +void Item::cleanup() +{ + DBUG_ENTER("Item::cleanup"); + DBUG_PRINT("info", ("Item: 0x%lx", this)); + DBUG_PRINT("info", ("Type: %d", (int)type())); + fixed=0; + DBUG_VOID_RETURN; +} + Item_ident::Item_ident(const char *db_name_par,const char *table_name_par, const char *field_name_par) :orig_db_name(db_name_par), orig_table_name(table_name_par), @@ -1397,9 +1406,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) } if (!tmp) return -1; - else if (!refer) + if (!refer) return 1; - else if (tmp == not_found_field && refer == (Item **)not_found_item) + if (tmp == not_found_field && refer == (Item **)not_found_item) { if (upward_lookup) { @@ -1903,7 +1912,7 @@ bool Item::send(Protocol *protocol, String *buffer) { bool result; enum_field_types type; - LINT_INIT(result); + LINT_INIT(result); // Will be set if null_value == 0 switch ((type=field_type())) { default: diff --git a/sql/item.h b/sql/item.h index 4d3f1736b4e..a9e4831b40b 100644 --- a/sql/item.h +++ b/sql/item.h @@ -143,13 +143,7 @@ public: } /*lint -e1509 */ void set_name(const char *str,uint length, CHARSET_INFO *cs); void init_make_field(Send_field *tmp_field,enum enum_field_types type); - virtual void cleanup() - { - DBUG_ENTER("Item::cleanup"); - DBUG_PRINT("info", ("Type: %d", (int)type())); - fixed=0; - DBUG_VOID_RETURN; - } + virtual void cleanup(); virtual void make_field(Send_field *field); virtual bool fix_fields(THD *, struct st_table_list *, Item **); /* diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index f6daf0f5ed4..0356ea02ada 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -217,14 +217,10 @@ void Item_bool_func2::fix_length_and_dec() in its memory: it will be reused on each execute. */ Item_arena *arena= thd->current_arena, backup; - if (!arena->is_stmt_prepare()) - arena= 0; - else - thd->set_n_backup_item_arena(arena, &backup); + thd->set_n_backup_item_arena(arena, &backup); conv= new Item_func_conv_charset(args[weak], args[strong]->collation.collation); - if (arena) - thd->restore_backup_item_arena(arena, &backup); + thd->restore_backup_item_arena(arena, &backup); conv->collation.set(args[weak]->collation.derivation); conv->fix_fields(thd, 0, &conv); } @@ -1625,7 +1621,7 @@ cmp_item* cmp_item_row::make_same() cmp_item_row::~cmp_item_row() { DBUG_ENTER("~cmp_item_row"); - DBUG_PRINT("enter",("this: %lx", this)); + DBUG_PRINT("enter",("this: 0x%lx", this)); if (comparators) { for (uint i= 0; i < n; i++) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 6d86d7d4b2d..23dbcf8af48 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -137,7 +137,6 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) DBUG_ASSERT(fixed == 0); engine->set_thd((thd= thd_param)); - arena= thd->current_arena; if (check_stack_overrun(thd, (gptr)&res)) return 1; @@ -872,7 +871,7 @@ Item_in_subselect::single_value_transformer(JOIN *join, ER_SELECT_REDUCED, warn_buff); } result= RES_REDUCE; - goto end; + goto err; } } } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index e870feddedf..ed3dbfa9855 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -36,8 +36,6 @@ class Item_subselect :public Item_result_field protected: /* thread handler, will be assigned in fix_fields only */ THD *thd; - /* Item_arena used or 0 */ - Item_arena *arena; /* substitution instead of subselect in case of optimization */ Item *substitution; /* unit of subquery */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 13b6329daae..bfa0f86c744 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -64,7 +64,7 @@ Item_sum::Item_sum(THD *thd, Item_sum *item): /* - Save copy of arguments if we prepare prepared statement + Save copy of arguments if we are preparing a prepared statement (arguments can be rewritten in get_tmp_table_item()) SYNOPSIS diff --git a/sql/log_event.cc b/sql/log_event.cc index 97e041774f8..0c3b36c37b5 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1266,6 +1266,8 @@ void Query_log_event::print(FILE* file, bool short_form, { // TODO: print the catalog ?? char buff[40],*end; // Enough for SET TIMESTAMP + bool different_db= 1; + if (!short_form) { print_header(file); @@ -1273,9 +1275,7 @@ void Query_log_event::print(FILE* file, bool short_form, (ulong) thread_id, (ulong) exec_time, error_code); } - bool different_db= 1; - - if (db && last_event_info->db) + if (db) { if ((different_db = memcmp(last_event_info->db, db, db_len + 1))) memcpy(last_event_info->db, db, db_len + 1); @@ -2300,7 +2300,7 @@ void Load_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_ev } bool different_db= 1; - if (db && last_event_info->db) + if (db) { /* If the database is different from the one of the previous statement, we @@ -2845,7 +2845,8 @@ int Intvar_log_event::write_data(IO_CACHE* file) */ #ifdef MYSQL_CLIENT -void Intvar_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_event_info) +void Intvar_log_event::print(FILE* file, bool short_form, + LAST_EVENT_INFO* last_event_info) { char llbuff[22]; const char *msg; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index c668e152df5..73ac000d953 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1038,7 +1038,8 @@ void mysql_lock_abort_for_thread(THD *thd, TABLE *table); MYSQL_LOCK *mysql_lock_merge(MYSQL_LOCK *a,MYSQL_LOCK *b); bool lock_global_read_lock(THD *thd); void unlock_global_read_lock(THD *thd); -bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, bool is_not_commit); +bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, + bool is_not_commit); void start_waiting_global_read_lock(THD *thd); void make_global_read_lock_block_commit(THD *thd); diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 81651862255..24f6c4a3fa9 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -528,14 +528,14 @@ static void close_connections(void) (void) pthread_mutex_lock(&LOCK_manager); if (manager_thread_in_use) { - DBUG_PRINT("quit",("killing manager thread: %lx",manager_thread)); + DBUG_PRINT("quit",("killing manager thread: 0x%lx",manager_thread)); (void) pthread_cond_signal(&COND_manager); } (void) pthread_mutex_unlock(&LOCK_manager); /* kill connection thread */ #if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) && !defined(__NETWARE__) - DBUG_PRINT("quit",("waiting for select thread: %lx",select_thread)); + DBUG_PRINT("quit",("waiting for select thread: 0x%lx",select_thread)); (void) pthread_mutex_lock(&LOCK_thread_count); while (select_thread_in_use) @@ -2476,7 +2476,7 @@ static void init_ssl() ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); - DBUG_PRINT("info",("ssl_acceptor_fd: %lx", (long) ssl_acceptor_fd)); + DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd)); if (!ssl_acceptor_fd) opt_use_ssl = 0; } @@ -4331,6 +4331,10 @@ Disable with --skip-isam.", log and this option justs turns on --log-bin instead.", (gptr*) &opt_update_logname, (gptr*) &opt_update_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"log-warnings", 'W', "Log some not critical warnings to the log file.", + (gptr*) &global_system_variables.log_warnings, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + 0, 0, 0}, {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES, "INSERT/DELETE/UPDATE has lower priority than selects.", (gptr*) &global_system_variables.low_priority_updates, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index e0e2b5c8045..e3a130f55f0 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1633,8 +1633,9 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, if (!head->used_keys.is_clear_all()) { int key_for_use= find_shortest_key(head, &head->used_keys); - double key_read_time= get_index_only_read_time(¶m, records, - key_for_use); + double key_read_time= (get_index_only_read_time(¶m, records, + key_for_use) + + (double) records / TIME_FOR_COMPARE); DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, " "read time %g", key_for_use, key_read_time)); if (key_read_time < read_time) @@ -2111,6 +2112,12 @@ skip_to_ror_scan: NOTES It is assumed that we will read trough the whole key range and that all key blocks are half full (normally things are much better). + + TODO: + Move this to handler->read_time() by adding a flag 'index-only-read' to + this call. The reason for doing this is that the current function doesn't + handle the case when the row is stored in the b-tree (like in innodb + clustered index) */ inline double get_index_only_read_time(const PARAM* param, ha_rows records, @@ -2125,6 +2132,7 @@ inline double get_index_only_read_time(const PARAM* param, ha_rows records, return read_time; } + typedef struct st_ror_scan_info { uint idx; /* # of used key in param->keys */ @@ -2992,7 +3000,8 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, !(pk_is_clustered && keynr == param->table->primary_key)) { /* We can resolve this by only reading through this key. */ - found_read_time= get_index_only_read_time(param,found_records,keynr); + found_read_time= (get_index_only_read_time(param,found_records,keynr)+ + (double) found_records / TIME_FOR_COMPARE); } else { @@ -3673,7 +3682,8 @@ tree_and(PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2) } result_keys.set_bit(key1 - tree1->keys); #ifdef EXTRA_DEBUG - (*key1)->test_use_count(*key1); + if (*key1) + (*key1)->test_use_count(*key1); #endif } } @@ -4654,7 +4664,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root) ulong count=count_key_part_usage(root,pos->next_key_part); if (count > pos->next_key_part->use_count) { - sql_print_error("Note: Use_count: Wrong count for key at %lx, %lu should be %lu", + sql_print_error("Note: Use_count: Wrong count for key at 0x%lx, %lu should be %lu", pos,pos->next_key_part->use_count,count); return; } @@ -4662,7 +4672,7 @@ void SEL_ARG::test_use_count(SEL_ARG *root) } } if (e_count != elements) - sql_print_error("Warning: Wrong use count: %u (should be %u) for tree at %lx", + sql_print_error("Warning: Wrong use count: %u (should be %u) for tree at 0x%lx", e_count, elements, (gptr) this); } diff --git a/sql/set_var.cc b/sql/set_var.cc index d92d5eb42b2..4b347f91869 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2404,7 +2404,7 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) #endif if (!(var->save_result.time_zone= - my_tz_find(res, thd->lex->time_zone_tables_used))) + my_tz_find(res, thd->lex->time_zone_tables_used))) { my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL"); return 1; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 16d13154263..d0ffe3fa051 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -262,6 +262,7 @@ sp_head::sp_head() { DBUG_ENTER("sp_head::sp_head"); + state= INITIALIZED; m_backpatch.empty(); m_lex.empty(); DBUG_VOID_RETURN; @@ -498,8 +499,7 @@ sp_head::execute(THD *thd) } } while (ret == 0 && !thd->killed && !thd->query_error); - if (thd->current_arena) - cleanup_items(thd->current_arena->free_list); + cleanup_items(thd->current_arena->free_list); thd->current_arena= old_arena; done: @@ -945,7 +945,9 @@ sp_head::restore_thd_mem_root(THD *thd) { DBUG_ENTER("sp_head::restore_thd_mem_root"); Item *flist= free_list; // The old list - set_item_arena(thd); // Get new fre_list and mem_root + set_item_arena(thd); // Get new free_list and mem_root + state= INITIALIZED; + DBUG_PRINT("info", ("mem_root 0x%lx returned from thd mem root 0x%lx", (ulong) &mem_root, (ulong) &thd->mem_root)); thd->free_list= flist; // Restore the old one diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 0aee91af0da..f07b93ec9f0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1732,10 +1732,10 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) { for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first; cursor; - cursor=cursor->next) + cursor=cursor->next_local) { - if (cursor->table_list) - cursor->table= cursor->table_list->table; + if (cursor->correspondent_table) + cursor->table= cursor->correspondent_table->table; } } } @@ -1948,15 +1948,8 @@ find_field_in_table(THD *thd, TABLE_LIST *table_list, *ref= trans[i]; else { - Item_arena *arena= thd->current_arena, backup; - if (!arena->is_stmt_prepare()) - arena= 0; - else - thd->set_n_backup_item_arena(arena, &backup); - *ref= new Item_ref(trans + i, 0, table_list->view_name.str, + *ref= new Item_ref(trans + i, ref, table_list->view_name.str, item_name); - if (arena) - thd->restore_backup_item_arena(arena, &backup); /* as far as Item_ref have defined refernce it do not need tables */ if (*ref) (*ref)->fix_fields(thd, 0, ref); @@ -2440,14 +2433,14 @@ int setup_wild(THD *thd, TABLE_LIST *tables, List &fields, if (!wild_num) return 0; Item_arena *arena= thd->current_arena, backup; - if (!arena->is_stmt_prepare()) - arena= 0; // For easier test /* - If we are in preparing prepared statement phase then we have change - temporary mem_root to statement mem root to save changes of SELECT list + Don't use arena if we are not in prepared statements or stored procedures + For PS/SP we have to use arena to remember the changes */ - if (arena) + if (arena->state == Item_arena::CONVENTIONAL_EXECUTION) + arena= 0; // For easier test later one + else thd->set_n_backup_item_arena(arena, &backup); List_iterator it(fields); @@ -3057,7 +3050,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) err: if (arena) - thd->restore_backup_item_arena(arena, &backup); + thd->restore_backup_item_arena(arena, &backup); DBUG_RETURN(1); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 456b58ee95e..a807a4b75e5 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -1472,8 +1472,10 @@ void Statement::end_statement() void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup) { + DBUG_ENTER("Item_arena::set_n_backup_item_arena"); backup->set_item_arena(this); set_item_arena(set); + DBUG_VOID_RETURN; } @@ -1482,7 +1484,7 @@ void Item_arena::restore_backup_item_arena(Item_arena *set, Item_arena *backup) set->set_item_arena(this); set_item_arena(backup); // reset backup mem_root to avoid its freeing - init_alloc_root(&backup->mem_root, 0, 0); + clear_alloc_root(&backup->mem_root); } void Item_arena::set_item_arena(Item_arena *set) diff --git a/sql/sql_class.h b/sql/sql_class.h index 2b941b317f6..1612ab6fb17 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1031,6 +1031,10 @@ public: return 0; #endif } + inline bool only_prepare() + { + return command == COM_PREPARE; + } inline gptr trans_alloc(unsigned int size) { return alloc_root(&transaction.mem_root,size); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index b0707955522..1f0b63b5df3 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1014,7 +1014,7 @@ void st_select_lex::init_query() subquery_in_having= explicit_limit= 0; first_execution= 1; first_cond_optimization= 1; - parsing_place= SELECT_LEX_NODE::NO_MATTER; + parsing_place= NO_MATTER; no_wrap_view_item= 0; } @@ -1659,11 +1659,6 @@ void st_select_lex_unit::set_limit(SELECT_LEX *values, } -st_lex::st_lex() - :result(0) -{} - - /* Unlink first table from global table list and first table from outer select list (lex->select_lex) @@ -1793,10 +1788,10 @@ void st_lex::link_first_table_back(TABLE_LIST *first, void st_select_lex::fix_prepare_information(THD *thd, Item **conds) { - if (thd->current_arena && first_execution) + if (thd->current_arena->is_stmt_prepare() && first_execution) { - prep_where= where; first_execution= 0; + prep_where= where; } } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index de0d5d90f16..d9eff46ea48 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -713,7 +713,7 @@ typedef struct st_lex */ bool empty_field_list_on_rset; - st_lex() + st_lex() :result(0) { bzero((char *)&spfuns, sizeof(spfuns)); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 59a3e4b545b..a1180d29e99 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1958,6 +1958,20 @@ mysql_execute_command(THD *thd) } #endif /* !HAVE_REPLICATION */ + if (lex->time_zone_tables_used) + { + TABLE_LIST *tmp; + if ((tmp= my_tz_get_table_list(thd, &lex->query_tables_last)) == + &fake_time_zone_tables_list) + { + send_error(thd, 0); + DBUG_RETURN(-1); + } + lex->time_zone_tables_used= tmp; + if (!all_tables) + all_tables= tmp; + } + /* When option readonly is set deny operations which change tables. Except for the replication thread and the 'super' users. @@ -2393,11 +2407,11 @@ mysql_execute_command(THD *thd) if (lex->create_info.used_fields & HA_CREATE_USED_UNION) { TABLE_LIST *tab; - for (tab= select_tables; tab; tab= tab->next) + for (tab= select_tables; tab; tab= tab->next_local) { - if (find_real_table_in_list((TABLE_LIST*) lex->create_info. - merge_list.first, - select_tables->db, tab->real_name)) + if (find_table_in_local_list((TABLE_LIST*) lex->create_info. + merge_list.first, + select_tables->db, tab->real_name)) { net_printf(thd, ER_UPDATE_TABLE_USED, tab->real_name); goto create_error; @@ -3767,7 +3781,7 @@ purposes internal to the MySQL server", MYF(0)); case SP_KEY_NOT_FOUND: if (lex->drop_if_exists) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST), SP_COM_STRING(lex), lex->spname->m_name.str); res= 0; @@ -4699,7 +4713,7 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, new_field->sql_type= FIELD_TYPE_BLOB; sprintf(warn_buff, ER(ER_AUTO_CONVERT), field_name, "CHAR", (cs == &my_charset_bin) ? "BLOB" : "TEXT"); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_AUTO_CONVERT, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT, warn_buff); /* fall through */ case FIELD_TYPE_BLOB: diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 5fccdd624de..c84d6457d4f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -414,6 +414,7 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len) *pos+= length; } + static void set_param_date(Item_param *param, uchar **pos, ulong len) { MYSQL_TIME tm; @@ -1864,7 +1865,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length) } thd->set_statement(&thd->stmt_backup); - thd->current_arena= 0; + thd->current_arena= thd; DBUG_VOID_RETURN; set_params_data_err: @@ -1891,6 +1892,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) String expanded_query; DBUG_ENTER("mysql_sql_stmt_execute"); + DBUG_ASSERT(thd->free_list == NULL); + if (!(stmt= (Prepared_statement*)thd->stmt_map.find_by_name(stmt_name))) { my_error(ER_UNKNOWN_STMT_HANDLER, MYF(0), stmt_name->length, @@ -1906,9 +1909,8 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) DBUG_VOID_RETURN; } - DBUG_ASSERT(thd->free_list == NULL); - thd->set_n_backup_statement(stmt, &thd->stmt_backup); + thd->set_statement(stmt); if (stmt->set_params_from_vars(stmt, thd->stmt_backup.lex->prepared_stmt_params, &expanded_query)) @@ -1916,9 +1918,7 @@ void mysql_sql_stmt_execute(THD *thd, LEX_STRING *stmt_name) my_error(ER_WRONG_ARGUMENTS, MYF(0), "EXECUTE"); send_error(thd); } - thd->current_arena= stmt; execute_stmt(thd, stmt, &expanded_query); - thd->current_arena= 0; DBUG_VOID_RETURN; } @@ -1941,7 +1941,6 @@ static void execute_stmt(THD *thd, Prepared_statement *stmt, { DBUG_ENTER("execute_stmt"); - thd->set_n_backup_statement(stmt, &thd->stmt_backup); reset_stmt_for_execute(thd, stmt->lex); if (expanded_query->length() && diff --git a/sql/sql_select.cc b/sql/sql_select.cc index db3a0c90141..2d8ea72ed51 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -4910,13 +4910,13 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) JOIN_TAB *tab=join->join_tab+i; JOIN_TAB *first_inner_tab= tab->first_inner; table_map current_map= tab->table->map; + bool use_quick_range=0; /* Following force including random expression in last table condition. It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5 */ if (i == join->tables-1) current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT; - bool use_quick_range=0; used_tables|=current_map; if (tab->type == JT_REF && tab->quick && @@ -4935,11 +4935,26 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) COND *tmp=make_cond_for_table(cond,used_tables,current_map); if (!tmp && tab->quick) { // Outer join - /* - Hack to handle the case where we only refer to a table - in the ON part of an OUTER JOIN. - */ - tmp=new Item_int((longlong) 1,1); // Always true + if (tab->type != JT_ALL) + { + /* + Don't use the quick method + We come here in the case where we have 'key=constant' and + the test is removed by make_cond_for_table() + */ + delete tab->quick; + tab->quick= 0; + } + else + { + /* + Hack to handle the case where we only refer to a table + in the ON part of an OUTER JOIN. In this case we want the code + below to check if we should use 'quick' instead. + */ + tmp= new Item_int((longlong) 1,1); // Always true + } + } if (tmp) { @@ -5989,6 +6004,7 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) NESTED_JOIN *nested_join; TABLE_LIST *prev_table= 0; List_iterator li(*join_list); + DBUG_ENTER("simplify_joins"); /* Try to simplify join operations from join_list. @@ -6122,36 +6138,34 @@ simplify_joins(JOIN *join, List *join_list, COND *conds, bool top) li.replace(nested_join->join_list); } } - return conds; + DBUG_RETURN(conds); } static COND * optimize_cond(JOIN *join, COND *conds, Item::cond_result *cond_value) { + THD *thd= join->thd; SELECT_LEX *select= thd->lex->current_select; DBUG_ENTER("optimize_cond"); - THD *thd= join->thd; - SELECT_LEX *select= thd->lex->current_select; if (select->first_cond_optimization) { - Item_arena *arena, backup; + /* + The following code will allocate the new items in a permanent + MEMROOT for prepared statements and stored procedures. + */ + + Item_arena *arena=thd->current_arena, backup; select->first_cond_optimization= 0; - arena= thd->current_arena; - if (!arena->is_stmt_prepare()) - arena= 0; - else - thd->set_n_backup_item_arena(arena, &backup); + thd->set_n_backup_item_arena(arena, &backup); /* Convert all outer joins to inner joins if possible */ conds= simplify_joins(join, join->join_list, conds, TRUE); select->prep_where= conds ? conds->copy_andor_structure(thd) : 0; - select->first_cond_optimization= 0; - if (arena) - thd->restore_backup_item_arena(arena, &backup); + thd->restore_backup_item_arena(arena, &backup); } if (!conds) @@ -6161,7 +6175,7 @@ optimize_cond(JOIN *join, COND *conds, Item::cond_result *cond_value) } else { - DBUG_EXECUTE("where", print_where(conds, "after negation elimination");); + DBUG_EXECUTE("where", print_where(conds, "original");); /* change field = field to field = const for each found field = const */ propagate_cond_constants((I_List *) 0,conds,conds); /* diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 03c20be198e..1d4414426d0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2209,7 +2209,7 @@ table_exists: char warn_buff[MYSQL_ERRMSG_SIZE]; my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TABLE_EXISTS_ERROR), table_name); - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_TABLE_EXISTS_ERROR,warn_buff); res= 0; } diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 827d75a9848..d23e11d5443 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -290,13 +290,14 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, thd_arg->lex->current_select= lex_select_save; if (!item_list.elements) { + Field **field; Item_arena *arena= thd->current_arena; Item_arena backup; if (!arena->is_stmt_prepare()) - arena= 0 + arena= 0; else thd->set_n_backup_item_arena(arena, &backup); - Field **field; + for (field= table->field; *field; field++) { Item_field *item= new Item_field(*field); diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 183b55ca12f..8cc342e99fe 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -271,9 +271,9 @@ int mysql_create_view(THD *thd, } #endif - if (wait_if_global_read_lock(thd, 0)) + if (wait_if_global_read_lock(thd, 0, 0)) { - VOID(pthread_mutex_unlock(&LOCK_open)); + res= -1; goto err; } VOID(pthread_mutex_lock(&LOCK_open)); @@ -513,7 +513,9 @@ mysql_make_view(File_parser *parser, TABLE_LIST *table) will be TRUE as far as we make new table cache). */ Item_arena *arena= thd->current_arena, backup; - if (arena) + if (!arena->is_stmt_prepare()) + arena= 0; + else thd->set_n_backup_item_arena(arena, &backup); /* init timestamp */ diff --git a/sql/table.cc b/sql/table.cc index 5d0c60718d3..d07d2ca085d 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -85,7 +85,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, SQL_CRYPT *crypted=0; MEM_ROOT *old_root; DBUG_ENTER("openfrm"); - DBUG_PRINT("enter",("name: '%s' form: %lx",name,outparam)); + DBUG_PRINT("enter",("name: '%s' form: 0x%lx",name,outparam)); error=1; disk_buff=NULL; @@ -1548,9 +1548,7 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) /* view fields translation table */ if (!(transl= - (Item**)(thd->current_arena ? - thd->current_arena : - thd)->alloc(select->item_list.elements * sizeof(Item*)))) + (Item**)(thd->current_arena->alloc(select->item_list.elements * sizeof(Item*))))) { DBUG_RETURN(1); } @@ -1585,6 +1583,9 @@ bool st_table_list::setup_ancestor(THD *thd, Item **conds) if (where) { Item_arena *arena= thd->current_arena, backup; + if (!arena->is_stmt_prepare()) + arena= 0; // For easier test + if (!where->fixed && where->fix_fields(thd, ancestor, &where)) goto err; diff --git a/sql/tztime.cc b/sql/tztime.cc index af9af530fec..5b7162a6a0e 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1406,20 +1406,30 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, for opening of time zone tables from preallocated array. */ -void -tz_init_table_list(TABLE_LIST *tz_tabs) +static void +tz_init_table_list(TABLE_LIST *tz_tabs, TABLE_LIST ***global_next_ptr) { bzero(tz_tabs, sizeof(TABLE_LIST) * 4); tz_tabs[0].alias= tz_tabs[0].real_name= (char*)"time_zone_name"; tz_tabs[1].alias= tz_tabs[1].real_name= (char*)"time_zone"; tz_tabs[2].alias= tz_tabs[2].real_name= (char*)"time_zone_transition_type"; tz_tabs[3].alias= tz_tabs[3].real_name= (char*)"time_zone_transition"; - tz_tabs[0].next= tz_tabs+1; - tz_tabs[1].next= tz_tabs+2; - tz_tabs[2].next= tz_tabs+3; + tz_tabs[0].next_global= tz_tabs[0].next_local= tz_tabs+1; + tz_tabs[1].next_global= tz_tabs[1].next_local= tz_tabs+2; + tz_tabs[2].next_global= tz_tabs[2].next_local= tz_tabs+3; tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type= tz_tabs[3].lock_type= TL_READ; tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql"; + + /* Link into global list */ + tz_tabs[0].prev_global= *global_next_ptr; + tz_tabs[1].prev_global= &tz_tabs[0].next_global; + tz_tabs[2].prev_global= &tz_tabs[1].next_global; + tz_tabs[3].prev_global= &tz_tabs[2].next_global; + + **global_next_ptr= tz_tabs; + /* Update last-global-pointer to point to pointer in last table */ + *global_next_ptr= &tz_tabs[3].next_global; } @@ -1440,19 +1450,20 @@ tz_init_table_list(TABLE_LIST *tz_tabs) */ TABLE_LIST * -my_tz_get_table_list(THD *thd) +my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr) { TABLE_LIST *tz_tabs; + DBUG_ENTER("my_tz_get_table_list"); if (!time_zone_tables_exist) - return 0; + DBUG_RETURN(0); if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4))) - return &fake_time_zone_tables_list; + DBUG_RETURN(&fake_time_zone_tables_list); - tz_init_table_list(tz_tabs); + tz_init_table_list(tz_tabs, global_next_ptr); - return tz_tabs; + DBUG_RETURN(tz_tabs); } @@ -1486,7 +1497,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { THD *thd; TABLE_LIST *tables= 0; - TABLE_LIST tables_buff[5]; + TABLE_LIST tables_buff[5], **tmp_link, *first_table; TABLE *table; TZ_NAMES_ENTRY *tmp_tzname; my_bool return_val= 1; @@ -1553,9 +1564,10 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) (char*)"time_zone_leap_second"; tables_buff[0].lock_type= TL_READ; tables_buff[0].db= thd->db; - tables_buff[0].next= tables_buff + 1; + tables_buff[0].next_global= tables_buff[0].next_local= tables_buff + 1; /* Fill TABLE_LIST for rest of the time zone describing tables */ - tz_init_table_list(tables_buff + 1); + tmp_link= &first_table; + tz_init_table_list(tables_buff + 1, &tmp_link); if (open_tables(thd, tables_buff, &counter) || lock_tables(thd, tables_buff, counter)) @@ -1757,8 +1769,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) and it is specifically for this purpose). */ table= tz_tables->table; - tz_tables= tz_tables->next; - table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); + tz_tables= tz_tables->next_local; + table->field[0]->store(tz_name->ptr(), tz_name->length(), + &my_charset_latin1); /* It is OK to ignore ha_index_init()/ha_index_end() return values since mysql.time_zone* tables are MyISAM and these operations always succeed @@ -1769,7 +1782,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { +#ifdef EXTRA_DEBUG sql_print_error("Can't find description of time zone."); +#endif goto end; } @@ -1783,7 +1798,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) using the only index in this table). */ table= tz_tables->table; - tz_tables= tz_tables->next; + tz_tables= tz_tables->next_local; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); @@ -1810,7 +1825,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) Right - using special index. */ table= tz_tables->table; - tz_tables= tz_tables->next; + tz_tables= tz_tables->next_local; table->field[0]->store((longlong)tzid); (void)table->file->ha_index_init(0); diff --git a/sql/tztime.h b/sql/tztime.h index aabec260ec7..1325e921c67 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -59,7 +59,7 @@ public: extern Time_zone * my_tz_UTC; extern Time_zone * my_tz_SYSTEM; -extern TABLE_LIST * my_tz_get_table_list(THD *thd); +extern TABLE_LIST * my_tz_get_table_list(THD *thd, TABLE_LIST ***global_next_ptr); extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables); extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap); extern void my_tz_free(); diff --git a/sql/unireg.cc b/sql/unireg.cc index c82fcc4abef..2a6abdb1cfd 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -321,7 +321,7 @@ static uint pack_keys(uchar *keybuff,uint key_count,KEY *keyinfo) pos[6]=pos[7]=0; // For the future pos+=8; key_parts+=key->key_parts; - DBUG_PRINT("loop",("flags: %d key_parts: %d at %lx", + DBUG_PRINT("loop",("flags: %d key_parts: %d at 0x%lx", key->flags,key->key_parts, key->key_part)); for (key_part=key->key_part,key_part_end=key_part+key->key_parts ; -- cgit v1.2.1 From bc787254247cb66a5e1adc0af6834c10737ecc6e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 9 Sep 2004 14:55:28 +0300 Subject: Update after merge --- sql/sql_prepare.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sql') diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 844a7723d89..124db39ef3f 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1057,7 +1057,7 @@ static int mysql_test_select(Prepared_statement *stmt, THD *thd= stmt->thd; LEX *lex= stmt->lex; SELECT_LEX_UNIT *unit= &lex->unit; - int result= 1; + int result; DBUG_ENTER("mysql_test_select"); #ifndef NO_EMBEDDED_ACCESS_CHECKS @@ -1073,6 +1073,7 @@ static int mysql_test_select(Prepared_statement *stmt, if ((result= open_and_lock_tables(thd, tables))) { + result= 1; // Error sent send_error(thd); goto err; } @@ -2223,4 +2224,3 @@ Item_arena::Type Prepared_statement::type() const { return PREPARED_STATEMENT; } - -- cgit v1.2.1