Below is the list of changes that have just been committed into a local
5.0 repository of igor. When igor does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.1967 05/12/10 23:31:03 igor@stripped +12 -0
Merge rurik.mysql.com:/home/igor/mysql-5.0
into rurik.mysql.com:/home/igor/dev/mysql-5.0-2
sql/sql_yacc.yy
1.445 05/12/10 23:30:53 igor@stripped +0 -0
Auto merged
sql/sql_select.cc
1.376 05/12/10 23:30:53 igor@stripped +0 -0
Auto merged
sql/sql_parse.cc
1.518 05/12/10 23:30:53 igor@stripped +0 -0
Auto merged
sql/sql_lex.h
1.210 05/12/10 23:30:52 igor@stripped +0 -0
Auto merged
sql/sql_lex.cc
1.176 05/12/10 23:30:52 igor@stripped +0 -0
Auto merged
sql/sql_class.h
1.278 05/12/10 23:30:52 igor@stripped +0 -0
Auto merged
sql/sql_class.cc
1.223 05/12/10 23:30:52 igor@stripped +0 -0
Auto merged
sql/sql_base.cc
1.319 05/12/10 23:30:52 igor@stripped +0 -0
Auto merged
sql/mysql_priv.h
1.370 05/12/10 23:30:52 igor@stripped +0 -0
Auto merged
sql/item_func.cc
1.270 05/12/10 23:30:51 igor@stripped +0 -0
Auto merged
sql/item.h
1.183 05/12/10 23:30:51 igor@stripped +0 -0
Auto merged
sql/item.cc
1.199 05/12/10 23:30:51 igor@stripped +0 -0
Auto merged
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: igor
# Host: rurik.mysql.com
# Root: /home/igor/dev/mysql-5.0-2/RESYNC
--- 1.198/sql/item.cc 2005-12-02 20:42:27 -08:00
+++ 1.199/sql/item.cc 2005-12-10 23:30:51 -08:00
@@ -296,23 +296,6 @@
}
-void *Item::operator new(size_t size, Item *reuse, uint *rsize)
-{
- if (reuse && size <= reuse->rsize)
- {
- if (rsize)
- (*rsize)= reuse->rsize;
- reuse->cleanup();
- delete reuse;
- TRASH((void *)reuse, size);
- return (void *)reuse;
- }
- if (rsize)
- (*rsize)= (uint) size;
- return (void *)sql_alloc((uint)size);
-}
-
-
Item::Item():
rsize(0), name(0), orig_name(0), name_length(0), fixed(0),
is_autogenerated_name(TRUE),
@@ -802,9 +785,41 @@
/*****************************************************************************
- Item_splocal methods
+ Item_sp_variable methods
*****************************************************************************/
-double Item_splocal::val_real()
+
+Item_sp_variable::Item_sp_variable(char *sp_var_name_str,
+ uint sp_var_name_length)
+ :m_thd(0)
+#ifndef DBUG_OFF
+ , m_sp(0)
+#endif
+{
+ m_name.str= sp_var_name_str;
+ m_name.length= sp_var_name_length;
+}
+
+
+bool Item_sp_variable::fix_fields(THD *thd, Item **)
+{
+ Item *it;
+
+ m_thd= thd; /* NOTE: this must be set before any this_xxx() */
+ it= this_item();
+
+ DBUG_ASSERT(it->fixed);
+
+ max_length= it->max_length;
+ decimals= it->decimals;
+ unsigned_flag= it->unsigned_flag;
+ fixed= 1;
+ collation.set(it->collation.collation, it->collation.derivation);
+
+ return FALSE;
+}
+
+
+double Item_sp_variable::val_real()
{
DBUG_ASSERT(fixed);
Item *it= this_item();
@@ -814,7 +829,7 @@
}
-longlong Item_splocal::val_int()
+longlong Item_sp_variable::val_int()
{
DBUG_ASSERT(fixed);
Item *it= this_item();
@@ -824,13 +839,14 @@
}
-String *Item_splocal::val_str(String *sp)
+String *Item_sp_variable::val_str(String *sp)
{
DBUG_ASSERT(fixed);
Item *it= this_item();
String *res= it->val_str(sp);
null_value= it->null_value;
+
if (!res)
return NULL;
@@ -854,11 +870,12 @@
str_value.set(res->ptr(), res->length(), res->charset());
else
res->mark_as_const();
+
return &str_value;
}
-my_decimal *Item_splocal::val_decimal(my_decimal *decimal_value)
+my_decimal *Item_sp_variable::val_decimal(my_decimal *decimal_value)
{
DBUG_ASSERT(fixed);
Item *it= this_item();
@@ -868,73 +885,108 @@
}
-bool Item_splocal::is_null()
+bool Item_sp_variable::is_null()
{
- Item *it= this_item();
- return it->is_null();
+ return this_item()->is_null();
+}
+
+
+/*****************************************************************************
+ Item_splocal methods
+*****************************************************************************/
+
+Item_splocal::Item_splocal(const LEX_STRING &sp_var_name,
+ uint sp_var_idx,
+ enum_field_types sp_var_type,
+ uint pos_in_q)
+ :Item_sp_variable(sp_var_name.str, sp_var_name.length),
+ m_var_idx(sp_var_idx), pos_in_query(pos_in_q)
+{
+ maybe_null= TRUE;
+
+ m_type= sp_map_item_type(sp_var_type);
+ m_result_type= sp_map_result_type(sp_var_type);
}
Item *
Item_splocal::this_item()
{
- DBUG_ASSERT(owner == thd->spcont->owner);
- return thd->spcont->get_item(m_offset);
+ DBUG_ASSERT(m_sp == m_thd->spcont->sp);
+
+ return m_thd->spcont->get_item(m_var_idx);
+}
+
+const Item *
+Item_splocal::this_item() const
+{
+ DBUG_ASSERT(m_sp == m_thd->spcont->sp);
+
+ return m_thd->spcont->get_item(m_var_idx);
}
Item **
-Item_splocal::this_item_addr(THD *thd, Item **addr)
+Item_splocal::this_item_addr(THD *thd, Item **)
{
- DBUG_ASSERT(owner == thd->spcont->owner);
- return thd->spcont->get_item_addr(m_offset);
+ DBUG_ASSERT(m_sp == thd->spcont->sp);
+
+ return thd->spcont->get_item_addr(m_var_idx);
}
-Item *
-Item_splocal::this_const_item() const
+
+void Item_splocal::print(String *str)
{
- DBUG_ASSERT(owner == thd->spcont->owner);
- return thd->spcont->get_item(m_offset);
+ str->reserve(m_name.length+8);
+ str->append(m_name.str, m_name.length);
+ str->append('@');
+ str->qs_append(m_var_idx);
}
-Item::Type
-Item_splocal::type() const
+
+/*****************************************************************************
+ Item_case_expr methods
+*****************************************************************************/
+
+Item_case_expr::Item_case_expr(int case_expr_id)
+ :Item_sp_variable(STRING_WITH_LEN("case_expr")),
+ m_case_expr_id(case_expr_id)
{
- if (thd && thd->spcont)
- {
- DBUG_ASSERT(owner == thd->spcont->owner);
- return thd->spcont->get_item(m_offset)->type();
- }
- return NULL_ITEM; // Anything but SUBSELECT_ITEM
}
-bool Item_splocal::fix_fields(THD *thd_arg, Item **ref)
+Item *
+Item_case_expr::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;
- unsigned_flag= it->unsigned_flag;
- fixed= 1;
- return FALSE;
+ DBUG_ASSERT(m_sp == m_thd->spcont->sp);
+
+ return m_thd->spcont->get_case_expr(m_case_expr_id);
}
-void Item_splocal::cleanup()
+
+const Item *
+Item_case_expr::this_item() const
{
- fixed= 0;
+ DBUG_ASSERT(m_sp == m_thd->spcont->sp);
+
+ return m_thd->spcont->get_case_expr(m_case_expr_id);
}
-void Item_splocal::print(String *str)
+Item **
+Item_case_expr::this_item_addr(THD *thd, Item **)
{
- str->reserve(m_name.length+8);
- str->append(m_name.str, m_name.length);
- str->append('@');
- str->qs_append(m_offset);
+ DBUG_ASSERT(m_sp == thd->spcont->sp);
+
+ return thd->spcont->get_case_expr_addr(m_case_expr_id);
+}
+
+
+void Item_case_expr::print(String *str)
+{
+ str->append(STRING_WITH_LEN("case_expr@"));
+ str->qs_append(m_case_expr_id);
}
@@ -1013,12 +1065,6 @@
}
-void Item_name_const::cleanup()
-{
- fixed= 0;
-}
-
-
void Item_name_const::print(String *str)
{
str->append(STRING_WITH_LEN("NAME_CONST("));
@@ -3924,6 +3970,9 @@
str_value.set_quick(0, 0, cs);
return set_field_to_null_with_conversions(field, no_conversions);
}
+
+ /* NOTE: If null_value == FALSE, "result" must be not NULL. */
+
field->set_notnull();
error=field->store(result->ptr(),result->length(),cs);
str_value.set_quick(0, 0, cs);
@@ -5111,10 +5160,17 @@
Item_ref *ref= (Item_ref *)arg;
if (ref->ref[0]->type() != FIELD_ITEM)
{
+ my_error(ER_BAD_FIELD_ERROR, MYF(0), "", "VALUES() function");
return TRUE;
}
arg= ref->ref[0];
}
+ /*
+ According to our SQL grammar, VALUES() function can reference
+ only to a column.
+ */
+ DBUG_ASSERT(arg->type() == FIELD_ITEM);
+
Item_field *field_arg= (Item_field *)arg;
if (field_arg->field->table->insert_values)
@@ -5177,7 +5233,7 @@
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);
thd->set_query_id= save_set_query_id;
triggers= table->triggers;
}
--- 1.182/sql/item.h 2005-12-02 20:42:27 -08:00
+++ 1.183/sql/item.h 2005-12-10 23:30:51 -08:00
@@ -326,6 +326,48 @@
};
+/*
+ Store and restore the current state of a name resolution context.
+*/
+
+class Name_resolution_context_state
+{
+private:
+ TABLE_LIST *save_table_list;
+ TABLE_LIST *save_first_name_resolution_table;
+ TABLE_LIST *save_next_name_resolution_table;
+ bool save_resolve_in_select_list;
+
+public:
+ TABLE_LIST *save_next_local;
+
+public:
+ /* Save the state of a name resolution context. */
+ void save_state(Name_resolution_context *context, TABLE_LIST *table_list)
+ {
+ save_table_list= context->table_list;
+ save_first_name_resolution_table= context->first_name_resolution_table;
+ save_next_name_resolution_table= (context->first_name_resolution_table) ?
+ context->first_name_resolution_table->
+ next_name_resolution_table :
+ NULL;
+ save_resolve_in_select_list= context->resolve_in_select_list;
+ save_next_local= table_list->next_local;
+ }
+
+ /* Restore a name resolution context from saved state. */
+ void restore_state(Name_resolution_context *context, TABLE_LIST *table_list)
+ {
+ table_list->next_local= save_next_local;
+ context->table_list= save_table_list;
+ context->first_name_resolution_table= save_first_name_resolution_table;
+ if (context->first_name_resolution_table)
+ context->first_name_resolution_table->
+ next_name_resolution_table= save_next_name_resolution_table;
+ context->resolve_in_select_list= save_resolve_in_select_list;
+ }
+};
+
/*************************************************************************/
typedef bool (Item::*Item_processor)(byte *arg);
@@ -341,8 +383,6 @@
{ return (void*) sql_alloc((uint) size); }
static void *operator new(size_t size, MEM_ROOT *mem_root)
{ return (void*) alloc_root(mem_root, (uint) size); }
- /* Special for SP local variable assignment - reusing slots */
- static void *operator new(size_t size, Item *reuse, uint *rsize);
static void operator delete(void *ptr,size_t size) { TRASH(ptr, size); }
static void operator delete(void *ptr, MEM_ROOT *mem_root) {}
@@ -671,13 +711,13 @@
current value and pointer to current Item otherwise.
*/
virtual Item *this_item() { return this; }
+ virtual const Item *this_item() const { return this; }
+
/*
For SP local variable returns address of pointer to Item representing its
current value and pointer passed via parameter otherwise.
*/
virtual Item **this_item_addr(THD *thd, Item **addr) { return addr; }
- /* For SPs mostly. */
- virtual Item *this_const_item() const { return const_cast<Item*>(this); }
// Row emulation
virtual uint cols() { return 1; }
@@ -706,21 +746,32 @@
class sp_head;
-/*
- A reference to local SP variable (incl. reference to SP parameter), used in
- runtime.
-
- NOTE
- This item has a "value" item, defined as
- this_item() = thd->spcont->get_item(m_offset)
- and it delegates everything to that item (if !this_item() then this item
- poses as Item_null) except for name, which is the name of SP local
- variable.
-*/
-class Item_splocal : public Item
+/*****************************************************************************
+ The class is a base class for representation of stored routine variables in
+ the Item-hierarchy. There are the following kinds of SP-vars:
+ - local variables (Item_splocal);
+ - CASE expression (Item_case_expr);
+*****************************************************************************/
+
+class Item_sp_variable :public Item
{
- uint m_offset;
+protected:
+ /*
+ THD, which is stored in fix_fields() and is used in this_item() to avoid
+ current_thd use.
+ */
+ THD *m_thd;
+
+public:
+ LEX_STRING m_name;
+
+ /*
+ Buffer, pointing to the string value of the item. We need it to
+ protect internal buffer from changes. See comment to analogous
+ member in Item_param for more details.
+ */
+ String str_value_ptr;
public:
#ifndef DBUG_OFF
@@ -728,11 +779,74 @@
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
*/
- sp_head *owner;
+ sp_head *m_sp;
#endif
- LEX_STRING m_name;
- THD *thd;
+public:
+ Item_sp_variable(char *sp_var_name_str, uint sp_var_name_length);
+
+public:
+ bool fix_fields(THD *thd, Item **);
+
+ double val_real();
+ longlong val_int();
+ String *val_str(String *sp);
+ my_decimal *val_decimal(my_decimal *decimal_value);
+ bool is_null();
+
+public:
+ inline void make_field(Send_field *field);
+
+ inline bool const_item() const;
+
+ inline int save_in_field(Field *field, bool no_conversions);
+ inline bool send(Protocol *protocol, String *str);
+};
+
+/*****************************************************************************
+ Item_sp_variable inline implementation.
+*****************************************************************************/
+
+inline void Item_sp_variable::make_field(Send_field *field)
+{
+ Item *it= this_item();
+
+ if (name)
+ it->set_name(name, (uint) strlen(name), system_charset_info);
+ else
+ it->set_name(m_name.str, m_name.length, system_charset_info);
+ it->make_field(field);
+}
+
+inline bool Item_sp_variable::const_item() const
+{
+ return TRUE;
+}
+
+inline int Item_sp_variable::save_in_field(Field *field, bool no_conversions)
+{
+ return this_item()->save_in_field(field, no_conversions);
+}
+
+inline bool Item_sp_variable::send(Protocol *protocol, String *str)
+{
+ return this_item()->send(protocol, str);
+}
+
+
+/*****************************************************************************
+ A reference to local SP variable (incl. reference to SP parameter), used in
+ runtime.
+*****************************************************************************/
+
+class Item_splocal :public Item_sp_variable
+{
+ uint m_var_idx;
+
+ Type m_type;
+ Item_result m_result_type;
+
+public:
/*
Position of this reference to SP variable in the statement (the
statement itself is in sp_instr_stmt::m_query).
@@ -745,78 +859,94 @@
*/
uint pos_in_query;
- Item_splocal(LEX_STRING name, uint offset, uint pos_in_q=0)
- : m_offset(offset), m_name(name), thd(0), pos_in_query(pos_in_q)
- {
- maybe_null= TRUE;
- }
-
- /* For error printing */
- inline LEX_STRING *my_name(LEX_STRING *get_name)
- {
- if (!get_name)
- return &m_name;
- (*get_name)= m_name;
- return get_name;
- }
+ Item_splocal(const LEX_STRING &sp_var_name, uint sp_var_idx,
+ enum_field_types sp_var_type, uint pos_in_q= 0);
bool is_splocal() { return 1; } /* Needed for error checking */
Item *this_item();
+ const Item *this_item() const;
Item **this_item_addr(THD *thd, Item **);
- Item *this_const_item() const;
- bool fix_fields(THD *, Item **);
- void cleanup();
+ void print(String *str);
- inline uint get_offset()
- {
- return m_offset;
- }
+public:
+ inline const LEX_STRING *my_name() const;
- // Abstract methods inherited from Item. Just defer the call to
- // the item in the frame
- enum Type type() const;
+ inline uint get_var_idx() const;
- double val_real();
- longlong val_int();
- String *val_str(String *sp);
- my_decimal *val_decimal(my_decimal *);
- bool is_null();
- void print(String *str);
+ inline enum Type type() const;
+ inline Item_result result_type() const;
+};
- void make_field(Send_field *field)
- {
- Item *it= this_item();
+/*****************************************************************************
+ Item_splocal inline implementation.
+*****************************************************************************/
- if (name)
- it->set_name(name, (uint) strlen(name), system_charset_info);
- else
- it->set_name(m_name.str, m_name.length, system_charset_info);
- it->make_field(field);
- }
+inline const LEX_STRING *Item_splocal::my_name() const
+{
+ return &m_name;
+}
- Item_result result_type() const
- {
- return this_const_item()->result_type();
- }
+inline uint Item_splocal::get_var_idx() const
+{
+ return m_var_idx;
+}
- bool const_item() const
- {
- return TRUE;
- }
+inline enum Item::Type Item_splocal::type() const
+{
+ return m_type;
+}
- int save_in_field(Field *field, bool no_conversions)
- {
- return this_item()->save_in_field(field, no_conversions);
- }
+inline Item_result Item_splocal::result_type() const
+{
+ return m_result_type;
+}
- bool send(Protocol *protocol, String *str)
- {
- return this_item()->send(protocol, str);
- }
+
+/*****************************************************************************
+ A reference to case expression in SP, used in runtime.
+*****************************************************************************/
+
+class Item_case_expr :public Item_sp_variable
+{
+public:
+ Item_case_expr(int case_expr_id);
+
+public:
+ Item *this_item();
+ const Item *this_item() const;
+ Item **this_item_addr(THD *thd, Item **);
+
+ inline enum Type type() const;
+ inline Item_result result_type() const;
+
+public:
+ /*
+ NOTE: print() is intended to be used from views and for debug.
+ Item_case_expr can not occur in views, so here it is only for debug
+ purposes.
+ */
+ void print(String *str);
+
+private:
+ int m_case_expr_id;
};
+/*****************************************************************************
+ Item_case_expr inline implementation.
+*****************************************************************************/
+
+inline enum Item::Type Item_case_expr::type() const
+{
+ return this_item()->type();
+}
+
+inline Item_result Item_case_expr::result_type() const
+{
+ return this_item()->result_type();
+}
+
/*
NAME_CONST(given_name, const_value).
@@ -843,7 +973,6 @@
}
bool fix_fields(THD *, Item **);
- void cleanup();
enum Type type() const;
double val_real();
@@ -1926,6 +2055,16 @@
return (this->*transformer)(args);
}
};
+
+/*
+ Item_insert_value -- an implementation of VALUES() function.
+ You can use the VALUES(col_name) function in the UPDATE clause
+ to refer to column values from the INSERT portion of the INSERT
+ ... UPDATE statement. In other words, VALUES(col_name) in the
+ UPDATE clause refers to the value of col_name that would be
+ inserted, had no duplicate-key conflict occurred.
+ In all other places this function returns NULL.
+*/
class Item_insert_value : public Item_field
{
--- 1.269/sql/item_func.cc 2005-12-02 20:42:27 -08:00
+++ 1.270/sql/item_func.cc 2005-12-10 23:30:51 -08:00
@@ -4716,7 +4716,7 @@
share->table_cache_key = empty_name;
share->table_name = empty_name;
}
- field= m_sp->make_field(max_length, name, dummy_table);
+ field= m_sp->create_result_field(max_length, name, dummy_table);
DBUG_RETURN(field);
}
@@ -4729,17 +4729,17 @@
1 value = NULL or error
*/
-int
+bool
Item_func_sp::execute(Field **flp)
{
- Item *it;
+ THD *thd= current_thd;
Field *f;
- if (execute(&it))
- {
- null_value= 1;
- context->process_error(current_thd);
- return 1;
- }
+
+ /*
+ Get field in virtual tmp table to store result. Create the field if
+ invoked first time.
+ */
+
if (!(f= *flp))
{
*flp= f= sp_result_field();
@@ -4748,20 +4748,33 @@
f->null_ptr= (uchar *)&null_value;
f->null_bit= 1;
}
- it->save_in_field(f, 1);
- return null_value= f->is_null();
+
+ /* Execute function and store the return value in the field. */
+
+ if (execute_impl(thd, f))
+ {
+ null_value= 1;
+ context->process_error(thd);
+ return TRUE;
+ }
+
+ /* Check that the field (the value) is not NULL. */
+
+ null_value= f->is_null();
+
+ return null_value;
}
-int
-Item_func_sp::execute(Item **itp)
+bool
+Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
{
- DBUG_ENTER("Item_func_sp::execute");
- THD *thd= current_thd;
- int res= -1;
+ bool err_status= TRUE;
Sub_statement_state statement_state;
Security_context *save_security_ctx= thd->security_ctx, *save_ctx_func;
+ DBUG_ENTER("Item_func_sp::execute_impl");
+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if (context->security_ctx)
{
@@ -4778,7 +4791,7 @@
function call into binlog.
*/
thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
- res= m_sp->execute_function(thd, args, arg_count, itp);
+ err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld);
thd->restore_sub_statement_state(&statement_state);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
@@ -4788,7 +4801,7 @@
#else
error:
#endif
- DBUG_RETURN(res);
+ DBUG_RETURN(err_status);
}
@@ -4884,7 +4897,7 @@
DBUG_ENTER("Item_func_sp::tmp_table_field");
if (m_sp)
- res= m_sp->make_field(max_length, (const char *)name, t_arg);
+ res= m_sp->create_result_field(max_length, (const char*) name, t_arg);
if (!res)
res= Item_func::tmp_table_field(t_arg);
--- 1.369/sql/mysql_priv.h 2005-12-02 20:42:28 -08:00
+++ 1.370/sql/mysql_priv.h 2005-12-10 23:30:52 -08:00
@@ -661,6 +661,7 @@
bool mysql_preload_keys(THD* thd, TABLE_LIST* table_list);
int reassign_keycache_tables(THD* thd, KEY_CACHE *src_cache,
KEY_CACHE *dst_cache);
+TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list);
bool mysql_xa_recover(THD *thd);
@@ -792,18 +793,15 @@
bool check_privileges, bool register_tree_change);
Field *
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
- const char *name, const char *item_name,
- const char *table_name, const char *db_name,
- uint length, Item **ref,
- bool check_grants_table, bool check_grants_view,
- bool allow_rowid,
+ const char *name, uint length,
+ const char *item_name, const char *db_name,
+ const char *table_name, Item **ref,
+ bool check_privileges, bool allow_rowid,
uint *cached_field_index_ptr,
bool register_tree_change, TABLE_LIST **actual_table);
Field *
-find_field_in_table(THD *thd, TABLE *table, const char *name,
- uint length, bool check_grants, bool allow_rowid,
- uint *cached_field_index_ptr,
- Security_context *sctx);
+find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
+ bool allow_rowid, uint *cached_field_index_ptr);
#ifdef HAVE_OPENSSL
#include <openssl/des.h>
@@ -919,8 +917,9 @@
uint uint_geom_type);
void store_position_for_column(const char *name);
bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc);
-Name_resolution_context *make_join_on_context(THD *thd, TABLE_LIST *left_op,
- TABLE_LIST *right_op);
+bool push_new_name_resolution_context(THD *thd,
+ TABLE_LIST *left_op,
+ TABLE_LIST *right_op);
void add_join_on(TABLE_LIST *b,Item *expr);
void add_join_natural(TABLE_LIST *a,TABLE_LIST *b,List<String> *using_fields);
bool add_proc_to_list(THD *thd, Item *item);
@@ -1102,8 +1101,8 @@
uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word);
-bool is_keyword(const char *name, uint len);
+bool is_keyword(const char *name, uint len);
#define MY_DB_OPT_FILE "db.opt"
bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create);
--- 1.318/sql/sql_base.cc 2005-11-23 21:44:10 -08:00
+++ 1.319/sql/sql_base.cc 2005-12-10 23:30:52 -08:00
@@ -1984,15 +1984,25 @@
if (!thd->prelocked_mode && !thd->lex->requires_prelocking() &&
thd->lex->sroutines_list.elements)
{
- bool first_no_prelocking, need_prelocking;
+ bool first_no_prelocking, need_prelocking, tabs_changed;
TABLE_LIST **save_query_tables_last= thd->lex->query_tables_last;
DBUG_ASSERT(thd->lex->query_tables == *start);
sp_get_prelocking_info(thd, &need_prelocking, &first_no_prelocking);
- if ((sp_cache_routines_and_add_tables(thd, thd->lex,
- first_no_prelocking) ||
- *start) && need_prelocking)
+ if (sp_cache_routines_and_add_tables(thd, thd->lex,
+ first_no_prelocking,
+ &tabs_changed))
+ {
+ /*
+ Serious error during reading stored routines from mysql.proc table.
+ Something's wrong with the table or its contents, and an error has
+ been emitted; we must abort.
+ */
+ result= -1;
+ goto err;
+ }
+ else if ((tabs_changed || *start) && need_prelocking)
{
query_tables_last_own= save_query_tables_last;
*start= thd->lex->query_tables;
@@ -2116,9 +2126,18 @@
tables->lock_type >= TL_WRITE_ALLOW_WRITE)
{
if (!query_tables_last_own)
- query_tables_last_own= thd->lex->query_tables_last;
- sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
- tables->table->triggers);
+ query_tables_last_own= thd->lex->query_tables_last;
+ if (sp_cache_routines_and_add_tables_for_triggers(thd, thd->lex,
+ tables))
+ {
+ /*
+ Serious error during reading stored routines from mysql.proc table.
+ Something's wrong with the table or its contents, and an error has
+ been emitted; we must abort.
+ */
+ result= -1;
+ goto err;
+ }
}
free_root(&new_frm_mem, MYF(MY_KEEP_PREALLOC));
}
@@ -2139,9 +2158,20 @@
/* We have at least one table in TL here. */
if (!query_tables_last_own)
query_tables_last_own= thd->lex->query_tables_last;
- sp_cache_routines_and_add_tables_for_view(thd, thd->lex, tables->view);
+ if (sp_cache_routines_and_add_tables_for_view(thd, thd->lex, tables))
+ {
+ /*
+ Serious error during reading stored routines from mysql.proc table.
+ Something's wrong with the table or its contents, and an error has
+ been emitted; we must abort.
+ */
+ result= -1;
+ goto err;
+ }
}
}
+
+ err:
thd->proc_info=0;
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
@@ -2683,47 +2713,6 @@
}
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
-/*
- Check column rights in given security context
-
- SYNOPSIS
- check_grant_column_in_sctx()
- thd thread handler
- grant grant information structure
- db db name
- table table name
- name column name
- length column name length
- check_grants need to check grants
- sctx 0 or security context
-
- RETURN
- FALSE OK
- TRUE access denied
-*/
-
-static bool check_grant_column_in_sctx(THD *thd, GRANT_INFO *grant,
- const char *db, const char *table,
- const char *name, uint length,
- bool check_grants,
- Security_context *sctx)
-{
- if (!check_grants)
- return FALSE;
- Security_context *save_security_ctx= thd->security_ctx;
- bool res;
- if (sctx)
- {
- thd->security_ctx= sctx;
- }
- res= check_grant_column(thd, grant, db, table, name, length);
- thd->security_ctx= save_security_ctx;
- return res;
-}
-#endif
-
-
/*
Find a field by name in a view that uses merge algorithm.
@@ -2732,11 +2721,10 @@
thd thread handler
table_list view to search for 'name'
name name of field
- item_name name of item if it will be created (VIEW)
length length of name
+ item_name name of item if it will be created (VIEW)
ref expression substituted in VIEW should be passed
using this reference (return view_ref_found)
- check_grants do check columns grants for view?
register_tree_change TRUE if ref is not stack variable and we
need register changes in item tree
@@ -2748,8 +2736,8 @@
static Field *
find_field_in_view(THD *thd, TABLE_LIST *table_list,
- const char *name, const char *item_name,
- uint length, Item **ref, bool check_grants,
+ const char *name, uint length,
+ const char *item_name, Item **ref,
bool register_tree_change)
{
DBUG_ENTER("find_field_in_view");
@@ -2766,24 +2754,13 @@
{
if (!my_strcasecmp(system_charset_info, field_it.name(), name))
{
- if (table_list->schema_table_reformed)
- /*
- Translation table items are always Item_fields and fixed already
- ('mysql_schema_table' function). So we can return ->field. It is
- used only for 'show & where' commands.
- */
- DBUG_RETURN(((Item_field*) (field_it.item()))->field);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_grant_column_in_sctx(thd, &table_list->grant,
- table_list->view_db.str,
- table_list->view_name.str, name, length,
- check_grants,
- table_list->security_ctx))
- DBUG_RETURN(WRONG_GRANT);
-#endif
// in PS use own arena or data will be freed after prepare
if (register_tree_change)
arena= thd->activate_stmt_arena_if_needed(&backup);
+ /*
+ create_item() may, or may not create a new Item, depending on
+ the column reference. See create_view_field() for details.
+ */
Item *item= field_it.create_item(thd);
if (register_tree_change && arena)
thd->restore_active_arena(arena, &backup);
@@ -2825,7 +2802,6 @@
length [in] length of name
ref [in/out] if 'name' is resolved to a view field, ref is
set to point to the found view field
- check_grants [in] do check columns grants?
register_tree_change [in] TRUE if ref is not stack variable and we
need register changes in item tree
actual_table [out] the original table reference where the field
@@ -2846,8 +2822,7 @@
static Field *
find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name,
- uint length, Item **ref, bool check_grants,
- bool register_tree_change,
+ uint length, Item **ref, bool register_tree_change,
TABLE_LIST **actual_table)
{
List_iterator_fast<Natural_join_column>
@@ -2872,23 +2847,16 @@
break;
}
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_grants && nj_col->check_grants(thd, name, length))
- DBUG_RETURN(WRONG_GRANT);
-#endif
-
if (nj_col->view_field)
{
Item *item;
- /*
- The found field is a view field, we do as in find_field_in_view()
- and return a pointer to pointer to the Item of that field.
- */
if (register_tree_change)
arena= thd->activate_stmt_arena_if_needed(&backup);
-
+ /*
+ create_item() may, or may not create a new Item, depending on the
+ column reference. See create_view_field() for details.
+ */
item= nj_col->create_item(thd);
-
if (register_tree_change && arena)
thd->restore_active_arena(arena, &backup);
@@ -2934,7 +2902,6 @@
table table where to search for the field
name name of field
length length of name
- check_grants do check columns grants?
allow_rowid do allow finding of "_rowid" field?
cached_field_index_ptr cached position in field list (used to speedup
lookup for fields in prepared tables)
@@ -2946,9 +2913,7 @@
Field *
find_field_in_table(THD *thd, TABLE *table, const char *name, uint length,
- bool check_grants, bool allow_rowid,
- uint *cached_field_index_ptr,
- Security_context *sctx)
+ bool allow_rowid, uint *cached_field_index_ptr)
{
Field **field_ptr, *field;
uint cached_field_index= *cached_field_index_ptr;
@@ -2987,13 +2952,6 @@
update_field_dependencies(thd, field, table);
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- if (check_grant_column_in_sctx(thd, &table->grant,
- table->s->db, table->s->table_name,
- name, length,
- check_grants, sctx))
- field= WRONG_GRANT;
-#endif
DBUG_RETURN(field);
}
@@ -3006,14 +2964,13 @@
thd [in] thread handler
table_list [in] table reference to search
name [in] name of field
+ length [in] field length of name
item_name [in] name of item if it will be created (VIEW)
- table_name [in] optional table name that qualifies the field
db_name [in] optional database name that qualifies the
- length [in] field length of name
+ table_name [in] optional table name that qualifies the field
ref [in/out] if 'name' is resolved to a view field, ref
is set to point to the found view field
- check_grants_table [in] do check columns grants for table?
- check_grants_view [in] do check columns grants for view?
+ check_privileges [in] check privileges
allow_rowid [in] do allow finding of "_rowid" field?
cached_field_index_ptr [in] cached position in field list (used to
speedup lookup for fields in prepared tables)
@@ -3043,11 +3000,11 @@
Field *
find_field_in_table_ref(THD *thd, TABLE_LIST *table_list,
- const char *name, const char *item_name,
- const char *table_name, const char *db_name,
- uint length, Item **ref,
- bool check_grants_table, bool check_grants_view,
- bool allow_rowid, uint *cached_field_index_ptr,
+ const char *name, uint length,
+ const char *item_name, const char *db_name,
+ const char *table_name, Item **ref,
+ bool check_privileges, bool allow_rowid,
+ uint *cached_field_index_ptr,
bool register_tree_change, TABLE_LIST **actual_table)
{
Field *fld;
@@ -3092,8 +3049,7 @@
if (table_list->field_translation)
{
/* 'table_list' is a view or an information schema table. */
- if ((fld= find_field_in_view(thd, table_list, name, item_name, length,
- ref, check_grants_view,
+ if ((fld= find_field_in_view(thd, table_list, name, length, item_name, ref,
register_tree_change)))
*actual_table= table_list;
}
@@ -3102,20 +3058,9 @@
/* 'table_list' is a stored table. */
DBUG_ASSERT(table_list->table);
if ((fld= find_field_in_table(thd, table_list->table, name, length,
- check_grants_table, allow_rowid,
- cached_field_index_ptr,
- table_list->security_ctx)))
+ allow_rowid,
+ cached_field_index_ptr)))
*actual_table= table_list;
-#ifndef NO_EMBEDDED_ACCESS_CHECKS
- /* check for views with temporary table algorithm */
- if (check_grants_view && table_list->view &&
- fld && fld != WRONG_GRANT &&
- check_grant_column(thd, &table_list->grant,
- table_list->view_db.str,
- table_list->view_name.str,
- name, length))
- fld= WRONG_GRANT;
-#endif
}
else
{
@@ -3132,11 +3077,10 @@
TABLE_LIST *table;
while ((table= it++))
{
- if ((fld= find_field_in_table_ref(thd, table, name, item_name,
- table_name, db_name, length, ref,
- check_grants_table,
- check_grants_view,
- allow_rowid, cached_field_index_ptr,
+ if ((fld= find_field_in_table_ref(thd, table, name, length, item_name,
+ db_name, table_name, ref,
+ check_privileges, allow_rowid,
+ cached_field_index_ptr,
register_tree_change, actual_table)))
DBUG_RETURN(fld);
}
@@ -3149,11 +3093,16 @@
directly the top-most NATURAL/USING join.
*/
fld= find_field_in_natural_join(thd, table_list, name, length, ref,
- /* TIMOUR_TODO: check this with Sanja */
- check_grants_table || check_grants_view,
register_tree_change, actual_table);
}
+#ifndef NO_EMBEDDED_ACCESS_CHECKS
+ /* Check if there are sufficient access rights to the found field. */
+ if (fld && check_privileges &&
+ check_column_grant_in_table_ref(thd, *actual_table, name, length))
+ fld= WRONG_GRANT;
+#endif
+
DBUG_RETURN(fld);
}
@@ -3235,21 +3184,11 @@
*/
if (table_ref->table && !table_ref->view)
found= find_field_in_table(thd, table_ref->table, name, length,
- test(table_ref->table->
- grant.want_privilege) &&
- check_privileges,
- 1, &(item->cached_field_index),
- table_ref->security_ctx);
+ TRUE, &(item->cached_field_index));
else
- found= find_field_in_table_ref(thd, table_ref, name, item->name,
- NULL, NULL, length, ref,
- (table_ref->table &&
- test(table_ref->table->grant.
- want_privilege) &&
- check_privileges),
- (test(table_ref->grant.want_privilege) &&
- check_privileges),
- 1, &(item->cached_field_index),
+ found= find_field_in_table_ref(thd, table_ref, name, length, item->name,
+ NULL, NULL, ref, check_privileges,
+ TRUE, &(item->cached_field_index),
register_tree_change,
&actual_table);
if (found)
@@ -3289,17 +3228,9 @@
for (; cur_table != last_table ;
cur_table= cur_table->next_name_resolution_table)
{
- Field *cur_field= find_field_in_table_ref(thd, cur_table, name, item->name,
- table_name, db,
- length, ref,
- (cur_table->table &&
- test(cur_table->table->grant.
- want_privilege) &&
- check_privileges),
- (test(cur_table->grant.
- want_privilege)
- && check_privileges),
- allow_rowid,
+ Field *cur_field= find_field_in_table_ref(thd, cur_table, name, length,
+ item->name, db, table_name, ref,
+ check_privileges, allow_rowid,
&(item->cached_field_index),
register_tree_change,
&actual_table);
@@ -3707,7 +3638,7 @@
{
bool is_created_1;
bool found= FALSE;
- if (!(nj_col_1= it_1.get_or_create_column_ref(thd, &is_created_1)))
+ if (!(nj_col_1= it_1.get_or_create_column_ref(&is_created_1)))
goto err;
field_name_1= nj_col_1->name();
@@ -3728,7 +3659,7 @@
bool is_created_2;
Natural_join_column *cur_nj_col_2;
const char *cur_field_name_2;
- if (!(cur_nj_col_2= it_2.get_or_create_column_ref(thd, &is_created_2)))
+ if (!(cur_nj_col_2= it_2.get_or_create_column_ref(&is_created_2)))
goto err;
cur_field_name_2= cur_nj_col_2->name();
@@ -3920,13 +3851,7 @@
/* Append the columns of the first join operand. */
for (it_1.set(table_ref_1); !it_1.end_of_fields(); it_1.next())
{
- if (!(nj_col_1= it_1.get_or_create_column_ref(thd, &is_created)))
- goto err;
- /*
- The following assert checks that mark_common_columns() was run and
- we created the list table_ref_1->join_columns.
- */
- DBUG_ASSERT(!is_created);
+ nj_col_1= it_1.get_natural_column_ref();
if (nj_col_1->is_common)
{
natural_using_join->join_columns->push_back(nj_col_1);
@@ -3972,13 +3897,7 @@
/* Append the non-equi-join columns of the second join operand. */
for (it_2.set(table_ref_2); !it_2.end_of_fields(); it_2.next())
{
- if (!(nj_col_2= it_2.get_or_create_column_ref(thd, &is_created)))
- goto err;
- /*
- The following assert checks that mark_common_columns() was run and
- we created the list table_ref_2->join_columns.
- */
- DBUG_ASSERT(!is_created);
+ nj_col_2= it_2.get_natural_column_ref();
if (!nj_col_2->is_common)
non_join_columns->push_back(nj_col_2);
else
@@ -4716,8 +4635,7 @@
because it was already created and stored with the natural join.
*/
Natural_join_column *nj_col;
- if (!(nj_col= field_iterator.get_or_create_column_ref(thd,
- &is_created)))
+ if (!(nj_col= field_iterator.get_or_create_column_ref(&is_created)))
DBUG_RETURN(TRUE);
DBUG_ASSERT(nj_col->table_field && !is_created);
field_table= nj_col->table_ref->table;
--- 1.222/sql/sql_class.cc 2005-12-02 20:42:28 -08:00
+++ 1.223/sql/sql_class.cc 2005-12-10 23:30:52 -08:00
@@ -1503,10 +1503,10 @@
my_var *mv= gl++;
if (mv->local)
{
- Item_splocal *var;
- (void)local_vars.push_back(var= new Item_splocal(mv->s, mv->offset));
+ Item_splocal *var= new Item_splocal(mv->s, mv->offset, mv->type);
+ (void)local_vars.push_back(var);
#ifndef DBUG_OFF
- var->owner= mv->owner;
+ var->m_sp= mv->sp;
#endif
}
else
@@ -1777,8 +1777,8 @@
{
if ((yy=var_li++))
{
- if (thd->spcont->set_item_eval(current_thd,
- yy->get_offset(), it.ref(), zz->type))
+ if (thd->spcont->set_variable(current_thd, yy->get_var_idx(),
+ *it.ref()))
DBUG_RETURN(1);
}
}
--- 1.277/sql/sql_class.h 2005-12-02 20:42:28 -08:00
+++ 1.278/sql/sql_class.h 2005-12-10 23:30:52 -08:00
@@ -2087,7 +2087,7 @@
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
*/
- sp_head *owner;
+ sp_head *sp;
#endif
bool local;
uint offset;
--- 1.175/sql/sql_lex.cc 2005-11-22 23:00:45 -08:00
+++ 1.176/sql/sql_lex.cc 2005-12-10 23:30:52 -08:00
@@ -1130,6 +1130,11 @@
/*
Add the name resolution context of the current (sub)query to the
stack of contexts for the whole query.
+ TODO:
+ push_context may return an error if there is no memory for a new
+ element in the stack, however this method has no return value,
+ thus push_context should be moved to a place where query
+ initialization is checked for failure.
*/
parent_lex->push_context(&context);
cond_count= with_wild= 0;
--- 1.209/sql/sql_lex.h 2005-12-02 20:42:28 -08:00
+++ 1.210/sql/sql_lex.h 2005-12-10 23:30:52 -08:00
@@ -1020,9 +1020,9 @@
}
void cleanup_after_one_table_open();
- void push_context(Name_resolution_context *context)
+ bool push_context(Name_resolution_context *context)
{
- context_stack.push_front(context);
+ return context_stack.push_front(context);
}
void pop_context()
--- 1.517/sql/sql_parse.cc 2005-12-02 20:42:28 -08:00
+++ 1.518/sql/sql_parse.cc 2005-12-10 23:30:53 -08:00
@@ -797,6 +797,9 @@
DBUG_PRINT("info",
("New connection received on %s", vio_description(net->vio)));
+#ifdef SIGNAL_WITH_VIO_CLOSE
+ thd->set_active_vio(net->vio);
+#endif
if (!thd->main_security_ctx.host) // If TCP/IP connection
{
@@ -2614,7 +2617,8 @@
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_backup_table(thd, first_table);
-
+ select_lex->table_list.first= (byte*) first_table;
+ lex->query_tables=all_tables;
break;
}
case SQLCOM_RESTORE_TABLE:
@@ -2626,6 +2630,8 @@
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_restore_table(thd, first_table);
+ select_lex->table_list.first= (byte*) first_table;
+ lex->query_tables=all_tables;
break;
}
case SQLCOM_ASSIGN_TO_KEYCACHE:
@@ -3128,6 +3134,8 @@
mysql_bin_log.write(&qinfo);
}
}
+ select_lex->table_list.first= (byte*) first_table;
+ lex->query_tables=all_tables;
break;
}
case SQLCOM_CHECK:
@@ -3138,6 +3146,8 @@
goto error; /* purecov: inspected */
thd->enable_slow_log= opt_log_slow_admin_statements;
res = mysql_check_table(thd, first_table, &lex->check_opt);
+ select_lex->table_list.first= (byte*) first_table;
+ lex->query_tables=all_tables;
break;
}
case SQLCOM_ANALYZE:
@@ -3158,6 +3168,8 @@
mysql_bin_log.write(&qinfo);
}
}
+ select_lex->table_list.first= (byte*) first_table;
+ lex->query_tables=all_tables;
break;
}
@@ -3181,6 +3193,8 @@
mysql_bin_log.write(&qinfo);
}
}
+ select_lex->table_list.first= (byte*) first_table;
+ lex->query_tables=all_tables;
break;
}
case SQLCOM_UPDATE:
@@ -4130,14 +4144,6 @@
}
}
#endif
- if (lex->sphead->m_type == TYPE_ENUM_FUNCTION &&
- !(lex->sphead->m_flags & sp_head::HAS_RETURN))
- {
- my_error(ER_SP_NORETURN, MYF(0), name);
- delete lex->sphead;
- lex->sphead= 0;
- goto error;
- }
/*
We need to copy name and db in order to use them for
@@ -5766,9 +5772,10 @@
buf, "TIMESTAMP");
}
- if (!(new_field= new_create_field(thd, field_name, type, length, decimals,
- type_modifier, default_value, on_update_value,
- comment, change, interval_list, cs, uint_geom_type)))
+ if (!(new_field= new create_field()) ||
+ new_field->init(thd, field_name, type, length, decimals, type_modifier,
+ default_value, on_update_value, comment, change,
+ interval_list, cs, uint_geom_type))
DBUG_RETURN(1);
lex->create_list.push_back(new_field);
@@ -5776,327 +5783,6 @@
DBUG_RETURN(0);
}
-/*****************************************************************************
-** Create field definition for create
-** Return 0 on failure, otherwise return create_field instance
-******************************************************************************/
-
-create_field *
-new_create_field(THD *thd, char *field_name, enum_field_types type,
- char *length, char *decimals,
- uint type_modifier,
- Item *default_value, Item *on_update_value,
- LEX_STRING *comment,
- char *change, List<String> *interval_list, CHARSET_INFO *cs,
- uint uint_geom_type)
-{
- register create_field *new_field;
- uint sign_len, allowed_type_modifier=0;
- ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
- DBUG_ENTER("new_create_field");
-
- if (!(new_field=new create_field()))
- DBUG_RETURN(NULL);
- new_field->field=0;
- new_field->field_name=field_name;
- new_field->def= default_value;
- new_field->flags= type_modifier;
- new_field->unireg_check= (type_modifier & AUTO_INCREMENT_FLAG ?
- Field::NEXT_NUMBER : Field::NONE);
- new_field->decimals= decimals ? (uint)atoi(decimals) : 0;
- if (new_field->decimals >= NOT_FIXED_DEC)
- {
- my_error(ER_TOO_BIG_SCALE, MYF(0), new_field->decimals, field_name,
- NOT_FIXED_DEC-1);
- DBUG_RETURN(NULL);
- }
-
- new_field->sql_type=type;
- new_field->length=0;
- new_field->change=change;
- new_field->interval=0;
- new_field->pack_length= new_field->key_length= 0;
- new_field->charset=cs;
- new_field->geom_type= (Field::geometry_type) uint_geom_type;
-
- new_field->comment=*comment;
- /*
- Set flag if this field doesn't have a default value
- */
- if (!default_value && !(type_modifier & AUTO_INCREMENT_FLAG) &&
- (type_modifier & NOT_NULL_FLAG) && type != FIELD_TYPE_TIMESTAMP)
- new_field->flags|= NO_DEFAULT_VALUE_FLAG;
-
- if (length && !(new_field->length= (uint) atoi(length)))
- length=0; /* purecov: inspected */
- sign_len=type_modifier & UNSIGNED_FLAG ? 0 : 1;
-
- switch (type) {
- case FIELD_TYPE_TINY:
- if (!length) new_field->length=MAX_TINYINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_SHORT:
- if (!length) new_field->length=MAX_SMALLINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_INT24:
- if (!length) new_field->length=MAX_MEDIUMINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_LONG:
- if (!length) new_field->length=MAX_INT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_LONGLONG:
- if (!length) new_field->length=MAX_BIGINT_WIDTH;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case FIELD_TYPE_NULL:
- break;
- case FIELD_TYPE_NEWDECIMAL:
- if (!length && !new_field->decimals)
- new_field->length= 10;
- if (new_field->length > DECIMAL_MAX_PRECISION)
- {
- my_error(ER_TOO_BIG_PRECISION, MYF(0), new_field->length, field_name,
- DECIMAL_MAX_PRECISION);
- DBUG_RETURN(NULL);
- }
- if (new_field->length < new_field->decimals)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- new_field->length=
- my_decimal_precision_to_length(new_field->length, new_field->decimals,
- type_modifier & UNSIGNED_FLAG);
- new_field->pack_length=
- my_decimal_get_binary_size(new_field->length, new_field->decimals);
- break;
- case MYSQL_TYPE_VARCHAR:
- /*
- Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
- if they don't have a default value
- */
- max_field_charlength= MAX_FIELD_VARCHARLENGTH;
- break;
- case MYSQL_TYPE_STRING:
- break;
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_GEOMETRY:
- if (default_value) // Allow empty as default value
- {
- String str,*res;
- res=default_value->val_str(&str);
- if (res->length())
- {
- my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
- field_name); /* purecov: inspected */
- DBUG_RETURN(NULL);
- }
- new_field->def=0;
- }
- new_field->flags|=BLOB_FLAG;
- break;
- case FIELD_TYPE_YEAR:
- if (!length || new_field->length != 2)
- new_field->length=4; // Default length
- new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- break;
- case FIELD_TYPE_FLOAT:
- /* change FLOAT(precision) to FLOAT or DOUBLE */
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- if (length && !decimals)
- {
- uint tmp_length=new_field->length;
- if (tmp_length > PRECISION_FOR_DOUBLE)
- {
- my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- else if (tmp_length > PRECISION_FOR_FLOAT)
- {
- new_field->sql_type=FIELD_TYPE_DOUBLE;
- new_field->length=DBL_DIG+7; // -[digits].E+###
- }
- else
- new_field->length=FLT_DIG+6; // -[digits].E+##
- new_field->decimals= NOT_FIXED_DEC;
- break;
- }
- if (!length && !decimals)
- {
- new_field->length = FLT_DIG+6;
- new_field->decimals= NOT_FIXED_DEC;
- }
- if (new_field->length < new_field->decimals &&
- new_field->decimals != NOT_FIXED_DEC)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- break;
- case FIELD_TYPE_DOUBLE:
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- if (!length && !decimals)
- {
- new_field->length = DBL_DIG+7;
- new_field->decimals=NOT_FIXED_DEC;
- }
- if (new_field->length < new_field->decimals &&
- new_field->decimals != NOT_FIXED_DEC)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- break;
- case FIELD_TYPE_TIMESTAMP:
- if (!length)
- new_field->length= 14; // Full date YYYYMMDDHHMMSS
- else if (new_field->length != 19)
- {
- /*
- We support only even TIMESTAMP lengths less or equal than 14
- and 19 as length of 4.1 compatible representation.
- */
- new_field->length=((new_field->length+1)/2)*2; /* purecov: inspected */
- new_field->length= min(new_field->length,14); /* purecov: inspected */
- }
- new_field->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- if (default_value)
- {
- /* Grammar allows only NOW() value for ON UPDATE clause */
- if (default_value->type() == Item::FUNC_ITEM &&
- ((Item_func*)default_value)->functype() == Item_func::NOW_FUNC)
- {
- new_field->unireg_check= (on_update_value?Field::TIMESTAMP_DNUN_FIELD:
- Field::TIMESTAMP_DN_FIELD);
- /*
- We don't need default value any longer moreover it is dangerous.
- Everything handled by unireg_check further.
- */
- new_field->def= 0;
- }
- else
- new_field->unireg_check= (on_update_value?Field::TIMESTAMP_UN_FIELD:
- Field::NONE);
- }
- else
- {
- /*
- If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
- or ON UPDATE values then for the sake of compatiblity we should treat
- this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
- have another TIMESTAMP column with auto-set option before this one)
- or DEFAULT 0 (in other cases).
- So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
- replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
- information about all TIMESTAMP fields in table will be availiable.
-
- If we have TIMESTAMP NULL column without explicit DEFAULT value
- we treat it as having DEFAULT NULL attribute.
- */
- new_field->unireg_check= (on_update_value ?
- Field::TIMESTAMP_UN_FIELD :
- (new_field->flags & NOT_NULL_FLAG ?
- Field::TIMESTAMP_OLD_FIELD:
- Field::NONE));
- }
- break;
- case FIELD_TYPE_DATE: // Old date type
- if (protocol_version != PROTOCOL_VERSION-1)
- new_field->sql_type=FIELD_TYPE_NEWDATE;
- /* fall trough */
- case FIELD_TYPE_NEWDATE:
- new_field->length=10;
- break;
- case FIELD_TYPE_TIME:
- new_field->length=10;
- break;
- case FIELD_TYPE_DATETIME:
- new_field->length=19;
- break;
- case FIELD_TYPE_SET:
- {
- if (interval_list->elements > sizeof(longlong)*8)
- {
- my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */
- DBUG_RETURN(NULL);
- }
- new_field->pack_length= get_set_pack_length(interval_list->elements);
-
- List_iterator<String> it(*interval_list);
- String *tmp;
- while ((tmp= it++))
- new_field->interval_list.push_back(tmp);
- /*
- Set fake length to 1 to pass the below conditions.
- Real length will be set in mysql_prepare_table()
- when we know the character set of the column
- */
- new_field->length= 1;
- break;
- }
- case FIELD_TYPE_ENUM:
- {
- // Should be safe
- new_field->pack_length= get_enum_pack_length(interval_list->elements);
-
- List_iterator<String> it(*interval_list);
- String *tmp;
- while ((tmp= it++))
- new_field->interval_list.push_back(tmp);
- new_field->length= 1; // See comment for FIELD_TYPE_SET above.
- break;
- }
- case MYSQL_TYPE_VAR_STRING:
- DBUG_ASSERT(0); // Impossible
- break;
- case MYSQL_TYPE_BIT:
- {
- if (!length)
- new_field->length= 1;
- if (new_field->length > MAX_BIT_FIELD_LENGTH)
- {
- my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name,
- MAX_BIT_FIELD_LENGTH);
- DBUG_RETURN(NULL);
- }
- new_field->pack_length= (new_field->length + 7) / 8;
- break;
- }
- case FIELD_TYPE_DECIMAL:
- DBUG_ASSERT(0); /* Was obsolete */
- }
-
- if (!(new_field->flags & BLOB_FLAG) &&
- ((new_field->length > max_field_charlength && type != FIELD_TYPE_SET &&
- type != FIELD_TYPE_ENUM &&
- (type != MYSQL_TYPE_VARCHAR || default_value)) ||
- (!new_field->length &&
- type != MYSQL_TYPE_STRING &&
- type != MYSQL_TYPE_VARCHAR && type != FIELD_TYPE_GEOMETRY)))
- {
- my_error((type == MYSQL_TYPE_VAR_STRING || type == MYSQL_TYPE_VARCHAR ||
- type == MYSQL_TYPE_STRING) ? ER_TOO_BIG_FIELDLENGTH :
- ER_TOO_BIG_DISPLAYWIDTH,
- MYF(0),
- field_name, max_field_charlength); /* purecov: inspected */
- DBUG_RETURN(NULL);
- }
- type_modifier&= AUTO_INCREMENT_FLAG;
- if ((~allowed_type_modifier) & type_modifier)
- {
- my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
- DBUG_RETURN(NULL);
- }
- DBUG_RETURN(new_field);
-}
-
/* Store position for column in ALTER TABLE .. ADD column */
@@ -6590,36 +6276,39 @@
/*
- Create a new name resolution context for a JOIN ... ON clause.
+ Push a new name resolution context for a JOIN ... ON clause to the
+ context stack of a query block.
SYNOPSIS
- make_join_on_context()
+ push_new_name_resolution_context()
thd pointer to current thread
left_op left operand of the JOIN
right_op rigth operand of the JOIN
DESCRIPTION
Create a new name resolution context for a JOIN ... ON clause,
- and set the first and last leaves of the list of table references
- to be used for name resolution.
+ set the first and last leaves of the list of table references
+ to be used for name resolution, and push the newly created
+ context to the stack of contexts of the query.
RETURN
- A new context if all is OK
- NULL - if a memory allocation error occured
+ FALSE if all is OK
+ TRUE if a memory allocation error occured
*/
-Name_resolution_context *
-make_join_on_context(THD *thd, TABLE_LIST *left_op, TABLE_LIST *right_op)
+bool
+push_new_name_resolution_context(THD *thd,
+ TABLE_LIST *left_op, TABLE_LIST *right_op)
{
Name_resolution_context *on_context;
if (!(on_context= new (thd->mem_root) Name_resolution_context))
- return NULL;
+ return TRUE;
on_context->init();
on_context->first_name_resolution_table=
left_op->first_leaf_for_name_resolution();
on_context->last_name_resolution_table=
right_op->last_leaf_for_name_resolution();
- return on_context;
+ return thd->lex->push_context(on_context);
}
--- 1.375/sql/sql_select.cc 2005-12-02 20:42:28 -08:00
+++ 1.376/sql/sql_select.cc 2005-12-10 23:30:53 -08:00
@@ -8925,6 +8925,7 @@
TABLE *create_virtual_tmp_table(THD *thd, List<create_field> &field_list)
{
uint field_count= field_list.elements;
+ uint blob_count= 0;
Field **field;
create_field *cdef; /* column definition */
uint record_length= 0;
@@ -8941,6 +8942,12 @@
table->s= s= &table->share_not_to_be_used;
s->fields= field_count;
+ if (!(s->blob_field= (uint*)thd->alloc((field_list.elements + 1) *
+ sizeof(uint))))
+ return 0;
+
+ s->blob_ptr_size= mi_portable_sizeof_char_ptr;
+
/* Create all fields and calculate the total length of record */
List_iterator_fast<create_field> it(field_list);
while ((cdef= it++))
@@ -8956,9 +8963,15 @@
record_length+= (**field).pack_length();
if (! ((**field).flags & NOT_NULL_FLAG))
++null_count;
+
+ if ((*field)->flags & BLOB_FLAG)
+ s->blob_field[blob_count++]= (uint) (field - table->field);
+
++field;
}
*field= NULL; /* mark the end of the list */
+ s->blob_field[blob_count]= 0; /* mark the end of the list */
+ s->blob_fields= blob_count;
null_pack_length= (null_count + 7)/8;
s->reclength= record_length + null_pack_length;
--- 1.444/sql/sql_yacc.yy 2005-12-02 20:42:29 -08:00
+++ 1.445/sql/sql_yacc.yy 2005-12-10 23:30:53 -08:00
@@ -1350,41 +1350,11 @@
{
LEX *lex= Lex;
sp_head *sp= lex->sphead;
- LEX_STRING cmt = { 0, 0 };
- create_field *new_field;
- uint unused1= 0;
- int unused2= 0;
-
- if (!(new_field= new_create_field(YYTHD, (char*) "",
- (enum enum_field_types)$8,
- lex->length, lex->dec, lex->type,
- (Item *)0, (Item *) 0, &cmt, 0,
- &lex->interval_list,
- (lex->charset ? lex->charset :
- default_charset_info),
- lex->uint_geom_type)))
- YYABORT;
-
- sp->m_returns_cs= new_field->charset;
-
- if (new_field->interval_list.elements)
- {
- new_field->interval=
- sp->create_typelib(&new_field->interval_list);
- }
- sp_prepare_create_field(YYTHD, new_field);
-
- if (prepare_create_field(new_field, &unused1, &unused2, &unused2,
- HA_CAN_GEOMETRY))
- YYABORT;
- sp->m_returns= new_field->sql_type;
- sp->m_returns_cs= new_field->charset;
- sp->m_returns_len= new_field->length;
- sp->m_returns_pack= new_field->pack_flag;
- sp->m_returns_typelib= new_field->interval;
- sp->m_geom_returns= new_field->geom_type;
- new_field->interval= NULL;
+ if (sp->fill_field_definition(YYTHD, lex,
+ (enum enum_field_types) $8,
+ &sp->m_return_field_def))
+ YYABORT;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
@@ -1407,6 +1377,11 @@
YYABORT;
lex->sql_command= SQLCOM_CREATE_SPFUNCTION;
sp->init_strings(YYTHD, lex, lex->spname);
+ if (!(sp->m_flags & sp_head::HAS_RETURN))
+ {
+ my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str);
+ YYABORT;
+ }
/* Restore flag if it was cleared above */
if (sp->m_old_cmq)
YYTHD->client_capabilities |= CLIENT_MULTI_QUERIES;
@@ -1501,8 +1476,28 @@
| sp_fdparam
;
+sp_init_param:
+ /* Empty */
+ {
+ LEX *lex= Lex;
+
+ lex->length= 0;
+ lex->dec= 0;
+ lex->type= 0;
+
+ lex->default_value= 0;
+ lex->on_update_value= 0;
+
+ lex->comment= null_lex_str;
+ lex->charset= NULL;
+
+ lex->interval_list.empty();
+ lex->uint_geom_type= 0;
+ }
+ ;
+
sp_fdparam:
- ident type
+ ident sp_init_param type
{
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@@ -1512,7 +1507,17 @@
my_error(ER_SP_DUP_PARAM, MYF(0), $1.str);
YYABORT;
}
- spc->push_pvar(&$1, (enum enum_field_types)$2, sp_param_in);
+ sp_pvar_t *pvar= spc->push_pvar(&$1, (enum enum_field_types)$3,
+ sp_param_in);
+
+ if (lex->sphead->fill_field_definition(YYTHD, lex,
+ (enum enum_field_types) $3,
+ &pvar->field_def))
+ {
+ YYABORT;
+ }
+ pvar->field_def.field_name= pvar->name.str;
+ pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
}
;
@@ -1528,18 +1533,27 @@
;
sp_pdparam:
- sp_opt_inout ident type
+ sp_opt_inout sp_init_param ident type
{
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
- if (spc->find_pvar(&$2, TRUE))
+ if (spc->find_pvar(&$3, TRUE))
{
- my_error(ER_SP_DUP_PARAM, MYF(0), $2.str);
+ my_error(ER_SP_DUP_PARAM, MYF(0), $3.str);
YYABORT;
}
- spc->push_pvar(&$2, (enum enum_field_types)$3,
- (sp_param_mode_t)$1);
+ sp_pvar_t *pvar= spc->push_pvar(&$3, (enum enum_field_types)$4,
+ (sp_param_mode_t)$1);
+
+ if (lex->sphead->fill_field_definition(YYTHD, lex,
+ (enum enum_field_types) $4,
+ &pvar->field_def))
+ {
+ YYABORT;
+ }
+ pvar->field_def.field_name= pvar->name.str;
+ pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
}
;
@@ -1591,45 +1605,60 @@
;
sp_decl:
- DECLARE_SYM sp_decl_idents type
+ DECLARE_SYM sp_decl_idents
{
LEX *lex= Lex;
lex->sphead->reset_lex(YYTHD);
lex->spcont->declare_var_boundary($2);
}
+ type
sp_opt_default
{
LEX *lex= Lex;
- sp_pcontext *ctx= lex->spcont;
- uint max= ctx->context_pvars();
- enum enum_field_types type= (enum enum_field_types)$3;
- Item *it= $5;
- bool has_default= (it != NULL);
-
- for (uint i = max-$2 ; i < max ; i++)
+ sp_pcontext *pctx= lex->spcont;
+ uint num_vars= pctx->context_pvars();
+ enum enum_field_types var_type= (enum enum_field_types) $4;
+ Item *dflt_value_item= $5;
+ create_field *create_field_op;
+
+ if (!dflt_value_item)
{
- sp_instr_set *in;
- uint off= ctx->pvar_context2index(i);
-
- ctx->set_type(off, type);
- if (! has_default)
- it= new Item_null(); /* QQ Set to the type with null_value? */
- in = new sp_instr_set(lex->sphead->instructions(),
- ctx,
- off,
- it, type, lex,
- (i == max - 1));
-
- /*
- The last instruction is assigned to be responsible for
- freeing LEX.
- */
- lex->sphead->add_instr(in);
- ctx->set_default(off, it);
+ dflt_value_item= new Item_null();
+ /* QQ Set to the var_type with null_value? */
+ }
+
+ for (uint i = num_vars-$2 ; i < num_vars ; i++)
+ {
+ uint var_idx= pctx->pvar_context2index(i);
+ sp_pvar_t *pvar= pctx->find_pvar(var_idx);
+
+ if (!pvar)
+ YYABORT;
+
+ pvar->type= var_type;
+ pvar->dflt= dflt_value_item;
+
+ if (lex->sphead->fill_field_definition(YYTHD, lex, var_type,
+ &pvar->field_def))
+ {
+ YYABORT;
+ }
+
+ pvar->field_def.field_name= pvar->name.str;
+ pvar->field_def.pack_flag |= FIELDFLAG_MAYBE_NULL;
+
+ /* The last instruction is responsible for freeing LEX. */
+
+ lex->sphead->add_instr(
+ new sp_instr_set(lex->sphead->instructions(), pctx, var_idx,
+ dflt_value_item, var_type, lex,
+ (i == num_vars - 1)));
}
- ctx->declare_var_boundary(0);
+
+ pctx->declare_var_boundary(0);
lex->sphead->restore_lex(YYTHD);
+
$$.vars= $2;
$$.conds= $$.hndlrs= $$.curs= 0;
}
@@ -1852,6 +1881,8 @@
sp_decl_idents:
ident
{
+ /* NOTE: field definition is filled in sp_decl section. */
+
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@@ -1865,6 +1896,8 @@
}
| sp_decl_idents ',' ident
{
+ /* NOTE: field definition is filled in sp_decl section. */
+
LEX *lex= Lex;
sp_pcontext *spc= lex->spcont;
@@ -1942,8 +1975,8 @@
{
sp_instr_freturn *i;
- i= new sp_instr_freturn(sp->instructions(), lex->spcont,
- $3, sp->m_returns, lex);
+ i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3,
+ sp->m_return_field_def.sql_type, lex);
sp->add_instr(i);
sp->m_flags|= sp_head::HAS_RETURN;
}
@@ -1959,25 +1992,27 @@
{ Lex->sphead->reset_lex(YYTHD); }
expr WHEN_SYM
{
- /* We "fake" this by using an anonymous variable which we
- set to the expression. Note that all WHENs are evaluate
- at the same frame level, so we then know that it's the
- top-most variable in the frame. */
- LEX *lex= Lex;
- uint offset= lex->spcont->current_pvars();
- sp_instr_set *i = new sp_instr_set(lex->sphead->instructions(),
- lex->spcont, offset, $3,
- MYSQL_TYPE_STRING, lex, TRUE);
- LEX_STRING dummy={(char*)"", 0};
-
- lex->spcont->push_pvar(&dummy, MYSQL_TYPE_STRING, sp_param_in);
- lex->sphead->add_instr(i);
- lex->sphead->m_flags|= sp_head::IN_SIMPLE_CASE;
- lex->sphead->restore_lex(YYTHD);
+ LEX *lex= Lex;
+ sp_head *sp= lex->sphead;
+ sp_pcontext *parsing_ctx= lex->spcont;
+ int case_expr_id= parsing_ctx->register_case_expr();
+
+ if (parsing_ctx->push_case_expr_id(case_expr_id))
+ YYABORT;
+
+ sp->add_instr(
+ new sp_instr_set_case_expr(sp->instructions(),
+ parsing_ctx,
+ case_expr_id,
+ $3,
+ lex));
+
+ sp->m_flags|= sp_head::IN_SIMPLE_CASE;
+ sp->restore_lex(YYTHD);
}
sp_case END CASE_SYM
{
- Lex->spcont->pop_pvar();
+ Lex->spcont->pop_case_expr_id();
}
| sp_labeled_control
{}
@@ -2288,20 +2323,20 @@
i= new sp_instr_jump_if_not(ip, ctx, $2, lex);
else
{ /* Simple case: <caseval> = <whenval> */
- LEX_STRING ivar;
- ivar.str= (char *)"_tmp_";
- ivar.length= 5;
- Item_splocal *var= new Item_splocal(ivar,
- ctx->current_pvars()-1);
+ Item_case_expr *var;
+ Item *expr;
+
+ var= new Item_case_expr(ctx->get_current_case_expr_id());
+
#ifndef DBUG_OFF
if (var)
- var->owner= sp;
+ var->m_sp= sp;
#endif
- Item *expr= new Item_func_eq(var, $2);
+
+ expr= new Item_func_eq(var, $2);
i= new sp_instr_jump_if_not(ip, ctx, expr, lex);
- lex->variables_used= 1;
}
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
sp->add_instr(i);
@@ -3778,11 +3813,6 @@
OPTIMIZE opt_no_write_to_binlog table_or_tables
{
LEX *lex=Lex;
- if (lex->sphead)
- {
- my_error(ER_SP_BADSTATEMENT, MYF(0), "OPTIMIZE TABLE");
- YYABORT;
- }
lex->sql_command = SQLCOM_OPTIMIZE;
lex->no_write_to_binlog= $2;
lex->check_opt.init();
@@ -4401,16 +4431,14 @@
{
if ($3->is_splocal())
{
- LEX_STRING *name;
Item_splocal *il= static_cast<Item_splocal *>($3);
- name= il->my_name(NULL);
- my_error(ER_WRONG_COLUMN_NAME, MYF(0), name->str);
+ my_error(ER_WRONG_COLUMN_NAME, MYF(0), il->my_name()->str);
YYABORT;
}
$$= new Item_default_value(Lex->current_context(), $3);
}
- | VALUES '(' simple_ident ')'
+ | VALUES '(' simple_ident_nospvar ')'
{ $$= new Item_insert_value(Lex->current_context(), $3); }
| FUNC_ARG0 '(' ')'
{
@@ -5180,10 +5208,8 @@
{
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
- Name_resolution_context *on_context;
- if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
+ if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
- Lex->push_context(on_context);
}
expr
{
@@ -5195,10 +5221,8 @@
{
YYERROR_UNLESS($1 && ($$=$3));
/* Change the current name resolution context to a local context. */
- Name_resolution_context *on_context;
- if (!(on_context= make_join_on_context(YYTHD,$1,$3)))
+ if (push_new_name_resolution_context(YYTHD, $1, $3))
YYABORT;
- Lex->push_context(on_context);
}
expr
{
@@ -5225,10 +5249,8 @@
ON
{
/* Change the current name resolution context to a local context. */
- Name_resolution_context *on_context;
- if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
+ if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
- Lex->push_context(on_context);
}
expr
{
@@ -5258,10 +5280,8 @@
ON
{
/* Change the current name resolution context to a local context. */
- Name_resolution_context *on_context;
- if (!(on_context= make_join_on_context(YYTHD,$1,$5)))
+ if (push_new_name_resolution_context(YYTHD, $1, $5))
YYABORT;
- Lex->push_context(on_context);
}
expr
{
@@ -5322,10 +5342,9 @@
ON
{
/* Change the current name resolution context to a local context. */
- Name_resolution_context *on_context;
- if (!(on_context= make_join_on_context(YYTHD,$3,$7)))
+ if (push_new_name_resolution_context(YYTHD, $3, $7))
YYABORT;
- Lex->push_context(on_context);
+
}
expr '}'
{
@@ -5882,7 +5901,7 @@
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
#ifndef DBUG_OFF
if (var)
- var->owner= lex->sphead;
+ var->sp= lex->sphead;
#endif
}
}
@@ -7184,11 +7203,12 @@
{
/* We're compiling a stored procedure and found a variable */
Item_splocal *splocal;
- splocal= new Item_splocal($1, spv->offset, lex->tok_start_prev -
+ splocal= new Item_splocal($1, spv->offset, spv->type,
+ lex->tok_start_prev -
lex->sphead->m_tmp_query);
#ifndef DBUG_OFF
if (splocal)
- splocal->owner= lex->sphead;
+ splocal->m_sp= lex->sphead;
#endif
$$ = (Item*) splocal;
lex->variables_used= 1;
| Thread |
|---|
| • bk commit into 5.0 tree (igor:1.1967) | igor | 11 Dec |