Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
30bec863
Commit
30bec863
authored
Sep 17, 2016
by
Alexander Barkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-10342 Providing compatibility for basic SQL built-in functions
Adding functions NVL() and NVL2().
parent
7e7ba7cb
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
183 additions
and
93 deletions
+183
-93
mysql-test/suite/compat/oracle/r/func_case.result
mysql-test/suite/compat/oracle/r/func_case.result
+7
-0
mysql-test/suite/compat/oracle/t/func_case.test
mysql-test/suite/compat/oracle/t/func_case.test
+9
-0
sql/item.h
sql/item.h
+41
-0
sql/item_cmpfunc.cc
sql/item_cmpfunc.cc
+0
-85
sql/item_cmpfunc.h
sql/item_cmpfunc.h
+102
-8
sql/item_create.cc
sql/item_create.cc
+24
-0
No files found.
mysql-test/suite/compat/oracle/r/func_case.result
0 → 100644
View file @
30bec863
SET sql_mode=ORACLE;
SELECT NVL(NULL, 'a'), NVL('a', 'b');
NVL(NULL, 'a') NVL('a', 'b')
a a
SELECT NVL2(NULL, 'a', 'b'), NVL2('a', 'b', 'c');
NVL2(NULL, 'a', 'b') NVL2('a', 'b', 'c')
b b
mysql-test/suite/compat/oracle/t/func_case.test
0 → 100644
View file @
30bec863
#
# Testing CASE and its abbreviations
#
SET
sql_mode
=
ORACLE
;
SELECT
NVL
(
NULL
,
'a'
),
NVL
(
'a'
,
'b'
);
SELECT
NVL2
(
NULL
,
'a'
,
'b'
),
NVL2
(
'a'
,
'b'
,
'c'
);
sql/item.h
View file @
30bec863
...
@@ -543,6 +543,47 @@ class Item: public Value_source,
...
@@ -543,6 +543,47 @@ class Item: public Value_source,
void
push_note_converted_to_negative_complement
(
THD
*
thd
);
void
push_note_converted_to_negative_complement
(
THD
*
thd
);
void
push_note_converted_to_positive_complement
(
THD
*
thd
);
void
push_note_converted_to_positive_complement
(
THD
*
thd
);
/* Helper methods, to get an Item value from another Item */
double
val_real_from_item
(
Item
*
item
)
{
DBUG_ASSERT
(
fixed
==
1
);
double
value
=
item
->
val_real
();
null_value
=
item
->
null_value
;
return
value
;
}
longlong
val_int_from_item
(
Item
*
item
)
{
DBUG_ASSERT
(
fixed
==
1
);
longlong
value
=
item
->
val_int
();
null_value
=
item
->
null_value
;
return
value
;
}
String
*
val_str_from_item
(
Item
*
item
,
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
String
*
res
=
item
->
val_str
(
str
);
if
(
res
)
res
->
set_charset
(
collation
.
collation
);
if
((
null_value
=
item
->
null_value
))
res
=
NULL
;
return
res
;
}
my_decimal
*
val_decimal_from_item
(
Item
*
item
,
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
fixed
==
1
);
my_decimal
*
value
=
item
->
val_decimal
(
decimal_value
);
if
((
null_value
=
item
->
null_value
))
value
=
NULL
;
return
value
;
}
bool
get_date_with_conversion_from_item
(
Item
*
item
,
MYSQL_TIME
*
ltime
,
uint
fuzzydate
)
{
DBUG_ASSERT
(
fixed
==
1
);
return
(
null_value
=
item
->
get_date_with_conversion
(
ltime
,
fuzzydate
));
}
public:
public:
/*
/*
Cache val_str() into the own buffer, e.g. to evaluate constant
Cache val_str() into the own buffer, e.g. to evaluate constant
...
...
sql/item_cmpfunc.cc
View file @
30bec863
...
@@ -2365,91 +2365,6 @@ void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref)
...
@@ -2365,91 +2365,6 @@ void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref)
}
}
void
Item_func_if
::
cache_type_info
(
Item
*
source
)
{
Type_std_attributes
::
set
(
source
);
set_handler_by_field_type
(
source
->
field_type
());
maybe_null
=
source
->
maybe_null
;
}
void
Item_func_if
::
fix_length_and_dec
()
{
// Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
if
(
args
[
1
]
->
type
()
==
NULL_ITEM
)
{
cache_type_info
(
args
[
2
]);
maybe_null
=
true
;
// If both arguments are NULL, make resulting type BINARY(0).
if
(
args
[
2
]
->
type
()
==
NULL_ITEM
)
set_handler_by_field_type
(
MYSQL_TYPE_STRING
);
return
;
}
if
(
args
[
2
]
->
type
()
==
NULL_ITEM
)
{
cache_type_info
(
args
[
1
]);
maybe_null
=
true
;
return
;
}
Item_func_case_abbreviation2
::
fix_length_and_dec2
(
args
+
1
);
}
double
Item_func_if
::
real_op
()
{
DBUG_ASSERT
(
fixed
==
1
);
Item
*
arg
=
args
[
0
]
->
val_bool
()
?
args
[
1
]
:
args
[
2
];
double
value
=
arg
->
val_real
();
null_value
=
arg
->
null_value
;
return
value
;
}
longlong
Item_func_if
::
int_op
()
{
DBUG_ASSERT
(
fixed
==
1
);
Item
*
arg
=
args
[
0
]
->
val_bool
()
?
args
[
1
]
:
args
[
2
];
longlong
value
=
arg
->
val_int
();
null_value
=
arg
->
null_value
;
return
value
;
}
String
*
Item_func_if
::
str_op
(
String
*
str
)
{
DBUG_ASSERT
(
fixed
==
1
);
Item
*
arg
=
args
[
0
]
->
val_bool
()
?
args
[
1
]
:
args
[
2
];
String
*
res
=
arg
->
val_str
(
str
);
if
(
res
)
res
->
set_charset
(
collation
.
collation
);
if
((
null_value
=
arg
->
null_value
))
res
=
NULL
;
return
res
;
}
my_decimal
*
Item_func_if
::
decimal_op
(
my_decimal
*
decimal_value
)
{
DBUG_ASSERT
(
fixed
==
1
);
Item
*
arg
=
args
[
0
]
->
val_bool
()
?
args
[
1
]
:
args
[
2
];
my_decimal
*
value
=
arg
->
val_decimal
(
decimal_value
);
if
((
null_value
=
arg
->
null_value
))
value
=
NULL
;
return
value
;
}
bool
Item_func_if
::
date_op
(
MYSQL_TIME
*
ltime
,
uint
fuzzydate
)
{
DBUG_ASSERT
(
fixed
==
1
);
Item
*
arg
=
args
[
0
]
->
val_bool
()
?
args
[
1
]
:
args
[
2
];
return
(
null_value
=
arg
->
get_date_with_conversion
(
ltime
,
fuzzydate
));
}
void
Item_func_nullif
::
split_sum_func
(
THD
*
thd
,
Ref_ptr_array
ref_pointer_array
,
void
Item_func_nullif
::
split_sum_func
(
THD
*
thd
,
Ref_ptr_array
ref_pointer_array
,
List
<
Item
>
&
fields
,
uint
flags
)
List
<
Item
>
&
fields
,
uint
flags
)
{
{
...
...
sql/item_cmpfunc.h
View file @
30bec863
...
@@ -993,6 +993,7 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
...
@@ -993,6 +993,7 @@ class Item_func_coalesce :public Item_func_hybrid_field_type
Case abbreviations that aggregate its result field type by two arguments:
Case abbreviations that aggregate its result field type by two arguments:
IFNULL(arg1, arg2)
IFNULL(arg1, arg2)
IF(switch, arg1, arg2)
IF(switch, arg1, arg2)
NVL2(switch, arg1, arg2)
*/
*/
class
Item_func_case_abbreviation2
:
public
Item_func_hybrid_field_type
class
Item_func_case_abbreviation2
:
public
Item_func_hybrid_field_type
{
{
...
@@ -1003,6 +1004,34 @@ class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type
...
@@ -1003,6 +1004,34 @@ class Item_func_case_abbreviation2 :public Item_func_hybrid_field_type
fix_attributes
(
items
,
2
);
fix_attributes
(
items
,
2
);
}
}
uint
decimal_precision2
(
Item
**
args
)
const
;
uint
decimal_precision2
(
Item
**
args
)
const
;
void
cache_type_info
(
const
Item
*
source
,
bool
maybe_null_arg
)
{
Type_std_attributes
::
set
(
source
);
set_handler_by_field_type
(
source
->
field_type
());
maybe_null
=
maybe_null_arg
;
}
void
fix_length_and_dec2_eliminate_null
(
Item
**
items
)
{
// Let IF(cond, expr, NULL) and IF(cond, NULL, expr) inherit type from expr.
if
(
items
[
0
]
->
type
()
==
NULL_ITEM
)
{
cache_type_info
(
items
[
1
],
true
);
// If both arguments are NULL, make resulting type BINARY(0).
if
(
items
[
1
]
->
type
()
==
NULL_ITEM
)
set_handler_by_field_type
(
MYSQL_TYPE_STRING
);
}
else
if
(
items
[
1
]
->
type
()
==
NULL_ITEM
)
{
cache_type_info
(
items
[
0
],
true
);
}
else
{
fix_length_and_dec2
(
items
);
}
}
public:
public:
Item_func_case_abbreviation2
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_case_abbreviation2
(
THD
*
thd
,
Item
*
a
,
Item
*
b
)
:
Item_func_hybrid_field_type
(
thd
,
a
,
b
)
{
}
Item_func_hybrid_field_type
(
thd
,
a
,
b
)
{
}
...
@@ -1040,19 +1069,61 @@ class Item_func_ifnull :public Item_func_case_abbreviation2
...
@@ -1040,19 +1069,61 @@ class Item_func_ifnull :public Item_func_case_abbreviation2
};
};
class
Item_func_if
:
public
Item_func_case_abbreviation2
/**
Case abbreviations that have a switch argument and
two return arguments to choose from. Returns the value
of either of the two return arguments depending on the switch argument value.
IF(switch, arg1, arg2)
NVL(switch, arg1, arg2)
*/
class
Item_func_case_abbreviation2_switch
:
public
Item_func_case_abbreviation2
{
protected:
virtual
Item
*
find_item
()
const
=
0
;
public:
Item_func_case_abbreviation2_switch
(
THD
*
thd
,
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func_case_abbreviation2
(
thd
,
a
,
b
,
c
)
{
}
bool
date_op
(
MYSQL_TIME
*
ltime
,
uint
fuzzydate
)
{
return
get_date_with_conversion_from_item
(
find_item
(),
ltime
,
fuzzydate
);
}
longlong
int_op
()
{
return
val_int_from_item
(
find_item
());
}
double
real_op
()
{
return
val_real_from_item
(
find_item
());
}
my_decimal
*
decimal_op
(
my_decimal
*
decimal_value
)
{
return
val_decimal_from_item
(
find_item
(),
decimal_value
);
}
String
*
str_op
(
String
*
str
)
{
return
val_str_from_item
(
find_item
(),
str
);
}
};
class
Item_func_if
:
public
Item_func_case_abbreviation2_switch
{
{
protected:
Item
*
find_item
()
const
{
return
args
[
0
]
->
val_bool
()
?
args
[
1
]
:
args
[
2
];
}
public:
public:
Item_func_if
(
THD
*
thd
,
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func_if
(
THD
*
thd
,
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func_case_abbreviation2
(
thd
,
a
,
b
,
c
)
Item_func_case_abbreviation2
_switch
(
thd
,
a
,
b
,
c
)
{}
{}
bool
date_op
(
MYSQL_TIME
*
ltime
,
uint
fuzzydate
);
longlong
int_op
();
double
real_op
();
my_decimal
*
decimal_op
(
my_decimal
*
);
String
*
str_op
(
String
*
);
bool
fix_fields
(
THD
*
,
Item
**
);
bool
fix_fields
(
THD
*
,
Item
**
);
void
fix_length_and_dec
();
void
fix_length_and_dec
()
{
fix_length_and_dec2_eliminate_null
(
args
+
1
);
}
uint
decimal_precision
()
const
uint
decimal_precision
()
const
{
{
return
Item_func_case_abbreviation2
::
decimal_precision2
(
args
+
1
);
return
Item_func_case_abbreviation2
::
decimal_precision2
(
args
+
1
);
...
@@ -1067,6 +1138,29 @@ class Item_func_if :public Item_func_case_abbreviation2
...
@@ -1067,6 +1138,29 @@ class Item_func_if :public Item_func_case_abbreviation2
};
};
class
Item_func_nvl2
:
public
Item_func_case_abbreviation2_switch
{
protected:
Item
*
find_item
()
const
{
return
args
[
0
]
->
is_null
()
?
args
[
2
]
:
args
[
1
];
}
public:
Item_func_nvl2
(
THD
*
thd
,
Item
*
a
,
Item
*
b
,
Item
*
c
)
:
Item_func_case_abbreviation2_switch
(
thd
,
a
,
b
,
c
)
{}
const
char
*
func_name
()
const
{
return
"nvl2"
;
}
void
fix_length_and_dec
()
{
fix_length_and_dec2_eliminate_null
(
args
+
1
);
}
uint
decimal_precision
()
const
{
return
Item_func_case_abbreviation2
::
decimal_precision2
(
args
+
1
);
}
Item
*
get_copy
(
THD
*
thd
,
MEM_ROOT
*
mem_root
)
{
return
get_item_copy
<
Item_func_nvl2
>
(
thd
,
mem_root
,
this
);
}
};
class
Item_func_nullif
:
public
Item_func_hybrid_field_type
class
Item_func_nullif
:
public
Item_func_hybrid_field_type
{
{
Arg_comparator
cmp
;
Arg_comparator
cmp
;
...
...
sql/item_create.cc
View file @
30bec863
...
@@ -711,6 +711,19 @@ class Create_func_contains : public Create_func_arg2
...
@@ -711,6 +711,19 @@ class Create_func_contains : public Create_func_arg2
#endif
#endif
class
Create_func_nvl2
:
public
Create_func_arg3
{
public:
virtual
Item
*
create_3_arg
(
THD
*
thd
,
Item
*
arg1
,
Item
*
arg2
,
Item
*
arg3
);
static
Create_func_nvl2
s_singleton
;
protected:
Create_func_nvl2
()
{}
virtual
~
Create_func_nvl2
()
{}
};
class
Create_func_conv
:
public
Create_func_arg3
class
Create_func_conv
:
public
Create_func_arg3
{
{
public:
public:
...
@@ -3931,6 +3944,15 @@ Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
...
@@ -3931,6 +3944,15 @@ Create_func_contains::create_2_arg(THD *thd, Item *arg1, Item *arg2)
#endif
#endif
Create_func_nvl2
Create_func_nvl2
::
s_singleton
;
Item
*
Create_func_nvl2
::
create_3_arg
(
THD
*
thd
,
Item
*
arg1
,
Item
*
arg2
,
Item
*
arg3
)
{
return
new
(
thd
->
mem_root
)
Item_func_nvl2
(
thd
,
arg1
,
arg2
,
arg3
);
}
Create_func_conv
Create_func_conv
::
s_singleton
;
Create_func_conv
Create_func_conv
::
s_singleton
;
Item
*
Item
*
...
@@ -6884,6 +6906,8 @@ static Native_func_registry func_array[] =
...
@@ -6884,6 +6906,8 @@ static Native_func_registry func_array[] =
{
{
C_STRING_WITH_LEN
(
"MULTIPOLYGONFROMTEXT"
)
},
GEOM_BUILDER
(
Create_func_geometry_from_text
)},
{
{
C_STRING_WITH_LEN
(
"MULTIPOLYGONFROMTEXT"
)
},
GEOM_BUILDER
(
Create_func_geometry_from_text
)},
{
{
C_STRING_WITH_LEN
(
"MULTIPOLYGONFROMWKB"
)
},
GEOM_BUILDER
(
Create_func_geometry_from_wkb
)},
{
{
C_STRING_WITH_LEN
(
"MULTIPOLYGONFROMWKB"
)
},
GEOM_BUILDER
(
Create_func_geometry_from_wkb
)},
{
{
C_STRING_WITH_LEN
(
"NAME_CONST"
)
},
BUILDER
(
Create_func_name_const
)},
{
{
C_STRING_WITH_LEN
(
"NAME_CONST"
)
},
BUILDER
(
Create_func_name_const
)},
{
{
C_STRING_WITH_LEN
(
"NVL"
)
},
BUILDER
(
Create_func_ifnull
)},
{
{
C_STRING_WITH_LEN
(
"NVL2"
)
},
BUILDER
(
Create_func_nvl2
)},
{
{
C_STRING_WITH_LEN
(
"NULLIF"
)
},
BUILDER
(
Create_func_nullif
)},
{
{
C_STRING_WITH_LEN
(
"NULLIF"
)
},
BUILDER
(
Create_func_nullif
)},
{
{
C_STRING_WITH_LEN
(
"NUMGEOMETRIES"
)
},
GEOM_BUILDER
(
Create_func_numgeometries
)},
{
{
C_STRING_WITH_LEN
(
"NUMGEOMETRIES"
)
},
GEOM_BUILDER
(
Create_func_numgeometries
)},
{
{
C_STRING_WITH_LEN
(
"NUMINTERIORRINGS"
)
},
GEOM_BUILDER
(
Create_func_numinteriorring
)},
{
{
C_STRING_WITH_LEN
(
"NUMINTERIORRINGS"
)
},
GEOM_BUILDER
(
Create_func_numinteriorring
)},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment