summaryrefslogtreecommitdiff
path: root/sql/item_cmpfunc.cc
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2018-11-15 13:57:35 +0100
committerOleksandr Byelkin <sanja@mariadb.com>2018-11-15 13:57:35 +0100
commita84d87fde8c0bc325c8e00f06ea02bcd84a75d55 (patch)
tree41fa1755fd5f639328f04b0b952634568eb6cc11 /sql/item_cmpfunc.cc
parent47274d902e63663522176614157b4eace8a17b8e (diff)
parent1956695c69467375fc634ad709f1b32a2daf29b1 (diff)
downloadmariadb-git-a84d87fde8c0bc325c8e00f06ea02bcd84a75d55.tar.gz
Merge branch '5.5' into 10.0
Diffstat (limited to 'sql/item_cmpfunc.cc')
-rw-r--r--sql/item_cmpfunc.cc190
1 files changed, 103 insertions, 87 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index bdef3c1a89f..a0c5798cb69 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -159,7 +159,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();
@@ -181,7 +184,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;
}
@@ -2359,7 +2364,7 @@ void Item_func_between::fix_length_and_dec()
*/
if (!args[0] || !args[1] || !args[2])
return;
- if ( agg_cmp_type(&cmp_type, args, 3))
+ if (agg_cmp_type(&cmp_type, args, 3, false))
return;
if (cmp_type == STRING_RESULT &&
agg_arg_charsets_for_comparison(cmp_collation, args, 3))
@@ -2393,6 +2398,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);
@@ -2434,94 +2530,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:
case IMPOSSIBLE_RESULT:
DBUG_ASSERT(0);