Commit e34496e5 authored by unknown's avatar unknown

BUG#19914 SELECT COUNT(*) sometimes returns MAX_INT on cluster tables

allow handler::info to return an error code (that will be returned to the user)


sql/ha_berkeley.cc:
  update handler::info interface to return int
sql/ha_berkeley.h:
  update handler::info interface to return int
sql/ha_heap.cc:
  update handler::info interface to return int
sql/ha_heap.h:
  update handler::info interface to return int
sql/ha_innodb.cc:
  update handler::info interface to return int
sql/ha_innodb.h:
  update handler::info interface to return int
sql/ha_myisam.cc:
  update handler::info interface to return int
sql/examples/ha_archive.cc:
  update handler::info interface to return int
sql/examples/ha_archive.h:
  update handler::info interface to return int
sql/examples/ha_example.cc:
  update handler::info interface to return int
sql/examples/ha_example.h:
  update handler::info interface to return int
sql/examples/ha_tina.cc:
  update handler::info interface to return int
sql/examples/ha_tina.h:
  update handler::info interface to return int
sql/ha_myisam.h:
  update handler::info interface to return int
sql/ha_myisammrg.cc:
  update handler::info interface to return int
sql/ha_myisammrg.h:
  update handler::info interface to return int
sql/ha_ndbcluster.cc:
  update handler::info interface to return int
sql/ha_ndbcluster.h:
  update handler::info interface to return int
sql/handler.h:
  update handler::info interface to return int
sql/opt_sum.cc:
  If we get an error when using handler::info to get count(*),
  print and return the error.
sql/sql_select.cc:
  if error, set fatal error.
