summaryrefslogtreecommitdiff
path: root/sql/sql_handler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_handler.cc')
-rw-r--r--sql/sql_handler.cc228
1 files changed, 104 insertions, 124 deletions
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index 1c5381a9fa0..1cd7778a053 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -64,7 +64,7 @@
#define HANDLER_TABLES_HASH_SIZE 120
static enum enum_ha_read_modes rkey_to_rnext[]=
- { RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
+{ RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV };
#define HANDLER_TABLES_HACK(thd) { \
TABLE *tmp=thd->open_tables; \
@@ -140,19 +140,19 @@ static void mysql_ha_hash_free(TABLE_LIST *tables)
error messages.
RETURN
- 0 ok
- != 0 error
+ FALSE OK
+ TRUE Error
*/
-int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
+bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
{
TABLE_LIST *hash_tables;
char *db, *name, *alias;
uint dblen, namelen, aliaslen, counter;
- int err;
+ int error;
DBUG_ENTER("mysql_ha_open");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' reopen: %d",
- tables->db, tables->real_name, tables->alias,
+ tables->db, tables->table_name, tables->alias,
(int) reopen));
if (! hash_inited(&thd->handler_tables_hash))
@@ -173,8 +173,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
{
DBUG_PRINT("info",("duplicate '%s'", tables->alias));
if (! reopen)
- my_printf_error(ER_NONUNIQ_TABLE, ER(ER_NONUNIQ_TABLE),
- MYF(0), tables->alias);
+ my_error(ER_NONUNIQ_TABLE, MYF(0), tables->alias);
goto err;
}
}
@@ -185,16 +184,20 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
*/
DBUG_ASSERT(! tables->table);
HANDLER_TABLES_HACK(thd);
- err=open_tables(thd, tables, &counter);
+
+ /* for now HANDLER can be used only for real TABLES */
+ tables->required_type= FRMTYPE_TABLE;
+ error= open_tables(thd, &tables, &counter, 0);
+
HANDLER_TABLES_HACK(thd);
- if (err)
+ if (error)
goto err;
/* There can be only one table in '*tables'. */
if (! (tables->table->file->table_flags() & HA_CAN_SQL_HANDLER))
{
if (! reopen)
- my_printf_error(ER_ILLEGAL_HA,ER(ER_ILLEGAL_HA),MYF(0), tables->alias);
+ my_error(ER_ILLEGAL_HA, MYF(0), tables->alias);
mysql_ha_close(thd, tables);
goto err;
}
@@ -203,7 +206,7 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
{
/* copy the TABLE_LIST struct */
dblen= strlen(tables->db) + 1;
- namelen= strlen(tables->real_name) + 1;
+ namelen= strlen(tables->table_name) + 1;
aliaslen= strlen(tables->alias) + 1;
if (!(my_multi_malloc(MYF(MY_WME),
&hash_tables, sizeof(*hash_tables),
@@ -215,15 +218,16 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
/* structure copy */
*hash_tables= *tables;
hash_tables->db= db;
- hash_tables->real_name= name;
+ hash_tables->table_name= name;
hash_tables->alias= alias;
memcpy(hash_tables->db, tables->db, dblen);
- memcpy(hash_tables->real_name, tables->real_name, namelen);
+ memcpy(hash_tables->table_name, tables->table_name, namelen);
memcpy(hash_tables->alias, tables->alias, aliaslen);
/* add to hash */
if (my_hash_insert(&thd->handler_tables_hash, (byte*) hash_tables))
{
+ my_free((char*) hash_tables, MYF(0));
mysql_ha_close(thd, tables);
goto err;
}
@@ -232,11 +236,11 @@ int mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
if (! reopen)
send_ok(thd);
DBUG_PRINT("exit",("OK"));
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
err:
DBUG_PRINT("exit",("ERROR"));
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
@@ -253,17 +257,17 @@ err:
will be closed. Broadcasts a COND_refresh condition.
RETURN
- 0 ok
- != 0 error
+ FALSE ok
+ TRUE error
*/
-int mysql_ha_close(THD *thd, TABLE_LIST *tables)
+bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
{
TABLE_LIST *hash_tables;
TABLE **table_ptr;
DBUG_ENTER("mysql_ha_close");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
- tables->db, tables->real_name, tables->alias));
+ tables->db, tables->table_name, tables->alias));
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
(byte*) tables->alias,
@@ -277,54 +281,32 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables)
*/
for (table_ptr= &(thd->handler_tables);
*table_ptr && (*table_ptr != hash_tables->table);
- table_ptr= &(*table_ptr)->next);
+ table_ptr= &(*table_ptr)->next)
+ ;
-#if MYSQL_VERSION_ID < 40100
- if (*tables->db && strcmp(hash_tables->db, tables->db))
+ if (*table_ptr)
{
- DBUG_PRINT("info",("wrong db"));
- hash_tables= NULL;
- }
- else
-#endif
- {
- if (*table_ptr)
+ (*table_ptr)->file->ha_index_or_rnd_end();
+ VOID(pthread_mutex_lock(&LOCK_open));
+ if (close_thread_table(thd, table_ptr))
{
- (*table_ptr)->file->ha_index_or_rnd_end();
- VOID(pthread_mutex_lock(&LOCK_open));
- if (close_thread_table(thd, table_ptr))
- {
- /* Tell threads waiting for refresh that something has happened */
- VOID(pthread_cond_broadcast(&COND_refresh));
- }
- VOID(pthread_mutex_unlock(&LOCK_open));
+ /* Tell threads waiting for refresh that something has happened */
+ VOID(pthread_cond_broadcast(&COND_refresh));
}
-
- hash_delete(&thd->handler_tables_hash, (byte*) hash_tables);
+ VOID(pthread_mutex_unlock(&LOCK_open));
}
+ hash_delete(&thd->handler_tables_hash, (byte*) hash_tables);
}
-
- if (! hash_tables)
+ else
{
-#if MYSQL_VERSION_ID < 40100
- char buff[MAX_DBKEY_LENGTH];
- if (*tables->db)
- strxnmov(buff, sizeof(buff), tables->db, ".", tables->real_name, NullS);
- else
- strncpy(buff, tables->alias, sizeof(buff));
- my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
- buff, "HANDLER");
-#else
- my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
- tables->alias, "HANDLER");
-#endif
+ my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER");
DBUG_PRINT("exit",("ERROR"));
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
send_ok(thd);
DBUG_PRINT("exit", ("OK"));
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
}
@@ -340,18 +322,19 @@ int mysql_ha_close(THD *thd, TABLE_LIST *tables)
key_expr
ha_rkey_mode
cond
- select_limit
- offset_limit
+ select_limit_cnt
+ offset_limit_cnt
RETURN
- 0 ok
- != 0 error
+ FALSE ok
+ TRUE error
*/
-int mysql_ha_read(THD *thd, TABLE_LIST *tables,
- enum enum_ha_read_modes mode, char *keyname, List<Item> *key_expr,
- enum ha_rkey_function ha_rkey_mode, Item *cond,
- ha_rows select_limit,ha_rows offset_limit)
+bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
+ enum enum_ha_read_modes mode, char *keyname,
+ List<Item> *key_expr,
+ enum ha_rkey_function ha_rkey_mode, Item *cond,
+ ha_rows select_limit_cnt, ha_rows offset_limit_cnt)
{
TABLE_LIST *hash_tables;
TABLE **table_ptr;
@@ -361,18 +344,21 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
Protocol *protocol= thd->protocol;
char buff[MAX_FIELD_WIDTH];
String buffer(buff, sizeof(buff), system_charset_info);
- int err, keyno= -1;
+ int error, keyno= -1;
uint num_rows;
byte *key;
uint key_len;
+ bool not_used;
DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
- tables->db, tables->real_name, tables->alias));
+ tables->db, tables->table_name, tables->alias));
LINT_INIT(key);
LINT_INIT(key_len);
- list.push_front(new Item_field(NULL,NULL,"*"));
+ thd->lex->select_lex.context.resolve_in_table_list_only(tables);
+ list.push_front(new Item_field(&thd->lex->select_lex.context,
+ NULL, NULL, "*"));
List_iterator<Item> it(list);
it++;
@@ -382,7 +368,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
{
table= hash_tables->table;
DBUG_PRINT("info-in-hash",("'%s'.'%s' as '%s' tab %p",
- hash_tables->db, hash_tables->real_name,
+ hash_tables->db, hash_tables->table_name,
hash_tables->alias, table));
if (!table)
{
@@ -397,7 +383,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
table= hash_tables->table;
DBUG_PRINT("info",("re-opened '%s'.'%s' as '%s' tab %p",
- hash_tables->db, hash_tables->real_name,
+ hash_tables->db, hash_tables->table_name,
hash_tables->alias, table));
}
@@ -417,21 +403,19 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
#if MYSQL_VERSION_ID < 40100
char buff[MAX_DBKEY_LENGTH];
if (*tables->db)
- strxnmov(buff, sizeof(buff), tables->db, ".", tables->real_name, NullS);
+ strxnmov(buff, sizeof(buff), tables->db, ".", tables->table_name, NullS);
else
strncpy(buff, tables->alias, sizeof(buff));
- my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
- buff, "HANDLER");
+ my_error(ER_UNKNOWN_TABLE, MYF(0), buff, "HANDLER");
#else
- my_printf_error(ER_UNKNOWN_TABLE, ER(ER_UNKNOWN_TABLE), MYF(0),
- tables->alias, "HANDLER");
+ my_error(ER_UNKNOWN_TABLE, MYF(0), tables->alias, "HANDLER");
#endif
goto err0;
}
tables->table=table;
HANDLER_TABLES_HACK(thd);
- lock= mysql_lock_tables(thd, &tables->table, 1, 0);
+ lock= mysql_lock_tables(thd, &tables->table, 1, 0, &not_used);
HANDLER_TABLES_HACK(thd);
if (!lock)
@@ -442,25 +426,24 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
if (table->query_id != thd->query_id)
cond->cleanup(); // File was reopened
if ((!cond->fixed &&
- cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1))
+ cond->fix_fields(thd, &cond)) || cond->check_cols(1))
goto err0;
}
if (keyname)
{
- if ((keyno=find_type(keyname, &table->keynames, 1+2)-1)<0)
+ if ((keyno=find_type(keyname, &table->s->keynames, 1+2)-1)<0)
{
- my_printf_error(ER_KEY_DOES_NOT_EXITS,ER(ER_KEY_DOES_NOT_EXITS),MYF(0),
- keyname,tables->alias);
+ my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias);
goto err0;
}
}
- if (insert_fields(thd,tables,tables->db,tables->alias,&it))
+ if (insert_fields(thd, &thd->lex->select_lex.context,
+ tables->db, tables->alias, &it, 0))
goto err0;
- select_limit+=offset_limit;
- protocol->send_fields(&list,1);
+ protocol->send_fields(&list, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
/*
In ::external_lock InnoDB resets the fields which tell it that
@@ -470,13 +453,13 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
table->file->init_table_handle_for_HANDLER();
- for (num_rows=0; num_rows < select_limit; )
+ for (num_rows=0; num_rows < select_limit_cnt; )
{
switch (mode) {
case RNEXT:
if (table->file->inited != handler::NONE)
{
- err=keyname ?
+ error=keyname ?
table->file->index_next(table->record[0]) :
table->file->rnd_next(table->record[0]);
break;
@@ -487,13 +470,13 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
{
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno);
- err=table->file->index_first(table->record[0]);
+ error= table->file->index_first(table->record[0]);
}
else
{
table->file->ha_index_or_rnd_end();
- if (!(err=table->file->ha_rnd_init(1)))
- err=table->file->rnd_next(table->record[0]);
+ if (!(error= table->file->ha_rnd_init(1)))
+ error= table->file->rnd_next(table->record[0]);
}
mode=RNEXT;
break;
@@ -501,7 +484,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
DBUG_ASSERT(keyname != 0);
if (table->file->inited != handler::NONE)
{
- err=table->file->index_prev(table->record[0]);
+ error=table->file->index_prev(table->record[0]);
break;
}
/* else fall through */
@@ -509,13 +492,13 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
DBUG_ASSERT(keyname != 0);
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno);
- err=table->file->index_last(table->record[0]);
+ error= table->file->index_last(table->record[0]);
mode=RPREV;
break;
case RNEXT_SAME:
/* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */
DBUG_ASSERT(keyname != 0);
- err= table->file->index_next_same(table->record[0], key, key_len);
+ error= table->file->index_next_same(table->record[0], key, key_len);
break;
case RKEY:
{
@@ -524,8 +507,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
KEY_PART_INFO *key_part=keyinfo->key_part;
if (key_expr->elements > keyinfo->key_parts)
{
- my_printf_error(ER_TOO_MANY_KEY_PARTS,ER(ER_TOO_MANY_KEY_PARTS),
- MYF(0),keyinfo->key_parts);
+ my_error(ER_TOO_MANY_KEY_PARTS, MYF(0), keyinfo->key_parts);
goto err;
}
List_iterator<Item> it_ke(*key_expr);
@@ -533,8 +515,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
for (key_len=0 ; (item=it_ke++) ; key_part++)
{
// 'item' can be changed by fix_fields() call
- if ((!item->fixed &&
- item->fix_fields(thd, tables, it_ke.ref())) ||
+ if ((!item->fixed &&
+ item->fix_fields(thd, it_ke.ref())) ||
(item= *it_ke.ref())->check_cols(1))
goto err;
if (item->used_tables() & ~RAND_TABLE_BIT)
@@ -546,39 +528,36 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
key_len+=key_part->store_length;
}
if (!(key= (byte*) thd->calloc(ALIGN_SIZE(key_len))))
- {
- send_error(thd,ER_OUTOFMEMORY);
goto err;
- }
- key_copy(key, table, keyno, key_len);
table->file->ha_index_or_rnd_end();
table->file->ha_index_init(keyno);
- err=table->file->index_read(table->record[0],
+ key_copy(key, table->record[0], table->key_info + keyno, key_len);
+ error= table->file->index_read(table->record[0],
key,key_len,ha_rkey_mode);
mode=rkey_to_rnext[(int)ha_rkey_mode];
break;
}
default:
- send_error(thd,ER_ILLEGAL_HA);
+ my_message(ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA), MYF(0));
goto err;
}
- if (err == HA_ERR_RECORD_DELETED)
- continue;
- if (err)
+ if (error)
{
- if (err != HA_ERR_KEY_NOT_FOUND && err != HA_ERR_END_OF_FILE)
+ if (error == HA_ERR_RECORD_DELETED)
+ continue;
+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
{
sql_print_error("mysql_ha_read: Got error %d when reading table '%s'",
- err, tables->real_name);
- table->file->print_error(err,MYF(0));
+ error, tables->table_name);
+ table->file->print_error(error,MYF(0));
goto err;
}
goto ok;
}
if (cond && !cond->val_int())
continue;
- if (num_rows >= offset_limit)
+ if (num_rows >= offset_limit_cnt)
{
Item *item;
protocol->prepare_for_resend();
@@ -588,7 +567,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
if (item->send(thd->protocol, &buffer))
{
protocol->free(); // Free used
- my_error(ER_OUT_OF_RESOURCES,MYF(0));
+ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
goto err;
}
}
@@ -600,13 +579,13 @@ ok:
mysql_unlock_tables(thd,lock);
send_eof(thd);
DBUG_PRINT("exit",("OK"));
- DBUG_RETURN(0);
+ DBUG_RETURN(FALSE);
err:
mysql_unlock_tables(thd,lock);
err0:
DBUG_PRINT("exit",("ERROR"));
- DBUG_RETURN(-1);
+ DBUG_RETURN(TRUE);
}
@@ -651,25 +630,25 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
if (tables)
{
/* Close all tables in the list. */
- for (tmp_tables= tables ; tmp_tables; tmp_tables= tmp_tables->next)
+ for (tmp_tables= tables ; tmp_tables; tmp_tables= tmp_tables->next_local)
{
DBUG_PRINT("info-in-tables-list",("'%s'.'%s' as '%s'",
- tmp_tables->db, tmp_tables->real_name,
+ tmp_tables->db, tmp_tables->table_name,
tmp_tables->alias));
/* Close all currently open handler tables with the same base table. */
table_ptr= &(thd->handler_tables);
while (*table_ptr)
{
- if ((! *tmp_tables->db ||
- ! my_strcasecmp(&my_charset_latin1, (*table_ptr)->table_cache_key,
+ if ((!*tmp_tables->db ||
+ !my_strcasecmp(&my_charset_latin1, (*table_ptr)->s->db,
tmp_tables->db)) &&
- ! my_strcasecmp(&my_charset_latin1, (*table_ptr)->real_name,
- tmp_tables->real_name))
+ ! my_strcasecmp(&my_charset_latin1, (*table_ptr)->s->table_name,
+ tmp_tables->table_name))
{
DBUG_PRINT("info",("*table_ptr '%s'.'%s' as '%s'",
- (*table_ptr)->table_cache_key,
- (*table_ptr)->real_name,
- (*table_ptr)->table_name));
+ (*table_ptr)->s->db,
+ (*table_ptr)->s->table_name,
+ (*table_ptr)->alias));
/* The first time it is required, lock for close_thread_table(). */
if (! did_lock && ! is_locked)
{
@@ -692,7 +671,7 @@ int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags,
while (*table_ptr)
{
if ((mode_flags & MYSQL_HA_FLUSH_ALL) ||
- ((*table_ptr)->version != refresh_version))
+ ((*table_ptr)->s->version != refresh_version))
{
/* The first time it is required, lock for close_thread_table(). */
if (! did_lock && ! is_locked)
@@ -738,12 +717,12 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
TABLE *table= *table_ptr;
DBUG_ENTER("mysql_ha_flush_table");
DBUG_PRINT("enter",("'%s'.'%s' as '%s' flags: 0x%02x",
- table->table_cache_key, table->real_name,
- table->table_name, mode_flags));
+ table->s->db, table->s->table_name,
+ table->alias, mode_flags));
if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash,
- (byte*) table->table_name,
- strlen(table->table_name) + 1)))
+ (byte*) table->alias,
+ strlen(table->alias) + 1)))
{
if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE))
{
@@ -759,6 +738,7 @@ static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags)
safe_mutex_assert_owner(&LOCK_open);
(*table_ptr)->file->ha_index_or_rnd_end();
+ safe_mutex_assert_owner(&LOCK_open);
if (close_thread_table(thd, table_ptr))
{
/* Tell threads waiting for refresh that something has happened */