summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <monty@donna.mysql.com>2000-08-29 12:31:01 +0300
committerunknown <monty@donna.mysql.com>2000-08-29 12:31:01 +0300
commit52046a7ba3c00111bf27195197b486a9ef558416 (patch)
tree8c9e3c031400ac400edcf6561fe51f4bdbd69369 /sql
parent844c92364e04fb17371c4a71dee52f179f8ad253 (diff)
downloadmariadb-git-52046a7ba3c00111bf27195197b486a9ef558416.tar.gz
Bug fixes for 3.23.23
myisam/mi_debug.c: ***MISSING WEAVE*** Docs/internals.texi: Added coding guidelines Docs/manual.texi: Changelog update + Win32 -> Windows client/mysql.cc: Changed --no-named-commands to be on by default client/mysqlimport.c: Bug fix include/config-win.h: Update of supported functions include/global.h: Removed compiler warning libmysql/libmysql.c: Fix for Ia64 myisam/ChangeLog: Changelog myisam/Makefile.am: Added file mi_dbug.c myisam/ft_stopwords.c: Fix for Ia64 myisam/mi_delete_table.c: Extra debugging myisam/mi_rename.c: Extra debugging myisam/mi_rnext.c: Fixed bug with MIN and concurrent insert myisam/mi_rprev.c: Fixed bug with MAX and concurrent insert myisam/mi_search.c: Fixed bug with DECIMAL/NUMERIC keys myisam/myisamdef.h: Extra debugging scripts/make_binary_distribution.sh: Added thread safe mysql library sql/ha_heap.cc: Fix of HEAP bug with range keys sql/ha_heap.h: Fix of HEAP bug with range keys sql/handler.cc: Optimizing sql/handler.h: Optimizing sql/lock.cc: More DEBUG + fix of RENAME bug sql/mini_client.cc: Fix for Ia64 sql/mysql_priv.h: Fix for name locks sql/mysqld.cc: Shorter message if wrong options sql/opt_range.cc: Added TODO sql/sql_base.cc: Fix for DROP TABLE sql/sql_parse.cc: Fix of permission checking for CHECK TABLE sql/sql_select.cc: Fix of using LEFT JOIN with empty table sql/table.h: Fix for name locks tests/fork_test.pl: Fixed typo
Diffstat (limited to 'sql')
-rw-r--r--sql/ha_heap.cc15
-rw-r--r--sql/ha_heap.h5
-rw-r--r--sql/handler.cc4
-rw-r--r--sql/handler.h2
-rw-r--r--sql/lock.cc22
-rw-r--r--sql/mini_client.cc5
-rw-r--r--sql/mysql_priv.h5
-rw-r--r--sql/mysqld.cc15
-rw-r--r--sql/opt_range.cc12
-rw-r--r--sql/sql_base.cc33
-rw-r--r--sql/sql_parse.cc12
-rw-r--r--sql/sql_select.cc8
-rw-r--r--sql/table.h1
13 files changed, 96 insertions, 43 deletions
diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc
index 989497cee6e..591ca0bc813 100644
--- a/sql/ha_heap.cc
+++ b/sql/ha_heap.cc
@@ -251,6 +251,21 @@ int ha_heap::rename_table(const char * from, const char * to)
}
+ha_rows ha_heap::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)
+{
+ KEY *pos=table->key_info+inx;
+ if (start_key_len != end_key_len ||
+ start_key_len != pos->key_length ||
+ start_search_flag != HA_READ_KEY_EXACT ||
+ end_search_flag != HA_READ_KEY_EXACT)
+ return HA_POS_ERROR; // Can't only use exact keys
+ return 10; // Good guess
+}
+
/* We can just delete the heap on creation */
int ha_heap::create(const char *name, TABLE *form, HA_CREATE_INFO *create_info)
diff --git a/sql/ha_heap.h b/sql/ha_heap.h
index acbc0975f1e..b56ee84822f 100644
--- a/sql/ha_heap.h
+++ b/sql/ha_heap.h
@@ -65,7 +65,10 @@ class ha_heap: public handler
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);
diff --git a/sql/handler.cc b/sql/handler.cc
index 592861e176b..437b11be5bb 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -317,8 +317,8 @@ int handler::ha_open(const char *name, int mode, int test_if_locked)
}
if (!error)
{
-
- if (!(ref=(byte*) my_malloc(ALIGN_SIZE(ref_length)*2,MYF(0))))
+ if (!(ref=(byte*) alloc_root(&table->mem_root,
+ ALIGN_SIZE(ref_length)*2)))
{
close();
error=HA_ERR_OUT_OF_MEM;
diff --git a/sql/handler.h b/sql/handler.h
index 67fd99c71d7..08bf355b60e 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -200,7 +200,7 @@ public:
create_time(0), check_time(0), update_time(0), mean_rec_length(0),
ft_handler(0)
{}
- virtual ~handler(void) { my_free((char*) ref,MYF(MY_ALLOW_ZERO_PTR)); }
+ virtual ~handler(void) {}
int ha_open(const char *name, int mode, int test_if_locked);
void update_timestamp(byte *record);
void update_auto_increment();
diff --git a/sql/lock.cc b/sql/lock.cc
index a2e4daa4590..eba1851bae0 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -407,15 +407,17 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
TABLE *table;
char key[MAX_DBKEY_LENGTH];
uint key_length;
- key_length=(uint) (strmov(strmov(key,table_list->db)+1,table_list->name)-key)+
- 1;
+ DBUG_ENTER("lock_table_name");
+
+ key_length=(uint) (strmov(strmov(key,table_list->db)+1,table_list->name)
+ -key)+ 1;
/* Only insert the table if we haven't insert it already */
for (table=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
table ;
table = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
if (table->in_use == thd)
- return 0;
+ DBUG_RETURN(0);
/* Create a table entry with the right key and with an old refresh version */
/* Note that we must use my_malloc() here as this is freed by the table
@@ -423,17 +425,18 @@ int lock_table_name(THD *thd, TABLE_LIST *table_list)
if (!(table= (TABLE*) my_malloc(sizeof(*table)+key_length,
MYF(MY_WME | MY_ZEROFILL))))
- return -1;
+ DBUG_RETURN(-1);
memcpy((table->table_cache_key= (char*) (table+1)), key, key_length);
table->key_length=key_length;
table->in_use=thd;
+ table->locked_by_name=1;
table_list->table=table;
if (hash_insert(&open_cache, (byte*) table))
- return -1;
+ DBUG_RETURN(-1);
if (remove_table_from_cache(thd, table_list->db, table_list->name))
- return 1; // Table is in use
- return 0;
+ DBUG_RETURN(1); // Table is in use
+ DBUG_RETURN(0);
}
void unlock_table_name(THD *thd, TABLE_LIST *table_list)
@@ -446,7 +449,7 @@ static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
{
for ( ; table_list ; table_list=table_list->next)
{
- if (table_list->table && table_is_used(table_list->table))
+ if (table_list->table && table_is_used(table_list->table,0))
return 1;
}
return 0; // All tables are locked
@@ -456,6 +459,7 @@ static bool locked_named_table(THD *thd, TABLE_LIST *table_list)
bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
{
bool result=0;
+ DBUG_ENTER("wait_for_locked_table_names");
while (locked_named_table(thd,table_list))
{
@@ -467,5 +471,5 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list)
wait_for_refresh(thd);
pthread_mutex_lock(&LOCK_open);
}
- return result;
+ DBUG_RETURN(result);
}
diff --git a/sql/mini_client.cc b/sql/mini_client.cc
index b9e66911475..90024f1ff47 100644
--- a/sql/mini_client.cc
+++ b/sql/mini_client.cc
@@ -225,7 +225,8 @@ static void mc_free_old_query(MYSQL *mysql)
* Base version coded by Steve Bernacki, Jr. <steve@navinet.net>
*****************************************************************************/
-static int mc_sock_connect(File s, const struct sockaddr *name, uint namelen, uint to)
+static int mc_sock_connect(my_socket s, const struct sockaddr *name,
+ uint namelen, uint to)
{
#if defined(__WIN__)
return connect(s, (struct sockaddr*) name, namelen);
@@ -451,7 +452,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user,
uint port, const char *unix_socket,uint client_flag)
{
char buff[100],*end,*host_info;
- int sock;
+ my_socket sock;
ulong ip_addr;
struct sockaddr_in sock_addr;
uint pkt_length;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index fa61102fb57..7e3186defd3 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -319,10 +319,11 @@ TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias,
TABLE *find_locked_table(THD *thd, const char *db,const char *table_name);
bool reopen_table(TABLE *table,bool locked=0);
bool reopen_tables(THD *thd,bool get_locks,bool in_refresh);
-void close_old_data_files(THD *thd, TABLE *table, bool abort_locks);
+void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
+ bool send_refresh);
bool close_data_tables(THD *thd,const char *db, const char *table_name);
bool wait_for_tables(THD *thd);
-bool table_is_used(TABLE *table);
+bool table_is_used(TABLE *table, bool wait_for_name_lock);
bool drop_locked_tables(THD *thd,const char *db, const char *table_name);
void abort_locked_tables(THD *thd,const char *db, const char *table_name);
Field *find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index bf0a88bb702..fbfa18ce114 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2407,6 +2407,12 @@ static void print_version(void)
server_version,SYSTEM_TYPE,MACHINE_TYPE);
}
+static void use_help(void)
+{
+ print_version();
+ printf("Use %s --help for a list of available options\n",my_progname);
+}
+
static void usage(void)
{
print_version();
@@ -2621,7 +2627,7 @@ static void get_options(int argc,char **argv)
case 'O':
if (set_changeable_var(optarg, changeable_vars))
{
- usage();
+ use_help();
exit(1);
}
break;
@@ -2666,7 +2672,8 @@ static void get_options(int argc,char **argv)
opt_noacl=1;
else
{
- usage();
+ fprintf(stderr,"%s: Unrecognized option: %s\n",my_progname,optarg);
+ use_help();
exit(1);
}
break;
@@ -2910,7 +2917,7 @@ static void get_options(int argc,char **argv)
default:
fprintf(stderr,"%s: Unrecognized option: %c\n",my_progname,c);
- usage();
+ use_help();
exit(1);
}
}
@@ -2920,7 +2927,7 @@ static void get_options(int argc,char **argv)
if (argc != optind)
{
fprintf(stderr,"%s: Too many parameters\n",my_progname);
- usage();
+ use_help();
exit(1);
}
fix_paths();
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 4f1abf9b685..25ee26dbdbd 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -14,6 +14,16 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/*
+ TODO:
+ Fix that MAYBE_KEY are stored in the tree so that we can detect use
+ of full hash keys for queries like:
+
+ select s.id, kws.keyword_id from sites as s,kws where s.id=kws.site_id and kws.keyword_id in (204,205);
+
+*/
+
+
#ifdef __GNUC__
#pragma implementation // gcc: Class implementation
@@ -557,7 +567,7 @@ SEL_ARG *SEL_ARG::clone_tree()
** Returns:
** -1 if impossible select
** 0 if can't use quick_select
-** 1 if found usably range
+** 1 if found usable range
** Updates the following in the select parameter:
** needed_reg ; Bits for keys with may be used if all prev regs are read
** quick ; Parameter to use when reading records.
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index e6468890ed6..1ccd009de07 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -582,9 +582,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
thd->mysys_var->current_cond= &COND_refresh;
thd->proc_info="Flushing tables";
pthread_mutex_unlock(&thd->mysys_var->mutex);
- VOID(pthread_cond_broadcast(&COND_refresh)); // If one flush is locked
- close_old_data_files(thd,thd->open_tables,1);
+ close_old_data_files(thd,thd->open_tables,1,1);
bool found=1;
/* Wait until all threads has closed all the tables we had locked */
DBUG_PRINT("info", ("Waiting for others threads to close their open tables"));
@@ -921,7 +920,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
** There is a refresh in progress for this table
** Wait until the table is freed or the thread is killed.
*/
- close_old_data_files(thd,thd->open_tables,0);
+ close_old_data_files(thd,thd->open_tables,0,0);
if (table->in_use != thd)
wait_for_refresh(thd);
else
@@ -1216,9 +1215,11 @@ bool reopen_tables(THD *thd,bool get_locks,bool in_refresh)
abort_locks is set if called from flush_tables.
*/
-void close_old_data_files(THD *thd, TABLE *table, bool abort_locks)
+void close_old_data_files(THD *thd, TABLE *table, bool abort_locks,
+ bool send_refresh)
{
- bool found=0;
+ DBUG_ENTER("close_old_data_files");
+ bool found=send_refresh;
for (; table ; table=table->next)
{
if (table->version != refresh_version)
@@ -1241,6 +1242,7 @@ void close_old_data_files(THD *thd, TABLE *table, bool abort_locks)
}
if (found)
VOID(pthread_cond_broadcast(&COND_refresh)); // Signal to refresh
+ DBUG_VOID_RETURN;
}
@@ -1250,17 +1252,19 @@ void close_old_data_files(THD *thd, TABLE *table, bool abort_locks)
if the table is closed
*/
-bool table_is_used(TABLE *table)
+bool table_is_used(TABLE *table, bool wait_for_name_lock)
{
do
{
char *key= table->table_cache_key;
uint key_length=table->key_length;
- for (TABLE *search=(TABLE*) hash_search(&open_cache,(byte*) key,key_length) ;
+ for (TABLE *search=(TABLE*) hash_search(&open_cache,
+ (byte*) key,key_length) ;
search ;
search = (TABLE*) hash_next(&open_cache,(byte*) key,key_length))
{
if (search->locked_by_flush ||
+ search->locked_by_name && wait_for_name_lock ||
search->db_stat && search->version < refresh_version)
return 1; // Table is used
}
@@ -1278,19 +1282,14 @@ bool wait_for_tables(THD *thd)
thd->proc_info="Waiting for tables";
pthread_mutex_lock(&LOCK_open);
- thd->some_tables_deleted=0;
- close_old_data_files(thd,thd->open_tables,0);
- if (dropping_tables)
- {
- (void) pthread_cond_broadcast(&COND_refresh); // Signal to refresh/delete
- (void) pthread_cond_wait(&COND_refresh,&LOCK_open);
- }
-
- while (table_is_used(thd->open_tables) && ! thd->killed)
+ while (!thd->killed)
{
+ thd->some_tables_deleted=0;
+ close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0);
+ if (!table_is_used(thd->open_tables,1))
+ break;
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
}
-
if (thd->killed)
result= 1; // aborted
else
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 8b7e16709c0..97e67127fd0 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1170,9 +1170,8 @@ mysql_execute_command(void)
#endif
case SQLCOM_REPAIR:
{
- if (!tables->db)
- tables->db=thd->db;
- if (check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
+ if (check_db_used(thd,tables) ||
+ check_table_access(thd,SELECT_ACL | INSERT_ACL, tables))
goto error; /* purecov: inspected */
res = mysql_repair_table(thd, tables, &lex->check_opt);
break;
@@ -1695,6 +1694,10 @@ error:
** Get the user (global) and database privileges for all used tables
** Returns true (error) if we can't get the privileges and we don't use
** table/column grants.
+** The idea of EXTRA_ACL is that one will be granted access to the table if
+** one has the asked privilege on any column combination of the table; For
+** example to be able to check a table one needs to have SELECT privilege on
+** any column of the table.
****************************************************************************/
bool
@@ -1760,7 +1763,8 @@ check_table_access(THD *thd,uint want_access,TABLE_LIST *tables)
TABLE_LIST *org_tables=tables;
for (; tables ; tables=tables->next)
{
- if ((thd->master_access & want_access) == want_access && thd->db)
+ if ((thd->master_access & want_access) == (want_access & ~EXTRA_ACL) &&
+ thd->db)
tables->grant.privilege= want_access;
else if (tables->db && tables->db == thd->db)
{
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index c779b9f555a..1eafa22aa1b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -800,6 +800,14 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds,
if ((s->on_expr=tables->on_expr))
{
// table->maybe_null=table->outer_join=1; // Mark for send fields
+ if (!table->file->records)
+ { // Empty table
+ s->key_dependent=s->dependent=0;
+ s->type=JT_SYSTEM;
+ const_table_map|=table->map;
+ set_position(join,const_count++,s,(KEYUSE*) 0);
+ continue;
+ }
s->key_dependent=s->dependent=
s->on_expr->used_tables() & ~(table->map);
s->dependent|=stat_vector[i-1]->dependent | table_vector[i-1]->map;
diff --git a/sql/table.h b/sql/table.h
index 7fe3e5de601..198e0d6e801 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -91,6 +91,7 @@ struct st_table {
my_bool crypted;
my_bool db_low_byte_first; /* Portable row format */
my_bool locked_by_flush;
+ my_bool locked_by_name;
Field *next_number_field, /* Set if next_number is activated */
*found_next_number_field, /* Set on open */
*rowid_field;