summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2005-07-04 01:36:55 +0300
committerunknown <bell@sanja.is.com.ua>2005-07-04 01:36:55 +0300
commitfbdfcae6a97749e9037a173103f9a5a3e30139d9 (patch)
tree2b655fd149ab34595524445832c75f7ec91137c2 /sql
parentb17793f5b554f6d78ab279507aa5937a1ee13432 (diff)
parentc7ab92c28a535d2419ffa906042fff7e476df972 (diff)
downloadmariadb-git-fbdfcae6a97749e9037a173103f9a5a3e30139d9.tar.gz
Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/bk/work-bug_qc-4.1
Diffstat (limited to 'sql')
-rw-r--r--sql/field.cc41
-rw-r--r--sql/item_cmpfunc.h6
-rw-r--r--sql/item_strfunc.h1
-rw-r--r--sql/item_subselect.cc4
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/opt_range.cc3
-rw-r--r--sql/sql_base.cc1
-rw-r--r--sql/sql_insert.cc4
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_select.cc33
-rw-r--r--sql/sql_select.h25
11 files changed, 80 insertions, 42 deletions
diff --git a/sql/field.cc b/sql/field.cc
index 88816151c10..64d5babd159 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2480,7 +2480,10 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
if (error ||
(from+len != end && table->in_use->count_cuted_fields &&
!test_if_int(from,len,end,cs)))
- error= 1;
+ {
+ if (error != 1)
+ error= 2;
+ }
#if SIZEOF_LONG > 4
if (unsigned_flag)
{
@@ -2508,10 +2511,7 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
}
#endif
if (error)
- {
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
- error= 1;
- }
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
{
@@ -2777,8 +2777,11 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs)
(from+len != end && table->in_use->count_cuted_fields &&
!test_if_int(from,len,end,cs)))
{
- set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
- error= 1;
+ if (error != 1)
+ {
+ set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
+ error= 2;
+ }
}
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -2998,7 +3001,7 @@ int Field_float::store(const char *from,uint len,CHARSET_INFO *cs)
double nr= my_strntod(cs,(char*) from,len,&end,&error);
if (error || ((uint) (end-from) != len && table->in_use->count_cuted_fields))
{
- error= 1;
+ error= 2;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
}
Field_float::store(nr);
@@ -3284,7 +3287,7 @@ int Field_double::store(const char *from,uint len,CHARSET_INFO *cs)
double nr= my_strntod(cs,(char*) from, len, &end, &error);
if (error || ((uint) (end-from) != len && table->in_use->count_cuted_fields))
{
- error= 1;
+ error= 2;
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
}
Field_double::store(nr);
@@ -3666,6 +3669,8 @@ int Field_timestamp::store(const char *from,uint len,CHARSET_INFO *cs)
error= 1;
}
}
+ if (error > 1)
+ error= 2;
#ifdef WORDS_BIGENDIAN
if (table->db_low_byte_first)
@@ -3954,7 +3959,7 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
if (str_to_time(from, len, &ltime, &error))
{
tmp=0L;
- error= 1;
+ error= 2;
set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED,
from, len, MYSQL_TIMESTAMP_TIME, 1);
}
@@ -3976,6 +3981,8 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs)
from, len, MYSQL_TIMESTAMP_TIME, !error);
error= 1;
}
+ if (error > 1)
+ error= 2;
}
if (ltime.neg)
@@ -4305,7 +4312,7 @@ int Field_date::store(const char *from, uint len,CHARSET_INFO *cs)
if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
{
tmp=0;
- error= 1;
+ error= 2;
}
else
tmp=(uint32) l_time.year*10000L + (uint32) (l_time.month*100+l_time.day);
@@ -4496,7 +4503,7 @@ int Field_newdate::store(const char *from,uint len,CHARSET_INFO *cs)
if (str_to_datetime(from, len, &l_time, 1, &error) <= MYSQL_TIMESTAMP_ERROR)
{
tmp=0L;
- error= 1;
+ error= 2;
}
else
tmp= l_time.day + l_time.month*32 + l_time.year*16*32;
@@ -4938,7 +4945,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
from= tmpstr.ptr();
length= tmpstr.length();
if (conv_errors)
- error= 1;
+ error= 2;
}
/*
@@ -4962,7 +4969,7 @@ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
from+= field_charset->cset->scan(field_charset, from, end,
MY_SEQ_SPACES);
if (from != end)
- error= 1;
+ error= 2;
}
if (error)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
@@ -5217,12 +5224,12 @@ int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
from= tmpstr.ptr();
length= tmpstr.length();
if (conv_errors)
- error= 1;
+ error= 2;
}
if (length > field_length)
{
length=field_length;
- error= 1;
+ error= 2;
}
if (error)
set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
@@ -5575,7 +5582,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
from= tmpstr.ptr();
length= tmpstr.length();
if (conv_errors)
- error= 1;
+ error= 2;
}
copy_length= max_data_length();
@@ -5590,7 +5597,7 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
copy_length,
&well_formed_error);
if (copy_length < length)
- error= 1;
+ error= 2;
Field_blob::store_length(copy_length);
if (was_conversion || table->copy_blobs || copy_length <= MAX_FIELD_WIDTH)
{ // Must make a copy
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index bea8250de9d..525f269e528 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -769,6 +769,12 @@ class Item_func_in :public Item_int_func
bool nulls_in_row();
bool is_bool_func() { return 1; }
CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
+ /*
+ IN() protect from NULL only first argument, if construction like
+ "expression IN ()" will be allowed, we will need to check number of
+ argument here, because "NOT(NULL IN ())" is TRUE.
+ */
+ table_map not_null_tables() const { return args[0]->not_null_tables(); }
};
/* Functions used by where clause */
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 6f6af415086..b01d75b8e02 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -95,6 +95,7 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "concat_ws"; }
+ table_map not_null_tables() const { return 0; }
};
class Item_func_reverse :public Item_str_func
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index ebc08545566..82954a664c0 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -1361,7 +1361,7 @@ int subselect_uniquesubquery_engine::exec()
TABLE *table= tab->table;
for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
{
- if (tab->ref.key_err= (*copy)->copy())
+ if ((tab->ref.key_err= (*copy)->copy()) & 1)
{
table->status= STATUS_NOT_FOUND;
DBUG_RETURN(1);
@@ -1414,7 +1414,7 @@ int subselect_indexsubquery_engine::exec()
for (store_key **copy=tab->ref.key_copy ; *copy ; copy++)
{
- if (tab->ref.key_err= (*copy)->copy())
+ if ((tab->ref.key_err= (*copy)->copy()) & 1)
{
table->status= STATUS_NOT_FOUND;
DBUG_RETURN(1);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 99c96a69ceb..a757c47366d 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5153,7 +5153,7 @@ The minimum value for this variable is 4096.",
"Default pointer size to be used for MyISAM tables.",
(gptr*) &myisam_data_pointer_size,
(gptr*) &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
- 4, 2, 8, 0, 1, 0},
+ 4, 2, 7, 0, 1, 0},
{"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
"Used to help MySQL to decide when to use the slow but safe key cache index create method.",
(gptr*) &global_system_variables.myisam_max_extra_sort_file_size,
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 75cf9e6b3f0..2dd097cbaab 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -981,8 +981,7 @@ get_mm_parts(PARAM *param, COND *cond_func, Field *field,
SEL_TREE *tree2= get_mm_parts(param, cond_func,
field, Item_func::GT_FUNC,
value, cmp_type);
- if (!tree2)
- DBUG_RETURN(0)
+ /* tree_or() will return 0 if tree2 is 0 */
tree= tree_or(param,tree,tree2);
}
DBUG_RETURN(tree);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index c9861790b06..7a36d33a42c 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -979,6 +979,7 @@ TABLE *open_table(THD *thd,const char *db,const char *table_name,
if (table->timestamp_field)
table->timestamp_field_type= table->timestamp_field->get_auto_set_type();
DBUG_ASSERT(table->key_read == 0);
+ DBUG_ASSERT(table->insert_values == 0);
DBUG_RETURN(table);
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index deccc1d4dca..7d613ad6fbf 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -516,6 +516,10 @@ abort:
ON DUPLICATE KEY ...
we should be able to refer to sum1 in the ON DUPLICATE KEY part
+ WARNING
+ You MUST set table->insert_values to 0 after calling this function
+ before releasing the table object.
+
RETURN VALUE
0 OK
-1 error (message is not sent to user)
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c0283f81315..d7fd3239df5 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2891,12 +2891,12 @@ unsent_create_error:
/* revert changes for SP */
lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE;
delete result;
- insert_table->insert_values= 0;
if (thd->net.report_error)
res= -1;
}
else
res= -1;
+ insert_table->insert_values= 0; // Set by mysql_prepare_insert()
first_local_table->next= tables;
lex->select_lex.table_list.first= (byte*) first_local_table;
break;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 1031773eeed..972fb4e0368 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -134,8 +134,8 @@ static void read_cached_record(JOIN_TAB *tab);
static bool cmp_buffer_with_ref(JOIN_TAB *tab);
static bool setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List<Item> &all_fields,ORDER *new_order);
-static ORDER *create_distinct_group(THD *thd, ORDER *order,
- List<Item> &fields,
+static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
+ ORDER *order, List<Item> &fields,
bool *all_order_by_fields_used);
static bool test_if_subpart(ORDER *a,ORDER *b);
static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
@@ -642,7 +642,8 @@ JOIN::optimize()
bool all_order_fields_used;
if (order)
skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1);
- if ((group_list=create_distinct_group(thd, order, fields_list,
+ if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
+ order, fields_list,
&all_order_fields_used)))
{
bool skip_group= (skip_sort_order &&
@@ -8221,11 +8222,13 @@ cp_buffer_from_ref(THD *thd, TABLE_REF *ref)
enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
for (store_key **copy=ref->key_copy ; *copy ; copy++)
- if ((*copy)->copy())
+ {
+ if ((*copy)->copy() & 1)
{
thd->count_cuted_fields= save_count_cuted_fields;
- return 1; // Something went wrong
+ return 1; // Something went wrong
}
+ }
thd->count_cuted_fields= save_count_cuted_fields;
return 0;
}
@@ -8436,12 +8439,14 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
*/
static ORDER *
-create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields,
+create_distinct_group(THD *thd, Item **ref_pointer_array,
+ ORDER *order_list, List<Item> &fields,
bool *all_order_by_fields_used)
{
List_iterator<Item> li(fields);
Item *item;
ORDER *order,*group,**prev;
+ uint index= 0;
*all_order_by_fields_used= 1;
while ((item=li++))
@@ -8473,11 +8478,17 @@ create_distinct_group(THD *thd, ORDER *order_list, List<Item> &fields,
ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
if (!ord)
return 0;
- ord->item=li.ref();
+ /*
+ We have here only field_list (not all_field_list), so we can use
+ simple indexing of ref_pointer_array (order in the array and in the
+ list are same)
+ */
+ ord->item= ref_pointer_array + index;
ord->asc=1;
*prev=ord;
prev= &ord->next;
}
+ index++;
}
*prev=0;
return group;
@@ -8721,7 +8732,7 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
{
Item *pos;
List_iterator_fast<Item> li(all_fields);
- Copy_field *copy;
+ Copy_field *copy= NULL;
res_selected_fields.empty();
res_all_fields.empty();
List_iterator_fast<Item> itr(res_all_fields);
@@ -8729,7 +8740,8 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
uint i, border= all_fields.elements - elements;
DBUG_ENTER("setup_copy_fields");
- if (!(copy=param->copy_field= new Copy_field[param->field_count]))
+ if (param->field_count &&
+ !(copy=param->copy_field= new Copy_field[param->field_count]))
goto err2;
param->copy_funcs.empty();
@@ -8813,7 +8825,8 @@ setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
DBUG_RETURN(0);
err:
- delete [] param->copy_field; // This is never 0
+ if (copy)
+ delete [] param->copy_field;
param->copy_field=0;
err2:
DBUG_RETURN(TRUE);
diff --git a/sql/sql_select.h b/sql/sql_select.h
index 7e69eca4683..c7440fe4c3a 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -356,6 +356,7 @@ class store_key :public Sql_alloc
char *null_ptr;
char err;
public:
+ enum store_key_result { STORE_KEY_OK, STORE_KEY_FATAL, STORE_KEY_CONV };
store_key(THD *thd, Field *field_arg, char *ptr, char *null, uint length)
:null_ptr(null),err(0)
{
@@ -371,7 +372,7 @@ class store_key :public Sql_alloc
}
}
virtual ~store_key() {} /* Not actually needed */
- virtual bool copy()=0;
+ virtual enum store_key_result copy()=0;
virtual const char *name() const=0;
};
@@ -392,10 +393,10 @@ class store_key_field: public store_key
copy_field.set(to_field,from_field,0);
}
}
- bool copy()
+ enum store_key_result copy()
{
copy_field.do_copy(&copy_field);
- return err != 0;
+ return err != 0 ? STORE_KEY_FATAL : STORE_KEY_OK;
}
const char *name() const { return field_name; }
};
@@ -412,9 +413,11 @@ public:
null_ptr_arg ? null_ptr_arg : item_arg->maybe_null ?
&err : NullS, length), item(item_arg)
{}
- bool copy()
+ enum store_key_result copy()
{
- return item->save_in_field(to_field, 1) || err != 0;
+ int res= item->save_in_field(to_field, 1);
+ return (err != 0 || res > 2 ? STORE_KEY_FATAL : (store_key_result) res);
+
}
const char *name() const { return "func"; }
};
@@ -432,15 +435,19 @@ public:
&err : NullS, length, item_arg), inited(0)
{
}
- bool copy()
+ enum store_key_result copy()
{
+ int res;
if (!inited)
{
inited=1;
- if (item->save_in_field(to_field, 1))
- err= 1;
+ if ((res= item->save_in_field(to_field, 1)))
+ {
+ if (!err)
+ err= res;
+ }
}
- return err != 0;
+ return (err > 2 ? STORE_KEY_FATAL : (store_key_result) err);
}
const char *name() const { return "const"; }
};