parent bfdbb780
...@@ -972,7 +972,7 @@ int ha_archive::index_last(byte * buf) ...@@ -972,7 +972,7 @@ int ha_archive::index_last(byte * buf)
} }
void ha_archive::info(uint flag) int ha_archive::info(uint flag)
{ {
DBUG_ENTER("ha_archive::info"); DBUG_ENTER("ha_archive::info");
...@@ -980,7 +980,7 @@ void ha_archive::info(uint flag) ...@@ -980,7 +980,7 @@ void ha_archive::info(uint flag)
records= share->rows_recorded; records= share->rows_recorded;
deleted= 0; deleted= 0;
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
int ha_archive::extra(enum ha_extra_function operation) int ha_archive::extra(enum ha_extra_function operation)
......
...@@ -116,7 +116,7 @@ public: ...@@ -116,7 +116,7 @@ public:
int read_data_header(gzFile file_to_read); int read_data_header(gzFile file_to_read);
int write_data_header(gzFile file_to_write); int write_data_header(gzFile file_to_write);
void position(const byte *record); void position(const byte *record);
void info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int reset(void); int reset(void);
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
......
...@@ -486,10 +486,10 @@ int ha_example::rnd_pos(byte * buf, byte *pos) ...@@ -486,10 +486,10 @@ int ha_example::rnd_pos(byte * buf, byte *pos)
sql_update.cc sql_update.cc
*/ */
void ha_example::info(uint flag) int ha_example::info(uint flag)
{ {
DBUG_ENTER("ha_example::info"); DBUG_ENTER("ha_example::info");
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
......
...@@ -138,7 +138,7 @@ public: ...@@ -138,7 +138,7 @@ public:
int rnd_next(byte *buf); //required int rnd_next(byte *buf); //required
int rnd_pos(byte * buf, byte *pos); //required int rnd_pos(byte * buf, byte *pos); //required
void position(const byte *record); //required void position(const byte *record); //required
void info(uint); //required int info(uint); //required
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int reset(void); int reset(void);
......
...@@ -683,13 +683,13 @@ int ha_tina::rnd_pos(byte * buf, byte *pos) ...@@ -683,13 +683,13 @@ int ha_tina::rnd_pos(byte * buf, byte *pos)
Currently this table handler doesn't implement most of the fields Currently this table handler doesn't implement most of the fields
really needed. SHOW also makes use of this data really needed. SHOW also makes use of this data
*/ */
void ha_tina::info(uint flag) int ha_tina::info(uint flag)
{ {
DBUG_ENTER("ha_tina::info"); DBUG_ENTER("ha_tina::info");
/* This is a lie, but you don't want the optimizer to see zero or 1 */ /* This is a lie, but you don't want the optimizer to see zero or 1 */
if (records < 2) if (records < 2)
records= 2; records= 2;
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
/* /*
......
...@@ -115,7 +115,7 @@ class ha_tina: public handler ...@@ -115,7 +115,7 @@ class ha_tina: public handler
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
int rnd_end(); int rnd_end();
void position(const byte *record); void position(const byte *record);
void info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int reset(void); int reset(void);
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
......
...@@ -1715,7 +1715,7 @@ void ha_berkeley::position(const byte *record) ...@@ -1715,7 +1715,7 @@ void ha_berkeley::position(const byte *record)
} }
void ha_berkeley::info(uint flag) int ha_berkeley::info(uint flag)
{ {
DBUG_ENTER("ha_berkeley::info"); DBUG_ENTER("ha_berkeley::info");
if (flag & HA_STATUS_VARIABLE) if (flag & HA_STATUS_VARIABLE)
...@@ -1735,7 +1735,7 @@ void ha_berkeley::info(uint flag) ...@@ -1735,7 +1735,7 @@ void ha_berkeley::info(uint flag)
/* Don't return key if we got an error for the internal primary key */ /* Don't return key if we got an error for the internal primary key */
if (flag & HA_STATUS_ERRKEY && last_dup_key < table->keys) if (flag & HA_STATUS_ERRKEY && last_dup_key < table->keys)
errkey= last_dup_key; errkey= last_dup_key;
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
......
...@@ -127,7 +127,7 @@ class ha_berkeley: public handler ...@@ -127,7 +127,7 @@ class ha_berkeley: public handler
int rnd_next(byte *buf); int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
void position(const byte *record); void position(const byte *record);
void info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int reset(void); int reset(void);
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
......
...@@ -282,7 +282,7 @@ void ha_heap::position(const byte *record) ...@@ -282,7 +282,7 @@ void ha_heap::position(const byte *record)
*(HEAP_PTR*) ref= heap_position(file); // Ref is aligned *(HEAP_PTR*) ref= heap_position(file); // Ref is aligned
} }
void ha_heap::info(uint flag) int ha_heap::info(uint flag)
{ {
HEAPINFO info; HEAPINFO info;
(void) heap_info(file,&info,flag); (void) heap_info(file,&info,flag);
...@@ -304,6 +304,7 @@ void ha_heap::info(uint flag) ...@@ -304,6 +304,7 @@ void ha_heap::info(uint flag)
*/ */
if (key_stat_version != file->s->key_stat_version) if (key_stat_version != file->s->key_stat_version)
update_key_stats(); update_key_stats();
return 0;
} }
int ha_heap::extra(enum ha_extra_function operation) int ha_heap::extra(enum ha_extra_function operation)
......
...@@ -80,7 +80,7 @@ public: ...@@ -80,7 +80,7 @@ public:
int rnd_next(byte *buf); int rnd_next(byte *buf);
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
void position(const byte *record); void position(const byte *record);
void info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
int delete_all_rows(void); int delete_all_rows(void);
......
...@@ -4570,7 +4570,7 @@ ha_innobase::read_time( ...@@ -4570,7 +4570,7 @@ ha_innobase::read_time(
Returns statistics information of the table to the MySQL interpreter, Returns statistics information of the table to the MySQL interpreter,
in various fields of the handle object. */ in various fields of the handle object. */
void int
ha_innobase::info( ha_innobase::info(
/*==============*/ /*==============*/
uint flag) /* in: what information MySQL requests */ uint flag) /* in: what information MySQL requests */
...@@ -4593,7 +4593,7 @@ ha_innobase::info( ...@@ -4593,7 +4593,7 @@ ha_innobase::info(
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) { if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
DBUG_VOID_RETURN; DBUG_RETURN(HA_ERR_CRASHED);
} }
/* We do not know if MySQL can call this function before calling /* We do not know if MySQL can call this function before calling
...@@ -4758,7 +4758,7 @@ ha_innobase::info( ...@@ -4758,7 +4758,7 @@ ha_innobase::info(
prebuilt->trx->op_info = (char*)""; prebuilt->trx->op_info = (char*)"";
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
/************************************************************************** /**************************************************************************
......
...@@ -142,7 +142,7 @@ class ha_innobase: public handler ...@@ -142,7 +142,7 @@ class ha_innobase: public handler
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
void position(const byte *record); void position(const byte *record);
void info(uint); int info(uint);
int analyze(THD* thd,HA_CHECK_OPT* check_opt); int analyze(THD* thd,HA_CHECK_OPT* check_opt);
int optimize(THD* thd,HA_CHECK_OPT* check_opt); int optimize(THD* thd,HA_CHECK_OPT* check_opt);
int discard_or_import_tablespace(my_bool discard); int discard_or_import_tablespace(my_bool discard);
......
...@@ -1214,7 +1214,7 @@ void ha_myisam::position(const byte* record) ...@@ -1214,7 +1214,7 @@ void ha_myisam::position(const byte* record)
ha_store_ptr(ref, ref_length, position); ha_store_ptr(ref, ref_length, position);
} }
void ha_myisam::info(uint flag) int ha_myisam::info(uint flag)
{ {
MI_ISAMINFO info; MI_ISAMINFO info;
char name_buff[FN_REFLEN]; char name_buff[FN_REFLEN];
...@@ -1273,6 +1273,8 @@ void ha_myisam::info(uint flag) ...@@ -1273,6 +1273,8 @@ void ha_myisam::info(uint flag)
update_time = info.update_time; update_time = info.update_time;
if (flag & HA_STATUS_AUTO) if (flag & HA_STATUS_AUTO)
auto_increment_value= info.auto_increment; auto_increment_value= info.auto_increment;
return 0;
} }
......
...@@ -100,7 +100,7 @@ class ha_myisam: public handler ...@@ -100,7 +100,7 @@ class ha_myisam: public handler
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
int restart_rnd_next(byte *buf, byte *pos); int restart_rnd_next(byte *buf, byte *pos);
void position(const byte *record); void position(const byte *record);
void info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size); int extra_opt(enum ha_extra_function operation, ulong cache_size);
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
......
...@@ -218,7 +218,7 @@ ha_rows ha_myisammrg::records_in_range(uint inx, key_range *min_key, ...@@ -218,7 +218,7 @@ ha_rows ha_myisammrg::records_in_range(uint inx, key_range *min_key,
} }
void ha_myisammrg::info(uint flag) int ha_myisammrg::info(uint flag)
{ {
MYMERGE_INFO info; MYMERGE_INFO info;
(void) myrg_status(file,&info,flag); (void) myrg_status(file,&info,flag);
...@@ -253,6 +253,7 @@ void ha_myisammrg::info(uint flag) ...@@ -253,6 +253,7 @@ void ha_myisammrg::info(uint flag)
(char*) info.rec_per_key, (char*) info.rec_per_key,
sizeof(table->key_info[0].rec_per_key)*table->key_parts); sizeof(table->key_info[0].rec_per_key)*table->key_parts);
} }
return 0;
} }
......
...@@ -71,7 +71,7 @@ class ha_myisammrg: public handler ...@@ -71,7 +71,7 @@ class ha_myisammrg: public handler
int rnd_pos(byte * buf, byte *pos); int rnd_pos(byte * buf, byte *pos);
void position(const byte *record); void position(const byte *record);
ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key); ha_rows records_in_range(uint inx, key_range *min_key, key_range *max_key);
void info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size); int extra_opt(enum ha_extra_function operation, ulong cache_size);
int external_lock(THD *thd, int lock_type); int external_lock(THD *thd, int lock_type);
......
...@@ -256,11 +256,13 @@ void ha_ndbcluster::set_rec_per_key() ...@@ -256,11 +256,13 @@ void ha_ndbcluster::set_rec_per_key()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void ha_ndbcluster::records_update() int ha_ndbcluster::records_update()
{ {
if (m_ha_not_exact_count) if (m_ha_not_exact_count)
return; return 0;
DBUG_ENTER("ha_ndbcluster::records_update"); DBUG_ENTER("ha_ndbcluster::records_update");
int result= 0;
struct Ndb_local_table_statistics *info= struct Ndb_local_table_statistics *info=
(struct Ndb_local_table_statistics *)m_table_info; (struct Ndb_local_table_statistics *)m_table_info;
DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d", DBUG_PRINT("info", ("id=%d, no_uncommitted_rows_count=%d",
...@@ -271,7 +273,7 @@ void ha_ndbcluster::records_update() ...@@ -271,7 +273,7 @@ void ha_ndbcluster::records_update()
Ndb *ndb= get_ndb(); Ndb *ndb= get_ndb();
Uint64 rows; Uint64 rows;
ndb->setDatabaseName(m_dbname); ndb->setDatabaseName(m_dbname);
if(ndb_get_table_statistics(ndb, m_tabname, &rows, 0) == 0){ if((result= ndb_get_table_statistics(ndb, m_tabname, &rows, 0)) == 0){
info->records= rows; info->records= rows;
} }
} }
...@@ -281,7 +283,7 @@ void ha_ndbcluster::records_update() ...@@ -281,7 +283,7 @@ void ha_ndbcluster::records_update()
info->no_uncommitted_rows_count= 0; info->no_uncommitted_rows_count= 0;
} }
records= info->records+ info->no_uncommitted_rows_count; records= info->records+ info->no_uncommitted_rows_count;
DBUG_VOID_RETURN; DBUG_RETURN(result);
} }
void ha_ndbcluster::no_uncommitted_rows_execute_failure() void ha_ndbcluster::no_uncommitted_rows_execute_failure()
...@@ -2858,8 +2860,9 @@ void ha_ndbcluster::position(const byte *record) ...@@ -2858,8 +2860,9 @@ void ha_ndbcluster::position(const byte *record)
} }
void ha_ndbcluster::info(uint flag) int ha_ndbcluster::info(uint flag)
{ {
int result= 0;
DBUG_ENTER("info"); DBUG_ENTER("info");
DBUG_PRINT("enter", ("flag: %d", flag)); DBUG_PRINT("enter", ("flag: %d", flag));
...@@ -2877,17 +2880,17 @@ void ha_ndbcluster::info(uint flag) ...@@ -2877,17 +2880,17 @@ void ha_ndbcluster::info(uint flag)
if (m_ha_not_exact_count) if (m_ha_not_exact_count)
records= 100; records= 100;
else else
records_update(); result= records_update();
} }
else else
{ {
if ((my_errno= check_ndb_connection())) if ((my_errno= check_ndb_connection()))
DBUG_VOID_RETURN; DBUG_RETURN(my_errno);
Ndb *ndb= get_ndb(); Ndb *ndb= get_ndb();
Uint64 rows= 100; Uint64 rows= 100;
ndb->setDatabaseName(m_dbname); ndb->setDatabaseName(m_dbname);
if (current_thd->variables.ndb_use_exact_count) if (current_thd->variables.ndb_use_exact_count)
ndb_get_table_statistics(ndb, m_tabname, &rows, 0); result= ndb_get_table_statistics(ndb, m_tabname, &rows, 0);
records= rows; records= rows;
} }
} }
...@@ -2912,7 +2915,11 @@ void ha_ndbcluster::info(uint flag) ...@@ -2912,7 +2915,11 @@ void ha_ndbcluster::info(uint flag)
ndb->readAutoIncrementValue((const NDBTAB *) m_table); ndb->readAutoIncrementValue((const NDBTAB *) m_table);
} }
} }
DBUG_VOID_RETURN;
if(result == -1)
result= HA_ERR_NO_CONNECTION;
DBUG_RETURN(result);
} }
......
...@@ -115,7 +115,7 @@ class ha_ndbcluster: public handler ...@@ -115,7 +115,7 @@ class ha_ndbcluster: public handler
int read_range_next(); int read_range_next();
bool get_error_message(int error, String *buf); bool get_error_message(int error, String *buf);
void info(uint); int info(uint);
int extra(enum ha_extra_function operation); int extra(enum ha_extra_function operation);
int extra_opt(enum ha_extra_function operation, ulong cache_size); int extra_opt(enum ha_extra_function operation, ulong cache_size);
int reset(); int reset();
...@@ -256,7 +256,7 @@ class ha_ndbcluster: public handler ...@@ -256,7 +256,7 @@ class ha_ndbcluster: public handler
Ndb *get_ndb(); Ndb *get_ndb();
void set_rec_per_key(); void set_rec_per_key();
void records_update(); int records_update();
void no_uncommitted_rows_execute_failure(); void no_uncommitted_rows_execute_failure();
void no_uncommitted_rows_update(int); void no_uncommitted_rows_update(int);
void no_uncommitted_rows_init(THD *); void no_uncommitted_rows_init(THD *);
......
...@@ -394,7 +394,7 @@ public: ...@@ -394,7 +394,7 @@ public:
key_range *max_key) key_range *max_key)
{ return (ha_rows) 10; } { return (ha_rows) 10; }
virtual void position(const byte *record)=0; virtual void position(const byte *record)=0;
virtual void info(uint)=0; virtual int info(uint)=0;
virtual int extra(enum ha_extra_function operation) virtual int extra(enum ha_extra_function operation)
{ return 0; } { return 0; }
virtual int extra_opt(enum ha_extra_function operation, ulong cache_size) virtual int extra_opt(enum ha_extra_function operation, ulong cache_size)
......
...@@ -125,7 +125,12 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds) ...@@ -125,7 +125,12 @@ int opt_sum_query(TABLE_LIST *tables, List<Item> &all_fields,COND *conds)
} }
else else
{ {
tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); error= tl->table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
if(error)
{
tl->table->file->print_error(error, MYF(0));
return error;
}
count*= tl->table->file->records; count*= tl->table->file->records;
} }
} }
......
...@@ -537,6 +537,8 @@ JOIN::optimize() ...@@ -537,6 +537,8 @@ JOIN::optimize()
{ {
if (res > 1) if (res > 1)
{ {
thd->fatal_error();
error= res;
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (res < 0) if (res < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment