summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorKonstantin Osipov <kostja@sun.com>2009-12-15 22:03:56 +0300
committerKonstantin Osipov <kostja@sun.com>2009-12-15 22:03:56 +0300
commit5e57d0916c3adefee12e6e37eb384bac54bda954 (patch)
tree3a91a2807267fcf278aa0b222b78ec3fb5e2d4c7 /storage
parent7a6e5c3f4cbbfeabd370e074ad03fb7dae90b964 (diff)
parent31c1efdb327fcfc4c601fb6698f8732f154948a4 (diff)
downloadmariadb-git-5e57d0916c3adefee12e6e37eb384bac54bda954.tar.gz
Merge next-mr -> next-4284.
Diffstat (limited to 'storage')
-rw-r--r--storage/csv/ha_tina.cc73
-rwxr-xr-xstorage/myisam/CMakeLists.txt3
-rw-r--r--storage/myisam/Makefile.am2
-rw-r--r--storage/myisam/ha_myisam.cc40
-rw-r--r--storage/myisam/mi_extrafunc.h21
-rw-r--r--storage/myisam/mi_locking.c4
-rw-r--r--storage/myisam/mi_test1.c2
-rw-r--r--storage/myisam/mi_test2.c2
-rw-r--r--storage/myisam/mi_test3.c2
-rw-r--r--storage/myisam/myisam_ftdump.c2
-rw-r--r--storage/myisam/myisamchk.c2
-rw-r--r--storage/myisam/myisamdef.h6
-rw-r--r--storage/myisam/myisamlog.c2
-rw-r--r--storage/myisam/myisampack.c2
-rw-r--r--storage/myisam/rt_test.c2
-rw-r--r--storage/myisam/sp_test.c1
16 files changed, 155 insertions, 11 deletions
diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc
index 65d7cd4a9c1..52462ca9c90 100644
--- a/storage/csv/ha_tina.cc
+++ b/storage/csv/ha_tina.cc
@@ -660,6 +660,33 @@ int ha_tina::find_current_row(uchar *buf)
memset(buf, 0, table->s->null_bytes);
+ /*
+ Parse the line obtained using the following algorithm
+
+ BEGIN
+ 1) Store the EOL (end of line) for the current row
+ 2) Until all the fields in the current query have not been
+ filled
+ 2.1) If the current character is a quote
+ 2.1.1) Until EOL has not been reached
+ a) If end of current field is reached, move
+ to next field and jump to step 2.3
+ b) If current character is a \\ handle
+ \\n, \\r, \\, \\"
+ c) else append the current character into the buffer
+ before checking that EOL has not been reached.
+ 2.2) If the current character does not begin with a quote
+ 2.2.1) Until EOL has not been reached
+ a) If the end of field has been reached move to the
+ next field and jump to step 2.3
+ b) If current character begins with \\ handle
+ \\n, \\r, \\, \\"
+ c) else append the current character into the buffer
+ before checking that EOL has not been reached.
+ 2.3) Store the current field value and jump to 2)
+ TERMINATE
+ */
+
for (Field **field=table->field ; *field ; field++)
{
char curr_char;
@@ -668,19 +695,23 @@ int ha_tina::find_current_row(uchar *buf)
if (curr_offset >= end_offset)
goto err;
curr_char= file_buff->get_value(curr_offset);
+ /* Handle the case where the first character is a quote */
if (curr_char == '"')
{
- curr_offset++; // Incrementpast the first quote
+ /* Increment past the first quote */
+ curr_offset++;
- for(; curr_offset < end_offset; curr_offset++)
+ /* Loop through the row to extract the values for the current field */
+ for ( ; curr_offset < end_offset; curr_offset++)
{
curr_char= file_buff->get_value(curr_offset);
- // Need to convert line feeds!
+ /* check for end of the current field */
if (curr_char == '"' &&
(curr_offset == end_offset - 1 ||
file_buff->get_value(curr_offset + 1) == ','))
{
- curr_offset+= 2; // Move past the , and the "
+ /* Move past the , and the " */
+ curr_offset+= 2;
break;
}
if (curr_char == '\\' && curr_offset != (end_offset - 1))
@@ -702,7 +733,7 @@ int ha_tina::find_current_row(uchar *buf)
else // ordinary symbol
{
/*
- We are at final symbol and no last quote was found =>
+ If we are at final symbol and no last quote was found =>
we are working with a damaged file.
*/
if (curr_offset == end_offset - 1)
@@ -713,15 +744,41 @@ int ha_tina::find_current_row(uchar *buf)
}
else
{
- for(; curr_offset < end_offset; curr_offset++)
+ for ( ; curr_offset < end_offset; curr_offset++)
{
curr_char= file_buff->get_value(curr_offset);
+ /* Move past the ,*/
if (curr_char == ',')
{
- curr_offset++; // Skip the ,
+ curr_offset++;
break;
}
- buffer.append(curr_char);
+ if (curr_char == '\\' && curr_offset != (end_offset - 1))
+ {
+ curr_offset++;
+ curr_char= file_buff->get_value(curr_offset);
+ if (curr_char == 'r')
+ buffer.append('\r');
+ else if (curr_char == 'n' )
+ buffer.append('\n');
+ else if (curr_char == '\\' || curr_char == '"')
+ buffer.append(curr_char);
+ else /* This could only happed with an externally created file */
+ {
+ buffer.append('\\');
+ buffer.append(curr_char);
+ }
+ }
+ else
+ {
+ /*
+ We are at the final symbol and a quote was found for the
+ unquoted field => We are working with a damaged field.
+ */
+ if (curr_offset == end_offset - 1 && curr_char == '"')
+ goto err;
+ buffer.append(curr_char);
+ }
}
}
diff --git a/storage/myisam/CMakeLists.txt b/storage/myisam/CMakeLists.txt
index 829d89a798a..9a0aa06e861 100755
--- a/storage/myisam/CMakeLists.txt
+++ b/storage/myisam/CMakeLists.txt
@@ -26,7 +26,8 @@ SET(MYISAM_SOURCES ft_boolean_search.c ft_nlq_search.c ft_parser.c ft_static.c
mi_rfirst.c mi_rlast.c mi_rnext.c mi_rnext_same.c mi_rprev.c mi_rrnd.c
mi_rsame.c mi_rsamepos.c mi_scan.c mi_search.c mi_static.c mi_statrec.c
mi_unique.c mi_update.c mi_write.c rt_index.c rt_key.c rt_mbr.c
- rt_split.c sort.c sp_key.c ft_eval.h myisamdef.h rt_index.h mi_rkey.c)
+ rt_split.c sort.c sp_key.c ft_eval.h mi_extrafunc.h myisamdef.h
+ rt_index.h mi_rkey.c)
MYSQL_STORAGE_ENGINE(MYISAM)
diff --git a/storage/myisam/Makefile.am b/storage/myisam/Makefile.am
index 6dd0d2bcbdb..c659d05be40 100644
--- a/storage/myisam/Makefile.am
+++ b/storage/myisam/Makefile.am
@@ -50,7 +50,7 @@ myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h \
fulltext.h ftdefs.h ft_test1.h ft_eval.h \
- ha_myisam.h
+ ha_myisam.h mi_extrafunc.h
mi_test1_DEPENDENCIES= $(LIBRARIES)
mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
$(top_builddir)/mysys/libmysys.a \
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index 994821a5065..c88fe737e0b 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -539,6 +539,45 @@ void mi_check_print_warning(MI_CHECK *param, const char *fmt,...)
va_end(args);
}
+
+/**
+ Report list of threads (and queries) accessing a table, thread_id of a
+ thread that detected corruption, ource file name and line number where
+ this corruption was detected, optional extra information (string).
+
+ This function is intended to be used when table corruption is detected.
+
+ @param[in] file MI_INFO object.
+ @param[in] message Optional error message.
+ @param[in] sfile Name of source file.
+ @param[in] sline Line number in source file.
+
+ @return void
+*/
+
+void _mi_report_crashed(MI_INFO *file, const char *message,
+ const char *sfile, uint sline)
+{
+ THD *cur_thd;
+ LIST *element;
+ char buf[1024];
+ mysql_mutex_lock(&file->s->intern_lock);
+ if ((cur_thd= (THD*) file->in_use.data))
+ sql_print_error("Got an error from thread_id=%lu, %s:%d", cur_thd->thread_id,
+ sfile, sline);
+ else
+ sql_print_error("Got an error from unknown thread, %s:%d", sfile, sline);
+ if (message)
+ sql_print_error("%s", message);
+ for (element= file->s->in_use; element; element= list_rest(element))
+ {
+ THD *thd= (THD*) element->data;
+ sql_print_error("%s", thd ? thd_security_context(thd, buf, sizeof(buf), 0)
+ : "Unknown thread accessing table");
+ }
+ mysql_mutex_unlock(&file->s->intern_lock);
+}
+
}
@@ -1703,6 +1742,7 @@ int ha_myisam::delete_table(const char *name)
int ha_myisam::external_lock(THD *thd, int lock_type)
{
+ file->in_use.data= thd;
return mi_lock_database(file, !table->s->tmp_table ?
lock_type : ((lock_type == F_UNLCK) ?
F_UNLCK : F_EXTRA_LCK));
diff --git a/storage/myisam/mi_extrafunc.h b/storage/myisam/mi_extrafunc.h
new file mode 100644
index 00000000000..4aa28832c6d
--- /dev/null
+++ b/storage/myisam/mi_extrafunc.h
@@ -0,0 +1,21 @@
+/* Copyright (C) 2000-2006 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
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+void _mi_report_crashed(MI_INFO *file __attribute__((unused)),
+ const char *message __attribute__((unused)),
+ const char *sfile __attribute__((unused)),
+ uint sline __attribute__((unused)))
+{
+}
diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c
index dd33fb71910..bfe79f51e4e 100644
--- a/storage/myisam/mi_locking.c
+++ b/storage/myisam/mi_locking.c
@@ -45,6 +45,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
++share->w_locks;
++share->tot_locks;
info->lock_type= lock_type;
+ info->s->in_use= list_add(info->s->in_use, &info->in_use);
DBUG_RETURN(0);
}
@@ -136,6 +137,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
}
info->opt_flag&= ~(READ_CACHE_USED | WRITE_CACHE_USED);
info->lock_type= F_UNLCK;
+ info->s->in_use= list_delete(info->s->in_use, &info->in_use);
break;
case F_RDLCK:
if (info->lock_type == F_WRLCK)
@@ -182,6 +184,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->r_locks++;
share->tot_locks++;
info->lock_type=lock_type;
+ info->s->in_use= list_add(info->s->in_use, &info->in_use);
break;
case F_WRLCK:
if (info->lock_type == F_RDLCK)
@@ -231,6 +234,7 @@ int mi_lock_database(MI_INFO *info, int lock_type)
info->invalidator=info->s->invalidator;
share->w_locks++;
share->tot_locks++;
+ info->s->in_use= list_add(info->s->in_use, &info->in_use);
break;
default:
break; /* Impossible */
diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c
index d4b8dea9ede..728ac9514fd 100644
--- a/storage/myisam/mi_test1.c
+++ b/storage/myisam/mi_test1.c
@@ -679,3 +679,5 @@ static void usage()
my_print_help(my_long_options);
my_print_variables(my_long_options);
}
+
+#include "mi_extrafunc.h"
diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c
index 860626b84a9..63525b08820 100644
--- a/storage/myisam/mi_test2.c
+++ b/storage/myisam/mi_test2.c
@@ -1055,3 +1055,5 @@ static void copy_key(MI_INFO *info,uint inx,uchar *rec,uchar *key_buff)
}
return;
}
+
+#include "mi_extrafunc.h"
diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c
index 6871658e486..7b16d6c05d6 100644
--- a/storage/myisam/mi_test3.c
+++ b/storage/myisam/mi_test3.c
@@ -488,6 +488,8 @@ int test_update(MI_INFO *file,int id,int lock_type)
return 0;
}
+#include "mi_extrafunc.h"
+
#else /* __NETWARE__ */
#include <stdio.h>
diff --git a/storage/myisam/myisam_ftdump.c b/storage/myisam/myisam_ftdump.c
index 63d954242a0..7c14ae37de2 100644
--- a/storage/myisam/myisam_ftdump.c
+++ b/storage/myisam/myisam_ftdump.c
@@ -274,3 +274,5 @@ static void complain(int val) /* Kinda assert :-) */
exit(1);
}
}
+
+#include "mi_extrafunc.h"
diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c
index 7df043ce801..b53a1009ba2 100644
--- a/storage/myisam/myisamchk.c
+++ b/storage/myisam/myisamchk.c
@@ -1815,3 +1815,5 @@ void mi_check_print_error(MI_CHECK *param, const char *fmt,...)
va_end(args);
DBUG_VOID_RETURN;
}
+
+#include "mi_extrafunc.h"
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 7f617fd044e..43746975232 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -166,6 +166,7 @@ typedef struct st_mi_isam_share { /* Shared between opens */
MI_COLUMNDEF *rec; /* Pointer to field information */
MI_PACK pack; /* Data about packed records */
MI_BLOB *blobs; /* Pointer to blobs */
+ LIST *in_use; /* List of threads using this table */
char *unique_file_name; /* realpath() of index file */
char *data_file_name, /* Resolved path names from symlinks */
*index_file_name;
@@ -243,6 +244,7 @@ struct st_myisam_info {
DYNAMIC_ARRAY *ft1_to_ft2; /* used only in ft1->ft2 conversion */
MEM_ROOT ft_memroot; /* used by the parser */
MYSQL_FTPARSER_PARAM *ftparser_param; /* share info between init/deinit */
+ LIST in_use; /* Thread using this table */
char *filename; /* parameter to open filename */
uchar *buff, /* Temp area for key */
*lastkey,*lastkey2; /* Last used search key */
@@ -386,8 +388,10 @@ typedef struct st_mi_sort_param
#define mi_putint(x,y,nod) { uint16 boh=(nod ? (uint16) 32768 : 0) + (uint16) (y);\
mi_int2store(x,boh); }
#define mi_test_if_nod(x) (x[0] & 128 ? info->s->base.key_reflength : 0)
+#define mi_report_crashed(A, B) _mi_report_crashed((A), (B), __FILE__, __LINE__)
#define mi_mark_crashed(x) do{(x)->s->state.changed|= STATE_CRASHED; \
DBUG_PRINT("error", ("Marked table crashed")); \
+ mi_report_crashed((x), 0); \
}while(0)
#define mi_mark_crashed_on_repair(x) do{(x)->s->state.changed|= \
STATE_CRASHED|STATE_CRASHED_ON_REPAIR; \
@@ -765,6 +769,8 @@ int mi_open_keyfile(MYISAM_SHARE *share);
void mi_setup_functions(register MYISAM_SHARE *share);
my_bool mi_dynmap_file(MI_INFO *info, my_off_t size);
void mi_remap_file(MI_INFO *info, my_off_t size);
+void _mi_report_crashed(MI_INFO *file, const char *message,
+ const char *sfile, uint sline);
/* Functions needed by mi_check */
volatile int *killed_ptr(MI_CHECK *param);
diff --git a/storage/myisam/myisamlog.c b/storage/myisam/myisamlog.c
index 622fd1a34a3..b2699d66f84 100644
--- a/storage/myisam/myisamlog.c
+++ b/storage/myisam/myisamlog.c
@@ -845,3 +845,5 @@ static my_bool cmp_filename(struct file_info *file_info, char * name)
return 1;
return strcmp(file_info->name,name) ? 1 : 0;
}
+
+#include "mi_extrafunc.h"
diff --git a/storage/myisam/myisampack.c b/storage/myisam/myisampack.c
index fec6d32133e..36e3b1e8cbb 100644
--- a/storage/myisam/myisampack.c
+++ b/storage/myisam/myisampack.c
@@ -3245,4 +3245,4 @@ static int fakecmp(my_off_t **count1, my_off_t **count2)
}
#endif
-
+#include "mi_extrafunc.h"
diff --git a/storage/myisam/rt_test.c b/storage/myisam/rt_test.c
index 7d15afd12ef..4a9b61605d9 100644
--- a/storage/myisam/rt_test.c
+++ b/storage/myisam/rt_test.c
@@ -468,3 +468,5 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
exit(0);
}
#endif /*HAVE_RTREE_KEYS*/
+
+#include "mi_extrafunc.h"
diff --git a/storage/myisam/sp_test.c b/storage/myisam/sp_test.c
index f572c7ab19b..069f43c320d 100644
--- a/storage/myisam/sp_test.c
+++ b/storage/myisam/sp_test.c
@@ -562,3 +562,4 @@ int main(int argc __attribute__((unused)),char *argv[] __attribute__((unused)))
}
#endif /*HAVE_SPATIAL*/
+#include "mi_extrafunc.h"