summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@mashka.mysql.fi>2003-01-09 02:19:14 +0200
committerunknown <monty@mashka.mysql.fi>2003-01-09 02:19:14 +0200
commitb5e37b242e23c1fed48007e0ec6f9eb7ecc34758 (patch)
treed8a4d338b246396e32745b9fe381fc6de42d5a9d /sql
parenta3f4a46bf29761fe73760a74ceb86491861dcbf4 (diff)
downloadmariadb-git-b5e37b242e23c1fed48007e0ec6f9eb7ecc34758.tar.gz
Don't count NULL values in cardinalty for MyISAM tables.
Free row buffer cache after each query for MyISAM tables. Added table join option FORCE INDEX Fixed core dump bug when connecting with hostname that could not be resolved. include/my_base.h: Don't count NULL values in cardinalty myisam/mi_check.c: Don't count NULL values in cardinalty myisam/mi_extra.c: Free row buffer cache after each query myisam/mi_open.c: Avoid realloc if cache size doesn't change myisam/mi_search.c: Don't count NULL values in cardinalty myisam/myisamdef.h: Change buffer length from uint to uint32 to make it more portable/predictable mysql-test/r/myisam.result: Test case for cardinality with NULL keys and FORCE INDEX mysql-test/t/myisam.test: Test case for cardinality with NULL keys and FORCE INDEX sql/lex.h: Added table join option FORCE INDEX sql/mysql_priv.h: Added table join option FORCE INDEX sql/opt_range.cc: Added table join option FORCE INDEX sql/sql_base.cc: Added table join option FORCE INDEX sql/sql_lex.h: Added table join option FORCE INDEX sql/sql_parse.cc: Added table join option FORCE INDEX Don't use strlen() on hostname without first checking if it's not NULL sql/sql_select.cc: Added table join option FORCE INDEX sql/sql_yacc.yy: Added table join option FORCE INDEX sql/table.h: Added table join option FORCE INDEX
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;