summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/lex.h1
-rw-r--r--sql/mysql_priv.h6
-rw-r--r--sql/opt_range.cc4
-rw-r--r--sql/sql_base.cc6
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_parse.cc36
-rw-r--r--sql/sql_select.cc3
-rw-r--r--sql/sql_yacc.yy55
-rw-r--r--sql/table.h2
9 files changed, 81 insertions, 34 deletions
diff --git a/sql/lex.h b/sql/lex.h
index 826b9b4a9ef..82ed322af83 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -151,6 +151,7 @@ static SYMBOL symbols[] = {
{ "FLOAT8", SYM(DOUBLE_SYM),0,0},
{ "FLUSH", SYM(FLUSH_SYM),0,0},
{ "FOREIGN", SYM(FOREIGN),0,0},
+ { "FORCE", SYM(FORCE_SYM),0,0},
{ "RAID_TYPE", SYM(RAID_TYPE),0,0},
{ "RAID_CHUNKS", SYM(RAID_CHUNKS),0,0},
{ "RAID_CHUNKSIZE", SYM(RAID_CHUNKSIZE),0,0},
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 2a8b263bf28..75bf4e97634 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -226,6 +226,10 @@ void debug_sync_point(const char* lock_name, uint lock_timeout);
#define SHOW_LOG_STATUS_FREE "FREE"
#define SHOW_LOG_STATUS_INUSE "IN USE"
+/* Options to add_table_to_list() */
+#define TL_OPTION_UPDATING 1
+#define TL_OPTION_FORCE_INDEX 2
+
/* Some portable defines */
#define portable_sizeof_char_ptr 8
@@ -509,7 +513,7 @@ bool add_field_to_list(char *field_name, enum enum_field_types type,
void store_position_for_column(const char *name);
bool add_to_list(SQL_LIST &list,Item *group,bool asc=0);
TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias,
- bool updating,
+ ulong table_option,
thr_lock_type flags=TL_UNLOCK,
List<String> *use_index=0,
List<String> *ignore_index=0);
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index a18c0178b5d..c607e71c01b 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -605,12 +605,14 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables,
records++; /* purecov: inspected */
scan_time=(double) records / TIME_FOR_COMPARE+1;
read_time=(double) head->file->scan_time()+ scan_time + 1.0;
+ if (head->force_index)
+ scan_time= read_time= DBL_MAX;
if (limit < records)
read_time=(double) records+scan_time+1; // Force to use index
else if (read_time <= 2.0 && !force_quick_range)
DBUG_RETURN(0); /* No need for quick select */
- DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time));
+ DBUG_PRINT("info",("Time to scan table: %g", read_time));
keys_to_use&=head->keys_in_use_for_query;
if (keys_to_use)
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 7b7c8c01aab..54c3e40244a 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -752,7 +752,7 @@ TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->outer_join=table->null_row=table->maybe_null=0;
+ table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
table->used_keys= table->keys_for_keyread;
@@ -910,7 +910,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
table->tablenr=thd->current_tablenr++;
table->used_fields=0;
table->const_table=0;
- table->outer_join=table->null_row=table->maybe_null=0;
+ table->outer_join= table->null_row= table->maybe_null= table->force_index= 0;
table->status=STATUS_NO_RECORD;
table->keys_in_use_for_query= table->keys_in_use;
table->used_keys= table->keys_for_keyread;
@@ -981,6 +981,7 @@ bool reopen_table(TABLE *table,bool locked)
tmp.status= table->status;
tmp.keys_in_use_for_query= tmp.keys_in_use;
tmp.used_keys= tmp.keys_for_keyread;
+ tmp.force_index= tmp.force_index;
/* Get state */
tmp.key_length= table->key_length;
@@ -1888,6 +1889,7 @@ bool setup_tables(TABLE_LIST *tables)
table->maybe_null=test(table->outer_join=table_list->outer_join);
table->tablenr=tablenr;
table->map= (table_map) 1 << tablenr;
+ table->force_index= table_list->force_index;
if (table_list->use_index)
{
key_map map= get_key_map_from_key_list(table,
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 54e72fafdd5..a905871e629 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -110,7 +110,7 @@ typedef struct st_select_lex
char *db,*db1,*table1,*db2,*table2; /* For outer join using .. */
Item *where,*having;
ha_rows select_limit,offset_limit;
- ulong options;
+ ulong options, table_join_options;
List<List_item> expr_list;
List<List_item> when_list;
SQL_LIST order_list,table_list,group_list;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a0336d0b50b..5bf3a1c0bcd 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -498,7 +498,8 @@ check_connections(THD *thd)
vio_in_addr(net->vio,&thd->remote.sin_addr);
thd->host=ip_to_hostname(&thd->remote.sin_addr,&connect_errors);
/* Cut very long hostnames to avoid possible overflows */
- thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
+ if (thd->host)
+ thd->host[min(strlen(thd->host), HOSTNAME_LENGTH)]= 0;
if (connect_errors > max_connect_errors)
return(ER_HOST_IS_BLOCKED);
}
@@ -3158,12 +3159,30 @@ bool add_to_list(SQL_LIST &list,Item *item,bool asc)
}
+/*
+ Add a table to list of used tables
+
+ SYNOPSIS
+ add_table_to_list()
+ table Table to add
+ alias alias for table (or null if no alias)
+ table_options A set of the following bits:
+ TL_OPTION_UPDATING Table will be updated
+ TL_OPTION_FORCE_INDEX Force usage of index
+ lock_type How table should be locked
+ use_index List of indexed used in USE INDEX
+ ignore_index List of indexed used in IGNORE INDEX
+
+ RETURN
+ 0 Error
+ # Pointer to TABLE_LIST element added to the total table list
+*/
+
TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
- bool updating,
- thr_lock_type flags,
+ ulong table_options,
+ thr_lock_type lock_type,
List<String> *use_index,
- List<String> *ignore_index
- )
+ List<String> *ignore_index)
{
register TABLE_LIST *ptr;
THD *thd=current_thd;
@@ -3211,8 +3230,9 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
}
ptr->real_name=table->table.str;
ptr->real_name_length=table->table.length;
- ptr->lock_type=flags;
- ptr->updating=updating;
+ ptr->lock_type= lock_type;
+ ptr->updating= test(table_options & TL_OPTION_UPDATING);
+ ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
if (use_index)
ptr->use_index=(List<String> *) thd->memdup((gptr) use_index,
sizeof(*use_index));
@@ -3221,7 +3241,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias,
sizeof(*ignore_index));
/* check that used name is unique */
- if (flags != TL_IGNORE)
+ if (lock_type != TL_IGNORE)
{
for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ;
tables ;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 28aa21e94ce..237197ba6be 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -2057,7 +2057,8 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
!(s->quick && best_key && s->quick->index == best_key->key &&
best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&
!((s->table->file->table_flags() & HA_TABLE_SCAN_ON_INDEX) &&
- s->table->used_keys && best_key))
+ s->table->used_keys && best_key) &&
+ !(s->table->force_index && best_key))
{ // Check full join
if (s->on_expr)
{
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index e26e57b8bbd..0e93f048406 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2001 MySQL AB
+/* 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
@@ -198,6 +198,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
%token FIRST_SYM
%token FIXED_SYM
%token FLOAT_NUM
+%token FORCE_SYM
%token FOREIGN
%token FROM
%token FULL
@@ -735,7 +736,8 @@ create:
lex->sql_command= SQLCOM_CREATE_TABLE;
if (!add_table_to_list($5,
($2 & HA_LEX_CREATE_TMP_TABLE ?
- &tmp_table_alias : (LEX_STRING*) 0),1))
+ &tmp_table_alias : (LEX_STRING*) 0),
+ TL_OPTION_UPDATING))
YYABORT;
lex->create_list.empty();
lex->key_list.empty();
@@ -751,7 +753,7 @@ create:
{
LEX *lex=Lex;
lex->sql_command= SQLCOM_CREATE_INDEX;
- if (!add_table_to_list($6,NULL,1))
+ if (!add_table_to_list($6, NULL, TL_OPTION_UPDATING))
YYABORT;
lex->create_list.empty();
lex->key_list.empty();
@@ -1171,7 +1173,7 @@ alter:
LEX *lex=Lex;
lex->sql_command = SQLCOM_ALTER_TABLE;
lex->name=0;
- if (!add_table_to_list($4, NULL,1))
+ if (!add_table_to_list($4, NULL, TL_OPTION_UPDATING))
YYABORT;
lex->drop_primary=0;
lex->create_list.empty();
@@ -1442,8 +1444,9 @@ table_to_table_list:
table_to_table:
table_ident TO_SYM table_ident
- { if (!add_table_to_list($1,NULL,1,TL_IGNORE) ||
- !add_table_to_list($3,NULL,1,TL_IGNORE))
+ {
+ if (!add_table_to_list($1, NULL, TL_OPTION_UPDATING, TL_IGNORE) ||
+ !add_table_to_list($3, NULL, TL_OPTION_UPDATING, TL_IGNORE))
YYABORT;
};
@@ -2127,11 +2130,13 @@ join_table:
{
SELECT_LEX *sel=Select;
sel->use_index_ptr=sel->ignore_index_ptr=0;
+ sel->table_join_options= 0;
}
table_ident opt_table_alias opt_key_definition
{
SELECT_LEX *sel=Select;
- if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, sel->use_index_ptr,
+ if (!($$=add_table_to_list($2, $3, sel->table_join_options,
+ TL_UNLOCK, sel->use_index_ptr,
sel->ignore_index_ptr)))
YYABORT;
}
@@ -2150,12 +2155,20 @@ opt_key_definition:
sel->use_index= *$2;
sel->use_index_ptr= &sel->use_index;
}
+ | FORCE_SYM key_usage_list
+ {
+ SELECT_LEX *sel=Select;
+ sel->use_index= *$2;
+ sel->use_index_ptr= &sel->use_index;
+ sel->table_join_options|= TL_OPTION_FORCE_INDEX;
+ }
| IGNORE_SYM key_usage_list
{
SELECT_LEX *sel=Select;
sel->ignore_index= *$2;
sel->ignore_index_ptr= &sel->ignore_index;
- };
+ }
+ ;
key_usage_list:
key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')'
@@ -2443,7 +2456,7 @@ drop:
lex->drop_list.empty();
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
$3.str));
- if (!add_table_to_list($5,NULL, 1))
+ if (!add_table_to_list($5, NULL, TL_OPTION_UPDATING))
YYABORT;
}
| DROP DATABASE if_exists ident
@@ -2467,7 +2480,7 @@ table_list:
table_name:
table_ident
- { if (!add_table_to_list($1,NULL,1)) YYABORT; };
+ { if (!add_table_to_list($1,NULL,TL_OPTION_UPDATING)) YYABORT; };
if_exists:
/* empty */ { $$= 0; }
@@ -2678,7 +2691,8 @@ delete:
single_multi:
FROM table_ident
{
- if (!add_table_to_list($2, NULL, 1, Lex->lock_option))
+ if (!add_table_to_list($2, NULL, TL_OPTION_UPDATING,
+ Lex->lock_option))
YYABORT;
}
where_clause opt_order_clause
@@ -2699,13 +2713,14 @@ table_wild_list:
table_wild_one:
ident opt_wild
{
- if (!add_table_to_list(new Table_ident($1), NULL, 1,
- Lex->lock_option))
+ if (!add_table_to_list(new Table_ident($1), NULL,
+ TL_OPTION_UPDATING, Lex->lock_option))
YYABORT;
}
| ident '.' ident opt_wild
{
- if (!add_table_to_list(new Table_ident($1,$3,0), NULL, 1,
+ if (!add_table_to_list(new Table_ident($1,$3,0), NULL,
+ TL_OPTION_UPDATING,
Lex->lock_option))
YYABORT;
}
@@ -2774,7 +2789,7 @@ show_param:
Lex->sql_command= SQLCOM_SHOW_FIELDS;
if ($5)
$4->change_db($5);
- if (!add_table_to_list($4,NULL,0))
+ if (!add_table_to_list($4, NULL, 0))
YYABORT;
}
| NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ
@@ -2807,7 +2822,7 @@ show_param:
Lex->sql_command= SQLCOM_SHOW_KEYS;
if ($4)
$3->change_db($4);
- if (!add_table_to_list($3,NULL,0))
+ if (!add_table_to_list($3, NULL, 0))
YYABORT;
}
| STATUS_SYM wild
@@ -2834,7 +2849,7 @@ show_param:
| CREATE TABLE_SYM table_ident
{
Lex->sql_command = SQLCOM_SHOW_CREATE;
- if(!add_table_to_list($3, NULL,0))
+ if(!add_table_to_list($3, NULL, 0))
YYABORT;
}
| MASTER_SYM STATUS_SYM
@@ -2879,7 +2894,7 @@ describe:
lex->wild=0;
lex->verbose=0;
lex->sql_command=SQLCOM_SHOW_FIELDS;
- if (!add_table_to_list($2, NULL,0))
+ if (!add_table_to_list($2, NULL, 0))
YYABORT;
}
opt_describe_column {}
@@ -2999,14 +3014,14 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING
opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term
opt_ignore_lines opt_field_spec
{
- if (!add_table_to_list($11,NULL,1))
+ if (!add_table_to_list($11, NULL, TL_OPTION_UPDATING))
YYABORT;
}
|
LOAD TABLE_SYM table_ident FROM MASTER_SYM
{
Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE;
- if (!add_table_to_list($3,NULL,1))
+ if (!add_table_to_list($3, NULL, TL_OPTION_UPDATING))
YYABORT;
}
diff --git a/sql/table.h b/sql/table.h
index 3a08cd11a2a..c3f469115b5 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -91,6 +91,7 @@ struct st_table {
my_bool copy_blobs; /* copy_blobs when storing */
my_bool null_row; /* All columns are null */
my_bool maybe_null,outer_join; /* Used with OUTER JOIN */
+ my_bool force_index;
my_bool distinct,const_table,no_rows;
my_bool key_read, bulk_insert;
my_bool crypted;
@@ -157,6 +158,7 @@ typedef struct st_table_list
bool straight; /* optimize with prev table */
bool updating; /* for replicate-do/ignore table */
bool do_redirect; /* To get the struct in UNION's */
+ bool force_index; /* Prefer index over table scan */
} TABLE_LIST;