summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorunknown <monty@mysql.com>2005-11-05 01:32:55 +0200
committerunknown <monty@mysql.com>2005-11-05 01:32:55 +0200
commit2361720c981fc2eb27bc97c1ea7e043b634ffae1 (patch)
tree4a7b533b6da471261f5c13c46e4e9f256ec63a0c /sql/item.cc
parenta3db4abe8b5ecad27adaff3baa78a913d0b84f10 (diff)
parentd4a7867a9ee0a44c8c943c75b5eb15e450ac61a7 (diff)
downloadmariadb-git-2361720c981fc2eb27bc97c1ea7e043b634ffae1.tar.gz
Merge mysql.com:/home/my/mysql-5.0
into mysql.com:/home/my/mysql-5.1 BUILD/FINISH.sh: Auto merged BitKeeper/deleted/.del-makefilewin.i~5c8479dcb8a455b2: Auto merged BitKeeper/deleted/.del-makefilewin~13888739357b3025: Auto merged BitKeeper/deleted/.del-makefilewin~14f24a4a173e2fcd: Auto merged BitKeeper/deleted/.del-makefilewin~15e9e5c9e8fa870b: Auto merged BitKeeper/deleted/.del-makefilewin~1c53f31b88dd36e: Auto merged BitKeeper/deleted/.del-makefilewin~1dbc058d76ebf1db: Auto merged BitKeeper/deleted/.del-makefilewin~2e0407fe123f8365: Auto merged BitKeeper/deleted/.del-makefilewin~2fc379bd4065c995: Auto merged BitKeeper/deleted/.del-makefilewin~389ee2dcf79afb79: Auto merged BitKeeper/deleted/.del-makefilewin~4d139e182457e553: Auto merged BitKeeper/deleted/.del-makefilewin~5104767c73775697: Auto merged BitKeeper/deleted/.del-makefilewin~608ed49dcd88e0f7: Auto merged BitKeeper/deleted/.del-makefilewin~63acd666293282a: Auto merged BitKeeper/deleted/.del-makefilewin~6ba64863bce3d0b8: Auto merged BitKeeper/deleted/.del-makefilewin~72a64128bacce71b: Auto merged BitKeeper/deleted/.del-makefilewin~78000390c783b1c5: Auto merged BitKeeper/deleted/.del-makefilewin~7a9d7d5a42bbfaf5: Auto merged Makefile.am: Auto merged BitKeeper/deleted/.del-makefilewin~a40ea12eebdd6ef0: Auto merged BitKeeper/deleted/.del-makefilewin~aeea7c82f21f7cf5: Auto merged BitKeeper/deleted/.del-makefilewin~b643e38d8da389ac: Auto merged BitKeeper/deleted/.del-makefilewin~c7b621c745e5de95: Auto merged BitKeeper/deleted/.del-makefilewin~c8273a47b90f52bb: Auto merged BitKeeper/deleted/.del-makefilewin~d1a9d1f7d33fcb73: Auto merged BitKeeper/deleted/.del-makefilewin~d37b6b303348c871: Auto merged BitKeeper/deleted/.del-makefilewin~d90f35fdc3f2ee5f: Auto merged BitKeeper/deleted/.del-makefilewin~dc4b8ad5ea53bd: Auto merged BitKeeper/deleted/.del-makefilewin~dea10ec1c94f7be: Auto merged BitKeeper/deleted/.del-makefilewin~ef3a208fa0e9b0db: Auto merged BitKeeper/deleted/.del-makefilewin~f1e3b890aa1c9ea3: Auto merged BitKeeper/deleted/.del-makefilewin~f4b7b99a887b7de: Auto merged BitKeeper/deleted/.del-makefilewin~fdda94ad32fa9e34: Auto merged BitKeeper/deleted/.del-my_cnf~977f69858affc57b: Auto merged BitKeeper/etc/config: Auto merged VC++Files/libmysqld/libmysqld.dsp: Auto merged VC++Files/sql/mysqld.dsp: Auto merged client/mysqltest.c: Auto merged include/Makefile.am: Auto merged include/base64.h: Auto merged include/my_base.h: Auto merged include/mysql_com.h: Auto merged libmysqld/Makefile.am: Auto merged mysql-test/mysql-test-run.pl: Auto merged mysql-test/mysql-test-run.sh: Auto merged mysql-test/r/ndb_basic.result: Auto merged mysql-test/r/ndb_condition_pushdown.result: Auto merged mysql-test/t/alter_table.test: Auto merged mysql-test/t/disabled.def: Auto merged mysql-test/t/query_cache.test: Auto merged mysys/Makefile.am: Auto merged mysys/base64.c: Auto merged scripts/make_win_src_distribution.sh: Auto merged scripts/mysql_create_system_tables.sh: Auto merged scripts/mysql_fix_privilege_tables.sql: Auto merged sql/Makefile.am: Auto merged sql/field.cc: Auto merged sql/field.h: Auto merged sql/ha_berkeley.cc: Auto merged sql/ha_berkeley.h: Auto merged sql/ha_federated.cc: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_myisam.cc: Auto merged sql/ha_ndbcluster.cc: Auto merged sql/handler.h: Auto merged sql/item.cc: Auto merged sql/item_subselect.cc: Auto merged sql/log.cc: Auto merged sql/log_event.cc: Auto merged sql/mysqld.cc: Auto merged sql/opt_range.cc: Auto merged sql/repl_failsafe.cc: Auto merged sql/slave.cc: Auto merged sql/slave.h: Auto merged sql/sp.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_delete.cc: Auto merged sql/sql_help.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_lex.cc: Auto merged sql/sql_lex.h: Auto merged sql/sql_load.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_repl.cc: Auto merged sql/sql_select.cc: Auto merged sql/sql_select.h: Auto merged sql/sql_show.cc: Auto merged sql/sql_yacc.yy: Auto merged sql/table.h: Auto merged storage/heap/_check.c: Auto merged storage/heap/hp_create.c: Auto merged storage/innobase/include/Makefile.am: Auto merged storage/innobase/include/rem0rec.h: Auto merged storage/innobase/include/rem0rec.ic: Auto merged storage/innobase/row/row0ins.c: Auto merged storage/innobase/row/row0upd.c: Auto merged storage/myisam/mi_check.c: Auto merged storage/myisam/mi_delete.c: Auto merged storage/myisam/mi_rkey.c: Auto merged storage/myisam/mi_rnext_same.c: Auto merged storage/myisam/mi_search.c: Auto merged storage/myisam/mi_write.c: Auto merged storage/myisam/myisamchk.c: Auto merged storage/myisam/myisamdef.h: Auto merged storage/myisam/sort.c: Auto merged storage/myisammrg/myrg_queue.c: Auto merged storage/ndb/config/type_util.mk.am: Auto merged storage/ndb/include/kernel/signaldata/DumpStateOrd.hpp: Auto merged storage/ndb/include/mgmapi/mgmapi_config_parameters.h: Auto merged storage/ndb/include/mgmapi/ndbd_exit_codes.h: Auto merged storage/ndb/include/transporter/TransporterCallback.hpp: Auto merged storage/ndb/src/common/mgmcommon/IPCConfig.cpp: Auto merged storage/ndb/src/common/transporter/SHM_Transporter.cpp: Auto merged storage/ndb/src/common/transporter/SHM_Transporter.hpp: Auto merged storage/ndb/src/common/transporter/SHM_Transporter.unix.cpp: Auto merged storage/ndb/src/common/transporter/SHM_Transporter.win32.cpp: Auto merged storage/ndb/src/common/transporter/Transporter.hpp: Auto merged storage/ndb/src/common/transporter/TransporterRegistry.cpp: Auto merged storage/ndb/src/common/util/Makefile.am: Auto merged storage/ndb/src/common/util/Parser.cpp: Auto merged storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Auto merged storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp: Auto merged storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp: Auto merged storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp: Auto merged storage/ndb/src/kernel/error/ndbd_exit_codes.c: Auto merged storage/ndb/src/kernel/vm/FastScheduler.cpp: Auto merged storage/ndb/src/kernel/vm/TransporterCallback.cpp: Auto merged storage/ndb/src/kernel/vm/VMSignal.hpp: Auto merged storage/ndb/src/mgmapi/mgmapi.cpp: Auto merged storage/ndb/src/mgmsrv/ConfigInfo.cpp: Auto merged storage/ndb/src/mgmsrv/InitConfigFileParser.cpp: Auto merged storage/ndb/src/mgmsrv/MgmtSrvr.cpp: Auto merged storage/ndb/src/mgmsrv/MgmtSrvr.hpp: Auto merged storage/ndb/src/mgmsrv/Services.cpp: Auto merged storage/ndb/src/ndbapi/TransporterFacade.cpp: Auto merged storage/ndb/test/ndbapi/testBackup.cpp: Auto merged storage/ndb/test/ndbapi/testOperations.cpp: Auto merged storage/ndb/test/src/HugoCalculator.cpp: Auto merged storage/ndb/tools/ndb_condig.cpp: Auto merged strings/ctype-big5.c: Auto merged strings/ctype-ucs2.c: Auto merged support-files/mysql.spec.sh: Auto merged BUILD/SETUP.sh: manual merge configure.in: manual merge mysql-test/r/alter_table.result: manual merge sql/handler.cc: manual merge sql/mysql_priv.h: manual merge sql/records.cc: manual merge sql/share/errmsg.txt: manual merge sql/sql_table.cc: manual merge Fix labels sql/sql_update.cc: manual merge sql/table.cc: manual merge sql/unireg.cc: manual merge storage/ndb/config/type_ndbapi.mk.am: manual merge
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc183
1 files changed, 118 insertions, 65 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 5caac05f6ca..9a64b02f80b 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -696,6 +696,32 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
}
+Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs)
+{
+ if (const_item())
+ {
+ Item_string *conv;
+ uint cnv_errors;
+ char buf[MAX_FIELD_WIDTH];
+ String tmp(buf, sizeof(buf), &my_charset_bin);
+ String cstr, *ostr= val_str(&tmp);
+ /*
+ As safe_charset_converter is not executed for
+ a parameter bound to NULL, ostr should never be 0.
+ */
+ cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &cnv_errors);
+ if (cnv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
+ cstr.charset(),
+ collation.derivation)))
+ return NULL;
+ conv->str_value.copy();
+ conv->str_value.mark_as_const();
+ return conv;
+ }
+ return NULL;
+}
+
+
Item *Item_static_string_func::safe_charset_converter(CHARSET_INFO *tocs)
{
Item_string *conv;
@@ -729,7 +755,8 @@ bool Item_string::eq(const Item *item, bool binary_cmp) const
{
if (binary_cmp)
return !stringcmp(&str_value, &item->str_value);
- return !sortcmp(&str_value, &item->str_value, collation.collation);
+ return (collation.collation == item->collation.collation &&
+ !sortcmp(&str_value, &item->str_value, collation.collation));
}
return 0;
}
@@ -817,9 +844,12 @@ String *Item_splocal::val_str(String *sp)
{
DBUG_ASSERT(fixed);
Item *it= this_item();
- String *ret= it->val_str(sp);
+ String *res= it->val_str(sp);
null_value= it->null_value;
+ if (!res)
+ return NULL;
+
/*
This way we mark returned value of val_str as const,
so that various functions (e.g. CONCAT) won't try to
@@ -836,12 +866,11 @@ String *Item_splocal::val_str(String *sp)
Item_param class contain some more details on the topic.
*/
- if (!ret)
- return NULL;
-
- str_value_ptr.set(ret->ptr(), ret->length(),
- ret->charset());
- return &str_value_ptr;
+ if (res != &str_value)
+ str_value.set(res->ptr(), res->length(), res->charset());
+ else
+ res->mark_as_const();
+ return &str_value;
}
@@ -858,17 +887,13 @@ my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value)
bool Item_splocal::is_null()
{
Item *it= this_item();
- bool ret= it->is_null();
- null_value= it->null_value;
- return ret;
+ return it->is_null();
}
Item *
Item_splocal::this_item()
{
- THD *thd= current_thd;
-
return thd->spcont->get_item(m_offset);
}
@@ -882,25 +907,23 @@ Item_splocal::this_item_addr(THD *thd, Item **addr)
Item *
Item_splocal::this_const_item() const
{
- THD *thd= current_thd;
-
return thd->spcont->get_item(m_offset);
}
Item::Type
Item_splocal::type() const
{
- THD *thd= current_thd;
-
- if (thd->spcont)
+ if (thd && thd->spcont)
return thd->spcont->get_item(m_offset)->type();
return NULL_ITEM; // Anything but SUBSELECT_ITEM
}
-bool Item_splocal::fix_fields(THD *, Item **)
+bool Item_splocal::fix_fields(THD *thd_arg, Item **ref)
{
- Item *it= this_item();
+ Item *it;
+ thd= thd_arg; // Must be set before this_item()
+ it= this_item();
DBUG_ASSERT(it->fixed);
max_length= it->max_length;
decimals= it->decimals;
@@ -928,6 +951,7 @@ void Item_splocal::print(String *str)
/*****************************************************************************
Item_name_const methods
*****************************************************************************/
+
double Item_name_const::val_real()
{
DBUG_ASSERT(fixed);
@@ -966,9 +990,7 @@ my_decimal *Item_name_const::val_decimal(my_decimal *decimal_value)
bool Item_name_const::is_null()
{
- bool ret= value_item->is_null();
- null_value= value_item->null_value;
- return ret;
+ return value_item->is_null();
}
Item::Type Item_name_const::type() const
@@ -977,7 +999,7 @@ Item::Type Item_name_const::type() const
}
-bool Item_name_const::fix_fields(THD *thd, Item **)
+bool Item_name_const::fix_fields(THD *thd, Item **ref)
{
char buf[128];
String *item_name;
@@ -1356,7 +1378,7 @@ bool agg_item_charsets(DTCollation &coll, const char *fname,
been created in prepare. In this case register the change for
rollback.
*/
- if (arena)
+ if (arena && arena->is_conventional())
*arg= conv;
else
thd->change_item_tree(arg, conv);
@@ -2783,7 +2805,7 @@ int Item_copy_string::save_in_field(Field *field, bool no_conversions)
*/
/* ARGSUSED */
-bool Item::fix_fields(THD *thd, Item ** ref)
+bool Item::fix_fields(THD *thd, Item **ref)
{
// We do not check fields which are fixed during construction
@@ -3213,11 +3235,26 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
context->last_name_resolution_table,
reference,
IGNORE_EXCEPT_NON_UNIQUE,
- !any_privileges &&
- context->check_privileges,
+ !any_privileges,
TRUE)) ==
not_found_field)
{
+
+ /* Look up in current select's item_list to find aliased fields */
+ if (thd->lex->current_select->is_item_list_lookup)
+ {
+ uint counter;
+ bool not_used;
+ Item** res= find_item_in_list(this, thd->lex->current_select->item_list,
+ &counter, REPORT_EXCEPT_NOT_FOUND,
+ &not_used);
+ if (res != (Item **)not_found_item && (*res)->type() == Item::FIELD_ITEM)
+ {
+ set_field((*((Item_field**)res))->field);
+ return 0;
+ }
+ }
+
/*
If there are outer contexts (outer selects, but current select is
not derived table or view) try to resolve this reference in the
@@ -3260,9 +3297,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
last_name_resolution_table,
reference,
IGNORE_EXCEPT_NON_UNIQUE,
- outer_context->
- check_privileges,
- TRUE)) !=
+ TRUE, TRUE)) !=
not_found_field)
{
if (from_field)
@@ -3337,7 +3372,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
context->last_name_resolution_table,
reference, REPORT_ALL_ERRORS,
!any_privileges &&
- context->check_privileges, TRUE);
+ TRUE, TRUE);
}
goto error;
}
@@ -3412,7 +3447,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can leave expression substituted from view for next PS/SP rexecution
(i.e. do not register this substitution for reverting on cleupup()
(register_item_tree_changing())), because this subtree will be
- fix_field'ed during setup_tables()->setup_ancestor() (i.e. before
+ fix_field'ed during setup_tables()->setup_underlying() (i.e. before
all other expressions of query, and references on tables which do
not present in query will not make problems.
@@ -4512,8 +4547,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference)
last_name_resolution_table,
reference,
IGNORE_EXCEPT_NON_UNIQUE,
- outer_context->check_privileges,
- TRUE);
+ TRUE, TRUE);
if (! from_field)
goto error;
if (from_field == view_ref_found)
@@ -4638,7 +4672,7 @@ void Item_ref::cleanup()
void Item_ref::print(String *str)
{
- if (ref && *ref)
+ if (ref)
(*ref)->print(str);
else
Item_ident::print(str);
@@ -4770,8 +4804,7 @@ String *Item_ref::val_str(String* tmp)
bool Item_ref::is_null()
{
DBUG_ASSERT(fixed);
- (void) (*ref)->val_int_result();
- return (*ref)->null_value;
+ return (*ref)->is_null();
}
@@ -4825,7 +4858,7 @@ void Item_ref::make_field(Send_field *field)
void Item_ref_null_helper::print(String *str)
{
str->append("<ref_null_helper>(", 18);
- if (ref && *ref)
+ if (ref)
(*ref)->print(str);
else
str->append('?');
@@ -5053,8 +5086,17 @@ bool Item_insert_value::eq(const Item *item, bool binary_cmp) const
bool Item_insert_value::fix_fields(THD *thd, Item **items)
{
DBUG_ASSERT(fixed == 0);
- if (!arg->fixed && arg->fix_fields(thd, &arg))
- return TRUE;
+ /* We should only check that arg is in first table */
+ if (!arg->fixed)
+ {
+ bool res;
+ st_table_list *orig_next_table= context->last_name_resolution_table;
+ context->last_name_resolution_table= context->first_name_resolution_table;
+ res= arg->fix_fields(thd, &arg);
+ context->last_name_resolution_table= orig_next_table;
+ if (res)
+ return TRUE;
+ }
if (arg->type() == REF_ITEM)
{
@@ -5066,6 +5108,7 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items)
arg= ref->ref[0];
}
Item_field *field_arg= (Item_field *)arg;
+
if (field_arg->field->table->insert_values)
{
Field *def_field= (Field*) sql_alloc(field_arg->field->size_of());
@@ -5126,7 +5169,7 @@ void Item_trigger_field::setup_field(THD *thd, TABLE *table)
set field_idx properly.
*/
(void)find_field_in_table(thd, table, field_name, (uint) strlen(field_name),
- 0, 0, &field_idx);
+ 0, 0, &field_idx, 0);
thd->set_query_id= save_set_query_id;
triggers= table->triggers;
}
@@ -5241,32 +5284,21 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
}
case ROW_RESULT:
{
+ Item_row *item_row= (Item_row*) item;
+ Item_row *comp_item_row= (Item_row*) comp_item;
+ uint col;
new_item= 0;
/*
If item and comp_item are both Item_rows and have same number of cols
- then process items in Item_row one by one. If Item_row contain nulls
- substitute it by Item_null. Otherwise just return.
+ then process items in Item_row one by one.
+ We can't ignore NULL values here as this item may be used with <=>, in
+ which case NULL's are significant.
*/
- if (item->result_type() == comp_item->result_type() &&
- ((Item_row*)item)->cols() == ((Item_row*)comp_item)->cols())
- {
- Item_row *item_row= (Item_row*)item,*comp_item_row= (Item_row*)comp_item;
- if (item_row->null_inside())
- new_item= (Item*) new Item_null(name);
- else
- {
- int i= item_row->cols() - 1;
- for (; i >= 0; i--)
- {
- if (item_row->maybe_null && item_row->el(i)->is_null())
- {
- new_item= (Item*) new Item_null(name);
- break;
- }
- resolve_const_item(thd, item_row->addr(i), comp_item_row->el(i));
- }
- }
- }
+ DBUG_ASSERT(item->result_type() == comp_item->result_type());
+ DBUG_ASSERT(item_row->cols() == comp_item_row->cols());
+ col= item_row->cols();
+ while (col-- > 0)
+ resolve_const_item(thd, item_row->addr(col), comp_item_row->el(col));
break;
}
case REAL_RESULT:
@@ -5721,6 +5753,8 @@ enum_field_types Item_type_holder::get_real_type(Item *item)
bool Item_type_holder::join_types(THD *thd, Item *item)
{
+ uint max_length_orig= max_length;
+ uint decimals_orig= decimals;
DBUG_ENTER("Item_type_holder::join_types");
DBUG_PRINT("info:", ("was type %d len %d, dec %d name %s",
fld_type, max_length, decimals,
@@ -5747,7 +5781,10 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
}
else
max_length= max(max_length, display_length(item));
- if (Field::result_merge_type(fld_type) == STRING_RESULT)
+
+ switch (Field::result_merge_type(fld_type))
+ {
+ case STRING_RESULT:
{
const char *old_cs, *old_derivation;
old_cs= collation.collation->name;
@@ -5761,7 +5798,23 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
"UNION");
DBUG_RETURN(TRUE);
}
+ break;
+ }
+ case REAL_RESULT:
+ {
+ if (decimals != NOT_FIXED_DEC)
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+ max_length= min(max(delta1, delta2) + decimals,
+ (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7);
+ }
+ else
+ max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7;
+ break;
}
+ default:;
+ };
maybe_null|= item->maybe_null;
get_full_info(item);