summaryrefslogtreecommitdiff
path: root/sql/item_func.cc
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2002-08-30 12:40:40 +0300
committerunknown <monty@narttu.mysql.fi>2002-08-30 12:40:40 +0300
commit9421f1dae99e0f2d6100b31a3641b2cd0ad68e58 (patch)
tree1bb81fd601075133af9ee99bd7ac94baf5ffc46c /sql/item_func.cc
parentcfc861537da2f256f11823b3a4997a033eec73dc (diff)
parent1895448e66b39542d58a77e705449b92414ff3f7 (diff)
downloadmariadb-git-9421f1dae99e0f2d6100b31a3641b2cd0ad68e58.tar.gz
Merge with 4.0.3
Some simple optimzations, more comments and indentation changes. Add ` around database in 'use database' in binary log. Moved max_error_count and max_warning_count to variables struct. Removed SHOW_WARNS_COUNT and SHOW_ERRORS_COUNT calls. Changed string functions to use character set of first string argument as default return characterset (Each string function can change the above assumption if needed) BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union BUILD/SETUP.sh: Auto merged BitKeeper/deleted/.del-getopt.h~a9ae679fa84f395: Auto merged BitKeeper/deleted/.del-getvar.c~2a29ff383970fd31: Auto merged Docs/manual.texi: Auto merged SSL/cacert.pem: Auto merged SSL/client-cert.pem: Auto merged SSL/client-key.pem: Auto merged SSL/server-cert.pem: Auto merged SSL/server-key.pem: Auto merged client/mysqldump.c: Auto merged include/my_base.h: Auto merged include/my_sys.h: Auto merged include/mysql_com.h: Auto merged isam/isamlog.c: Auto merged isam/pack_isam.c: Auto merged libmysqld/lib_sql.cc: Auto merged myisam/ft_dump.c: Auto merged myisam/ft_parser.c: Auto merged myisam/ft_static.c: Auto merged myisam/ft_test1.c: Auto merged myisam/ft_update.c: Auto merged myisam/mi_create.c: Auto merged myisam/mi_key.c: Auto merged myisam/mi_open.c: Auto merged myisam/mi_static.c: Auto merged myisam/mi_test1.c: Auto merged myisam/mi_test2.c: Auto merged myisam/mi_test3.c: Auto merged myisam/mi_update.c: Auto merged myisam/mi_write.c: Auto merged myisam/myisamchk.c: Auto merged myisam/myisamdef.h: Auto merged myisam/myisamlog.c: Auto merged myisam/myisampack.c: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/create.result: Auto merged mysql-test/r/fulltext.result: Auto merged mysql-test/r/func_math.result: Auto merged mysql-test/r/innodb.result: Auto merged mysql-test/r/merge.result: Auto merged mysql-test/r/myisam.result: Auto merged mysql-test/r/select.result: Auto merged mysql-test/r/select_found.result: Auto merged mysql-test/r/union.result: Auto merged mysql-test/t/create.test: Auto merged mysql-test/t/myisam.test: Auto merged mysql-test/t/select_found.test: Auto merged mysql-test/t/union.test: Auto merged mysys/default.c: Auto merged mysys/mf_iocache2.c: Auto merged mysys/my_error.c: Auto merged mysys/my_init.c: Auto merged scripts/mysql_config.sh: Auto merged sql/convert.cc: Auto merged sql/filesort.cc: Auto merged sql/gen_lex_hash.cc: Auto merged sql/ha_berkeley.cc: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_myisam.cc: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/hostname.cc: Auto merged sql/item.cc: Auto merged sql/item_sum.cc: Auto merged sql/item_sum.h: Auto merged sql/item_timefunc.cc: Auto merged sql/item_timefunc.h: Auto merged sql/key.cc: Auto merged sql/log.cc: Auto merged sql/net_pkg.cc: Auto merged sql/opt_range.cc: Auto merged sql/opt_range.h: Auto merged sql/opt_sum.cc: Auto merged sql/repl_failsafe.cc: Auto merged sql/slave.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_db.cc: Auto merged sql/sql_handler.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_load.cc: Auto merged sql/sql_string.cc: Auto merged sql/sql_table.cc: Auto merged sql/sql_test.cc: Auto merged sql/time.cc: Auto merged sql/unireg.cc: Auto merged strings/Makefile.am: Auto merged strings/ctype-latin1_de.c: Auto merged strings/ctype-tis620.c: Auto merged tools/mysqlmanager.c: Auto merged BitKeeper/deleted/.del-sslopt-case.h~224c80e75dad4997: merge with 4.0.3 BitKeeper/triggers/post-commit: merge with 4.0.3 client/mysql.cc: merge with 4.0.3 + simple optimsation client/mysqltest.c: merge with 4.0.3 (Indentation change) configure.in: merge with 4.0.3 extra/resolve_stack_dump.c: merge with 4.0.3 (Indentation change) include/Makefile.am: merge with 4.0.3 include/myisam.h: merge with 4.0.3 (Indentation change) include/mysql.h: merge with 4.0.3 (removed not used structure) include/mysqld_error.h: merge with 4.0.3 libmysql/Makefile.shared: merge with 4.0.3 libmysql/libmysql.c: merge with 4.0.3 (Indentation change) libmysqld/Makefile.am: merge with 4.0.3 myisam/ft_boolean_search.c: merge with 4.0.3 (Indentation change) myisam/ft_nlq_search.c: merge with 4.0.3 (Indentation change) myisam/mi_check.c: merge with 4.0.3 myisam/mi_search.c: merge with 4.0.3 myisam/mi_unique.c: merge with 4.0.3 mysys/Makefile.am: merge with 4.0.3 mysys/mf_casecnv.c: merge with 4.0.3 sql-bench/server-cfg.sh: Removed 8000 max row limit for Innodb sql/Makefile.am: merge with 4.0.3 sql/field.cc: Indentation cleanup Changed sprintf -> my_sprintf sql/field.h: merge with 4.0.3 sql/ha_heap.cc: merge with 4.0.3 (Indentation change) sql/item.h: merge with 4.0.3 (Indentation change) sql/item_cmpfunc.cc: merge with 4.0.3 sql/item_cmpfunc.h: Removed size_of() from items Indentation cleanup sql/item_create.cc: merge sql/item_create.h: merge sql/item_func.cc: Added comments Changed string functions to use character set of first string argument as default return characterset Simple optimizations. Removed return of uninitalized variable. sql/item_func.h: merge sql/item_strfunc.cc: merge with 4.0.3 (Indentation change) sql/item_strfunc.h: removed size_of() sql/item_uniq.h: removed size_of() sql/lex.h: merge with 4.0.3 (Indentation change) sql/log_event.cc: Add ` around database in 'use database' in binary log. sql/mysql_priv.h: merge with 4.0.3 sql/mysqld.cc: merge with 4.0.3 (Indentation change) sql/share/czech/errmsg.txt: merge sql/share/danish/errmsg.txt: merge sql/share/dutch/errmsg.txt: merge sql/share/english/errmsg.txt: merge sql/share/estonian/errmsg.txt: merge sql/share/french/errmsg.txt: merge sql/share/german/errmsg.txt: merge sql/share/greek/errmsg.txt: merge sql/share/hungarian/errmsg.txt: merge sql/share/italian/errmsg.txt: merge sql/share/japanese/errmsg.txt: merge sql/share/korean/errmsg.txt: merge sql/share/norwegian-ny/errmsg.txt: merge sql/share/norwegian/errmsg.txt: merge sql/share/polish/errmsg.txt: merge sql/share/portuguese/errmsg.txt: merge sql/share/romanian/errmsg.txt: merge sql/share/russian/errmsg.txt: merge sql/share/slovak/errmsg.txt: merge sql/share/spanish/errmsg.txt: merge sql/share/swedish/errmsg.txt: merge sql/share/ukrainian/errmsg.txt: merge sql/sql_acl.cc: merge with 4.0.3 sql/sql_base.cc: More comments Fixed bug in send_fields() when using convert sql/sql_class.cc: merge sql/sql_class.h: Merge with 4.0.3 Moved max_error_count and max_warning_count to variables struct. sql/sql_delete.cc: merge with 4.0.3 (Indentation change) sql/sql_lex.h: merge with 4.0.3 sql/sql_parse.cc: Removed SHOW_WARNS_COUNT and SHOW_ERRORS_COUNT. (Should be retrived from variables) sql/sql_select.cc: merge with 4.0.3 sql/sql_show.cc: merge with 4.0.3 sql/sql_union.cc: merge with 4.0.3 sql/sql_update.cc: merge with 4.0.3 sql/sql_yacc.yy: merge with 4.0.3 Indentation cleanup sql/structs.h: merge with 4.0.3 sql/table.cc: merge with 4.0.3 sql/table.h: merge with 4.0.3
Diffstat (limited to 'sql/item_func.cc')
-rw-r--r--sql/item_func.cc242
1 files changed, 213 insertions, 29 deletions
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 8b05109b289..bd811726b47 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -26,7 +26,10 @@
#include <hash.h>
#include <time.h>
#include <ft_global.h>
+#include <zlib.h>
#include "slave.h" // for wait_for_master_pos
+#include "gstream.h"
+
/* return TRUE if item is a constant */
@@ -55,8 +58,43 @@ Item_func::Item_func(List<Item> &list)
list.empty(); // Fields are used
}
+
+/*
+ Resolve references to table column for a function and it's argument
+
+ SYNOPSIS:
+ fix_fields()
+ thd Thread object
+ tables List of all open tables involved in the query
+ ref Pointer to where this object is used. This reference
+ is used if we want to replace this object with another
+ one (for example in the summary functions).
+
+ DESCRIPTION
+ Call fix_fields() for all arguments to the function. The main intention
+ is to allow all Item_field() objects to setup pointers to the table fields.
+
+ Sets as a side effect the following class variables:
+ maybe_null Set if any argument may return NULL
+ binary Set if any of the arguments is binary
+ with_sum_func Set if any of the arguments contains a sum function
+ used_table_cache Set to union of the arguments used table
+
+ str_value.charset If this is a string function, set this to the
+ character set for the first argument.
+
+ If for any item any of the defaults are wrong, then this can
+ be fixed in the fix_length_and_dec() function that is called
+ after this one or by writing a specialized fix_fields() for the
+ item.
+
+ RETURN VALUES
+ 0 ok
+ 1 Got error. Stored with my_error().
+*/
+
bool
-Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
+Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{
Item **arg,**arg_end;
char buff[STACK_BUFF_ALLOC]; // Max argument in function
@@ -70,7 +108,7 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
{ // Print purify happy
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- if ((*arg)->fix_fields(thd,tables))
+ if ((*arg)->fix_fields(thd, tables, arg))
return 1; /* purecov: inspected */
if ((*arg)->maybe_null)
maybe_null=1;
@@ -80,6 +118,12 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
used_tables_cache|=(*arg)->used_tables();
const_item_cache&= (*arg)->const_item();
}
+ /*
+ Set return character set to first argument if we are returning a
+ string.
+ */
+ if (result_type() == STRING_RESULT)
+ str_value.set_charset((*args)->str_value.charset());
}
fix_length_and_dec();
return 0;
@@ -847,6 +891,18 @@ longlong Item_func_min_max::val_int()
return value;
}
+longlong Item_func_crc32::val_int()
+{
+ String *res=args[0]->val_str(&value);
+ if (!res)
+ {
+ null_value=1;
+ return 0; /* purecov: inspected */
+ }
+ null_value=0;
+ return (longlong) crc32(0L, (Bytef*)res->ptr(), res->length());
+}
+
longlong Item_func_length::val_int()
{
@@ -892,7 +948,7 @@ longlong Item_func_locate::val_int()
{
start=(uint) args[2]->val_int()-1;
#ifdef USE_MB
- if (use_mb(default_charset_info))
+ if (use_mb(a->charset()))
{
start0=start;
if (!binary_str)
@@ -905,7 +961,7 @@ longlong Item_func_locate::val_int()
if (!b->length()) // Found empty string at start
return (longlong) (start+1);
#ifdef USE_MB
- if (use_mb(default_charset_info) && !binary_str)
+ if (use_mb(a->charset()) && !binary_str)
{
const char *ptr=a->ptr()+start;
const char *search=b->ptr();
@@ -924,7 +980,8 @@ longlong Item_func_locate::val_int()
return (longlong) start0+1;
}
skipp:
- if ((l=my_ismbchar(default_charset_info,ptr,strend))) ptr+=l;
+ if ((l=my_ismbchar(a->charset(),ptr,strend)))
+ ptr+=l;
else ++ptr;
++start0;
}
@@ -975,12 +1032,12 @@ longlong Item_func_ord::val_int()
null_value=0;
if (!res->length()) return 0;
#ifdef USE_MB
- if (use_mb(default_charset_info) && !args[0]->binary)
+ if (use_mb(res->charset()) && !args[0]->binary)
{
register const char *str=res->ptr();
- register uint32 n=0, l=my_ismbchar(default_charset_info,
- str,str+res->length());
- if (!l) return (longlong)((uchar) *str);
+ register uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length());
+ if (!l)
+ return (longlong)((uchar) *str);
while (l--)
n=(n<<8)|(uint32)((uchar) *str++);
return (longlong) n;
@@ -1040,6 +1097,7 @@ longlong Item_func_find_in_set::val_int()
null_value=0;
int diff;
+ CHARSET_INFO *charset= find->charset();
if ((diff=buffer->length() - find->length()) >= 0)
{
const char *f_pos=find->ptr();
@@ -1053,7 +1111,7 @@ longlong Item_func_find_in_set::val_int()
const char *pos= f_pos;
while (pos != f_end)
{
- if (toupper(*str) != toupper(*pos))
+ if (my_toupper(charset,*str) != my_toupper(charset,*pos))
goto not_found;
str++;
pos++;
@@ -1148,7 +1206,7 @@ udf_handler::~udf_handler()
bool
-udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
+udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
uint arg_count, Item **arguments)
{
char buff[STACK_BUFF_ALLOC]; // Max argument in function
@@ -1192,7 +1250,7 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
arg != arg_end ;
arg++,i++)
{
- if ((*arg)->fix_fields(thd,tables))
+ if ((*arg)->fix_fields(thd, tables, arg))
return 1;
if ((*arg)->binary)
func->binary=1;
@@ -1358,7 +1416,7 @@ String *udf_handler::val_str(String *str,String *save_str)
str->length(res_length);
return str;
}
- save_str->set(res, res_length);
+ save_str->set(res, res_length, default_charset_info);
return save_str;
}
@@ -1483,7 +1541,8 @@ char *ull_get_key(const ULL *ull,uint *length,
void item_user_lock_init(void)
{
pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW);
- hash_init(&hash_user_locks,16,0,0,(hash_get_key) ull_get_key,NULL,0);
+ hash_init(&hash_user_locks,system_charset_info,
+ 16,0,0,(hash_get_key) ull_get_key,NULL,0);
}
void item_user_lock_free(void)
@@ -1497,9 +1556,9 @@ void item_user_lock_release(ULL *ull)
if (mysql_bin_log.is_open())
{
char buf[256];
- String tmp(buf,sizeof(buf));
- tmp.length(0);
- tmp.append("DO RELEASE_LOCK(\"");
+ const char *command="DO RELEASE_LOCK(\"";
+ String tmp(buf,sizeof(buf), system_charset_info);
+ tmp.copy(command, strlen(command));
tmp.append(ull->key,ull->key_length);
tmp.append("\")");
Query_log_event qev(current_thd,tmp.ptr(), tmp.length());
@@ -1757,7 +1816,7 @@ longlong Item_func_set_last_insert_id::val_int()
longlong Item_func_benchmark::val_int()
{
char buff[MAX_FIELD_WIDTH];
- String tmp(buff,sizeof(buff));
+ String tmp(buff,sizeof(buff), default_charset_info);
THD *thd=current_thd;
for (ulong loop=0 ; loop < loop_count && !thd->killed; loop++)
@@ -1812,11 +1871,12 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
}
-bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables)
+bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
+ Item **ref)
{
if (!thd)
thd=current_thd; // Should never happen
- if (Item_func::fix_fields(thd,tables) ||
+ if (Item_func::fix_fields(thd, tables, ref) ||
!(entry= get_variable(&thd->user_vars, name, 1)))
return 1;
entry->update_query_id=thd->query_id;
@@ -1895,7 +1955,7 @@ Item_func_set_user_var::update()
break;
case STRING_RESULT:
char buffer[MAX_FIELD_WIDTH];
- String tmp(buffer,sizeof(buffer));
+ String tmp(buffer,sizeof(buffer),default_charset_info);
(void) val_str(&tmp);
break;
}
@@ -2070,7 +2130,7 @@ longlong Item_func_inet_aton::val_int()
char c = '.'; // we mark c to indicate invalid IP in case length is 0
char buff[36];
- String *s,tmp(buff,sizeof(buff));
+ String *s,tmp(buff,sizeof(buff),default_charset_info);
if (!(s = args[0]->val_str(&tmp))) // If null value
goto err;
null_value=0;
@@ -2108,7 +2168,9 @@ void Item_func_match::init_search(bool no_order)
return;
if (key == NO_SUCH_KEY)
- concat= new Item_func_concat_ws(new Item_string(" ",1), fields);
+ concat=new Item_func_concat_ws(new Item_string(" ",1,
+ default_charset_info),
+ fields);
if (master)
{
@@ -2119,15 +2181,15 @@ void Item_func_match::init_search(bool no_order)
return;
}
- String *ft_tmp=0;
+ String *ft_tmp= 0;
char tmp1[FT_QUERY_MAXLEN];
- String tmp2(tmp1,sizeof(tmp1));
+ String tmp2(tmp1,sizeof(tmp1),default_charset_info);
// MATCH ... AGAINST (NULL) is meaningless, but possible
if (!(ft_tmp=key_item()->val_str(&tmp2)))
{
ft_tmp= &tmp2;
- tmp2.set("",0);
+ tmp2.set("",0,default_charset_info);
}
ft_handler=table->file->ft_init_ext(mode, key,
@@ -2143,7 +2205,7 @@ void Item_func_match::init_search(bool no_order)
}
-bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
+bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{
List_iterator<Item> li(fields);
Item *item;
@@ -2157,7 +2219,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
modifications to find_best and auto_close as complement to auto_init code
above.
*/
- if (Item_func::fix_fields(thd,tlist) || !const_item())
+ if (Item_func::fix_fields(thd, tlist, ref) || !const_item())
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
return 1;
@@ -2165,7 +2227,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
while ((item=li++))
{
- if (item->fix_fields(thd,tlist))
+ if (item->fix_fields(thd, tlist, li.ref()))
return 1;
if (item->type() == Item::REF_ITEM)
li.replace(item= *((Item_ref *)item)->ref);
@@ -2311,6 +2373,7 @@ double Item_func_match::val()
return ft_handler->please->find_relevance(ft_handler, record, 0);
}
+
longlong Item_func_bit_xor::val_int()
{
ulonglong arg1= (ulonglong) args[0]->val_int();
@@ -2386,3 +2449,124 @@ longlong Item_func_is_free_lock::val_int()
return 1;
return 0;
}
+
+
+/**************************************************************************
+ Spatial functions
+***************************************************************************/
+
+longlong Item_func_dimension::val_int()
+{
+ uint32 dim;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ args[0]->null_value ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ geom.dimension(&dim));
+
+ return (longlong) dim;
+}
+
+longlong Item_func_numinteriorring::val_int()
+{
+ uint32 num;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ !GEOM_METHOD_PRESENT(geom,num_interior_ring) ||
+ geom.num_interior_ring(&num));
+
+ return (longlong) num;
+}
+
+longlong Item_func_numgeometries::val_int()
+{
+ uint32 num=0;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ !GEOM_METHOD_PRESENT(geom,num_geometries) ||
+ geom.num_geometries(&num));
+
+ return (longlong) num;
+}
+
+longlong Item_func_numpoints::val_int()
+{
+ uint32 num=0;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ args[0]->null_value ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ !GEOM_METHOD_PRESENT(geom,num_points) ||
+ geom.num_points(&num));
+
+ return (longlong) num;
+}
+
+
+double Item_func_x::val()
+{
+ double res=0;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ !GEOM_METHOD_PRESENT(geom,get_x) ||
+ geom.get_x(&res));
+
+ return res;
+}
+
+
+double Item_func_y::val()
+{
+ double res=0;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ !GEOM_METHOD_PRESENT(geom,get_y) ||
+ geom.get_y(&res));
+
+ return res;
+}
+
+
+double Item_func_area::val()
+{
+ double res=0;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ !GEOM_METHOD_PRESENT(geom,area) ||
+ geom.area(&res));
+
+ return res;
+}
+
+
+double Item_func_glength::val()
+{
+ double res=0;
+ String *wkb=args[0]->val_str(&value);
+ Geometry geom;
+
+ null_value= (!wkb ||
+ geom.create_from_wkb(wkb->ptr(),wkb->length()) ||
+ !GEOM_METHOD_PRESENT(geom,length) ||
+ geom.length(&res));
+ return res;
+}