summaryrefslogtreecommitdiff
path: root/sql/item.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item.h')
-rw-r--r--sql/item.h93
1 files changed, 73 insertions, 20 deletions
diff --git a/sql/item.h b/sql/item.h
index 69a6718a5a9..a169fc32a0b 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -98,7 +98,8 @@ public:
COPY_STR_ITEM, FIELD_AVG_ITEM, DEFAULT_VALUE_ITEM,
PROC_ITEM,COND_ITEM, REF_ITEM, FIELD_STD_ITEM,
FIELD_VARIANCE_ITEM, INSERT_VALUE_ITEM,
- SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER};
+ SUBSELECT_ITEM, ROW_ITEM, CACHE_ITEM, TYPE_HOLDER,
+ PARAM_ITEM};
enum cond_result { COND_UNDEF,COND_OK,COND_TRUE,COND_FALSE };
@@ -161,6 +162,31 @@ public:
/* valXXX methods must return NULL or 0 or 0.0 if null_value is set. */
virtual double val()=0;
virtual longlong val_int()=0;
+ /*
+ Return string representation of this item object.
+
+ The argument to val_str() is an allocated buffer this or any
+ nested Item object can use to store return value of this method.
+ This buffer should only be used if the item itself doesn't have an
+ own String buffer. In case when the item maintains it's own string
+ buffer, it's preferrable to return it instead to minimize number of
+ mallocs/memcpys.
+ The caller of this method can modify returned string, but only in
+ case when it was allocated on heap, (is_alloced() is true). This
+ allows the caller to efficiently use a buffer allocated by a child
+ without having to allocate a buffer of it's own. The buffer, given
+ to val_str() as agrument, belongs to the caller and is later used
+ by the caller at it's own choosing.
+ A few implications from the above:
+ - unless you return a string object which only points to your buffer
+ but doesn't manages it you should be ready that it will be
+ modified.
+ - even for not allocated strings (is_alloced() == false) the caller
+ can change charset (see Item_func_{typecast/binary}. XXX: is this
+ a bug?
+ - still you should try to minimize data copying and return internal
+ object whenever possible.
+ */
virtual String *val_str(String*)=0;
virtual Field *get_tmp_table_field() { return 0; }
virtual Field *tmp_table_field(TABLE *t_arg) { return 0; }
@@ -221,7 +247,7 @@ public:
virtual Item *real_item() { return this; }
virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
- CHARSET_INFO *default_charset() const;
+ static CHARSET_INFO *default_charset();
virtual CHARSET_INFO *compare_collation() { return NULL; }
virtual bool walk(Item_processor processor, byte *arg)
@@ -409,17 +435,11 @@ class Item_field :public Item_ident
void set_field(Field *field);
public:
Field *field,*result_field;
-#ifndef DBUG_OFF
- bool double_fix;
-#endif
Item_field(const char *db_par,const char *table_name_par,
const char *field_name_par)
:Item_ident(db_par,table_name_par,field_name_par),
field(0), result_field(0)
-#ifndef DBUG_OFF
- ,double_fix(0)
-#endif
{ collation.set(DERIVATION_IMPLICIT); }
// Constructor need to process subselect with temporary tables (see Item)
Item_field(THD *thd, Item_field *item);
@@ -459,6 +479,7 @@ public:
bool is_null() { return field->is_null(); }
Item *get_tmp_table_item(THD *thd);
void cleanup();
+ inline uint32 max_disp_length() { return field->max_length(); }
friend class Item_default_value;
friend class Item_insert_value;
friend class st_select_lex_unit;
@@ -492,19 +513,33 @@ public:
void print(String *str) { str->append("NULL", 4); }
};
+
+/* Item represents one placeholder ('?') of prepared statement */
+
class Item_param :public Item
{
-public:
+public:
enum enum_item_param_state
{
NO_VALUE, NULL_VALUE, INT_VALUE, REAL_VALUE,
STRING_VALUE, TIME_VALUE, LONG_DATA_VALUE
} state;
+ /*
+ A buffer for string and long data values. Historically all allocated
+ values returned from val_str() were treated as eligible to
+ modification. I. e. in some cases Item_func_concat can append it's
+ second argument to return value of the first one. Because of that we
+ can't return the original buffer holding string data from val_str(),
+ and have to have one buffer for data and another just pointing to
+ the data. This is the latter one and it's returned from val_str().
+ Can not be declared inside the union as it's not a POD type.
+ */
+ String str_value_ptr;
union
{
- longlong integer;
- double real;
+ longlong integer;
+ double real;
/*
Character sets conversion info for string values.
Character sets of client and connection defined at bind time are used
@@ -517,7 +552,7 @@ public:
/*
This points at character set of connection if conversion
to it is required (i. e. if placeholder typecode is not BLOB).
- Otherwise it's equal to character_set_client (to simplify
+ Otherwise it's equal to character_set_client (to simplify
check in convert_str_value()).
*/
CHARSET_INFO *final_character_set_of_str_value;
@@ -528,22 +563,33 @@ public:
/* Cached values for virtual methods to save us one switch. */
enum Item_result item_result_type;
enum Type item_type;
- /*
+
+ /*
+ Used when this item is used in a temporary table.
+ This is NOT placeholder metadata sent to client, as this value
+ is assigned after sending metadata (in setup_one_conversion_function).
+ For example in case of 'SELECT ?' you'll get MYSQL_TYPE_STRING both
+ in result set and placeholders metadata, no matter what type you will
+ supply for this placeholder in mysql_stmt_execute.
+ */
+ enum enum_field_types param_type;
+ /*
Offset of placeholder inside statement text. Used to create
no-placeholders version of this statement for the binary log.
- */
+ */
uint pos_in_query;
Item_param(uint pos_in_query_arg);
enum Item_result result_type () const { return item_result_type; }
enum Type type() const { return item_type; }
- enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
+ enum_field_types field_type() const { return param_type; }
double val();
longlong val_int();
String *val_str(String*);
bool get_time(TIME *tm);
+ bool get_date(TIME *tm, uint fuzzydate);
int save_in_field(Field *field, bool no_conversions);
void set_null();
@@ -552,6 +598,7 @@ public:
bool set_str(const char *str, ulong length);
bool set_longdata(const char *str, ulong length);
void set_time(TIME *tm, timestamp_type type, uint32 max_length_arg);
+ bool set_from_user_var(THD *thd, const user_var_entry *entry);
void reset();
/*
Assign placeholder value from bind data.
@@ -564,16 +611,18 @@ public:
const String *query_val_str(String *str) const;
bool convert_str_value(THD *thd);
-
+
Item *new_item() { return new Item_param(pos_in_query); }
- /*
- If value for parameter was not set we treat it as non-const
- so noone will use parameters value in fix_fields still
+ /*
+ If value for parameter was not set we treat it as non-const
+ so noone will use parameters value in fix_fields still
parameter is constant during execution.
*/
virtual table_map used_tables() const
{ return state != NO_VALUE ? (table_map)0 : PARAM_TABLE_BIT; }
void print(String *str) { str->append('?'); }
+ /* parameter never equal to other parameter of other item */
+ bool eq(const Item *item, bool binary_cmp) const { return 0; }
};
class Item_int :public Item_num
@@ -871,7 +920,10 @@ public:
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); }
enum_field_types field_type() const { return (*ref)->field_type(); }
- table_map used_tables() const { return (*ref)->used_tables(); }
+ table_map used_tables() const
+ {
+ return depended_from ? OUTER_REF_TABLE_BIT : (*ref)->used_tables();
+ }
void set_result_field(Field *field) { result_field= field; }
bool is_result_field() { return 1; }
void save_in_result_field(bool no_conversions)
@@ -1250,6 +1302,7 @@ public:
String *val_str(String*);
bool join_types(THD *thd, Item *);
Field *example() { return field_example; }
+ static uint32 real_length(Item *item);
void cleanup()
{
DBUG_ENTER("Item_type_holder::cleanup");