Merge branch '10.0' into 10.1

This commit is contained in:
Oleksandr Byelkin 2018-11-15 17:20:26 +01:00
commit a77f80b79e
8 changed files with 277 additions and 87 deletions

View file

@ -118,7 +118,10 @@ static int cmp_row_type(Item* item1, Item* item2)
0 otherwise
*/
static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
static int agg_cmp_type(Item_result *type,
Item **items,
uint nitems,
bool int_uint_as_dec)
{
uint unsigned_count= items[0]->unsigned_flag;
type[0]= items[0]->cmp_type();
@ -140,7 +143,9 @@ static int agg_cmp_type(Item_result *type, Item **items, uint nitems)
If all arguments are of INT type but have different unsigned_flag values,
switch to DECIMAL_RESULT.
*/
if (type[0] == INT_RESULT && unsigned_count != nitems && unsigned_count != 0)
if (int_uint_as_dec &&
type[0] == INT_RESULT &&
unsigned_count != nitems && unsigned_count != 0)
type[0]= DECIMAL_RESULT;
return 0;
}
@ -2131,7 +2136,7 @@ void Item_func_between::fix_length_and_dec()
*/
if (!args[0] || !args[1] || !args[2])
return;
if (agg_cmp_type(&m_compare_type, args, 3))
if (agg_cmp_type(&m_compare_type, args, 3, false))
return;
if (m_compare_type == STRING_RESULT &&
@ -2166,6 +2171,97 @@ void Item_func_between::fix_length_and_dec()
}
longlong Item_func_between::val_int_cmp_string()
{
String *value,*a,*b;
value=args[0]->val_str(&value0);
if ((null_value=args[0]->null_value))
return 0;
a= args[1]->val_str(&value1);
b= args[2]->val_str(&value2);
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
sortcmp(value,b,cmp_collation.collation) <= 0) !=
negated);
if (args[1]->null_value && args[2]->null_value)
null_value= true;
else if (args[1]->null_value)
{
// Set to not null if false range.
null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
}
else
{
// Set to not null if false range.
null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
}
return (longlong) (!null_value && negated);
}
longlong Item_func_between::val_int_cmp_int()
{
Longlong_hybrid value= args[0]->to_longlong_hybrid();
if ((null_value= args[0]->null_value))
return 0; /* purecov: inspected */
Longlong_hybrid a= args[1]->to_longlong_hybrid();
Longlong_hybrid b= args[2]->to_longlong_hybrid();
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((value.cmp(a) >= 0 && value.cmp(b) <= 0) != negated);
if (args[1]->null_value && args[2]->null_value)
null_value= true;
else if (args[1]->null_value)
null_value= value.cmp(b) <= 0; // not null if false range.
else
null_value= value.cmp(a) >= 0;
return (longlong) (!null_value && negated);
}
longlong Item_func_between::val_int_cmp_decimal()
{
my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
a_buf, *a_dec, b_buf, *b_dec;
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
a_dec= args[1]->val_decimal(&a_buf);
b_dec= args[2]->val_decimal(&b_buf);
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
my_decimal_cmp(dec, b_dec) <= 0) != negated);
if (args[1]->null_value && args[2]->null_value)
null_value= true;
else if (args[1]->null_value)
null_value= (my_decimal_cmp(dec, b_dec) <= 0);
else
null_value= (my_decimal_cmp(dec, a_dec) >= 0);
return (longlong) (!null_value && negated);
}
longlong Item_func_between::val_int_cmp_real()
{
double value= args[0]->val_real(),a,b;
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
a= args[1]->val_real();
b= args[2]->val_real();
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((value >= a && value <= b) != negated);
if (args[1]->null_value && args[2]->null_value)
null_value= true;
else if (args[1]->null_value)
{
null_value= value <= b; // not null if false range.
}
else
{
null_value= value >= a;
}
return (longlong) (!null_value && negated);
}
longlong Item_func_between::val_int()
{
DBUG_ASSERT(fixed == 1);
@ -2207,94 +2303,14 @@ longlong Item_func_between::val_int()
null_value= value >= a;
break;
}
case STRING_RESULT:
{
String *value,*a,*b;
value=args[0]->val_str(&value0);
if ((null_value=args[0]->null_value))
return 0;
a=args[1]->val_str(&value1);
b=args[2]->val_str(&value2);
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((sortcmp(value,a,cmp_collation.collation) >= 0 &&
sortcmp(value,b,cmp_collation.collation) <= 0) !=
negated);
if (args[1]->null_value && args[2]->null_value)
null_value=1;
else if (args[1]->null_value)
{
// Set to not null if false range.
null_value= sortcmp(value,b,cmp_collation.collation) <= 0;
}
else
{
// Set to not null if false range.
null_value= sortcmp(value,a,cmp_collation.collation) >= 0;
}
break;
}
return val_int_cmp_string();
case INT_RESULT:
{
longlong value=args[0]->val_int(), a, b;
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
a=args[1]->val_int();
b=args[2]->val_int();
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((value >= a && value <= b) != negated);
if (args[1]->null_value && args[2]->null_value)
null_value=1;
else if (args[1]->null_value)
{
null_value= value <= b; // not null if false range.
}
else
{
null_value= value >= a;
}
break;
}
return val_int_cmp_int();
case DECIMAL_RESULT:
{
my_decimal dec_buf, *dec= args[0]->val_decimal(&dec_buf),
a_buf, *a_dec, b_buf, *b_dec;
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
a_dec= args[1]->val_decimal(&a_buf);
b_dec= args[2]->val_decimal(&b_buf);
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((my_decimal_cmp(dec, a_dec) >= 0 &&
my_decimal_cmp(dec, b_dec) <= 0) != negated);
if (args[1]->null_value && args[2]->null_value)
null_value=1;
else if (args[1]->null_value)
null_value= (my_decimal_cmp(dec, b_dec) <= 0);
else
null_value= (my_decimal_cmp(dec, a_dec) >= 0);
break;
}
return val_int_cmp_decimal();
case REAL_RESULT:
{
double value= args[0]->val_real(),a,b;
if ((null_value=args[0]->null_value))
return 0; /* purecov: inspected */
a= args[1]->val_real();
b= args[2]->val_real();
if (!args[1]->null_value && !args[2]->null_value)
return (longlong) ((value >= a && value <= b) != negated);
if (args[1]->null_value && args[2]->null_value)
null_value=1;
else if (args[1]->null_value)
{
null_value= value <= b; // not null if false range.
}
else
{
null_value= value >= a;
}
break;
}
return val_int_cmp_real();
case ROW_RESULT:
DBUG_ASSERT(0);
null_value= 1;