Merge changes
client/mysqlcheck.c: Auto merged myisam/ft_boolean_search.c: Auto merged myisam/ft_static.c: Auto merged mysql-test/r/func_group.result: Auto merged mysql-test/r/union.result: Auto merged mysql-test/t/func_group.test: Auto merged mysql-test/t/multi_update.test: Auto merged mysql-test/t/union.test: Auto merged scripts/make_binary_distribution.sh: Auto merged sql/ha_myisam.h: Auto merged sql/handler.h: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_func.cc: Auto merged sql/sql_union.cc: Auto merged sql/field.cc: Clean up merge
This commit is contained in:
commit
1be345edc0
@ -195,7 +195,7 @@ static void usage(void)
|
||||
puts("and you are welcome to modify and redistribute it under the GPL license.\n");
|
||||
puts("This program can be used to CHECK (-c,-m,-C), REPAIR (-r), ANALYZE (-a)");
|
||||
puts("or OPTIMIZE (-o) tables. Some of the options (like -e or -q) can be");
|
||||
puts("used at the same time. It works on MyISAM and in some cases on BDB tables.");
|
||||
puts("used at the same time. Not all options are supported by all storage engines.");
|
||||
puts("Please consult the MySQL manual for latest information about the");
|
||||
puts("above. The options -c,-r,-a and -o are exclusive to each other, which");
|
||||
puts("means that the last option will be used, if several was specified.\n");
|
||||
|
@ -62,7 +62,7 @@ void ft_free_stopwords(void);
|
||||
#define FT_SORTED 2
|
||||
#define FT_EXPAND 4 /* query expansion */
|
||||
|
||||
FT_INFO *ft_init_search(uint,void *, uint, byte *, uint, byte *);
|
||||
FT_INFO *ft_init_search(uint,void *, uint, byte *, uint,CHARSET_INFO *, byte *);
|
||||
my_bool ft_boolean_check_syntax_string(const byte *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -366,6 +366,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
|
||||
reset_tree(& ftb->no_dupes);
|
||||
}
|
||||
|
||||
ftbw->off=0; /* in case of reinit */
|
||||
if (_ft2_search(ftb, ftbw, 1))
|
||||
return;
|
||||
}
|
||||
@ -374,7 +375,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
|
||||
|
||||
|
||||
FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
|
||||
uint query_len)
|
||||
uint query_len, CHARSET_INFO *cs)
|
||||
{
|
||||
FTB *ftb;
|
||||
FTB_EXPR *ftbe;
|
||||
@ -386,8 +387,8 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
|
||||
ftb->state=UNINITIALIZED;
|
||||
ftb->info=info;
|
||||
ftb->keynr=keynr;
|
||||
ftb->charset= ((keynr==NO_SUCH_KEY) ?
|
||||
default_charset_info : info->s->keyinfo[keynr].seg->charset);
|
||||
ftb->charset=cs;
|
||||
DBUG_ASSERT(keynr==NO_SUCH_KEY || cs == info->s->keyinfo[keynr].seg->charset);
|
||||
ftb->with_scan=0;
|
||||
ftb->lastpos=HA_OFFSET_ERROR;
|
||||
bzero(& ftb->no_dupes, sizeof(TREE));
|
||||
|
@ -57,11 +57,12 @@ const struct _ft_vft _ft_vft_boolean = {
|
||||
|
||||
|
||||
FT_INFO *ft_init_search(uint flags, void *info, uint keynr,
|
||||
byte *query, uint query_len, byte *record)
|
||||
byte *query, uint query_len, CHARSET_INFO *cs,
|
||||
byte *record)
|
||||
{
|
||||
FT_INFO *res;
|
||||
if (flags & FT_BOOL)
|
||||
res= ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len);
|
||||
res= ft_init_boolean_search((MI_INFO *)info, keynr, query, query_len,cs);
|
||||
else
|
||||
res= ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags,
|
||||
record);
|
||||
|
@ -131,7 +131,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, const byte *);
|
||||
uint _mi_ft_parse(TREE *, MI_INFO *, uint, const byte *, my_bool);
|
||||
|
||||
FT_INFO *ft_init_nlq_search(MI_INFO *, uint, byte *, uint, uint, byte *);
|
||||
FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint);
|
||||
FT_INFO *ft_init_boolean_search(MI_INFO *, uint, byte *, uint, CHARSET_INFO *);
|
||||
|
||||
extern const struct _ft_vft _ft_vft_nlq;
|
||||
int ft_nlq_read_next(FT_INFO *, char *);
|
||||
|
@ -737,3 +737,15 @@ one 2
|
||||
two 2
|
||||
three 1
|
||||
drop table t1;
|
||||
create table t1(f1 datetime);
|
||||
insert into t1 values (now());
|
||||
create table t2 select f2 from (select max(now()) f2 from t1) a;
|
||||
show columns from t2;
|
||||
Field Type Null Key Default Extra
|
||||
f2 datetime 0000-00-00 00:00:00
|
||||
drop table t2;
|
||||
create table t2 select f2 from (select now() f2 from t1) a;
|
||||
show columns from t2;
|
||||
Field Type Null Key Default Extra
|
||||
f2 datetime 0000-00-00 00:00:00
|
||||
drop table t2, t1;
|
||||
|
@ -633,3 +633,15 @@ No Field Count
|
||||
0 1 100
|
||||
0 2 100
|
||||
drop table t1, t2;
|
||||
CREATE TABLE t1 (
|
||||
ID int(11) NOT NULL auto_increment,
|
||||
NO int(11) NOT NULL default '0',
|
||||
SEQ int(11) NOT NULL default '0',
|
||||
PRIMARY KEY (ID),
|
||||
KEY t1$NO (SEQ,NO)
|
||||
) ENGINE=MyISAM;
|
||||
INSERT INTO t1 (SEQ, NO) SELECT "1" AS SEQ, IF(MAX(NO) IS NULL, 0, MAX(NO)) + 1 AS NO FROM t1 WHERE (SEQ = 1);
|
||||
select SQL_BUFFER_RESULT * from t1 WHERE (SEQ = 1);
|
||||
ID NO SEQ
|
||||
1 1 1
|
||||
drop table t1;
|
||||
|
@ -96,3 +96,11 @@ f2
|
||||
19781126
|
||||
19781126
|
||||
DROP TABLE t1, t2, t3;
|
||||
CREATE TABLE t1 (y YEAR);
|
||||
INSERT INTO t1 VALUES ('abc');
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'y' at row 1
|
||||
SELECT * FROM t1;
|
||||
y
|
||||
0000
|
||||
DROP TABLE t1;
|
||||
|
@ -1137,3 +1137,39 @@ t1 CREATE TABLE `t1` (
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
create table t1(a1 int, f1 char(10));
|
||||
create table t2
|
||||
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
|
||||
union
|
||||
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
|
||||
order by f2, a1;
|
||||
show columns from t2;
|
||||
Field Type Null Key Default Extra
|
||||
f2 date YES NULL
|
||||
a1 int(11) YES NULL
|
||||
drop table t1, t2;
|
||||
create table t1 (f1 int);
|
||||
create table t2 (f1 int, f2 int ,f3 date);
|
||||
create table t3 (f1 int, f2 char(10));
|
||||
create table t4
|
||||
(
|
||||
select t2.f3 as sdate
|
||||
from t1
|
||||
left outer join t2 on (t1.f1 = t2.f1)
|
||||
inner join t3 on (t2.f2 = t3.f1)
|
||||
order by t1.f1, t3.f1, t2.f3
|
||||
)
|
||||
union
|
||||
(
|
||||
select cast('2004-12-31' as date) as sdate
|
||||
from t1
|
||||
left outer join t2 on (t1.f1 = t2.f1)
|
||||
inner join t3 on (t2.f2 = t3.f1)
|
||||
group by t1.f1
|
||||
order by t1.f1, t3.f1, t2.f3
|
||||
)
|
||||
order by sdate;
|
||||
show columns from t4;
|
||||
Field Type Null Key Default Extra
|
||||
sdate date YES NULL
|
||||
drop table t1, t2, t3, t4;
|
||||
|
@ -473,3 +473,17 @@ INSERT INTO t1 VALUES
|
||||
|
||||
select val, count(*) from t1 group by val;
|
||||
drop table t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug 7833: Wrong datatype of aggregate column is returned
|
||||
#
|
||||
|
||||
create table t1(f1 datetime);
|
||||
insert into t1 values (now());
|
||||
create table t2 select f2 from (select max(now()) f2 from t1) a;
|
||||
show columns from t2;
|
||||
drop table t2;
|
||||
create table t2 select f2 from (select now() f2 from t1) a;
|
||||
show columns from t2;
|
||||
drop table t2, t1;
|
||||
|
@ -107,3 +107,10 @@ SELECT * FROM t2;
|
||||
SELECT * FROM t3;
|
||||
|
||||
DROP TABLE t1, t2, t3;
|
||||
|
||||
# Test that setting YEAR to invalid string results in default value, not
|
||||
# 2000. (Bug #6067)
|
||||
CREATE TABLE t1 (y YEAR);
|
||||
INSERT INTO t1 VALUES ('abc');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
@ -682,3 +682,38 @@ show create table t1;
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
||||
#
|
||||
# Bug 6931: Date Type column problem when using UNION-Table.
|
||||
#
|
||||
create table t1(a1 int, f1 char(10));
|
||||
create table t2
|
||||
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
|
||||
union
|
||||
select f2,a1 from (select a1, CAST('2004-12-31' AS DATE) f2 from t1) a
|
||||
order by f2, a1;
|
||||
show columns from t2;
|
||||
drop table t1, t2;
|
||||
|
||||
create table t1 (f1 int);
|
||||
create table t2 (f1 int, f2 int ,f3 date);
|
||||
create table t3 (f1 int, f2 char(10));
|
||||
create table t4
|
||||
(
|
||||
select t2.f3 as sdate
|
||||
from t1
|
||||
left outer join t2 on (t1.f1 = t2.f1)
|
||||
inner join t3 on (t2.f2 = t3.f1)
|
||||
order by t1.f1, t3.f1, t2.f3
|
||||
)
|
||||
union
|
||||
(
|
||||
select cast('2004-12-31' as date) as sdate
|
||||
from t1
|
||||
left outer join t2 on (t1.f1 = t2.f1)
|
||||
inner join t3 on (t2.f2 = t3.f1)
|
||||
group by t1.f1
|
||||
order by t1.f1, t3.f1, t2.f3
|
||||
)
|
||||
order by sdate;
|
||||
show columns from t4;
|
||||
drop table t1, t2, t3, t4;
|
||||
|
@ -221,7 +221,7 @@ $CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \
|
||||
mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \
|
||||
$BASE/mysql-test/std_data
|
||||
$CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi mysql-test/t/*.sh $BASE/mysql-test/t
|
||||
$CP mysql-test/r/*result mysql-test/r/*.require $BASE/mysql-test/r
|
||||
$CP mysql-test/r/*result mysql-test/r/*result.es mysql-test/r/*.require $BASE/mysql-test/r
|
||||
|
||||
if [ $BASE_SYSTEM != "netware" ] ; then
|
||||
chmod a+x $BASE/bin/*
|
||||
|
35
sql/field.cc
35
sql/field.cc
@ -261,6 +261,7 @@ static Field::field_cast_enum field_cast_date[]=
|
||||
Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP};
|
||||
static Field::field_cast_enum field_cast_newdate[]=
|
||||
{Field::FIELD_CAST_NEWDATE,
|
||||
Field::FIELD_CAST_DATE,
|
||||
Field::FIELD_CAST_DATETIME,
|
||||
Field::FIELD_CAST_STRING, Field::FIELD_CAST_VARSTRING,
|
||||
Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP};
|
||||
@ -6834,6 +6835,40 @@ Field *make_field(char *ptr, uint32 field_length,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if field_type is appropriate field type
|
||||
to create field for tmp table using
|
||||
item->tmp_table_field() method
|
||||
|
||||
SYNOPSIS
|
||||
field_types_to_be_kept()
|
||||
field_type - field type
|
||||
|
||||
NOTE
|
||||
it is used in function get_holder_example_field()
|
||||
from item.cc
|
||||
|
||||
RETURN
|
||||
1 - can use item->tmp_table_field() method
|
||||
0 - can not use item->tmp_table_field() method
|
||||
|
||||
*/
|
||||
|
||||
bool field_types_to_be_kept(enum_field_types field_type)
|
||||
{
|
||||
switch (field_type)
|
||||
{
|
||||
case FIELD_TYPE_DATE:
|
||||
case FIELD_TYPE_NEWDATE:
|
||||
case FIELD_TYPE_TIME:
|
||||
case FIELD_TYPE_DATETIME:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Create a field suitable for create of table */
|
||||
|
||||
create_field::create_field(Field *old_field,Field *orig_field)
|
||||
|
241
sql/field.h
241
sql/field.h
@ -37,7 +37,11 @@ class Field
|
||||
void operator=(Field &);
|
||||
public:
|
||||
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); }
|
||||
static void operator delete(void *ptr_arg, size_t size) { TRASH(ptr_arg, size); }
|
||||
static void operator delete(void *ptr_arg, size_t size) {
|
||||
#ifdef SAFEMALLOC
|
||||
bfill(ptr_arg, size, 0x8F);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *ptr; // Position to field in record
|
||||
uchar *null_ptr; // Byte where null_bit is
|
||||
@ -47,7 +51,7 @@ public:
|
||||
*/
|
||||
struct st_table *table; // Pointer for table
|
||||
struct st_table *orig_table; // Pointer to original table
|
||||
const char **table_name, *field_name;
|
||||
const char *table_name,*field_name;
|
||||
LEX_STRING comment;
|
||||
ulong query_id; // For quick test of used fields
|
||||
/* Field is part of the following keys */
|
||||
@ -80,7 +84,7 @@ public:
|
||||
FIELD_CAST_TIMESTAMP, FIELD_CAST_YEAR, FIELD_CAST_DATE, FIELD_CAST_NEWDATE,
|
||||
FIELD_CAST_TIME, FIELD_CAST_DATETIME,
|
||||
FIELD_CAST_STRING, FIELD_CAST_VARSTRING, FIELD_CAST_BLOB,
|
||||
FIELD_CAST_GEOM, FIELD_CAST_ENUM, FIELD_CAST_SET, FIELD_CAST_BIT
|
||||
FIELD_CAST_GEOM, FIELD_CAST_ENUM, FIELD_CAST_SET
|
||||
};
|
||||
|
||||
utype unireg_check;
|
||||
@ -96,7 +100,7 @@ public:
|
||||
virtual int store(const char *to,uint length,CHARSET_INFO *cs)=0;
|
||||
virtual int store(double nr)=0;
|
||||
virtual int store(longlong nr)=0;
|
||||
virtual int store_time(TIME *ltime, timestamp_type t_type);
|
||||
virtual void store_time(TIME *ltime,timestamp_type t_type);
|
||||
virtual double val_real(void)=0;
|
||||
virtual longlong val_int(void)=0;
|
||||
inline String *val_str(String *str) { return val_str(str, str); }
|
||||
@ -113,22 +117,16 @@ public:
|
||||
This trickery is used to decrease a number of malloc calls.
|
||||
*/
|
||||
virtual String *val_str(String*,String *)=0;
|
||||
String *val_int_as_str(String *val_buffer, my_bool unsigned_flag);
|
||||
virtual Item_result result_type () const=0;
|
||||
virtual Item_result cmp_type () const { return result_type(); }
|
||||
bool eq(Field *field)
|
||||
{
|
||||
return (ptr == field->ptr && null_ptr == field->null_ptr &&
|
||||
null_bit == field->null_bit);
|
||||
}
|
||||
bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; }
|
||||
virtual bool eq_def(Field *field);
|
||||
virtual uint32 pack_length() const { return (uint32) field_length; }
|
||||
virtual uint32 pack_length_in_rec() const { return pack_length(); }
|
||||
virtual void reset(void) { bzero(ptr,pack_length()); }
|
||||
virtual void reset_fields() {}
|
||||
virtual void set_default()
|
||||
{
|
||||
my_ptrdiff_t offset = (my_ptrdiff_t) (table->s->default_values -
|
||||
my_ptrdiff_t offset = (my_ptrdiff_t) (table->default_values -
|
||||
table->record[0]);
|
||||
memcpy(ptr, ptr + offset, pack_length());
|
||||
if (null_ptr)
|
||||
@ -145,9 +143,10 @@ public:
|
||||
virtual int cmp(const char *,const char *)=0;
|
||||
virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L)
|
||||
{ return memcmp(a,b,pack_length()); }
|
||||
int cmp_offset(uint row_offset) { return cmp(ptr,ptr+row_offset); }
|
||||
int cmp_binary_offset(uint row_offset)
|
||||
{ return cmp_binary(ptr, ptr+row_offset); };
|
||||
virtual int cmp_offset(uint row_offset)
|
||||
{ return memcmp(ptr,ptr+row_offset,pack_length()); }
|
||||
virtual int cmp_binary_offset(uint row_offset)
|
||||
{ return memcmp(ptr,ptr+row_offset,pack_length()); }
|
||||
virtual int key_cmp(const byte *a,const byte *b)
|
||||
{ return cmp((char*) a,(char*) b); }
|
||||
virtual int key_cmp(const byte *str, uint length)
|
||||
@ -177,7 +176,7 @@ public:
|
||||
{ if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
|
||||
inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; }
|
||||
inline bool real_maybe_null(void) { return null_ptr != 0; }
|
||||
virtual void make_field(Send_field *);
|
||||
virtual void make_field(Send_field *)=0;
|
||||
virtual void sort_string(char *buff,uint length)=0;
|
||||
virtual bool optimize_range(uint idx, uint part);
|
||||
/*
|
||||
@ -189,11 +188,28 @@ public:
|
||||
*/
|
||||
virtual bool can_be_compared_as_longlong() const { return FALSE; }
|
||||
virtual void free() {}
|
||||
virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table);
|
||||
virtual Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
||||
char *new_ptr, uchar *new_null_ptr,
|
||||
uint new_null_bit);
|
||||
virtual void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
|
||||
Field *new_field(MEM_ROOT *root, struct st_table *new_table)
|
||||
{
|
||||
Field *tmp= (Field*) memdup_root(root,(char*) this,size_of());
|
||||
if (tmp)
|
||||
{
|
||||
if (tmp->table->maybe_null)
|
||||
tmp->flags&= ~NOT_NULL_FLAG;
|
||||
tmp->table= new_table;
|
||||
tmp->key_start.init(0);
|
||||
tmp->part_of_key.init(0);
|
||||
tmp->part_of_sortkey.init(0);
|
||||
tmp->unireg_check=Field::NONE;
|
||||
tmp->flags&= (NOT_NULL_FLAG | BLOB_FLAG | UNSIGNED_FLAG |
|
||||
ZEROFILL_FLAG | BINARY_FLAG | ENUM_FLAG | SET_FLAG);
|
||||
#ifdef PROBABLY_WRONG
|
||||
tmp->table_name= new_table->table_name;
|
||||
#endif
|
||||
tmp->reset_fields();
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
inline void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
|
||||
{
|
||||
ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
|
||||
}
|
||||
@ -208,10 +224,11 @@ public:
|
||||
{ memcpy(buff,ptr,length); }
|
||||
inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
|
||||
{ memcpy(ptr,buff,length); }
|
||||
virtual void get_key_image(char *buff, uint length, imagetype type)
|
||||
{ get_image(buff,length, &my_charset_bin); }
|
||||
virtual void set_key_image(char *buff,uint length)
|
||||
{ set_image(buff,length, &my_charset_bin); }
|
||||
virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs,
|
||||
imagetype type)
|
||||
{ get_image(buff,length,cs); }
|
||||
virtual void set_key_image(char *buff,uint length, CHARSET_INFO *cs)
|
||||
{ set_image(buff,length,cs); }
|
||||
inline longlong val_int_offset(uint row_offset)
|
||||
{
|
||||
ptr+=row_offset;
|
||||
@ -219,17 +236,6 @@ public:
|
||||
ptr-=row_offset;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline String *val_str(String *str, char *new_ptr)
|
||||
{
|
||||
char *old_ptr= ptr;
|
||||
ptr= new_ptr;
|
||||
val_str(str);
|
||||
ptr= old_ptr;
|
||||
return str;
|
||||
}
|
||||
bool quote_data(String *unquoted_string);
|
||||
bool needs_quotes(void);
|
||||
virtual bool send_binary(Protocol *protocol);
|
||||
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
|
||||
{
|
||||
@ -261,11 +267,9 @@ public:
|
||||
virtual uint max_packed_col_length(uint max_length)
|
||||
{ return max_length;}
|
||||
|
||||
virtual int pack_cmp(const char *a,const char *b, uint key_length_arg,
|
||||
my_bool insert_or_update)
|
||||
virtual int pack_cmp(const char *a,const char *b, uint key_length_arg)
|
||||
{ return cmp(a,b); }
|
||||
virtual int pack_cmp(const char *b, uint key_length_arg,
|
||||
my_bool insert_or_update)
|
||||
virtual int pack_cmp(const char *b, uint key_length_arg)
|
||||
{ return cmp(ptr,b); }
|
||||
uint offset(); // Should be inline ...
|
||||
void copy_from_tmp(int offset);
|
||||
@ -277,8 +281,6 @@ public:
|
||||
virtual void set_charset(CHARSET_INFO *charset) { }
|
||||
bool set_warning(const unsigned int level, const unsigned int code,
|
||||
int cuted_increment);
|
||||
bool check_int(const char *str, int length, const char *int_end,
|
||||
CHARSET_INFO *cs);
|
||||
void set_datetime_warning(const uint level, const uint code,
|
||||
const char *str, uint str_len,
|
||||
timestamp_type ts_type, int cuted_increment);
|
||||
@ -358,6 +360,7 @@ public:
|
||||
int store(double nr);
|
||||
int store(longlong nr)=0;
|
||||
int store(const char *to,uint length,CHARSET_INFO *cs)=0;
|
||||
void make_field(Send_field *);
|
||||
uint size_of() const { return sizeof(*this); }
|
||||
CHARSET_INFO *charset(void) const { return field_charset; }
|
||||
void set_charset(CHARSET_INFO *charset) { field_charset=charset; }
|
||||
@ -716,7 +719,7 @@ public:
|
||||
if ((*null_value= is_null()))
|
||||
return 0;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
if (table->s->db_low_byte_first)
|
||||
if (table->db_low_byte_first)
|
||||
return sint4korr(ptr);
|
||||
#endif
|
||||
long tmp;
|
||||
@ -800,7 +803,7 @@ public:
|
||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||
int store(double nr);
|
||||
int store(longlong nr);
|
||||
int store_time(TIME *ltime, timestamp_type type);
|
||||
void store_time(TIME *ltime,timestamp_type type);
|
||||
void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
|
||||
double val_real(void);
|
||||
longlong val_int(void);
|
||||
@ -833,7 +836,6 @@ public:
|
||||
enum_field_types type() const { return FIELD_TYPE_TIME;}
|
||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
|
||||
enum Item_result cmp_type () const { return INT_RESULT; }
|
||||
int store_time(TIME *ltime, timestamp_type type);
|
||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||
int store(double nr);
|
||||
int store(longlong nr);
|
||||
@ -874,7 +876,7 @@ public:
|
||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||
int store(double nr);
|
||||
int store(longlong nr);
|
||||
int store_time(TIME *ltime, timestamp_type type);
|
||||
void store_time(TIME *ltime,timestamp_type type);
|
||||
void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; }
|
||||
double val_real(void);
|
||||
longlong val_int(void);
|
||||
@ -907,11 +909,9 @@ public:
|
||||
|
||||
enum_field_types type() const
|
||||
{
|
||||
return ((orig_table &&
|
||||
orig_table->s->db_create_options & HA_OPTION_PACK_RECORD &&
|
||||
field_length >= 4) &&
|
||||
orig_table->s->frm_version < FRM_VER_TRUE_VARCHAR ?
|
||||
MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING);
|
||||
return ((table && table->db_create_options & HA_OPTION_PACK_RECORD &&
|
||||
field_length >= 4) ?
|
||||
FIELD_TYPE_VAR_STRING : FIELD_TYPE_STRING);
|
||||
}
|
||||
enum ha_base_keytype key_type() const
|
||||
{ return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
|
||||
@ -928,9 +928,8 @@ public:
|
||||
void sql_type(String &str) const;
|
||||
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
|
||||
const char *unpack(char* to, const char *from);
|
||||
int pack_cmp(const char *a,const char *b,uint key_length,
|
||||
my_bool insert_or_update);
|
||||
int pack_cmp(const char *b,uint key_length,my_bool insert_or_update);
|
||||
int pack_cmp(const char *a,const char *b,uint key_length);
|
||||
int pack_cmp(const char *b,uint key_length);
|
||||
uint packed_col_length(const char *to, uint length);
|
||||
uint max_packed_col_length(uint max_length);
|
||||
uint size_of() const { return sizeof(*this); }
|
||||
@ -938,43 +937,31 @@ public:
|
||||
bool has_charset(void) const
|
||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||
field_cast_enum field_cast_type() { return FIELD_CAST_STRING; }
|
||||
Field *new_field(MEM_ROOT *root, struct st_table *new_table);
|
||||
};
|
||||
|
||||
|
||||
class Field_varstring :public Field_str {
|
||||
public:
|
||||
/* Store number of bytes used to store length (1 or 2) */
|
||||
uint32 length_bytes;
|
||||
Field_varstring(char *ptr_arg,
|
||||
uint32 len_arg, uint length_bytes_arg,
|
||||
uchar *null_ptr_arg,
|
||||
Field_varstring(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
|
||||
uchar null_bit_arg,
|
||||
enum utype unireg_check_arg, const char *field_name_arg,
|
||||
struct st_table *table_arg, CHARSET_INFO *cs)
|
||||
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
|
||||
unireg_check_arg, field_name_arg, table_arg, cs),
|
||||
length_bytes(length_bytes_arg)
|
||||
{
|
||||
if (table)
|
||||
table->s->varchar_fields++;
|
||||
}
|
||||
unireg_check_arg, field_name_arg, table_arg, cs)
|
||||
{}
|
||||
Field_varstring(uint32 len_arg,bool maybe_null_arg,
|
||||
const char *field_name_arg,
|
||||
struct st_table *table_arg, CHARSET_INFO *cs)
|
||||
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
|
||||
NONE, field_name_arg, table_arg, cs),
|
||||
length_bytes(len_arg < 256 ? 1 :2)
|
||||
{
|
||||
if (table)
|
||||
table->s->varchar_fields++;
|
||||
}
|
||||
NONE, field_name_arg, table_arg, cs)
|
||||
{}
|
||||
|
||||
enum_field_types type() const { return MYSQL_TYPE_VARCHAR; }
|
||||
enum ha_base_keytype key_type() const;
|
||||
enum_field_types type() const { return FIELD_TYPE_VAR_STRING; }
|
||||
enum ha_base_keytype key_type() const
|
||||
{ return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
|
||||
bool zero_pack() const { return 0; }
|
||||
void reset(void) { bzero(ptr,field_length+length_bytes); }
|
||||
uint32 pack_length() const { return (uint32) field_length+length_bytes; }
|
||||
void reset(void) { bzero(ptr,field_length+2); }
|
||||
uint32 pack_length() const { return (uint32) field_length+2; }
|
||||
uint32 key_length() const { return (uint32) field_length; }
|
||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||
int store(longlong nr);
|
||||
@ -984,31 +971,21 @@ public:
|
||||
String *val_str(String*,String *);
|
||||
int cmp(const char *,const char*);
|
||||
void sort_string(char *buff,uint length);
|
||||
void get_key_image(char *buff,uint length, imagetype type);
|
||||
void set_key_image(char *buff,uint length);
|
||||
void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
|
||||
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
|
||||
void sql_type(String &str) const;
|
||||
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
|
||||
char *pack_key(char *to, const char *from, uint max_length);
|
||||
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
|
||||
const char *unpack(char* to, const char *from);
|
||||
const char *unpack_key(char* to, const char *from, uint max_length);
|
||||
int pack_cmp(const char *a, const char *b, uint key_length,
|
||||
my_bool insert_or_update);
|
||||
int pack_cmp(const char *b, uint key_length,my_bool insert_or_update);
|
||||
int cmp_binary(const char *a,const char *b, uint32 max_length=~0L);
|
||||
int key_cmp(const byte *,const byte*);
|
||||
int key_cmp(const byte *str, uint length);
|
||||
int pack_cmp(const char *a, const char *b, uint key_length);
|
||||
int pack_cmp(const char *b, uint key_length);
|
||||
uint packed_col_length(const char *to, uint length);
|
||||
uint max_packed_col_length(uint max_length);
|
||||
uint size_of() const { return sizeof(*this); }
|
||||
enum_field_types real_type() const { return MYSQL_TYPE_VARCHAR; }
|
||||
enum_field_types real_type() const { return FIELD_TYPE_VAR_STRING; }
|
||||
bool has_charset(void) const
|
||||
{ return charset() == &my_charset_bin ? FALSE : TRUE; }
|
||||
field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; }
|
||||
Field *new_field(MEM_ROOT *root, struct st_table *new_table);
|
||||
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
||||
char *new_ptr, uchar *new_null_ptr,
|
||||
uint new_null_bit);
|
||||
};
|
||||
|
||||
|
||||
@ -1031,7 +1008,7 @@ public:
|
||||
}
|
||||
enum_field_types type() const { return FIELD_TYPE_BLOB;}
|
||||
enum ha_base_keytype key_type() const
|
||||
{ return binary() ? HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2; }
|
||||
{ return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
|
||||
int store(const char *to,uint length,CHARSET_INFO *charset);
|
||||
int store(double nr);
|
||||
int store(longlong nr);
|
||||
@ -1040,13 +1017,15 @@ public:
|
||||
String *val_str(String*,String *);
|
||||
int cmp(const char *,const char*);
|
||||
int cmp(const char *a, uint32 a_length, const char *b, uint32 b_length);
|
||||
int cmp_offset(uint offset);
|
||||
int cmp_binary(const char *a,const char *b, uint32 max_length=~0L);
|
||||
int cmp_binary_offset(uint row_offset);
|
||||
int key_cmp(const byte *,const byte*);
|
||||
int key_cmp(const byte *str, uint length);
|
||||
uint32 key_length() const { return 0; }
|
||||
void sort_string(char *buff,uint length);
|
||||
uint32 pack_length() const
|
||||
{ return (uint32) (packlength+table->s->blob_ptr_size); }
|
||||
{ return (uint32) (packlength+table->blob_ptr_size); }
|
||||
inline uint32 max_data_length() const
|
||||
{
|
||||
return (uint32) (((ulonglong) 1 << (packlength*8)) -1);
|
||||
@ -1072,8 +1051,8 @@ public:
|
||||
store_length(length);
|
||||
memcpy_fixed(ptr+packlength,&data,sizeof(char*));
|
||||
}
|
||||
void get_key_image(char *buff,uint length, imagetype type);
|
||||
void set_key_image(char *buff,uint length);
|
||||
void get_key_image(char *buff,uint length, CHARSET_INFO *cs, imagetype type);
|
||||
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
|
||||
void sql_type(String &str) const;
|
||||
inline bool copy()
|
||||
{ char *tmp;
|
||||
@ -1087,13 +1066,12 @@ public:
|
||||
return 0;
|
||||
}
|
||||
char *pack(char *to, const char *from, uint max_length= ~(uint) 0);
|
||||
const char *unpack(char *to, const char *from);
|
||||
char *pack_key(char *to, const char *from, uint max_length);
|
||||
char *pack_key_from_key_image(char* to, const char *from, uint max_length);
|
||||
const char *unpack(char *to, const char *from);
|
||||
const char *unpack_key(char* to, const char *from, uint max_length);
|
||||
int pack_cmp(const char *a, const char *b, uint key_length,
|
||||
my_bool insert_or_update);
|
||||
int pack_cmp(const char *b, uint key_length,my_bool insert_or_update);
|
||||
int pack_cmp(const char *a, const char *b, uint key_length);
|
||||
int pack_cmp(const char *b, uint key_length);
|
||||
uint packed_col_length(const char *col_ptr, uint length);
|
||||
uint max_packed_col_length(uint max_length);
|
||||
void free() { value.free(); }
|
||||
@ -1106,7 +1084,6 @@ public:
|
||||
uint32 max_length();
|
||||
};
|
||||
|
||||
|
||||
#ifdef HAVE_SPATIAL
|
||||
class Field_geom :public Field_blob {
|
||||
public:
|
||||
@ -1124,19 +1101,19 @@ public:
|
||||
:Field_blob(len_arg, maybe_null_arg, field_name_arg,
|
||||
table_arg, &my_charset_bin)
|
||||
{ geom_type= geom_type_arg; }
|
||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY2; }
|
||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_VARBINARY; }
|
||||
enum_field_types type() const { return FIELD_TYPE_GEOMETRY; }
|
||||
void sql_type(String &str) const;
|
||||
int store(const char *to, uint length, CHARSET_INFO *charset);
|
||||
int store(double nr) { return 1; }
|
||||
int store(longlong nr) { return 1; }
|
||||
|
||||
void get_key_image(char *buff,uint length,imagetype type);
|
||||
void get_key_image(char *buff,uint length, CHARSET_INFO *cs,imagetype type);
|
||||
void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
|
||||
field_cast_enum field_cast_type() { return FIELD_CAST_GEOM; }
|
||||
};
|
||||
#endif /*HAVE_SPATIAL*/
|
||||
|
||||
|
||||
class Field_enum :public Field_str {
|
||||
protected:
|
||||
uint packlength;
|
||||
@ -1205,52 +1182,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class Field_bit :public Field {
|
||||
public:
|
||||
uchar *bit_ptr; // position in record where 'uneven' bits store
|
||||
uchar bit_ofs; // offset to 'uneven' high bits
|
||||
uint bit_len; // number of 'uneven' high bits
|
||||
Field_bit(char *ptr_arg, uint32 len_arg, uchar *null_ptr_arg,
|
||||
uchar null_bit_arg, uchar *bit_ptr_arg, uchar bit_ofs_arg,
|
||||
enum utype unireg_check_arg, const char *field_name_arg,
|
||||
struct st_table *table_arg);
|
||||
enum_field_types type() const { return FIELD_TYPE_BIT; }
|
||||
enum ha_base_keytype key_type() const { return HA_KEYTYPE_BIT; }
|
||||
uint32 key_length() const { return (uint32) field_length + (bit_len > 0); }
|
||||
uint32 max_length() { return (uint32) field_length + (bit_len > 0); }
|
||||
uint size_of() const { return sizeof(*this); }
|
||||
Item_result result_type () const { return INT_RESULT; }
|
||||
void reset(void) { bzero(ptr, field_length); }
|
||||
int store(const char *to, uint length, CHARSET_INFO *charset);
|
||||
int store(double nr);
|
||||
int store(longlong nr);
|
||||
double val_real(void);
|
||||
longlong val_int(void);
|
||||
String *val_str(String*, String *);
|
||||
int cmp(const char *a, const char *b)
|
||||
{ return cmp_binary(a, b); }
|
||||
int key_cmp(const byte *a, const byte *b)
|
||||
{ return cmp_binary((char *) a, (char *) b); }
|
||||
int key_cmp(const byte *str, uint length);
|
||||
int cmp_offset(uint row_offset);
|
||||
void get_key_image(char *buff, uint length, imagetype type);
|
||||
void set_key_image(char *buff, uint length)
|
||||
{ Field_bit::store(buff, length, &my_charset_bin); }
|
||||
void sort_string(char *buff, uint length)
|
||||
{ get_key_image(buff, length, itRAW); }
|
||||
uint32 pack_length() const
|
||||
{ return (uint32) field_length + (bit_len > 0); }
|
||||
uint32 pack_length_in_rec() const { return field_length; }
|
||||
void sql_type(String &str) const;
|
||||
field_cast_enum field_cast_type() { return FIELD_CAST_BIT; }
|
||||
char *pack(char *to, const char *from, uint max_length=~(uint) 0);
|
||||
const char *unpack(char* to, const char *from);
|
||||
Field *new_key_field(MEM_ROOT *root, struct st_table *new_table,
|
||||
char *new_ptr, uchar *new_null_ptr,
|
||||
uint new_null_bit);
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Create field class for CREATE TABLE
|
||||
*/
|
||||
@ -1263,8 +1194,8 @@ public:
|
||||
LEX_STRING comment; // Comment for field
|
||||
Item *def; // Default value
|
||||
enum enum_field_types sql_type;
|
||||
ulong length;
|
||||
uint decimals, flags, pack_length, key_length;
|
||||
uint32 length;
|
||||
uint decimals,flags,pack_length;
|
||||
Field::utype unireg_check;
|
||||
TYPELIB *interval; // Which interval to use
|
||||
List<String> interval_list;
|
||||
@ -1329,10 +1260,12 @@ Field *make_field(char *ptr, uint32 field_length,
|
||||
TYPELIB *interval, const char *field_name,
|
||||
struct st_table *table);
|
||||
uint pack_length_to_packflag(uint type);
|
||||
enum_field_types get_blob_type_from_length(ulong length);
|
||||
uint32 calc_pack_length(enum_field_types type,uint32 length);
|
||||
int set_field_to_null(Field *field);
|
||||
int set_field_to_null_with_conversions(Field *field, bool no_conversions);
|
||||
bool test_if_int(const char *str, int length, const char *int_end,
|
||||
CHARSET_INFO *cs);
|
||||
bool field_types_to_be_kept(enum_field_types field_type);
|
||||
|
||||
/*
|
||||
The following are for the interface with the .frm file
|
||||
@ -1351,7 +1284,6 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions);
|
||||
#define FIELDFLAG_LEFT_FULLSCREEN 8192
|
||||
#define FIELDFLAG_RIGHT_FULLSCREEN 16384
|
||||
#define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output
|
||||
#define FIELDFLAG_NO_DEFAULT 16384 /* sql */
|
||||
#define FIELDFLAG_SUM ((uint) 32768)// predit: +#fieldflag
|
||||
#define FIELDFLAG_MAYBE_NULL ((uint) 32768)// sql
|
||||
#define FIELDFLAG_PACK_SHIFT 3
|
||||
@ -1360,6 +1292,8 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions);
|
||||
#define FIELDFLAG_NUM_SCREEN_TYPE 0x7F01
|
||||
#define FIELDFLAG_ALFA_SCREEN_TYPE 0x7800
|
||||
|
||||
#define FIELD_SORT_REVERSE 16384
|
||||
|
||||
#define MTYP_TYPENR(type) (type & 127) /* Remove bits from type */
|
||||
|
||||
#define f_is_dec(x) ((x) & FIELDFLAG_DECIMAL)
|
||||
@ -1377,4 +1311,3 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions);
|
||||
#define f_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256))
|
||||
#define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT)
|
||||
#define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL)
|
||||
#define f_no_default(x) (x & FIELDFLAG_NO_DEFAULT)
|
||||
|
@ -88,8 +88,12 @@ class ha_myisam: public handler
|
||||
ft_handler->please->reinit_search(ft_handler);
|
||||
return 0;
|
||||
}
|
||||
FT_INFO *ft_init_ext(uint flags, uint inx,const byte *key, uint keylen)
|
||||
{ return ft_init_search(flags,file,inx,(byte*) key,keylen, table->record[0]); }
|
||||
FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
|
||||
{
|
||||
return ft_init_search(flags,file,inx,
|
||||
(byte *)key->ptr(), key->length(), key->charset(),
|
||||
table->record[0]);
|
||||
}
|
||||
int ft_read(byte *buf);
|
||||
int rnd_init(bool scan);
|
||||
int rnd_next(byte *buf);
|
||||
|
@ -455,8 +455,7 @@ public:
|
||||
int compare_key(key_range *range);
|
||||
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
|
||||
void ft_end() { ft_handler=NULL; }
|
||||
virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key,
|
||||
uint keylen)
|
||||
virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
|
||||
{ return NULL; }
|
||||
virtual int ft_read(byte *buf) { return HA_ERR_WRONG_COMMAND; }
|
||||
virtual int rnd_next(byte *buf)=0;
|
||||
|
65
sql/item.cc
65
sql/item.cc
@ -3633,7 +3633,53 @@ void Item_cache_row::bring_value()
|
||||
}
|
||||
|
||||
|
||||
Item_type_holder::Item_type_holder(THD *thd, Item *item)
|
||||
/*
|
||||
Returns field for temporary table dependind on item type
|
||||
|
||||
SYNOPSIS
|
||||
get_holder_example_field()
|
||||
thd - thread handler
|
||||
item - pointer to item
|
||||
table - empty table object
|
||||
|
||||
NOTE
|
||||
It is possible to return field for Item_func
|
||||
items only if field type of this item is
|
||||
date or time or datetime type.
|
||||
also see function field_types_to_be_kept() from
|
||||
field.cc
|
||||
|
||||
RETURN
|
||||
# - field
|
||||
0 - no field
|
||||
*/
|
||||
|
||||
Field *get_holder_example_field(THD *thd, Item *item, TABLE *table)
|
||||
{
|
||||
DBUG_ASSERT(table);
|
||||
|
||||
Item_func *tmp_item= 0;
|
||||
if (item->type() == Item::FIELD_ITEM)
|
||||
return (((Item_field*) item)->field);
|
||||
if (item->type() == Item::FUNC_ITEM)
|
||||
tmp_item= (Item_func *) item;
|
||||
else if (item->type() == Item::SUM_FUNC_ITEM)
|
||||
{
|
||||
Item_sum *item_sum= (Item_sum *) item;
|
||||
if (item_sum->keep_field_type())
|
||||
{
|
||||
if (item_sum->args[0]->type() == Item::FIELD_ITEM)
|
||||
return (((Item_field*) item_sum->args[0])->field);
|
||||
if (item_sum->args[0]->type() == Item::FUNC_ITEM)
|
||||
tmp_item= (Item_func *) item_sum->args[0];
|
||||
}
|
||||
}
|
||||
return (tmp_item && field_types_to_be_kept(tmp_item->field_type()) ?
|
||||
tmp_item->tmp_table_field(table) : 0);
|
||||
}
|
||||
|
||||
|
||||
Item_type_holder::Item_type_holder(THD *thd, Item *item, TABLE *table)
|
||||
:Item(thd, item), item_type(item->result_type()),
|
||||
orig_type(item_type)
|
||||
{
|
||||
@ -3643,10 +3689,7 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item)
|
||||
It is safe assign pointer on field, because it will be used just after
|
||||
all JOIN::prepare calls and before any SELECT execution
|
||||
*/
|
||||
if (item->type() == Item::FIELD_ITEM)
|
||||
field_example= ((Item_field*) item)->field;
|
||||
else
|
||||
field_example= 0;
|
||||
field_example= get_holder_example_field(thd, item, table);
|
||||
max_length= real_length(item);
|
||||
maybe_null= item->maybe_null;
|
||||
collation.set(item->collation);
|
||||
@ -3686,25 +3729,23 @@ inline bool is_attr_compatible(Item *from, Item *to)
|
||||
(to->maybe_null || !from->maybe_null) &&
|
||||
(to->result_type() != STRING_RESULT ||
|
||||
from->result_type() != STRING_RESULT ||
|
||||
my_charset_same(from->collation.collation,
|
||||
to->collation.collation)));
|
||||
(from->collation.collation == to->collation.collation)));
|
||||
}
|
||||
|
||||
|
||||
bool Item_type_holder::join_types(THD *thd, Item *item)
|
||||
bool Item_type_holder::join_types(THD *thd, Item *item, TABLE *table)
|
||||
{
|
||||
uint32 new_length= real_length(item);
|
||||
bool use_new_field= 0, use_expression_type= 0;
|
||||
Item_result new_result_type= type_convertor[item_type][item->result_type()];
|
||||
bool item_is_a_field= item->type() == Item::FIELD_ITEM;
|
||||
|
||||
Field *field= get_holder_example_field(thd, item, table);
|
||||
bool item_is_a_field= field;
|
||||
/*
|
||||
Check if both items point to fields: in this case we
|
||||
can adjust column types of result table in the union smartly.
|
||||
*/
|
||||
if (field_example && item_is_a_field)
|
||||
{
|
||||
Field *field= ((Item_field *)item)->field;
|
||||
/* Can 'field_example' field store data of the column? */
|
||||
if ((use_new_field=
|
||||
(!field->field_cast_compatible(field_example->field_cast_type()) ||
|
||||
@ -3745,7 +3786,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item)
|
||||
It is safe to assign a pointer to field here, because it will be used
|
||||
before any table is closed.
|
||||
*/
|
||||
field_example= ((Item_field*) item)->field;
|
||||
field_example= field;
|
||||
}
|
||||
|
||||
old_cs= collation.collation->name;
|
||||
|
@ -1579,14 +1579,14 @@ protected:
|
||||
Item_result orig_type;
|
||||
Field *field_example;
|
||||
public:
|
||||
Item_type_holder(THD*, Item*);
|
||||
Item_type_holder(THD*, Item*, TABLE *);
|
||||
|
||||
Item_result result_type () const { return item_type; }
|
||||
enum Type type() const { return TYPE_HOLDER; }
|
||||
double val_real();
|
||||
longlong val_int();
|
||||
String *val_str(String*);
|
||||
bool join_types(THD *thd, Item *);
|
||||
bool join_types(THD *thd, Item *, TABLE *);
|
||||
Field *example() { return field_example; }
|
||||
static uint32 real_length(Item *item);
|
||||
void cleanup()
|
||||
|
@ -3138,9 +3138,7 @@ void Item_func_match::init_search(bool no_order)
|
||||
|
||||
if (join_key && !no_order)
|
||||
flags|=FT_SORTED;
|
||||
ft_handler=table->file->ft_init_ext(flags, key,
|
||||
(byte*) ft_tmp->ptr(),
|
||||
ft_tmp->length());
|
||||
ft_handler=table->file->ft_init_ext(flags, key, ft_tmp);
|
||||
|
||||
if (join_key)
|
||||
table->file->ft_handler=ft_handler;
|
||||
@ -3182,12 +3180,12 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
|
||||
}
|
||||
/*
|
||||
Check that all columns come from the same table.
|
||||
We've already checked that columns in MATCH are fields so
|
||||
We've already checked that columns in MATCH are fields so
|
||||
PARAM_TABLE_BIT can only appear from AGAINST argument.
|
||||
*/
|
||||
if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables())
|
||||
key=NO_SUCH_KEY;
|
||||
|
||||
|
||||
if (key == NO_SUCH_KEY && !(flags & FT_BOOL))
|
||||
{
|
||||
my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
|
||||
|
@ -153,6 +153,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
SELECT_LEX *sl, *first_select;
|
||||
select_result *tmp_result;
|
||||
bool is_union;
|
||||
TABLE *empty_table= 0;
|
||||
DBUG_ENTER("st_select_lex_unit::prepare");
|
||||
|
||||
describe= test(additional_options & SELECT_DESCRIBE);
|
||||
@ -249,13 +250,21 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
goto err;
|
||||
if (sl == first_select)
|
||||
{
|
||||
/*
|
||||
We need to create an empty table object. It is used
|
||||
to create tmp_table fields in Item_type_holder.
|
||||
The main reason of this is that we can't create
|
||||
field object without table.
|
||||
*/
|
||||
DBUG_ASSERT(!empty_table);
|
||||
empty_table= (TABLE*) thd->calloc(sizeof(TABLE));
|
||||
types.empty();
|
||||
List_iterator_fast<Item> it(sl->item_list);
|
||||
Item *item_tmp;
|
||||
while ((item_tmp= it++))
|
||||
{
|
||||
/* Error's in 'new' will be detected after loop */
|
||||
types.push_back(new Item_type_holder(thd_arg, item_tmp));
|
||||
types.push_back(new Item_type_holder(thd_arg, item_tmp, empty_table));
|
||||
}
|
||||
|
||||
if (thd_arg->is_fatal_error)
|
||||
@ -274,7 +283,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
Item *type, *item_tmp;
|
||||
while ((type= tp++, item_tmp= it++))
|
||||
{
|
||||
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
|
||||
if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp,
|
||||
empty_table))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user