summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2004-10-29 19:26:52 +0300
committerunknown <monty@mysql.com>2004-10-29 19:26:52 +0300
commitf095274fe8c3d3394d6c0ce0a68f4bea04311999 (patch)
tree23bcc9a71fe7237887a111b158e30f5a6bb665d3 /sql/item_strfunc.cc
parentf41bba8c6156a7adf4c67dfa75e16112767a5d3c (diff)
parent5be6c328f5a9f78f37176bbbd88a538fa3b65fe9 (diff)
downloadmariadb-git-f095274fe8c3d3394d6c0ce0a68f4bea04311999.tar.gz
merge with 4.1
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union BitKeeper/triggers/post-commit: Auto merged Docs/Support/texi2html: Auto merged Makefile.am: Auto merged client/Makefile.am: Auto merged client/mysql.cc: Auto merged client/mysqldump.c: Auto merged include/my_base.h: Auto merged include/my_global.h: Auto merged include/my_pthread.h: Auto merged include/my_sys.h: Auto merged include/my_time.h: Auto merged include/mysql.h: Auto merged include/mysql_com.h: Auto merged innobase/buf/buf0buf.c: Auto merged innobase/include/row0mysql.h: Auto merged innobase/row/row0sel.c: Auto merged libmysql/libmysql.c: Auto merged libmysqld/examples/Makefile.am: Auto merged myisam/mi_check.c: Auto merged mysql-test/include/ps_modify.inc: Auto merged mysql-test/install_test_db.sh: Auto merged mysql-test/r/alter_table.result: Auto merged mysql-test/r/auto_increment.result: Auto merged mysql-test/r/bdb.result: Auto merged mysql-test/r/ctype_latin1_de.result: Auto merged mysql-test/r/ctype_recoding.result: Auto merged mysql-test/r/fulltext.result: Auto merged mysql-test/r/func_gconcat.result: Auto merged mysql-test/r/func_group.result: Auto merged mysql-test/r/func_if.result: Auto merged mysql-test/t/derived.test: Auto merged mysql-test/t/insert.test: merge with 4.1 Fixed test case to not use 'if exists' when it shouldn't mysql-test/t/range.test: merge with 4.1 Added missing drop table sql/ha_ndbcluster.cc: merge with 4.1 Simple optimization: use max() instead of ? : sql/item_func.cc: merge with 4.1 (Added back old variable names for easier merges) sql/opt_range.cc: merge with 4.1 Removed argument 'parent_alloc' from QUICK_RANGE_SELECT as this was not used Added assert if using QUICK_GROUP_MIN_MAX_SELECT with parent_alloc as the init() function can't handle this Changed back get_quick_select_for_ref() to use it's own alloc root becasue this function may be called several times for one query sql/sql_handler.cc: merge with 4.1 change variable 'err' to 'error' as same function had a label named 'err' sql/sql_update.cc: Use multi-update code from 5.0 instead of 4.1 We will fix the locking code shortly in 5.0 to be faster than in 4.1
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc137
1 files changed, 55 insertions, 82 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index b3665edad39..d015ca36eac 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -289,7 +289,8 @@ String *Item_func_concat::val_str(String *str)
str->copy(*res);
str->append(*res2);
}
- res=str;
+ res= str;
+ use_as_buff= &tmp_value;
}
else if (res == &tmp_value)
{
@@ -531,7 +532,7 @@ String *Item_func_concat_ws::val_str(String *str)
uint i;
null_value=0;
- if (!(sep_str= separator->val_str(&tmp_sep_str)))
+ if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
goto null;
use_as_buff= &tmp_value;
@@ -540,7 +541,7 @@ String *Item_func_concat_ws::val_str(String *str)
// Skip until non-null argument is found.
// If not, return the empty string
- for (i=0; i < arg_count; i++)
+ for (i=1; i < arg_count; i++)
if ((res= args[i]->val_str(str)))
break;
if (i == arg_count)
@@ -634,67 +635,25 @@ null:
return 0;
}
-void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array,
- List<Item> &fields)
-{
- if (separator->with_sum_func && separator->type() != SUM_FUNC_ITEM)
- separator->split_sum_func(ref_pointer_array, fields);
- else if (separator->used_tables() || separator->type() == SUM_FUNC_ITEM)
- {
- uint el= fields.elements;
- fields.push_front(separator);
- ref_pointer_array[el]= separator;
- separator= new Item_ref(ref_pointer_array + el,
- &separator, 0, separator->name);
- }
- Item_str_func::split_sum_func(ref_pointer_array, fields);
-}
void Item_func_concat_ws::fix_length_and_dec()
{
- collation.set(separator->collation);
- max_length=separator->max_length*(arg_count-1);
- for (uint i=0 ; i < arg_count ; i++)
- {
- DTCollation tmp(collation.collation, collation.derivation);
+ max_length=0;
+
+ if (agg_arg_collations(collation, args, arg_count))
+ return;
+
+ max_length= arg_count > 1 ? args[0]->max_length * (arg_count - 2) : 0;
+ for (uint i=1 ; i < arg_count ; i++)
max_length+=args[i]->max_length;
- if (collation.aggregate(args[i]->collation))
- {
- collation.set(tmp); // Restore the previous value
- my_coll_agg_error(collation, args[i]->collation, func_name());
- break;
- }
- }
+
if (max_length > MAX_BLOB_WIDTH)
{
max_length=MAX_BLOB_WIDTH;
maybe_null=1;
}
- used_tables_cache|= separator->used_tables();
- not_null_tables_cache&= separator->not_null_tables();
- const_item_cache&= separator->const_item();
- with_sum_func= with_sum_func || separator->with_sum_func;
}
-void Item_func_concat_ws::update_used_tables()
-{
- Item_func::update_used_tables();
- separator->update_used_tables();
- used_tables_cache|=separator->used_tables();
- const_item_cache&=separator->const_item();
-}
-
-void Item_func_concat_ws::print(String *str)
-{
- str->append("concat_ws(", 10);
- separator->print(str);
- if (arg_count)
- {
- str->append(',');
- print_args(str, 0);
- }
- str->append(')');
-}
String *Item_func_reverse::val_str(String *str)
{
@@ -1244,7 +1203,7 @@ String *Item_func_ltrim::val_str(String *str)
{
const char *r_ptr=remove_str->ptr();
end-=remove_length;
- while (ptr < end && !memcmp(ptr,r_ptr,remove_length))
+ while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
ptr+=remove_length;
end+=remove_length;
}
@@ -1316,8 +1275,8 @@ String *Item_func_rtrim::val_str(String *str)
else
#endif /* USE_MB */
{
- while (ptr + remove_length < end &&
- !memcmp(end-remove_length,r_ptr,remove_length))
+ while (ptr + remove_length <= end &&
+ !memcmp(end-remove_length, r_ptr, remove_length))
end-=remove_length;
}
}
@@ -1770,19 +1729,20 @@ String *Item_func_elt::val_str(String *str)
}
-void Item_func_make_set::split_sum_func(Item **ref_pointer_array,
+void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
List<Item> &fields)
{
if (item->with_sum_func && item->type() != SUM_FUNC_ITEM)
- item->split_sum_func(ref_pointer_array, fields);
+ item->split_sum_func(thd, ref_pointer_array, fields);
else if (item->used_tables() || item->type() == SUM_FUNC_ITEM)
{
uint el= fields.elements;
+ Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
fields.push_front(item);
ref_pointer_array[el]= item;
- item= new Item_ref(ref_pointer_array + el, &item, 0, item->name);
+ thd->change_item_tree(&item, new_item);
}
- Item_str_func::split_sum_func(ref_pointer_array, fields);
+ Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
}
@@ -2424,14 +2384,22 @@ String *Item_load_file::val_str(String *str)
String *file_name;
File file;
MY_STAT stat_info;
+ char path[FN_REFLEN];
DBUG_ENTER("load_file");
- if (!(file_name= args[0]->val_str(str)) ||
+ if (!(file_name= args[0]->val_str(str))
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- !(current_thd->master_access & FILE_ACL) ||
+ || !(current_thd->master_access & FILE_ACL)
#endif
- !my_stat(file_name->c_ptr(), &stat_info, MYF(MY_WME)))
+ )
goto err;
+
+ (void) fn_format(path, file_name->c_ptr(), mysql_real_data_home, "",
+ MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
+
+ if (!my_stat(path, &stat_info, MYF(MY_WME)))
+ goto err;
+
if (!(stat_info.st_mode & S_IROTH))
{
/* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */
@@ -2711,35 +2679,40 @@ longlong Item_func_crc32::val_int()
String *Item_func_compress::val_str(String *str)
{
+ int err= Z_OK, code;
+ ulong new_size;
+ String *res;
+ Byte *body;
+ char *tmp, *last_char;
DBUG_ASSERT(fixed == 1);
- String *res= args[0]->val_str(str);
- if (!res)
+
+ if (!(res= args[0]->val_str(str)))
{
null_value= 1;
return 0;
}
if (res->is_empty()) return res;
- int err= Z_OK;
- int code;
-
/*
- citation from zlib.h (comment for compress function):
+ Citation from zlib.h (comment for compress function):
Compresses the source buffer into the destination buffer. sourceLen is
- the byte length of the source buffer. Upon entry, destLen is the total
- size of the destination buffer, which must be at least 0.1% larger than
- sourceLen plus 12 bytes.
-
- Proportion 120/100 founded by Sinisa with help of procedure
- compress(compress(compress(...)))
- I.e. zlib give number 'at least'..
+ the byte length of the source buffer. Upon entry, destLen is the total
+ size of the destination buffer, which must be at least 0.1% larger than
+ sourceLen plus 12 bytes.
+ We assume here that the buffer can't grow more than .25 %.
*/
- ulong new_size= (ulong)((res->length()*120)/100)+12;
+ new_size= res->length() + res->length() / 5 + 12;
- buffer.realloc((uint32)new_size + 4 + 1);
- Byte *body= ((Byte*)buffer.ptr()) + 4;
+ // Check new_size overflow: new_size <= res->length()
+ if (((uint32) (new_size+5) <= res->length()) ||
+ buffer.realloc((uint32) new_size + 4 + 1))
+ {
+ null_value= 1;
+ return 0;
+ }
+ body= ((Byte*)buffer.ptr()) + 4;
// As far as we have checked res->is_empty() we can use ptr()
if ((err= compress(body, &new_size,
@@ -2751,11 +2724,11 @@ String *Item_func_compress::val_str(String *str)
return 0;
}
- char *tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects
+ tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects
int4store(tmp, res->length() & 0x3FFFFFFF);
- /* This is for the stupid char fields which trim ' ': */
- char *last_char= ((char*)body)+new_size-1;
+ /* This is to ensure that things works for CHAR fields, which trim ' ': */
+ last_char= ((char*)body)+new_size-1;
if (*last_char == ' ')
{
*++last_char= '.';