mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
Merge in fix Bug#3788
This commit is contained in:
commit
be3c863ba0
15 changed files with 469 additions and 216 deletions
|
@ -7,6 +7,7 @@ Greg@greg-laptop.
|
|||
Miguel@light.local
|
||||
Sinisa@sinisa.nasamreza.org
|
||||
WAX@sergbook.mysql.com
|
||||
acurtis@ltantony.rdg.cyberkinetica.homeunix.net
|
||||
acurtis@pcgem.rdg.cyberkinetica.com
|
||||
administrador@light.hegel.local
|
||||
ahlentz@co3064164-a.rochd1.qld.optusnet.com.au
|
||||
|
|
|
@ -203,7 +203,7 @@ select parameter_style, sql_data_access, dtd_identifier
|
|||
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
|
||||
|
|
|
@ -962,7 +962,7 @@ comment 'Characteristics procedure test'
|
|||
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 @@ no sql
|
|||
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 @@ bug2564_2 ANSI_QUOTES CREATE PROCEDURE "test"."bug2564_2"()
|
|||
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|
|
||||
|
@ -2095,6 +2095,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)|
|
||||
drop procedure if exists bug4726|
|
||||
|
|
|
@ -2546,6 +2546,35 @@ drop procedure bug4579_1|
|
|||
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
|
||||
|
|
|
@ -3521,7 +3521,7 @@ bool Item_ref::fix_fields(THD *thd, TABLE_LIST *tables, Item **reference)
|
|||
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();
|
||||
|
|
|
@ -4368,13 +4368,33 @@ longlong Item_func_row_count::val_int()
|
|||
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 @@ Item_func_sp::func_name() const
|
|||
}
|
||||
|
||||
|
||||
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 @@ Item_func_sp::execute(Item **itp)
|
|||
}
|
||||
|
||||
|
||||
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_func_sp::field_type() const
|
|||
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 @@ Item_func_sp::fix_length_and_dec()
|
|||
}
|
||||
else
|
||||
{
|
||||
switch (m_sp->result()) {
|
||||
switch (result_type()) {
|
||||
case STRING_RESULT:
|
||||
maybe_null= 1;
|
||||
max_length= MAX_BLOB_WIDTH;
|
||||
|
@ -4530,3 +4586,19 @@ longlong Item_func_found_rows::val_int()
|
|||
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -1252,8 +1252,13 @@ class Item_func_sp :public Item_func
|
|||
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:
|
||||
|
||||
|
@ -1268,6 +1273,10 @@ public:
|
|||
|
||||
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;
|
||||
|
||||
longlong val_int()
|
||||
|
|
|
@ -629,6 +629,10 @@ int mysql_derived_filling(THD *thd, LEX *lex, TABLE_LIST *t);
|
|||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum enum_field_types type,
|
|||
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);
|
||||
|
|
24
sql/sp.cc
24
sql/sp.cc
|
@ -334,6 +334,22 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
|
|||
}
|
||||
|
||||
|
||||
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 @@ db_create_routine(THD *thd, int type, sp_head *sp)
|
|||
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]->
|
||||
|
|
|
@ -305,11 +305,11 @@ sp_head::init(LEX *lex)
|
|||
*/
|
||||
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 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
|
|||
(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 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name)
|
|||
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)
|
||||
{
|
||||
|
@ -481,6 +467,21 @@ sp_head::destroy()
|
|||
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
|
||||
sp_head::execute(THD *thd)
|
||||
{
|
||||
|
|
|
@ -84,6 +84,9 @@ public:
|
|||
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 @@ public:
|
|||
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 @@ public:
|
|||
*/
|
||||
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 @@ public:
|
|||
void
|
||||
init_strings(THD *thd, LEX *lex, sp_name *name);
|
||||
|
||||
TYPELIB *
|
||||
create_typelib(List<String> *src);
|
||||
|
||||
int
|
||||
create(THD *thd);
|
||||
|
||||
|
@ -204,10 +208,7 @@ public:
|
|||
|
||||
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,
|
||||
|
|
|
@ -5207,9 +5207,6 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
{
|
||||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
{
|
||||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
{
|
||||
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 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
|
|||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
314
sql/sql_table.cc
314
sql/sql_table.cc
|
@ -431,6 +431,173 @@ void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
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
|
||||
|
||||
|
@ -690,142 +857,17 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||
{
|
||||
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 @@ TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
|
|||
((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);
|
||||
}
|
||||
/*
|
||||
|
|
|
@ -1372,19 +1372,37 @@ create_function_tail:
|
|||
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
|
||||
|
|
|
@ -695,6 +695,7 @@ static bool make_empty_rec(File file,enum db_type table_type,
|
|||
field->interval,
|
||||
field->field_name,
|
||||
&table);
|
||||
DBUG_ASSERT(regfield);
|
||||
|
||||
if (!(field->flags & NOT_NULL_FLAG))
|
||||
null_count++;
|
||||
|
|
Loading…
Reference in a new issue