Commit 1be345ed authored by unknown's avatar unknown

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
parents 74ad9e8f 2f911184
...@@ -195,7 +195,7 @@ static void usage(void) ...@@ -195,7 +195,7 @@ static void usage(void)
puts("and you are welcome to modify and redistribute it under the GPL license.\n"); 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("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("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("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("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"); puts("means that the last option will be used, if several was specified.\n");
......
...@@ -62,7 +62,7 @@ void ft_free_stopwords(void); ...@@ -62,7 +62,7 @@ void ft_free_stopwords(void);
#define FT_SORTED 2 #define FT_SORTED 2
#define FT_EXPAND 4 /* query expansion */ #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 *); my_bool ft_boolean_check_syntax_string(const byte *);
#ifdef __cplusplus #ifdef __cplusplus
......
...@@ -366,6 +366,7 @@ static void _ftb_init_index_search(FT_INFO *ftb) ...@@ -366,6 +366,7 @@ static void _ftb_init_index_search(FT_INFO *ftb)
reset_tree(& ftb->no_dupes); reset_tree(& ftb->no_dupes);
} }
ftbw->off=0; /* in case of reinit */
if (_ft2_search(ftb, ftbw, 1)) if (_ft2_search(ftb, ftbw, 1))
return; return;
} }
...@@ -374,7 +375,7 @@ static void _ftb_init_index_search(FT_INFO *ftb) ...@@ -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, 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 *ftb;
FTB_EXPR *ftbe; FTB_EXPR *ftbe;
...@@ -386,8 +387,8 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query, ...@@ -386,8 +387,8 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, byte *query,
ftb->state=UNINITIALIZED; ftb->state=UNINITIALIZED;
ftb->info=info; ftb->info=info;
ftb->keynr=keynr; ftb->keynr=keynr;
ftb->charset= ((keynr==NO_SUCH_KEY) ? ftb->charset=cs;
default_charset_info : info->s->keyinfo[keynr].seg->charset); DBUG_ASSERT(keynr==NO_SUCH_KEY || cs == info->s->keyinfo[keynr].seg->charset);
ftb->with_scan=0; ftb->with_scan=0;
ftb->lastpos=HA_OFFSET_ERROR; ftb->lastpos=HA_OFFSET_ERROR;
bzero(& ftb->no_dupes, sizeof(TREE)); bzero(& ftb->no_dupes, sizeof(TREE));
......
...@@ -57,11 +57,12 @@ const struct _ft_vft _ft_vft_boolean = { ...@@ -57,11 +57,12 @@ const struct _ft_vft _ft_vft_boolean = {
FT_INFO *ft_init_search(uint flags, void *info, uint keynr, 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; FT_INFO *res;
if (flags & FT_BOOL) 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 else
res= ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags, res= ft_init_nlq_search((MI_INFO *)info, keynr, query, query_len, flags,
record); record);
......
...@@ -131,7 +131,7 @@ FT_WORD * _mi_ft_parserecord(MI_INFO *, uint, const byte *); ...@@ -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); 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_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; extern const struct _ft_vft _ft_vft_nlq;
int ft_nlq_read_next(FT_INFO *, char *); int ft_nlq_read_next(FT_INFO *, char *);
......
...@@ -737,3 +737,15 @@ one 2 ...@@ -737,3 +737,15 @@ one 2
two 2 two 2
three 1 three 1
drop table t1; 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 ...@@ -633,3 +633,15 @@ No Field Count
0 1 100 0 1 100
0 2 100 0 2 100
drop table t1, t2; 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 ...@@ -96,3 +96,11 @@ f2
19781126 19781126
19781126 19781126
DROP TABLE t1, t2, t3; 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` ( ...@@ -1137,3 +1137,39 @@ t1 CREATE TABLE `t1` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1; drop table t1;
drop table t2; 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 ...@@ -473,3 +473,17 @@ INSERT INTO t1 VALUES
select val, count(*) from t1 group by val; select val, count(*) from t1 group by val;
drop table t1; 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; ...@@ -107,3 +107,10 @@ SELECT * FROM t2;
SELECT * FROM t3; SELECT * FROM t3;
DROP TABLE t1, t2, 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; ...@@ -682,3 +682,38 @@ show create table t1;
drop table t1; drop table t1;
drop table t2; 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 \ ...@@ -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 \ mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \
$BASE/mysql-test/std_data $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/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 if [ $BASE_SYSTEM != "netware" ] ; then
chmod a+x $BASE/bin/* chmod a+x $BASE/bin/*
......
...@@ -261,6 +261,7 @@ static Field::field_cast_enum field_cast_date[]= ...@@ -261,6 +261,7 @@ static Field::field_cast_enum field_cast_date[]=
Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP}; Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP};
static Field::field_cast_enum field_cast_newdate[]= static Field::field_cast_enum field_cast_newdate[]=
{Field::FIELD_CAST_NEWDATE, {Field::FIELD_CAST_NEWDATE,
Field::FIELD_CAST_DATE,
Field::FIELD_CAST_DATETIME, Field::FIELD_CAST_DATETIME,
Field::FIELD_CAST_STRING, Field::FIELD_CAST_VARSTRING, Field::FIELD_CAST_STRING, Field::FIELD_CAST_VARSTRING,
Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP}; Field::FIELD_CAST_BLOB, Field::FIELD_CAST_STOP};
...@@ -6834,6 +6835,40 @@ Field *make_field(char *ptr, uint32 field_length, ...@@ -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 a field suitable for create of table */
create_field::create_field(Field *old_field,Field *orig_field) create_field::create_field(Field *old_field,Field *orig_field)
......
...@@ -37,7 +37,11 @@ class Field ...@@ -37,7 +37,11 @@ class Field
void operator=(Field &); void operator=(Field &);
public: public:
static void *operator new(size_t size) {return (void*) sql_alloc((uint) size); } 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 char *ptr; // Position to field in record
uchar *null_ptr; // Byte where null_bit is uchar *null_ptr; // Byte where null_bit is
...@@ -47,7 +51,7 @@ class Field ...@@ -47,7 +51,7 @@ class Field
*/ */
struct st_table *table; // Pointer for table struct st_table *table; // Pointer for table
struct st_table *orig_table; // Pointer to original 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; LEX_STRING comment;
ulong query_id; // For quick test of used fields ulong query_id; // For quick test of used fields
/* Field is part of the following keys */ /* Field is part of the following keys */
...@@ -80,7 +84,7 @@ class Field ...@@ -80,7 +84,7 @@ class Field
FIELD_CAST_TIMESTAMP, FIELD_CAST_YEAR, FIELD_CAST_DATE, FIELD_CAST_NEWDATE, FIELD_CAST_TIMESTAMP, FIELD_CAST_YEAR, FIELD_CAST_DATE, FIELD_CAST_NEWDATE,
FIELD_CAST_TIME, FIELD_CAST_DATETIME, FIELD_CAST_TIME, FIELD_CAST_DATETIME,
FIELD_CAST_STRING, FIELD_CAST_VARSTRING, FIELD_CAST_BLOB, 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; utype unireg_check;
...@@ -96,7 +100,7 @@ class Field ...@@ -96,7 +100,7 @@ class Field
virtual int store(const char *to,uint length,CHARSET_INFO *cs)=0; virtual int store(const char *to,uint length,CHARSET_INFO *cs)=0;
virtual int store(double nr)=0; virtual int store(double nr)=0;
virtual int store(longlong 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 double val_real(void)=0;
virtual longlong val_int(void)=0; virtual longlong val_int(void)=0;
inline String *val_str(String *str) { return val_str(str, str); } inline String *val_str(String *str) { return val_str(str, str); }
...@@ -113,22 +117,16 @@ class Field ...@@ -113,22 +117,16 @@ class Field
This trickery is used to decrease a number of malloc calls. This trickery is used to decrease a number of malloc calls.
*/ */
virtual String *val_str(String*,String *)=0; 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 result_type () const=0;
virtual Item_result cmp_type () const { return result_type(); } virtual Item_result cmp_type () const { return result_type(); }
bool eq(Field *field) bool eq(Field *field) { return ptr == field->ptr && null_ptr == field->null_ptr; }
{
return (ptr == field->ptr && null_ptr == field->null_ptr &&
null_bit == field->null_bit);
}
virtual bool eq_def(Field *field); virtual bool eq_def(Field *field);
virtual uint32 pack_length() const { return (uint32) field_length; } 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(void) { bzero(ptr,pack_length()); }
virtual void reset_fields() {} virtual void reset_fields() {}
virtual void set_default() 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]); table->record[0]);
memcpy(ptr, ptr + offset, pack_length()); memcpy(ptr, ptr + offset, pack_length());
if (null_ptr) if (null_ptr)
...@@ -145,9 +143,10 @@ class Field ...@@ -145,9 +143,10 @@ class Field
virtual int cmp(const char *,const char *)=0; virtual int cmp(const char *,const char *)=0;
virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L) virtual int cmp_binary(const char *a,const char *b, uint32 max_length=~0L)
{ return memcmp(a,b,pack_length()); } { return memcmp(a,b,pack_length()); }
int cmp_offset(uint row_offset) { return cmp(ptr,ptr+row_offset); } virtual int cmp_offset(uint row_offset)
int cmp_binary_offset(uint row_offset) { return memcmp(ptr,ptr+row_offset,pack_length()); }
{ return cmp_binary(ptr, ptr+row_offset); }; 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) virtual int key_cmp(const byte *a,const byte *b)
{ return cmp((char*) a,(char*) b); } { return cmp((char*) a,(char*) b); }
virtual int key_cmp(const byte *str, uint length) virtual int key_cmp(const byte *str, uint length)
...@@ -177,7 +176,7 @@ class Field ...@@ -177,7 +176,7 @@ class Field
{ if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; } { if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; } inline bool maybe_null(void) { return null_ptr != 0 || table->maybe_null; }
inline bool real_maybe_null(void) { return null_ptr != 0; } 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 void sort_string(char *buff,uint length)=0;
virtual bool optimize_range(uint idx, uint part); virtual bool optimize_range(uint idx, uint part);
/* /*
...@@ -189,11 +188,28 @@ class Field ...@@ -189,11 +188,28 @@ class Field
*/ */
virtual bool can_be_compared_as_longlong() const { return FALSE; } virtual bool can_be_compared_as_longlong() const { return FALSE; }
virtual void free() {} virtual void free() {}
virtual Field *new_field(MEM_ROOT *root, struct st_table *new_table); 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, Field *tmp= (Field*) memdup_root(root,(char*) this,size_of());
uint new_null_bit); if (tmp)
virtual void move_field(char *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg) {
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; ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
} }
...@@ -208,10 +224,11 @@ class Field ...@@ -208,10 +224,11 @@ class Field
{ memcpy(buff,ptr,length); } { memcpy(buff,ptr,length); }
inline void set_image(char *buff,uint length, CHARSET_INFO *cs) inline void set_image(char *buff,uint length, CHARSET_INFO *cs)
{ memcpy(ptr,buff,length); } { memcpy(ptr,buff,length); }
virtual void get_key_image(char *buff, uint length, imagetype type) virtual void get_key_image(char *buff,uint length, CHARSET_INFO *cs,
{ get_image(buff,length, &my_charset_bin); } imagetype type)
virtual void set_key_image(char *buff,uint length) { get_image(buff,length,cs); }
{ set_image(buff,length, &my_charset_bin); } 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) inline longlong val_int_offset(uint row_offset)
{ {
ptr+=row_offset; ptr+=row_offset;
...@@ -219,17 +236,6 @@ class Field ...@@ -219,17 +236,6 @@ class Field
ptr-=row_offset; ptr-=row_offset;
return tmp; 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 bool send_binary(Protocol *protocol);
virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0) virtual char *pack(char* to, const char *from, uint max_length=~(uint) 0)
{ {
...@@ -261,11 +267,9 @@ class Field ...@@ -261,11 +267,9 @@ class Field
virtual uint max_packed_col_length(uint max_length) virtual uint max_packed_col_length(uint max_length)
{ return max_length;} { return max_length;}
virtual int pack_cmp(const char *a,const char *b, uint key_length_arg, virtual int pack_cmp(const char *a,const char *b, uint key_length_arg)
my_bool insert_or_update)
{ return cmp(a,b); } { return cmp(a,b); }
virtual int pack_cmp(const char *b, uint key_length_arg, virtual int pack_cmp(const char *b, uint key_length_arg)
my_bool insert_or_update)
{ return cmp(ptr,b); } { return cmp(ptr,b); }
uint offset(); // Should be inline ... uint offset(); // Should be inline ...
void copy_from_tmp(int offset); void copy_from_tmp(int offset);
...@@ -277,8 +281,6 @@ class Field ...@@ -277,8 +281,6 @@ class Field
virtual void set_charset(CHARSET_INFO *charset) { } virtual void set_charset(CHARSET_INFO *charset) { }
bool set_warning(const unsigned int level, const unsigned int code, bool set_warning(const unsigned int level, const unsigned int code,
int cuted_increment); 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, void set_datetime_warning(const uint level, const uint code,
const char *str, uint str_len, const char *str, uint str_len,
timestamp_type ts_type, int cuted_increment); timestamp_type ts_type, int cuted_increment);
...@@ -358,6 +360,7 @@ class Field_str :public Field { ...@@ -358,6 +360,7 @@ class Field_str :public Field {
int store(double nr); int store(double nr);
int store(longlong nr)=0; int store(longlong nr)=0;
int store(const char *to,uint length,CHARSET_INFO *cs)=0; int store(const char *to,uint length,CHARSET_INFO *cs)=0;
void make_field(Send_field *);
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
CHARSET_INFO *charset(void) const { return field_charset; } CHARSET_INFO *charset(void) const { return field_charset; }
void set_charset(CHARSET_INFO *charset) { field_charset=charset; } void set_charset(CHARSET_INFO *charset) { field_charset=charset; }
...@@ -716,7 +719,7 @@ class Field_timestamp :public Field_str { ...@@ -716,7 +719,7 @@ class Field_timestamp :public Field_str {
if ((*null_value= is_null())) if ((*null_value= is_null()))
return 0; return 0;
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
if (table->s->db_low_byte_first) if (table->db_low_byte_first)
return sint4korr(ptr); return sint4korr(ptr);
#endif #endif
long tmp; long tmp;
...@@ -800,7 +803,7 @@ class Field_newdate :public Field_str { ...@@ -800,7 +803,7 @@ class Field_newdate :public Field_str {
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);
int store(longlong 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; } void reset(void) { ptr[0]=ptr[1]=ptr[2]=0; }
double val_real(void); double val_real(void);
longlong val_int(void); longlong val_int(void);
...@@ -833,7 +836,6 @@ class Field_time :public Field_str { ...@@ -833,7 +836,6 @@ class Field_time :public Field_str {
enum_field_types type() const { return FIELD_TYPE_TIME;} enum_field_types type() const { return FIELD_TYPE_TIME;}
enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; } enum ha_base_keytype key_type() const { return HA_KEYTYPE_INT24; }
enum Item_result cmp_type () const { return INT_RESULT; } 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(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);
int store(longlong nr); int store(longlong nr);
...@@ -874,7 +876,7 @@ class Field_datetime :public Field_str { ...@@ -874,7 +876,7 @@ class Field_datetime :public Field_str {
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);
int store(longlong 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; } void reset(void) { ptr[0]=ptr[1]=ptr[2]=ptr[3]=ptr[4]=ptr[5]=ptr[6]=ptr[7]=0; }
double val_real(void); double val_real(void);
longlong val_int(void); longlong val_int(void);
...@@ -907,11 +909,9 @@ class Field_string :public Field_str { ...@@ -907,11 +909,9 @@ class Field_string :public Field_str {
enum_field_types type() const enum_field_types type() const
{ {
return ((orig_table && return ((table && table->db_create_options & HA_OPTION_PACK_RECORD &&
orig_table->s->db_create_options & HA_OPTION_PACK_RECORD && field_length >= 4) ?
field_length >= 4) && FIELD_TYPE_VAR_STRING : FIELD_TYPE_STRING);
orig_table->s->frm_version < FRM_VER_TRUE_VARCHAR ?
MYSQL_TYPE_VAR_STRING : MYSQL_TYPE_STRING);
} }
enum ha_base_keytype key_type() const enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; } { return binary() ? HA_KEYTYPE_BINARY : HA_KEYTYPE_TEXT; }
...@@ -928,9 +928,8 @@ class Field_string :public Field_str { ...@@ -928,9 +928,8 @@ class Field_string :public Field_str {
void sql_type(String &str) const; void sql_type(String &str) const;
char *pack(char *to, const char *from, uint max_length=~(uint) 0); char *pack(char *to, const char *from, uint max_length=~(uint) 0);
const char *unpack(char* to, const char *from); const char *unpack(char* to, const char *from);
int pack_cmp(const char *a,const char *b,uint key_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);
int pack_cmp(const char *b,uint key_length,my_bool insert_or_update);
uint packed_col_length(const char *to, uint length); uint packed_col_length(const char *to, uint length);
uint max_packed_col_length(uint max_length); uint max_packed_col_length(uint max_length);
uint size_of() const { return sizeof(*this); } uint size_of() const { return sizeof(*this); }
...@@ -938,43 +937,31 @@ class Field_string :public Field_str { ...@@ -938,43 +937,31 @@ class Field_string :public Field_str {
bool has_charset(void) const bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; } { return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_STRING; } 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 { class Field_varstring :public Field_str {
public: public:
/* Store number of bytes used to store length (1 or 2) */ Field_varstring(char *ptr_arg, uint32 len_arg,uchar *null_ptr_arg,
uint32 length_bytes;
Field_varstring(char *ptr_arg,
uint32 len_arg, uint length_bytes_arg,
uchar *null_ptr_arg,
uchar null_bit_arg, uchar null_bit_arg,
enum utype unireg_check_arg, const char *field_name_arg, enum utype unireg_check_arg, const char *field_name_arg,
struct st_table *table_arg, CHARSET_INFO *cs) struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg, :Field_str(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
unireg_check_arg, field_name_arg, table_arg, cs), unireg_check_arg, field_name_arg, table_arg, cs)
length_bytes(length_bytes_arg) {}
{
if (table)
table->s->varchar_fields++;
}
Field_varstring(uint32 len_arg,bool maybe_null_arg, Field_varstring(uint32 len_arg,bool maybe_null_arg,
const char *field_name_arg, const char *field_name_arg,
struct st_table *table_arg, CHARSET_INFO *cs) struct st_table *table_arg, CHARSET_INFO *cs)
:Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0, :Field_str((char*) 0,len_arg, maybe_null_arg ? (uchar*) "": 0,0,
NONE, field_name_arg, table_arg, cs), NONE, field_name_arg, table_arg, cs)
length_bytes(len_arg < 256 ? 1 :2) {}
{
if (table)
table->s->varchar_fields++;
}
enum_field_types type() const { return MYSQL_TYPE_VARCHAR; } enum_field_types type() const { return FIELD_TYPE_VAR_STRING; }
enum ha_base_keytype key_type() const; enum ha_base_keytype key_type() const
{ return binary() ? HA_KEYTYPE_VARBINARY : HA_KEYTYPE_VARTEXT; }
bool zero_pack() const { return 0; } bool zero_pack() const { return 0; }
void reset(void) { bzero(ptr,field_length+length_bytes); } void reset(void) { bzero(ptr,field_length+2); }
uint32 pack_length() const { return (uint32) field_length+length_bytes; } uint32 pack_length() const { return (uint32) field_length+2; }
uint32 key_length() const { return (uint32) field_length; } uint32 key_length() const { return (uint32) field_length; }
int store(const char *to,uint length,CHARSET_INFO *charset); int store(const char *to,uint length,CHARSET_INFO *charset);
int store(longlong nr); int store(longlong nr);
...@@ -984,31 +971,21 @@ class Field_varstring :public Field_str { ...@@ -984,31 +971,21 @@ class Field_varstring :public Field_str {
String *val_str(String*,String *); String *val_str(String*,String *);
int cmp(const char *,const char*); int cmp(const char *,const char*);
void sort_string(char *buff,uint length); void sort_string(char *buff,uint length);
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); void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
void sql_type(String &str) const; void sql_type(String &str) const;
char *pack(char *to, const char *from, uint max_length=~(uint) 0); 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(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(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);
int pack_cmp(const char *a, const char *b, uint key_length, int pack_cmp(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);
uint packed_col_length(const char *to, uint length); uint packed_col_length(const char *to, uint length);
uint max_packed_col_length(uint max_length); uint max_packed_col_length(uint max_length);
uint size_of() const { return sizeof(*this); } 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 bool has_charset(void) const
{ return charset() == &my_charset_bin ? FALSE : TRUE; } { return charset() == &my_charset_bin ? FALSE : TRUE; }
field_cast_enum field_cast_type() { return FIELD_CAST_VARSTRING; } 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 @@ class Field_blob :public Field_str { ...@@ -1031,7 +1008,7 @@ class Field_blob :public Field_str {
} }
enum_field_types type() const { return FIELD_TYPE_BLOB;} enum_field_types type() const { return FIELD_TYPE_BLOB;}
enum ha_base_keytype key_type() const 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(const char *to,uint length,CHARSET_INFO *charset);
int store(double nr); int store(double nr);
int store(longlong nr); int store(longlong nr);
...@@ -1040,13 +1017,15 @@ class Field_blob :public Field_str { ...@@ -1040,13 +1017,15 @@ class Field_blob :public Field_str {
String *val_str(String*,String *); String *val_str(String*,String *);
int cmp(const char *,const char*); int cmp(const char *,const char*);
int cmp(const char *a, uint32 a_length, const char *b, uint32 b_length); 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(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 *,const byte*);
int key_cmp(const byte *str, uint length); int key_cmp(const byte *str, uint length);
uint32 key_length() const { return 0; } uint32 key_length() const { return 0; }
void sort_string(char *buff,uint length); void sort_string(char *buff,uint length);
uint32 pack_length() const 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 inline uint32 max_data_length() const
{ {
return (uint32) (((ulonglong) 1 << (packlength*8)) -1); return (uint32) (((ulonglong) 1 << (packlength*8)) -1);
...@@ -1072,8 +1051,8 @@ class Field_blob :public Field_str { ...@@ -1072,8 +1051,8 @@ class Field_blob :public Field_str {
store_length(length); store_length(length);
memcpy_fixed(ptr+packlength,&data,sizeof(char*)); memcpy_fixed(ptr+packlength,&data,sizeof(char*));
} }
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); void set_key_image(char *buff,uint length, CHARSET_INFO *cs);
void sql_type(String &str) const; void sql_type(String &str) const;
inline bool copy() inline bool copy()
{ char *tmp; { char *tmp;
...@@ -1087,13 +1066,12 @@ class Field_blob :public Field_str { ...@@ -1087,13 +1066,12 @@ class Field_blob :public Field_str {
return 0; return 0;
} }
char *pack(char *to, const char *from, uint max_length= ~(uint) 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(char *to, const char *from, uint max_length);
char *pack_key_from_key_image(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); const char *unpack_key(char* to, const char *from, uint max_length);
int pack_cmp(const char *a, const char *b, uint key_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);
int pack_cmp(const char *b, uint key_length,my_bool insert_or_update);
uint packed_col_length(const char *col_ptr, uint length); uint packed_col_length(const char *col_ptr, uint length);
uint max_packed_col_length(uint max_length); uint max_packed_col_length(uint max_length);
void free() { value.free(); } void free() { value.free(); }
...@@ -1106,7 +1084,6 @@ class Field_blob :public Field_str { ...@@ -1106,7 +1084,6 @@ class Field_blob :public Field_str {
uint32 max_length(); uint32 max_length();
}; };
#ifdef HAVE_SPATIAL #ifdef HAVE_SPATIAL
class Field_geom :public Field_blob { class Field_geom :public Field_blob {
public: public:
...@@ -1124,19 +1101,19 @@ class Field_geom :public Field_blob { ...@@ -1124,19 +1101,19 @@ class Field_geom :public Field_blob {
:Field_blob(len_arg, maybe_null_arg, field_name_arg, :Field_blob(len_arg, maybe_null_arg, field_name_arg,
table_arg, &my_charset_bin) table_arg, &my_charset_bin)
{ geom_type= geom_type_arg; } { 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; } enum_field_types type() const { return FIELD_TYPE_GEOMETRY; }
void sql_type(String &str) const; void sql_type(String &str) const;
int store(const char *to, uint length, CHARSET_INFO *charset); int store(const char *to, uint length, CHARSET_INFO *charset);
int store(double nr) { return 1; } int store(double nr) { return 1; }
int store(longlong 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; } field_cast_enum field_cast_type() { return FIELD_CAST_GEOM; }
}; };
#endif /*HAVE_SPATIAL*/ #endif /*HAVE_SPATIAL*/
class Field_enum :public Field_str { class Field_enum :public Field_str {
protected: protected:
uint packlength; uint packlength;
...@@ -1205,52 +1182,6 @@ class Field_set :public Field_enum { ...@@ -1205,52 +1182,6 @@ class Field_set :public Field_enum {
}; };
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 Create field class for CREATE TABLE
*/ */
...@@ -1263,8 +1194,8 @@ class create_field :public Sql_alloc { ...@@ -1263,8 +1194,8 @@ class create_field :public Sql_alloc {
LEX_STRING comment; // Comment for field LEX_STRING comment; // Comment for field
Item *def; // Default value Item *def; // Default value
enum enum_field_types sql_type; enum enum_field_types sql_type;
ulong length; uint32 length;
uint decimals, flags, pack_length, key_length; uint decimals,flags,pack_length;
Field::utype unireg_check; Field::utype unireg_check;
TYPELIB *interval; // Which interval to use TYPELIB *interval; // Which interval to use
List<String> interval_list; List<String> interval_list;
...@@ -1329,10 +1260,12 @@ Field *make_field(char *ptr, uint32 field_length, ...@@ -1329,10 +1260,12 @@ Field *make_field(char *ptr, uint32 field_length,
TYPELIB *interval, const char *field_name, TYPELIB *interval, const char *field_name,
struct st_table *table); struct st_table *table);
uint pack_length_to_packflag(uint type); 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); uint32 calc_pack_length(enum_field_types type,uint32 length);
int set_field_to_null(Field *field); int set_field_to_null(Field *field);
int set_field_to_null_with_conversions(Field *field, bool no_conversions); 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 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); ...@@ -1351,7 +1284,6 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions);
#define FIELDFLAG_LEFT_FULLSCREEN 8192 #define FIELDFLAG_LEFT_FULLSCREEN 8192
#define FIELDFLAG_RIGHT_FULLSCREEN 16384 #define FIELDFLAG_RIGHT_FULLSCREEN 16384
#define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output #define FIELDFLAG_FORMAT_NUMBER 16384 // predit: ###,,## in output
#define FIELDFLAG_NO_DEFAULT 16384 /* sql */
#define FIELDFLAG_SUM ((uint) 32768)// predit: +#fieldflag #define FIELDFLAG_SUM ((uint) 32768)// predit: +#fieldflag
#define FIELDFLAG_MAYBE_NULL ((uint) 32768)// sql #define FIELDFLAG_MAYBE_NULL ((uint) 32768)// sql
#define FIELDFLAG_PACK_SHIFT 3 #define FIELDFLAG_PACK_SHIFT 3
...@@ -1360,6 +1292,8 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); ...@@ -1360,6 +1292,8 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions);
#define FIELDFLAG_NUM_SCREEN_TYPE 0x7F01 #define FIELDFLAG_NUM_SCREEN_TYPE 0x7F01
#define FIELDFLAG_ALFA_SCREEN_TYPE 0x7800 #define FIELDFLAG_ALFA_SCREEN_TYPE 0x7800
#define FIELD_SORT_REVERSE 16384
#define MTYP_TYPENR(type) (type & 127) /* Remove bits from type */ #define MTYP_TYPENR(type) (type & 127) /* Remove bits from type */
#define f_is_dec(x) ((x) & FIELDFLAG_DECIMAL) #define f_is_dec(x) ((x) & FIELDFLAG_DECIMAL)
...@@ -1377,4 +1311,3 @@ int set_field_to_null_with_conversions(Field *field, bool no_conversions); ...@@ -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_is_equ(x) ((x) & (1+2+FIELDFLAG_PACK+31*256))
#define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT) #define f_settype(x) (((int) x) << FIELDFLAG_PACK_SHIFT)
#define f_maybe_null(x) (x & FIELDFLAG_MAYBE_NULL) #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 ...@@ -88,8 +88,12 @@ class ha_myisam: public handler
ft_handler->please->reinit_search(ft_handler); ft_handler->please->reinit_search(ft_handler);
return 0; return 0;
} }
FT_INFO *ft_init_ext(uint flags, uint inx,const byte *key, uint keylen) FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
{ return ft_init_search(flags,file,inx,(byte*) key,keylen, table->record[0]); } {
return ft_init_search(flags,file,inx,
(byte *)key->ptr(), key->length(), key->charset(),
table->record[0]);
}
int ft_read(byte *buf); int ft_read(byte *buf);
int rnd_init(bool scan); int rnd_init(bool scan);
int rnd_next(byte *buf); int rnd_next(byte *buf);
......
...@@ -455,8 +455,7 @@ class handler :public Sql_alloc ...@@ -455,8 +455,7 @@ class handler :public Sql_alloc
int compare_key(key_range *range); int compare_key(key_range *range);
virtual int ft_init() { return HA_ERR_WRONG_COMMAND; } virtual int ft_init() { return HA_ERR_WRONG_COMMAND; }
void ft_end() { ft_handler=NULL; } void ft_end() { ft_handler=NULL; }
virtual FT_INFO *ft_init_ext(uint flags,uint inx,const byte *key, virtual FT_INFO *ft_init_ext(uint flags, uint inx,String *key)
uint keylen)
{ return NULL; } { return NULL; }
virtual int ft_read(byte *buf) { return HA_ERR_WRONG_COMMAND; } virtual int ft_read(byte *buf) { return HA_ERR_WRONG_COMMAND; }
virtual int rnd_next(byte *buf)=0; virtual int rnd_next(byte *buf)=0;
......
...@@ -3633,7 +3633,53 @@ void Item_cache_row::bring_value() ...@@ -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()), :Item(thd, item), item_type(item->result_type()),
orig_type(item_type) orig_type(item_type)
{ {
...@@ -3643,10 +3689,7 @@ Item_type_holder::Item_type_holder(THD *thd, Item *item) ...@@ -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 It is safe assign pointer on field, because it will be used just after
all JOIN::prepare calls and before any SELECT execution all JOIN::prepare calls and before any SELECT execution
*/ */
if (item->type() == Item::FIELD_ITEM) field_example= get_holder_example_field(thd, item, table);
field_example= ((Item_field*) item)->field;
else
field_example= 0;
max_length= real_length(item); max_length= real_length(item);
maybe_null= item->maybe_null; maybe_null= item->maybe_null;
collation.set(item->collation); collation.set(item->collation);
...@@ -3686,25 +3729,23 @@ inline bool is_attr_compatible(Item *from, Item *to) ...@@ -3686,25 +3729,23 @@ inline bool is_attr_compatible(Item *from, Item *to)
(to->maybe_null || !from->maybe_null) && (to->maybe_null || !from->maybe_null) &&
(to->result_type() != STRING_RESULT || (to->result_type() != STRING_RESULT ||
from->result_type() != STRING_RESULT || from->result_type() != STRING_RESULT ||
my_charset_same(from->collation.collation, (from->collation.collation == to->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); uint32 new_length= real_length(item);
bool use_new_field= 0, use_expression_type= 0; bool use_new_field= 0, use_expression_type= 0;
Item_result new_result_type= type_convertor[item_type][item->result_type()]; 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 Check if both items point to fields: in this case we
can adjust column types of result table in the union smartly. can adjust column types of result table in the union smartly.
*/ */
if (field_example && item_is_a_field) if (field_example && item_is_a_field)
{ {
Field *field= ((Item_field *)item)->field;
/* Can 'field_example' field store data of the column? */ /* Can 'field_example' field store data of the column? */
if ((use_new_field= if ((use_new_field=
(!field->field_cast_compatible(field_example->field_cast_type()) || (!field->field_cast_compatible(field_example->field_cast_type()) ||
...@@ -3745,7 +3786,7 @@ bool Item_type_holder::join_types(THD *thd, Item *item) ...@@ -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 It is safe to assign a pointer to field here, because it will be used
before any table is closed. before any table is closed.
*/ */
field_example= ((Item_field*) item)->field; field_example= field;
} }
old_cs= collation.collation->name; old_cs= collation.collation->name;
......
...@@ -1579,14 +1579,14 @@ class Item_type_holder: public Item ...@@ -1579,14 +1579,14 @@ class Item_type_holder: public Item
Item_result orig_type; Item_result orig_type;
Field *field_example; Field *field_example;
public: public:
Item_type_holder(THD*, Item*); Item_type_holder(THD*, Item*, TABLE *);
Item_result result_type () const { return item_type; } Item_result result_type () const { return item_type; }
enum Type type() const { return TYPE_HOLDER; } enum Type type() const { return TYPE_HOLDER; }
double val_real(); double val_real();
longlong val_int(); longlong val_int();
String *val_str(String*); String *val_str(String*);
bool join_types(THD *thd, Item *); bool join_types(THD *thd, Item *, TABLE *);
Field *example() { return field_example; } Field *example() { return field_example; }
static uint32 real_length(Item *item); static uint32 real_length(Item *item);
void cleanup() void cleanup()
......
...@@ -3138,9 +3138,7 @@ void Item_func_match::init_search(bool no_order) ...@@ -3138,9 +3138,7 @@ void Item_func_match::init_search(bool no_order)
if (join_key && !no_order) if (join_key && !no_order)
flags|=FT_SORTED; flags|=FT_SORTED;
ft_handler=table->file->ft_init_ext(flags, key, ft_handler=table->file->ft_init_ext(flags, key, ft_tmp);
(byte*) ft_tmp->ptr(),
ft_tmp->length());
if (join_key) if (join_key)
table->file->ft_handler=ft_handler; table->file->ft_handler=ft_handler;
...@@ -3182,12 +3180,12 @@ bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) ...@@ -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. 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. PARAM_TABLE_BIT can only appear from AGAINST argument.
*/ */
if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables()) if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables())
key=NO_SUCH_KEY; key=NO_SUCH_KEY;
if (key == NO_SUCH_KEY && !(flags & FT_BOOL)) if (key == NO_SUCH_KEY && !(flags & FT_BOOL))
{ {
my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH"); 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, ...@@ -153,6 +153,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
SELECT_LEX *sl, *first_select; SELECT_LEX *sl, *first_select;
select_result *tmp_result; select_result *tmp_result;
bool is_union; bool is_union;
TABLE *empty_table= 0;
DBUG_ENTER("st_select_lex_unit::prepare"); DBUG_ENTER("st_select_lex_unit::prepare");
describe= test(additional_options & SELECT_DESCRIBE); describe= test(additional_options & SELECT_DESCRIBE);
...@@ -249,13 +250,21 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -249,13 +250,21 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
goto err; goto err;
if (sl == first_select) 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(); types.empty();
List_iterator_fast<Item> it(sl->item_list); List_iterator_fast<Item> it(sl->item_list);
Item *item_tmp; Item *item_tmp;
while ((item_tmp= it++)) while ((item_tmp= it++))
{ {
/* Error's in 'new' will be detected after loop */ /* 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) if (thd_arg->is_fatal_error)
...@@ -274,7 +283,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -274,7 +283,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Item *type, *item_tmp; Item *type, *item_tmp;
while ((type= tp++, item_tmp= it++)) 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); DBUG_RETURN(TRUE);
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment