mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-12707 Split resolve_const_item() into virtual methods in Type_handler
This commit is contained in:
@ -173,29 +173,29 @@ SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02');
|
|||||||
DATE'2001-01-01' IN ('2001-01-01','2001-02-02')
|
DATE'2001-01-01' IN ('2001-01-01','2001-02-02')
|
||||||
1
|
1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL);
|
SELECT DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL);
|
||||||
DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL)
|
DATE'2001-01-01' IN ('2001-01-01','2001-02-02',NULL)
|
||||||
1
|
1
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02');
|
SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02');
|
||||||
DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02')
|
DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02')
|
||||||
0
|
0
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL);
|
SELECT DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL);
|
||||||
DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL)
|
DATE'2001-01-01' NOT IN ('2001-01-01','2001-02-02',NULL)
|
||||||
0
|
0
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
# Column predicant, compatible types, bisect
|
# Column predicant, compatible types, bisect
|
||||||
CREATE TABLE t1 (a INT UNSIGNED);
|
CREATE TABLE t1 (a INT UNSIGNED);
|
||||||
@ -354,38 +354,38 @@ CREATE TABLE t1 (a DATE);
|
|||||||
SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1;
|
SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1;
|
||||||
a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0)
|
a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: [2] arg=3 handler=0 (datetime)
|
Note 1105 DBUG: [2] arg=3 handler=0 (date)
|
||||||
Note 1105 DBUG: [3] arg=4 handler=0 (datetime)
|
Note 1105 DBUG: [3] arg=4 handler=0 (date)
|
||||||
Note 1105 DBUG: [4] arg=5 handler=0 (datetime)
|
Note 1105 DBUG: [4] arg=5 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1;
|
SELECT a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1;
|
||||||
a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL)
|
a IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: [2] arg=3 handler=0 (datetime)
|
Note 1105 DBUG: [2] arg=3 handler=0 (date)
|
||||||
Note 1105 DBUG: [3] arg=4 handler=0 (datetime)
|
Note 1105 DBUG: [3] arg=4 handler=0 (date)
|
||||||
Note 1105 DBUG: [4] arg=5 handler=0 (datetime)
|
Note 1105 DBUG: [4] arg=5 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1;
|
SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0) FROM t1;
|
||||||
a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0)
|
a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: [2] arg=3 handler=0 (datetime)
|
Note 1105 DBUG: [2] arg=3 handler=0 (date)
|
||||||
Note 1105 DBUG: [3] arg=4 handler=0 (datetime)
|
Note 1105 DBUG: [3] arg=4 handler=0 (date)
|
||||||
Note 1105 DBUG: [4] arg=5 handler=0 (datetime)
|
Note 1105 DBUG: [4] arg=5 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1;
|
SELECT a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL) FROM t1;
|
||||||
a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL)
|
a NOT IN ('2001-01-01',DATE'2001-01-02',20010102,20010102.0,20010102e0,NULL)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: [2] arg=3 handler=0 (datetime)
|
Note 1105 DBUG: [2] arg=3 handler=0 (date)
|
||||||
Note 1105 DBUG: [3] arg=4 handler=0 (datetime)
|
Note 1105 DBUG: [3] arg=4 handler=0 (date)
|
||||||
Note 1105 DBUG: [4] arg=5 handler=0 (datetime)
|
Note 1105 DBUG: [4] arg=5 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=yes
|
Note 1105 DBUG: types_compatible=yes bisect=yes
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a TIME);
|
CREATE TABLE t1 (a TIME);
|
||||||
@ -610,26 +610,26 @@ CREATE TABLE t1 (a DATE);
|
|||||||
SELECT DATE'2001-01-01' IN (a,'2001-01-01') FROM t1;
|
SELECT DATE'2001-01-01' IN (a,'2001-01-01') FROM t1;
|
||||||
DATE'2001-01-01' IN (a,'2001-01-01')
|
DATE'2001-01-01' IN (a,'2001-01-01')
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=no
|
Note 1105 DBUG: types_compatible=yes bisect=no
|
||||||
SELECT DATE'2001-01-01' IN (a,'2001-01-01',NULL) FROM t1;
|
SELECT DATE'2001-01-01' IN (a,'2001-01-01',NULL) FROM t1;
|
||||||
DATE'2001-01-01' IN (a,'2001-01-01',NULL)
|
DATE'2001-01-01' IN (a,'2001-01-01',NULL)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=no
|
Note 1105 DBUG: types_compatible=yes bisect=no
|
||||||
SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01') FROM t1;
|
SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01') FROM t1;
|
||||||
DATE'2001-01-01' NOT IN (a,'2001-01-01')
|
DATE'2001-01-01' NOT IN (a,'2001-01-01')
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=no
|
Note 1105 DBUG: types_compatible=yes bisect=no
|
||||||
SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL) FROM t1;
|
SELECT DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL) FROM t1;
|
||||||
DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL)
|
DATE'2001-01-01' NOT IN (a,'2001-01-01',NULL)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (datetime)
|
Note 1105 DBUG: [0] arg=1 handler=0 (date)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=0 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=0 (date)
|
||||||
Note 1105 DBUG: types_compatible=yes bisect=no
|
Note 1105 DBUG: types_compatible=yes bisect=no
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CREATE TABLE t1 (a TIME);
|
CREATE TABLE t1 (a TIME);
|
||||||
@ -1147,25 +1147,25 @@ SELECT a IN (1,DATE'2001-01-01') FROM t1;
|
|||||||
a IN (1,DATE'2001-01-01')
|
a IN (1,DATE'2001-01-01')
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=1 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=1 (date)
|
||||||
Note 1105 DBUG: types_compatible=no bisect=no
|
Note 1105 DBUG: types_compatible=no bisect=no
|
||||||
SELECT a IN (1,DATE'2001-01-01',NULL) FROM t1;
|
SELECT a IN (1,DATE'2001-01-01',NULL) FROM t1;
|
||||||
a IN (1,DATE'2001-01-01',NULL)
|
a IN (1,DATE'2001-01-01',NULL)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=1 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=1 (date)
|
||||||
Note 1105 DBUG: types_compatible=no bisect=no
|
Note 1105 DBUG: types_compatible=no bisect=no
|
||||||
SELECT a NOT IN (1,DATE'2001-01-01') FROM t1;
|
SELECT a NOT IN (1,DATE'2001-01-01') FROM t1;
|
||||||
a NOT IN (1,DATE'2001-01-01')
|
a NOT IN (1,DATE'2001-01-01')
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=1 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=1 (date)
|
||||||
Note 1105 DBUG: types_compatible=no bisect=no
|
Note 1105 DBUG: types_compatible=no bisect=no
|
||||||
SELECT a NOT IN (1,DATE'2001-01-01',NULL) FROM t1;
|
SELECT a NOT IN (1,DATE'2001-01-01',NULL) FROM t1;
|
||||||
a NOT IN (1,DATE'2001-01-01',NULL)
|
a NOT IN (1,DATE'2001-01-01',NULL)
|
||||||
Warnings:
|
Warnings:
|
||||||
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
Note 1105 DBUG: [0] arg=1 handler=0 (double)
|
||||||
Note 1105 DBUG: [1] arg=2 handler=1 (datetime)
|
Note 1105 DBUG: [1] arg=2 handler=1 (date)
|
||||||
Note 1105 DBUG: types_compatible=no bisect=no
|
Note 1105 DBUG: types_compatible=no bisect=no
|
||||||
SELECT a IN (1,TIMESTAMP'2001-01-01 10:20:30') FROM t1;
|
SELECT a IN (1,TIMESTAMP'2001-01-01 10:20:30') FROM t1;
|
||||||
a IN (1,TIMESTAMP'2001-01-01 10:20:30')
|
a IN (1,TIMESTAMP'2001-01-01 10:20:30')
|
||||||
|
99
sql/item.cc
99
sql/item.cc
@ -9101,101 +9101,14 @@ void resolve_const_item(THD *thd, Item **ref, Item *comp_item)
|
|||||||
Item *item= *ref;
|
Item *item= *ref;
|
||||||
if (item->basic_const_item())
|
if (item->basic_const_item())
|
||||||
return; // Can't be better
|
return; // Can't be better
|
||||||
|
Type_handler_hybrid_field_type cmp(comp_item->type_handler_for_comparison());
|
||||||
Item *new_item= NULL;
|
if (!cmp.aggregate_for_comparison(item->type_handler_for_comparison()))
|
||||||
Item_result res_type= item_cmp_type(comp_item, item);
|
|
||||||
const char *name= item->name.str; // Alloced on THD::mem_root
|
|
||||||
MEM_ROOT *mem_root= thd->mem_root;
|
|
||||||
|
|
||||||
switch (res_type) {
|
|
||||||
case TIME_RESULT:
|
|
||||||
{
|
{
|
||||||
bool is_null;
|
Item *new_item= cmp.type_handler()->
|
||||||
Item **ref_copy= ref;
|
make_const_item_for_comparison(thd, item, comp_item);
|
||||||
/* the following call creates a constant and puts it in new_item */
|
if (new_item)
|
||||||
enum_field_types type= item->field_type_for_temporal_comparison(comp_item);
|
thd->change_item_tree(ref, new_item);
|
||||||
get_datetime_value(thd, &ref_copy, &new_item, type, &is_null);
|
|
||||||
if (is_null)
|
|
||||||
new_item= new (mem_root) Item_null(thd, name);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case STRING_RESULT:
|
|
||||||
{
|
|
||||||
char buff[MAX_FIELD_WIDTH];
|
|
||||||
String tmp(buff,sizeof(buff),&my_charset_bin),*result;
|
|
||||||
result=item->val_str(&tmp);
|
|
||||||
if (item->null_value)
|
|
||||||
new_item= new (mem_root) Item_null(thd, name);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
uint length= result->length();
|
|
||||||
char *tmp_str= thd->strmake(result->ptr(), length);
|
|
||||||
new_item= new (mem_root) Item_string(thd, name, tmp_str, length, result->charset());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case INT_RESULT:
|
|
||||||
{
|
|
||||||
longlong result=item->val_int();
|
|
||||||
uint length=item->max_length;
|
|
||||||
bool null_value=item->null_value;
|
|
||||||
new_item= (null_value ? (Item*) new (mem_root) Item_null(thd, name) :
|
|
||||||
(Item*) new (mem_root) Item_int(thd, name, result, length));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ROW_RESULT:
|
|
||||||
if (item->type() == Item::ROW_ITEM && comp_item->type() == Item::ROW_ITEM)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Substitute constants only in Item_row's. Don't affect other Items
|
|
||||||
with ROW_RESULT (eg Item_singlerow_subselect).
|
|
||||||
|
|
||||||
For such Items more optimal is to detect if it is constant and replace
|
|
||||||
it with Item_row. This would optimize queries like this:
|
|
||||||
SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
|
|
||||||
*/
|
|
||||||
Item_row *item_row= (Item_row*) item;
|
|
||||||
Item_row *comp_item_row= (Item_row*) comp_item;
|
|
||||||
uint col;
|
|
||||||
new_item= 0;
|
|
||||||
/*
|
|
||||||
If item and comp_item are both Item_row's and have same number of cols
|
|
||||||
then process items in Item_row one by one.
|
|
||||||
We can't ignore NULL values here as this item may be used with <=>, in
|
|
||||||
which case NULL's are significant.
|
|
||||||
*/
|
|
||||||
DBUG_ASSERT(item->result_type() == comp_item->result_type());
|
|
||||||
DBUG_ASSERT(item_row->cols() == comp_item_row->cols());
|
|
||||||
col= item_row->cols();
|
|
||||||
while (col-- > 0)
|
|
||||||
resolve_const_item(thd, item_row->addr(col),
|
|
||||||
comp_item_row->element_index(col));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Fallthrough */
|
|
||||||
case REAL_RESULT:
|
|
||||||
{ // It must REAL_RESULT
|
|
||||||
double result= item->val_real();
|
|
||||||
uint length=item->max_length,decimals=item->decimals;
|
|
||||||
bool null_value=item->null_value;
|
|
||||||
new_item= (null_value ? (Item*) new (mem_root) Item_null(thd, name) : (Item*)
|
|
||||||
new (mem_root) Item_float(thd, name, result, decimals, length));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DECIMAL_RESULT:
|
|
||||||
{
|
|
||||||
my_decimal decimal_value;
|
|
||||||
my_decimal *result= item->val_decimal(&decimal_value);
|
|
||||||
uint length= item->max_length, decimals= item->decimals;
|
|
||||||
bool null_value= item->null_value;
|
|
||||||
new_item= (null_value ?
|
|
||||||
(Item*) new (mem_root) Item_null(thd, name) :
|
|
||||||
(Item*) new (mem_root) Item_decimal(thd, name, result, length, decimals));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (new_item)
|
|
||||||
thd->change_item_tree(ref, new_item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
21
sql/item.h
21
sql/item.h
@ -733,6 +733,10 @@ public:
|
|||||||
{
|
{
|
||||||
return Type_handler::get_handler_by_field_type(field_type());
|
return Type_handler::get_handler_by_field_type(field_type());
|
||||||
}
|
}
|
||||||
|
const Type_handler *type_handler_for_comparison() const
|
||||||
|
{
|
||||||
|
return type_handler()->type_handler_for_comparison();
|
||||||
|
}
|
||||||
virtual const Type_handler *real_type_handler() const
|
virtual const Type_handler *real_type_handler() const
|
||||||
{
|
{
|
||||||
return type_handler();
|
return type_handler();
|
||||||
@ -1317,23 +1321,6 @@ public:
|
|||||||
return f_type == MYSQL_TYPE_TIME ? val_time_packed() :
|
return f_type == MYSQL_TYPE_TIME ? val_time_packed() :
|
||||||
val_datetime_packed();
|
val_datetime_packed();
|
||||||
}
|
}
|
||||||
enum_field_types field_type_for_temporal_comparison(const Item *other) const
|
|
||||||
{
|
|
||||||
if (cmp_type() == TIME_RESULT)
|
|
||||||
{
|
|
||||||
if (other->cmp_type() == TIME_RESULT)
|
|
||||||
return Field::field_type_merge(field_type(), other->field_type());
|
|
||||||
else
|
|
||||||
return field_type();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (other->cmp_type() == TIME_RESULT)
|
|
||||||
return other->field_type();
|
|
||||||
DBUG_ASSERT(0); // Two non-temporal data types, we should not get to here
|
|
||||||
return MYSQL_TYPE_DATETIME;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bool get_seconds(ulonglong *sec, ulong *sec_part);
|
bool get_seconds(ulonglong *sec, ulong *sec_part);
|
||||||
virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
virtual bool get_date_result(MYSQL_TIME *ltime, ulonglong fuzzydate)
|
||||||
{ return get_date(ltime,fuzzydate); }
|
{ return get_date(ltime,fuzzydate); }
|
||||||
|
@ -552,20 +552,20 @@ bool Arg_comparator::set_cmp_func_string()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Arg_comparator::set_cmp_func_temporal()
|
bool Arg_comparator::set_cmp_func_time()
|
||||||
{
|
{
|
||||||
enum_field_types f_type= a[0]->field_type_for_temporal_comparison(b[0]);
|
|
||||||
m_compare_collation= &my_charset_numeric;
|
m_compare_collation= &my_charset_numeric;
|
||||||
if (f_type == MYSQL_TYPE_TIME)
|
func= is_owner_equal_func() ? &Arg_comparator::compare_e_time :
|
||||||
{
|
&Arg_comparator::compare_time;
|
||||||
func= is_owner_equal_func() ? &Arg_comparator::compare_e_time :
|
return false;
|
||||||
&Arg_comparator::compare_time;
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
bool Arg_comparator::set_cmp_func_datetime()
|
||||||
func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
|
{
|
||||||
&Arg_comparator::compare_datetime;
|
m_compare_collation= &my_charset_numeric;
|
||||||
}
|
func= is_owner_equal_func() ? &Arg_comparator::compare_e_datetime :
|
||||||
|
&Arg_comparator::compare_datetime;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,8 @@ public:
|
|||||||
bool set_cmp_func_for_row_arguments();
|
bool set_cmp_func_for_row_arguments();
|
||||||
bool set_cmp_func_row();
|
bool set_cmp_func_row();
|
||||||
bool set_cmp_func_string();
|
bool set_cmp_func_string();
|
||||||
bool set_cmp_func_temporal();
|
bool set_cmp_func_time();
|
||||||
|
bool set_cmp_func_datetime();
|
||||||
bool set_cmp_func_int();
|
bool set_cmp_func_int();
|
||||||
bool set_cmp_func_real();
|
bool set_cmp_func_real();
|
||||||
bool set_cmp_func_decimal();
|
bool set_cmp_func_decimal();
|
||||||
|
143
sql/sql_type.cc
143
sql/sql_type.cc
@ -457,7 +457,19 @@ const Type_handler *Type_handler_time_common::type_handler_for_comparison() cons
|
|||||||
return &type_handler_time;
|
return &type_handler_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Type_handler *Type_handler_temporal_with_date::type_handler_for_comparison() const
|
const Type_handler *Type_handler_date_common::type_handler_for_comparison() const
|
||||||
|
{
|
||||||
|
return &type_handler_newdate;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *Type_handler_datetime_common::type_handler_for_comparison() const
|
||||||
|
{
|
||||||
|
return &type_handler_datetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const Type_handler *Type_handler_timestamp_common::type_handler_for_comparison() const
|
||||||
{
|
{
|
||||||
return &type_handler_datetime;
|
return &type_handler_datetime;
|
||||||
}
|
}
|
||||||
@ -652,9 +664,14 @@ Type_handler_hybrid_field_type::aggregate_for_comparison(const Type_handler *h)
|
|||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
We're here if both m_type_handler and h are temporal data types.
|
We're here if both m_type_handler and h are temporal data types.
|
||||||
|
- If both data types are TIME, we preserve TIME.
|
||||||
|
- If both data types are DATE, we preserve DATE.
|
||||||
|
Preserving DATE is needed for EXPLAIN FORMAT=JSON,
|
||||||
|
to print DATE constants using proper format:
|
||||||
|
'YYYY-MM-DD' rather than 'YYYY-MM-DD 00:00:00'.
|
||||||
*/
|
*/
|
||||||
if (field_type() != MYSQL_TYPE_TIME || h->field_type() != MYSQL_TYPE_TIME)
|
if (field_type() != h->field_type())
|
||||||
m_type_handler= &type_handler_datetime; // DATETIME bits TIME
|
m_type_handler= &type_handler_datetime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
|
else if ((a == INT_RESULT || a == DECIMAL_RESULT) &&
|
||||||
@ -1917,9 +1934,15 @@ bool Type_handler_string_result::set_comparator_func(Arg_comparator *cmp) const
|
|||||||
return cmp->set_cmp_func_string();
|
return cmp->set_cmp_func_string();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Type_handler_temporal_result::set_comparator_func(Arg_comparator *cmp) const
|
bool Type_handler_time_common::set_comparator_func(Arg_comparator *cmp) const
|
||||||
{
|
{
|
||||||
return cmp->set_cmp_func_temporal();
|
return cmp->set_cmp_func_time();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Type_handler_temporal_with_date::set_comparator_func(Arg_comparator *cmp) const
|
||||||
|
{
|
||||||
|
return cmp->set_cmp_func_datetime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -4211,3 +4234,113 @@ bool Type_handler::
|
|||||||
}
|
}
|
||||||
|
|
||||||
/***************************************************************************/
|
/***************************************************************************/
|
||||||
|
|
||||||
|
Item *Type_handler_int_result::
|
||||||
|
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
|
||||||
|
{
|
||||||
|
longlong result= item->val_int();
|
||||||
|
if (item->null_value)
|
||||||
|
return new (thd->mem_root) Item_null(thd, item->name.str);
|
||||||
|
return new (thd->mem_root) Item_int(thd, item->name.str, result,
|
||||||
|
item->max_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *Type_handler_real_result::
|
||||||
|
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
|
||||||
|
{
|
||||||
|
double result= item->val_real();
|
||||||
|
if (item->null_value)
|
||||||
|
return new (thd->mem_root) Item_null(thd, item->name.str);
|
||||||
|
return new (thd->mem_root) Item_float(thd, item->name.str, result,
|
||||||
|
item->decimals, item->max_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *Type_handler_decimal_result::
|
||||||
|
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
|
||||||
|
{
|
||||||
|
my_decimal decimal_value;
|
||||||
|
my_decimal *result= item->val_decimal(&decimal_value);
|
||||||
|
if (item->null_value)
|
||||||
|
return new (thd->mem_root) Item_null(thd, item->name.str);
|
||||||
|
return new (thd->mem_root) Item_decimal(thd, item->name.str, result,
|
||||||
|
item->max_length, item->decimals);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *Type_handler_string_result::
|
||||||
|
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
|
||||||
|
{
|
||||||
|
StringBuffer<MAX_FIELD_WIDTH> tmp;
|
||||||
|
String *result= item->val_str(&tmp);
|
||||||
|
if (item->null_value)
|
||||||
|
return new (thd->mem_root) Item_null(thd, item->name.str);
|
||||||
|
uint length= result->length();
|
||||||
|
char *tmp_str= thd->strmake(result->ptr(), length);
|
||||||
|
return new (thd->mem_root) Item_string(thd, item->name.str,
|
||||||
|
tmp_str, length, result->charset());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *Type_handler_time_common::
|
||||||
|
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
|
||||||
|
{
|
||||||
|
Item_cache_temporal *cache;
|
||||||
|
longlong value= item->val_time_packed();
|
||||||
|
if (item->null_value)
|
||||||
|
return new (thd->mem_root) Item_null(thd, item->name.str);
|
||||||
|
cache= new (thd->mem_root) Item_cache_temporal(thd, field_type());
|
||||||
|
if (cache)
|
||||||
|
cache->store_packed(value, item);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *Type_handler_temporal_with_date::
|
||||||
|
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
|
||||||
|
{
|
||||||
|
Item_cache_temporal *cache;
|
||||||
|
longlong value= item->val_datetime_packed();
|
||||||
|
if (item->null_value)
|
||||||
|
return new (thd->mem_root) Item_null(thd, item->name.str);
|
||||||
|
cache= new (thd->mem_root) Item_cache_temporal(thd, field_type());
|
||||||
|
if (cache)
|
||||||
|
cache->store_packed(value, item);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *Type_handler_row::
|
||||||
|
make_const_item_for_comparison(THD *thd, Item *item, Item *cmp) const
|
||||||
|
{
|
||||||
|
if (item->type() == Item::ROW_ITEM && cmp->type() == Item::ROW_ITEM)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Substitute constants only in Item_row's. Don't affect other Items
|
||||||
|
with ROW_RESULT (eg Item_singlerow_subselect).
|
||||||
|
|
||||||
|
For such Items more optimal is to detect if it is constant and replace
|
||||||
|
it with Item_row. This would optimize queries like this:
|
||||||
|
SELECT * FROM t1 WHERE (a,b) = (SELECT a,b FROM t2 LIMIT 1);
|
||||||
|
*/
|
||||||
|
Item_row *item_row= (Item_row*) item;
|
||||||
|
Item_row *comp_item_row= (Item_row*) cmp;
|
||||||
|
uint col;
|
||||||
|
/*
|
||||||
|
If item and comp_item are both Item_row's and have same number of cols
|
||||||
|
then process items in Item_row one by one.
|
||||||
|
We can't ignore NULL values here as this item may be used with <=>, in
|
||||||
|
which case NULL's are significant.
|
||||||
|
*/
|
||||||
|
DBUG_ASSERT(item->result_type() == cmp->result_type());
|
||||||
|
DBUG_ASSERT(item_row->cols() == comp_item_row->cols());
|
||||||
|
col= item_row->cols();
|
||||||
|
while (col-- > 0)
|
||||||
|
resolve_const_item(thd, item_row->addr(col),
|
||||||
|
comp_item_row->element_index(col));
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************/
|
||||||
|
@ -746,6 +746,26 @@ public:
|
|||||||
virtual bool
|
virtual bool
|
||||||
subquery_type_allows_materialization(const Item *inner,
|
subquery_type_allows_materialization(const Item *inner,
|
||||||
const Item *outer) const= 0;
|
const Item *outer) const= 0;
|
||||||
|
/**
|
||||||
|
Make a simple constant replacement item for a constant "src",
|
||||||
|
so the new item can futher be used for comparison with "cmp", e.g.:
|
||||||
|
src = cmp -> replacement = cmp
|
||||||
|
|
||||||
|
"this" is the type handler that is used to compare "src" and "cmp".
|
||||||
|
|
||||||
|
@param thd - current thread, for mem_root
|
||||||
|
@param src - The item that we want to replace. It's a const item,
|
||||||
|
but it can be complex enough to calculate on every row.
|
||||||
|
@param cmp - The src's comparand.
|
||||||
|
@retval - a pointer to the created replacement Item
|
||||||
|
@retval - NULL, if could not create a replacement (e.g. on EOM).
|
||||||
|
NULL is also returned for ROWs, because instead of replacing
|
||||||
|
a Item_row to a new Item_row, Type_handler_row just replaces
|
||||||
|
its elements.
|
||||||
|
*/
|
||||||
|
virtual Item *make_const_item_for_comparison(THD *thd,
|
||||||
|
Item *src,
|
||||||
|
Item *cmp) const= 0;
|
||||||
virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0;
|
virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0;
|
||||||
virtual bool set_comparator_func(Arg_comparator *cmp) const= 0;
|
virtual bool set_comparator_func(Arg_comparator *cmp) const= 0;
|
||||||
virtual bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
virtual bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@ -935,6 +955,7 @@ public:
|
|||||||
DBUG_ASSERT(0);
|
DBUG_ASSERT(0);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@ -1137,6 +1158,7 @@ public:
|
|||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
|
Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@ -1201,6 +1223,7 @@ public:
|
|||||||
return Item_send_str(item, protocol, buf);
|
return Item_send_str(item, protocol, buf);
|
||||||
}
|
}
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
|
Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@ -1257,6 +1280,7 @@ public:
|
|||||||
SORT_FIELD_ATTR *attr) const;
|
SORT_FIELD_ATTR *attr) const;
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
|
Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@ -1318,7 +1342,6 @@ public:
|
|||||||
bool subquery_type_allows_materialization(const Item *inner,
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
const Item *outer) const;
|
const Item *outer) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
|
||||||
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
|
||||||
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
|
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
|
||||||
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
|
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
|
||||||
@ -1401,6 +1424,7 @@ public:
|
|||||||
Item *source_expr, Item *source_const) const;
|
Item *source_expr, Item *source_const) const;
|
||||||
bool subquery_type_allows_materialization(const Item *inner,
|
bool subquery_type_allows_materialization(const Item *inner,
|
||||||
const Item *outer) const;
|
const Item *outer) const;
|
||||||
|
Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const;
|
||||||
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
|
||||||
bool set_comparator_func(Arg_comparator *cmp) const;
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
@ -1693,6 +1717,8 @@ public:
|
|||||||
String *print_item_value(THD *thd, Item *item, String *str) const;
|
String *print_item_value(THD *thd, Item *item, String *str) const;
|
||||||
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
|
||||||
Item **items, uint nitems) const;
|
Item **items, uint nitems) const;
|
||||||
|
Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const;
|
||||||
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
||||||
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
||||||
};
|
};
|
||||||
@ -1729,13 +1755,14 @@ class Type_handler_temporal_with_date: public Type_handler_temporal_result
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
virtual ~Type_handler_temporal_with_date() {}
|
virtual ~Type_handler_temporal_with_date() {}
|
||||||
const Type_handler *type_handler_for_comparison() const;
|
|
||||||
bool Item_save_in_value(Item *item, st_value *value) const;
|
bool Item_save_in_value(Item *item, st_value *value) const;
|
||||||
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
|
||||||
{
|
{
|
||||||
return Item_send_date(item, protocol, buf);
|
return Item_send_date(item, protocol, buf);
|
||||||
}
|
}
|
||||||
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
|
||||||
|
Item *make_const_item_for_comparison(THD *thd, Item *src, Item *cmp) const;
|
||||||
|
bool set_comparator_func(Arg_comparator *cmp) const;
|
||||||
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const;
|
||||||
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
in_vector *make_in_vector(THD *, const Item_func_in *, uint nargs) const;
|
||||||
};
|
};
|
||||||
@ -1747,6 +1774,7 @@ class Type_handler_date_common: public Type_handler_temporal_with_date
|
|||||||
public:
|
public:
|
||||||
virtual ~Type_handler_date_common() {}
|
virtual ~Type_handler_date_common() {}
|
||||||
const Name name() const { return m_name_date; }
|
const Name name() const { return m_name_date; }
|
||||||
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
|
||||||
enum_mysql_timestamp_type mysql_timestamp_type() const
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
{
|
{
|
||||||
@ -1790,6 +1818,7 @@ class Type_handler_datetime_common: public Type_handler_temporal_with_date
|
|||||||
public:
|
public:
|
||||||
virtual ~Type_handler_datetime_common() {}
|
virtual ~Type_handler_datetime_common() {}
|
||||||
const Name name() const { return m_name_datetime; }
|
const Name name() const { return m_name_datetime; }
|
||||||
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
|
||||||
enum_mysql_timestamp_type mysql_timestamp_type() const
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
{
|
{
|
||||||
@ -1846,6 +1875,7 @@ class Type_handler_timestamp_common: public Type_handler_temporal_with_date
|
|||||||
public:
|
public:
|
||||||
virtual ~Type_handler_timestamp_common() {}
|
virtual ~Type_handler_timestamp_common() {}
|
||||||
const Name name() const { return m_name_timestamp; }
|
const Name name() const { return m_name_timestamp; }
|
||||||
|
const Type_handler *type_handler_for_comparison() const;
|
||||||
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
enum_field_types field_type() const { return MYSQL_TYPE_TIMESTAMP; }
|
||||||
enum_mysql_timestamp_type mysql_timestamp_type() const
|
enum_mysql_timestamp_type mysql_timestamp_type() const
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user