Below is the list of changes that have just been committed into a local
5.0 repository of acurtis. When acurtis 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.1817 05/03/08 22:32:09 acurtis@stripped +14 -0
Merge in fix Bug#3788
BitKeeper/etc/logging_ok
1.297 05/03/08 22:32:09 acurtis@stripped +1 -0
Logging to logging@stripped accepted
mysql-test/r/sp.result
1.116 05/03/08 22:31:31 acurtis@stripped +0 -1
Merge
sql/sql_yacc.yy
1.348 05/03/08 18:53:03 acurtis@stripped +0 -0
Auto merged
sql/sql_table.cc
1.223 05/03/08 18:53:02 acurtis@stripped +0 -0
Auto merged
sql/sql_parse.cc
1.414 05/03/08 18:53:01 acurtis@stripped +0 -0
Auto merged
sql/sp_head.h
1.52 05/03/08 18:53:00 acurtis@stripped +0 -0
Auto merged
sql/sp_head.cc
1.121 05/03/08 18:53:00 acurtis@stripped +0 -0
Auto merged
sql/sp.cc
1.70 05/03/08 18:52:59 acurtis@stripped +0 -0
Auto merged
sql/mysql_priv.h
1.272 05/03/08 18:52:59 acurtis@stripped +0 -0
Auto merged
sql/item_func.h
1.99 05/03/08 18:52:58 acurtis@stripped +0 -0
Auto merged
sql/item_func.cc
1.171 05/03/08 18:52:57 acurtis@stripped +0 -0
Auto merged
sql/item.cc
1.121 05/03/08 18:52:57 acurtis@stripped +0 -0
Auto merged
mysql-test/t/sp.test
1.110 05/03/08 18:52:56 acurtis@stripped +0 -0
Auto merged
mysql-test/r/information_schema.result
1.36 05/03/08 18:52:55 acurtis@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: acurtis
# Host: ltantony.rdg.cyberkinetica.homeunix.net
# Root: /var/db/bk/work-acurtis/bug3788.4/RESYNC
--- 1.120/sql/item.cc 2005-03-05 14:12:29 +00:00
+++ 1.121/sql/item.cc 2005-03-08 18:52:57 +00:00
@@ -3521,7 +3521,7 @@
enum_parsing_place place= NO_MATTER;
SELECT_LEX *current_sel= thd->lex->current_select;
- if (!ref)
+ if (!ref || ref == not_found_item)
{
SELECT_LEX_UNIT *prev_unit= current_sel->master_unit();
SELECT_LEX *outer_sel= prev_unit->outer_select();
--- 1.170/sql/item_func.cc 2005-03-05 14:12:29 +00:00
+++ 1.171/sql/item_func.cc 2005-03-08 18:52:57 +00:00
@@ -4368,13 +4368,33 @@
Item_func_sp::Item_func_sp(sp_name *name)
:Item_func(), m_name(name), m_sp(NULL)
{
+ char *empty_name= (char *) "";
+ maybe_null= 1;
m_name->init_qname(current_thd);
+ bzero(&dummy_table, sizeof(dummy_table));
+ dummy_table.share.table_cache_key = empty_name;
+ dummy_table.share.table_name = empty_name;
+ dummy_table.table.alias = empty_name;
+ dummy_table.share.table_name = empty_name;
+ dummy_table.table.maybe_null = maybe_null;
+ dummy_table.table.in_use= current_thd;
+ dummy_table.table.s = &dummy_table.share;
}
Item_func_sp::Item_func_sp(sp_name *name, List<Item> &list)
:Item_func(list), m_name(name), m_sp(NULL)
{
+ char *empty_name= (char *) "";
+ maybe_null= 1;
m_name->init_qname(current_thd);
+ bzero(&dummy_table, sizeof(dummy_table));
+ dummy_table.share.table_cache_key = empty_name;
+ dummy_table.share.table_name = empty_name;
+ dummy_table.table.alias = empty_name;
+ dummy_table.share.table_name = empty_name;
+ dummy_table.table.maybe_null = maybe_null;
+ dummy_table.table.in_use= current_thd;
+ dummy_table.table.s = &dummy_table.share;
}
const char *
@@ -4399,6 +4419,18 @@
}
+Field *
+Item_func_sp::sp_result_field(void) const
+{
+ Field *field= 0;
+ THD *thd= current_thd;
+ DBUG_ENTER("Item_func_sp::sp_result_field");
+ if (m_sp)
+ field= m_sp->make_field(max_length, name, &dummy_table.table);
+ DBUG_RETURN(field);
+}
+
+
int
Item_func_sp::execute(Item **itp)
{
@@ -4449,17 +4481,38 @@
}
+void
+Item_func_sp::make_field(Send_field *tmp_field)
+{
+ Field *field;
+ DBUG_ENTER("Item_func_sp::make_field");
+ if (! m_sp)
+ m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only
+ if ((field= sp_result_field()))
+ {
+ field->make_field(tmp_field);
+ delete field;
+ DBUG_VOID_RETURN;
+ }
+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
+ init_make_field(tmp_field, MYSQL_TYPE_VARCHAR);
+ DBUG_VOID_RETURN;
+}
+
+
enum enum_field_types
Item_func_sp::field_type() const
{
+ Field *field= 0;
DBUG_ENTER("Item_func_sp::field_type");
if (! m_sp)
m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only
- if (m_sp)
+ if ((field= sp_result_field()))
{
- DBUG_PRINT("info", ("m_returns = %d", m_sp->m_returns));
- DBUG_RETURN(m_sp->m_returns);
+ enum_field_types result= field->type();
+ delete field;
+ DBUG_RETURN(result);
}
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
DBUG_RETURN(MYSQL_TYPE_VARCHAR);
@@ -4469,14 +4522,17 @@
Item_result
Item_func_sp::result_type() const
{
+ Field *field= 0;
DBUG_ENTER("Item_func_sp::result_type");
DBUG_PRINT("info", ("m_sp = %p", m_sp));
if (! m_sp)
m_sp= sp_find_function(current_thd, m_name, TRUE); // cache only
- if (m_sp)
+ if ((field= sp_result_field()))
{
- DBUG_RETURN(m_sp->result());
+ Item_result result= field->result_type();
+ delete field;
+ DBUG_RETURN(result);
}
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
DBUG_RETURN(STRING_RESULT);
@@ -4495,7 +4551,7 @@
}
else
{
- switch (m_sp->result()) {
+ switch (result_type()) {
case STRING_RESULT:
maybe_null= 1;
max_length= MAX_BLOB_WIDTH;
@@ -4529,4 +4585,20 @@
THD *thd= current_thd;
return thd->found_rows();
+}
+
+Field *
+Item_func_sp::tmp_table_field(TABLE *t_arg)
+{
+ Field *res= 0;
+ enum_field_types ftype;
+ DBUG_ENTER("Item_func_sp::tmp_table_field");
+
+ if (m_sp)
+ res= m_sp->make_field(max_length, (const char *)name, t_arg);
+
+ if (!res)
+ res= Item_func::tmp_table_field(t_arg);
+
+ DBUG_RETURN(res);
}
--- 1.98/sql/item_func.h 2005-03-02 09:38:14 +00:00
+++ 1.99/sql/item_func.h 2005-03-08 18:52:58 +00:00
@@ -1252,8 +1252,13 @@
private:
sp_name *m_name;
mutable sp_head *m_sp;
+ mutable struct {
+ TABLE table;
+ TABLE_SHARE share;
+ } dummy_table;
int execute(Item **itp);
+ Field *sp_result_field(void) const;
public:
@@ -1267,6 +1272,10 @@
const char *func_name() const;
enum enum_field_types field_type() const;
+
+ Field *tmp_table_field(TABLE *t_arg);
+
+ void make_field(Send_field *tmp_field);
Item_result result_type() const;
--- 1.271/sql/mysql_priv.h 2005-03-05 11:34:18 +00:00
+++ 1.272/sql/mysql_priv.h 2005-03-08 18:52:59 +00:00
@@ -629,6 +629,10 @@
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item ***copy_func, Field **from_field,
bool group, bool modify_item, uint convert_blob_length);
+int prepare_create_field(create_field *sql_field,
+ uint &blob_columns,
+ int ×tamps, int ×tamps_with_niladic,
+ uint table_flags);
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
List<create_field> &fields,
List<Key> &keys, uint &db_options,
@@ -838,6 +842,13 @@
char *change, List<String> *interval_list,
CHARSET_INFO *cs,
uint uint_geom_type);
+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);
void store_position_for_column(const char *name);
bool add_to_list(THD *thd, SQL_LIST &list,Item *group,bool asc=0);
void add_join_on(TABLE_LIST *b,Item *expr);
--- 1.413/sql/sql_parse.cc 2005-03-05 13:33:26 +00:00
+++ 1.414/sql/sql_parse.cc 2005-03-08 18:53:01 +00:00
@@ -5207,9 +5207,6 @@
{
register create_field *new_field;
LEX *lex= thd->lex;
- uint allowed_type_modifier=0;
- uint sign_len;
- ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
DBUG_ENTER("add_field_to_list");
if (strlen(field_name) > NAME_LEN)
@@ -5270,9 +5267,38 @@
my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name);
DBUG_RETURN(1);
}
-
- if (!(new_field=new create_field()))
+
+ 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)))
DBUG_RETURN(1);
+
+ lex->create_list.push_back(new_field);
+ lex->last_field=new_field;
+ 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;
@@ -5344,7 +5370,7 @@
new_field->length >= new_field->decimals)
break;
my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
- DBUG_RETURN(1);
+ DBUG_RETURN(NULL);
case MYSQL_TYPE_VARCHAR:
/*
Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
@@ -5367,7 +5393,7 @@
{
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0),
field_name); /* purecov: inspected */
- DBUG_RETURN(1); /* purecov: inspected */
+ DBUG_RETURN(NULL);
}
new_field->def=0;
}
@@ -5387,7 +5413,7 @@
if (tmp_length > PRECISION_FOR_DOUBLE)
{
my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name);
- DBUG_RETURN(1);
+ DBUG_RETURN(NULL);
}
else if (tmp_length > PRECISION_FOR_FLOAT)
{
@@ -5484,7 +5510,7 @@
if (interval_list->elements > sizeof(longlong)*8)
{
my_error(ER_TOO_BIG_SET, MYF(0), field_name); /* purecov: inspected */
- DBUG_RETURN(1); /* purecov: inspected */
+ DBUG_RETURN(NULL);
}
new_field->pack_length= (interval_list->elements + 7) / 8;
if (new_field->pack_length > 4)
@@ -5525,7 +5551,7 @@
{
my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name,
MAX_BIT_FIELD_LENGTH);
- DBUG_RETURN(1);
+ DBUG_RETURN(NULL);
}
new_field->pack_length= (new_field->length + 7) / 8;
break;
@@ -5544,17 +5570,15 @@
{
my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0),
field_name, max_field_charlength); /* purecov: inspected */
- DBUG_RETURN(1); /* 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(1);
+ DBUG_RETURN(NULL);
}
- lex->create_list.push_back(new_field);
- lex->last_field=new_field;
- DBUG_RETURN(0);
+ DBUG_RETURN(new_field);
}
--- 1.222/sql/sql_table.cc 2005-02-25 14:53:16 +00:00
+++ 1.223/sql/sql_table.cc 2005-03-08 18:53:02 +00:00
@@ -432,6 +432,173 @@
/*
+ Prepare a create_table instance for packing
+
+ SYNOPSIS
+ prepare_create_field()
+ sql_field field to prepare for packing
+ blob_columns count for BLOBs
+ timestamps count for timestamps
+ table_flags table flags
+
+ DESCRIPTION
+ This function prepares a create_field instance.
+ Fields such as pack_flag are valid after this call.
+
+ RETURN VALUES
+ 0 ok
+ 1 Error
+*/
+
+int prepare_create_field(create_field *sql_field,
+ uint &blob_columns,
+ int ×tamps, int ×tamps_with_niladic,
+ uint table_flags)
+{
+ DBUG_ENTER("prepare_field");
+ {
+ /* This code came from mysql_prepare_table.
+ Indent preserved to make patching easier */
+ DBUG_ASSERT(sql_field->charset);
+
+ switch (sql_field->sql_type) {
+ case FIELD_TYPE_BLOB:
+ case FIELD_TYPE_MEDIUM_BLOB:
+ case FIELD_TYPE_TINY_BLOB:
+ case FIELD_TYPE_LONG_BLOB:
+ sql_field->pack_flag=FIELDFLAG_BLOB |
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
+ sql_field->unireg_check=Field::BLOB_FIELD;
+ blob_columns++;
+ break;
+ case FIELD_TYPE_GEOMETRY:
+#ifdef HAVE_SPATIAL
+ if (!(table_flags & HA_CAN_GEOMETRY))
+ {
+ my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
+ MYF(0), "GEOMETRY");
+ DBUG_RETURN(1);
+ }
+ sql_field->pack_flag=FIELDFLAG_GEOM |
+ pack_length_to_packflag(sql_field->pack_length -
+ portable_sizeof_char_ptr);
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->length=8; // Unireg field length
+ sql_field->unireg_check=Field::BLOB_FIELD;
+ blob_columns++;
+ break;
+#else
+ my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
+ sym_group_geom.name, sym_group_geom.needed_define);
+ DBUG_RETURN(1);
+#endif /*HAVE_SPATIAL*/
+ case MYSQL_TYPE_VARCHAR:
+#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
+ if (table_flags & HA_NO_VARCHAR)
+ {
+ /* convert VARCHAR to CHAR because handler is not yet up to date */
+ sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
+ sql_field->pack_length= calc_pack_length(sql_field->sql_type,
+ (uint) sql_field->length);
+ if ((sql_field->length / sql_field->charset->mbmaxlen) >
+ MAX_FIELD_CHARLENGTH)
+ {
+ my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
+ MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
+ DBUG_RETURN(1);
+ }
+ }
+#endif
+ /* fall through */
+ case FIELD_TYPE_STRING:
+ sql_field->pack_flag=0;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ break;
+ case FIELD_TYPE_ENUM:
+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
+ FIELDFLAG_INTERVAL;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->unireg_check=Field::INTERVAL_FIELD;
+ check_duplicates_in_interval("ENUM",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset);
+ break;
+ case FIELD_TYPE_SET:
+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
+ FIELDFLAG_BITFIELD;
+ if (sql_field->charset->state & MY_CS_BINSORT)
+ sql_field->pack_flag|=FIELDFLAG_BINARY;
+ sql_field->unireg_check=Field::BIT_FIELD;
+ check_duplicates_in_interval("SET",sql_field->field_name,
+ sql_field->interval,
+ sql_field->charset);
+ break;
+ case FIELD_TYPE_DATE: // Rest of string types
+ case FIELD_TYPE_NEWDATE:
+ case FIELD_TYPE_TIME:
+ case FIELD_TYPE_DATETIME:
+ case FIELD_TYPE_NULL:
+ sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
+ break;
+ case FIELD_TYPE_BIT:
+ if (!(table_flags & HA_CAN_BIT_FIELD))
+ {
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
+ DBUG_RETURN(1);
+ }
+ sql_field->pack_flag= FIELDFLAG_NUMBER;
+ break;
+ case FIELD_TYPE_NEWDECIMAL:
+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
+ FIELDFLAG_DECIMAL) |
+ (sql_field->flags & ZEROFILL_FLAG ?
+ FIELDFLAG_ZEROFILL : 0) |
+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ break;
+ case FIELD_TYPE_TIMESTAMP:
+ /* We should replace old TIMESTAMP fields with their newer analogs */
+ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
+ {
+ if (!timestamps)
+ {
+ sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
+ timestamps_with_niladic++;
+ }
+ else
+ sql_field->unireg_check= Field::NONE;
+ }
+ else if (sql_field->unireg_check != Field::NONE)
+ timestamps_with_niladic++;
+
+ timestamps++;
+ /* fall-through */
+ default:
+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
+ FIELDFLAG_DECIMAL) |
+ (sql_field->flags & ZEROFILL_FLAG ?
+ FIELDFLAG_ZEROFILL : 0) |
+ f_settype((uint) sql_field->sql_type) |
+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
+ break;
+ }
+ if (!(sql_field->flags & NOT_NULL_FLAG))
+ sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
+ if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
+ sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
+ }
+ DBUG_RETURN(0);
+}
+
+/*
Preparation for table creation
SYNOPSIS
@@ -690,142 +857,17 @@
{
DBUG_ASSERT(sql_field->charset != 0);
- switch (sql_field->sql_type) {
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- sql_field->pack_flag=FIELDFLAG_BLOB |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
- sql_field->unireg_check=Field::BLOB_FIELD;
- blob_columns++;
- create_info->varchar= 1;
- break;
- case FIELD_TYPE_GEOMETRY:
-#ifdef HAVE_SPATIAL
- if (!(file->table_flags() & HA_CAN_GEOMETRY))
- {
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "GEOMETRY");
- DBUG_RETURN(-1);
- }
- sql_field->pack_flag=FIELDFLAG_GEOM |
- pack_length_to_packflag(sql_field->pack_length -
- portable_sizeof_char_ptr);
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->length=8; // Unireg field length
- sql_field->unireg_check=Field::BLOB_FIELD;
- blob_columns++;
- create_info->varchar= 1;
- break;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
+ if (prepare_create_field(sql_field, blob_columns,
+ timestamps, timestamps_with_niladic,
+ file->table_flags()))
DBUG_RETURN(-1);
-#endif /*HAVE_SPATIAL*/
- case MYSQL_TYPE_VARCHAR:
-#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
- if (file->table_flags() & HA_NO_VARCHAR)
- {
- /* convert VARCHAR to CHAR because handler is not yet up to date */
- sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
- sql_field->pack_length= calc_pack_length(sql_field->sql_type,
- (uint) sql_field->length);
- if ((sql_field->length / sql_field->charset->mbmaxlen) >
- MAX_FIELD_CHARLENGTH)
- {
- my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
- MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
- DBUG_RETURN(-1);
- }
- }
- else
-#endif
- create_info->varchar= 1;
- /* fall through */
- case MYSQL_TYPE_STRING:
- sql_field->pack_flag=0;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|= FIELDFLAG_BINARY;
- break;
- case FIELD_TYPE_ENUM:
- sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_INTERVAL;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->unireg_check=Field::INTERVAL_FIELD;
- check_duplicates_in_interval("ENUM",sql_field->field_name,
- sql_field->interval,
- sql_field->charset);
- break;
- case FIELD_TYPE_SET:
- sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
- FIELDFLAG_BITFIELD;
- if (sql_field->charset->state & MY_CS_BINSORT)
- sql_field->pack_flag|=FIELDFLAG_BINARY;
- sql_field->unireg_check=Field::BIT_FIELD;
- check_duplicates_in_interval("SET",sql_field->field_name,
- sql_field->interval,
- sql_field->charset);
- break;
- case FIELD_TYPE_DATE: // Rest of string types
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_NULL:
- sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
- break;
- case FIELD_TYPE_BIT:
- if (!(file->table_flags() & HA_CAN_BIT_FIELD))
- {
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "BIT FIELD");
- DBUG_RETURN(-1);
- }
- sql_field->pack_flag= FIELDFLAG_NUMBER;
- break;
- case FIELD_TYPE_NEWDECIMAL:
- sql_field->pack_flag=(FIELDFLAG_NUMBER |
- (sql_field->flags & UNSIGNED_FLAG ? 0 :
- FIELDFLAG_DECIMAL) |
- (sql_field->flags & ZEROFILL_FLAG ?
- FIELDFLAG_ZEROFILL : 0) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
- break;
- case FIELD_TYPE_TIMESTAMP:
- /* We should replace old TIMESTAMP fields with their newer analogs */
- if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
- {
- if (!timestamps)
- {
- sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
- timestamps_with_niladic++;
- }
- else
- sql_field->unireg_check= Field::NONE;
- }
- else if (sql_field->unireg_check != Field::NONE)
- timestamps_with_niladic++;
-
- timestamps++;
- /* fall-through */
- default:
- sql_field->pack_flag=(FIELDFLAG_NUMBER |
- (sql_field->flags & UNSIGNED_FLAG ? 0 :
- FIELDFLAG_DECIMAL) |
- (sql_field->flags & ZEROFILL_FLAG ?
- FIELDFLAG_ZEROFILL : 0) |
- f_settype((uint) sql_field->sql_type) |
- (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
- break;
- }
- if (!(sql_field->flags & NOT_NULL_FLAG))
- sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
- if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
- sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
+ if (sql_field->sql_type == FIELD_TYPE_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_LONG_BLOB ||
+ sql_field->sql_type == FIELD_TYPE_GEOMETRY ||
+ sql_field->sql_type == MYSQL_TYPE_VARCHAR)
+ create_info->varchar= 1;
sql_field->offset= pos;
if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
auto_increment++;
@@ -1592,6 +1634,8 @@
((Item_field *)item)->field :
(Field*) 0))))
DBUG_RETURN(0);
+ if (item->maybe_null)
+ cr_field->flags &= ~NOT_NULL_FLAG;
extra_fields->push_back(cr_field);
}
/*
--- 1.347/sql/sql_yacc.yy 2005-03-04 14:46:41 +00:00
+++ 1.348/sql/sql_yacc.yy 2005-03-08 18:53:03 +00:00
@@ -1372,19 +1372,37 @@
RETURNS_SYM
{
LEX *lex= Lex;
- sp_head *sp= lex->sphead;
-
- sp->m_returns_begin= lex->tok_start;
- sp->m_returns_cs= lex->charset= NULL;
+ lex->charset= NULL;
+ lex->length= lex->dec= NULL;
+ lex->interval_list.empty();
+ lex->type= 0;
}
type
{
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, "", (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;
+
+ if (prepare_create_field(new_field, unused1, unused2, unused2, 0))
+ 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=
+ sp->create_typelib(&new_field->interval_list);
- sp->m_returns_end= lex->tok_start;
- sp->m_returns= (enum enum_field_types)$8;
- sp->m_returns_cs= lex->charset;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
sp_c_chistics
--- 1.296/BitKeeper/etc/logging_ok 2005-03-07 11:49:37 +00:00
+++ 1.297/BitKeeper/etc/logging_ok 2005-03-08 22:32:09 +00:00
@@ -7,6 +7,7 @@
Miguel@stripped
Sinisa@stripped
WAX@stripped
+acurtis@stripped
acurtis@stripped
administrador@stripped
ahlentz@stripped
--- 1.35/mysql-test/r/information_schema.result 2005-03-05 11:34:18 +00:00
+++ 1.36/mysql-test/r/information_schema.result 2005-03-08 18:52:55 +00:00
@@ -203,7 +203,7 @@
from information_schema.routines;
parameter_style sql_data_access dtd_identifier
SQL CONTAINS SQL NULL
-SQL CONTAINS SQL int
+SQL CONTAINS SQL int(11)
show procedure status;
Db Name Type Definer Modified Created Security_type Comment
test sel2 PROCEDURE root@localhost # # DEFINER
--- 1.115/mysql-test/r/sp.result 2005-03-07 17:09:47 +00:00
+++ 1.116/mysql-test/r/sp.result 2005-03-08 22:31:31 +00:00
@@ -962,7 +962,7 @@
return 42|
show create function chistics|
Function sql_mode Create Function
-chistics CREATE FUNCTION `test`.`chistics`() RETURNS int
+chistics CREATE FUNCTION `test`.`chistics`() RETURNS int(11)
DETERMINISTIC
SQL SECURITY INVOKER
COMMENT 'Characteristics procedure test'
@@ -975,7 +975,7 @@
comment 'Characteristics function test'|
show create function chistics|
Function sql_mode Create Function
-chistics CREATE FUNCTION `test`.`chistics`() RETURNS int
+chistics CREATE FUNCTION `test`.`chistics`() RETURNS int(11)
NO SQL
DETERMINISTIC
SQL SECURITY INVOKER
@@ -2026,11 +2026,11 @@
insert into "t1" values ('foo', 1)
show create function bug2564_3|
Function sql_mode Create Function
-bug2564_3 CREATE FUNCTION `test`.`bug2564_3`(x int, y int) RETURNS int
+bug2564_3 CREATE FUNCTION `test`.`bug2564_3`(x int, y int) RETURNS int(11)
return x || y
show create function bug2564_4|
Function sql_mode Create Function
-bug2564_4 REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI CREATE FUNCTION "test"."bug2564_4"(x int, y int) RETURNS int
+bug2564_4 REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ONLY_FULL_GROUP_BY,ANSI CREATE FUNCTION "test"."bug2564_4"(x int, y int) RETURNS int(11)
return x || y
drop procedure bug2564_1|
drop procedure bug2564_2|
@@ -2094,6 +2094,28 @@
drop procedure bug4579_1|
drop procedure bug4579_2|
drop table t3|
+drop table if exists t3|
+drop procedure if exists bug2773|
+create function bug2773() returns int return null|
+create table t3 as select bug2773()|
+show create table t3|
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `bug2773()` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+drop table t3|
+drop function bug2773|
+drop procedure if exists bug3788|
+create function bug3788() returns date return cast("2005-03-04" as date)|
+select bug3788()|
+bug3788()
+2005-03-04
+drop function bug3788|
+create function bug3788() returns binary(5) return 5|
+select bug3788()|
+bug3788()
+5
+drop function bug3788|
drop table if exists t3|
create table t3 (f1 int, f2 int, f3 int)|
insert into t3 values (1,1,1)|
--- 1.109/mysql-test/t/sp.test 2005-03-07 17:09:47 +00:00
+++ 1.110/mysql-test/t/sp.test 2005-03-08 18:52:56 +00:00
@@ -2546,6 +2546,35 @@
drop procedure bug4579_2|
drop table t3|
+#
+# BUG#2773: Function's data type ignored in stored procedures
+#
+--disable_warnings
+drop table if exists t3|
+drop procedure if exists bug2773|
+--enable_warnings
+
+create function bug2773() returns int return null|
+create table t3 as select bug2773()|
+show create table t3|
+drop table t3|
+drop function bug2773|
+
+#
+# BUG#3788: Stored procedure packet error
+#
+--disable_warnings
+drop procedure if exists bug3788|
+--enable_warnings
+
+create function bug3788() returns date return cast("2005-03-04" as date)|
+select bug3788()|
+drop function bug3788|
+
+create function bug3788() returns binary(5) return 5|
+select bug3788()|
+drop function bug3788|
+
#
# BUG#4726
--- 1.69/sql/sp.cc 2005-03-05 13:31:44 +00:00
+++ 1.70/sql/sp.cc 2005-03-08 18:52:59 +00:00
@@ -334,6 +334,22 @@
}
+static void
+sp_returns_type(THD *thd, String &result, sp_head *sp)
+{
+ struct {
+ TABLE table;
+ TABLE_SHARE share;
+ } dummy;
+ Field *field;
+ bzero(&dummy, sizeof(dummy));
+ dummy.table.in_use= thd;
+ dummy.table.s = &dummy.share;
+ field= sp->make_field(0, 0, &dummy.table);
+ field->sql_type(result);
+ delete field;
+}
+
static int
db_create_routine(THD *thd, int type, sp_head *sp)
{
@@ -388,9 +404,13 @@
store((longlong)sp->m_chistics->suid);
table->field[MYSQL_PROC_FIELD_PARAM_LIST]->
store(sp->m_params.str, sp->m_params.length, system_charset_info);
- if (sp->m_retstr.str)
+ if (sp->m_type == TYPE_ENUM_FUNCTION)
+ {
+ String retstr(64);
+ sp_returns_type(thd, retstr, sp);
table->field[MYSQL_PROC_FIELD_RETURNS]->
- store(sp->m_retstr.str, sp->m_retstr.length, system_charset_info);
+ store(retstr.ptr(), retstr.length(), system_charset_info);
+ }
table->field[MYSQL_PROC_FIELD_BODY]->
store(sp->m_body.str, sp->m_body.length, system_charset_info);
table->field[MYSQL_PROC_FIELD_DEFINER]->
--- 1.120/sql/sp_head.cc 2005-03-05 13:33:26 +00:00
+++ 1.121/sql/sp_head.cc 2005-03-08 18:53:00 +00:00
@@ -305,11 +305,11 @@
*/
lex->trg_table_fields.empty();
my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8);
- m_param_begin= m_param_end= m_returns_begin= m_returns_end= m_body_begin= 0;
- m_qname.str= m_db.str= m_name.str= m_params.str= m_retstr.str=
+ m_param_begin= m_param_end= m_body_begin= 0;
+ m_qname.str= m_db.str= m_name.str= m_params.str=
m_body.str= m_defstr.str= 0;
m_qname.length= m_db.length= m_name.length= m_params.length=
- m_retstr.length= m_body.length= m_defstr.length= 0;
+ m_body.length= m_defstr.length= 0;
m_returns_cs= NULL;
DBUG_VOID_RETURN;
}
@@ -351,41 +351,6 @@
(char *)m_param_begin, m_params.length);
}
- if (m_returns_begin && m_returns_end)
- {
- /* QQ KLUDGE: We can't seem to cut out just the type in the parser
- (without the RETURNS), so we'll have to do it here. :-(
- Furthermore, if there's a character type as well, it's not include
- (beyond the m_returns_end pointer), in which case we need
- m_returns_cs. */
- char *p= (char *)m_returns_begin+strspn((char *)m_returns_begin,"\t\n\r ");
- p+= strcspn(p, "\t\n\r ");
- p+= strspn(p, "\t\n\r ");
- if (p < (char *)m_returns_end)
- m_returns_begin= (uchar *)p;
- /* While we're at it, trim the end too. */
- p= (char *)m_returns_end-1;
- while (p > (char *)m_returns_begin &&
- (*p == '\t' || *p == '\n' || *p == '\r' || *p == ' '))
- p-= 1;
- m_returns_end= (uchar *)p+1;
- if (m_returns_cs)
- {
- String s((char *)m_returns_begin, m_returns_end - m_returns_begin,
- system_charset_info);
-
- s.append(' ');
- s.append(m_returns_cs->csname);
- m_retstr.length= s.length();
- m_retstr.str= strmake_root(root, s.ptr(), m_retstr.length);
- }
- else
- {
- m_retstr.length= m_returns_end - m_returns_begin;
- m_retstr.str= strmake_root(root,
- (char *)m_returns_begin, m_retstr.length);
- }
- }
m_body.length= lex->ptr - m_body_begin;
/* Trim nuls at the end */
n= 0;
@@ -401,6 +366,27 @@
DBUG_VOID_RETURN;
}
+TYPELIB *
+sp_head::create_typelib(List<String> *src)
+{
+ TYPELIB *result= NULL;
+ DBUG_ENTER("sp_head::clone_typelib");
+ if (src->elements)
+ {
+ result= (TYPELIB*) alloc_root(mem_root, sizeof(TYPELIB));
+ result->count= src->elements;
+ result->name= "";
+ if (!(result->type_names=(const char **)
+ alloc_root(mem_root,sizeof(char *)*(result->count+1))))
+ return 0;
+ List_iterator<String> it(*src);
+ for (uint i=0; i<result->count; i++)
+ result->type_names[i]= strdup_root(mem_root, (it++)->c_ptr());
+ result->type_names[result->count]= 0;
+ }
+ return result;
+}
+
int
sp_head::create(THD *thd)
{
@@ -479,6 +465,21 @@
hash_free(&m_spfuns);
hash_free(&m_spprocs);
DBUG_VOID_RETURN;
+}
+
+
+Field *
+sp_head::make_field(uint max_length, const char *name, TABLE *dummy)
+{
+ Field *field;
+ DBUG_ENTER("sp_head::make_field");
+ field= ::make_field((char *)0,
+ !m_returns_len ? max_length : m_returns_len,
+ (uchar *)"", 0, m_returns_pack, m_returns, m_returns_cs,
+ (enum Field::geometry_type)0, Field::NONE,
+ m_returns_typelib,
+ name ? name : (const char *)m_name.str, dummy);
+ DBUG_RETURN(field);
}
int
--- 1.51/sql/sp_head.h 2005-03-04 13:34:53 +00:00
+++ 1.52/sql/sp_head.h 2005-03-08 18:53:00 +00:00
@@ -84,6 +84,9 @@
int m_type; // TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
enum enum_field_types m_returns; // For FUNCTIONs only
CHARSET_INFO *m_returns_cs; // For FUNCTIONs only
+ TYPELIB *m_returns_typelib; // For FUNCTIONs only
+ uint m_returns_len; // For FUNCTIONs only
+ uint m_returns_pack; // For FUNCTIONs only
my_bool m_has_return; // For FUNCTIONs only
my_bool m_simple_case; // TRUE if parsing simple case, FALSE otherwise
my_bool m_multi_results; // TRUE if a procedure with SELECT(s)
@@ -96,7 +99,6 @@
LEX_STRING m_db;
LEX_STRING m_name;
LEX_STRING m_params;
- LEX_STRING m_retstr; // For FUNCTIONs only
LEX_STRING m_body;
LEX_STRING m_defstr;
LEX_STRING m_definer_user;
@@ -112,8 +114,7 @@
*/
HASH m_spfuns, m_spprocs;
// Pointers set during parsing
- uchar *m_param_begin, *m_param_end, *m_returns_begin, *m_returns_end,
- *m_body_begin;
+ uchar *m_param_begin, *m_param_end, *m_body_begin;
static void *
operator new(size_t size);
@@ -131,6 +132,9 @@
void
init_strings(THD *thd, LEX *lex, sp_name *name);
+ TYPELIB *
+ create_typelib(List<String> *src);
+
int
create(THD *thd);
@@ -204,10 +208,7 @@
char *create_string(THD *thd, ulong *lenp);
- inline Item_result result()
- {
- return sp_map_result_type(m_returns);
- }
+ Field *make_field(uint max_length, const char *name, TABLE *dummy);
void set_info(char *definer, uint definerlen,
longlong created, longlong modified,
| Thread |
|---|
| • bk commit into 5.0 tree (acurtis:1.1817) BUG#3788 | antony | 9 Mar |