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
ab23aa25
Commit
ab23aa25
authored
Mar 16, 2007
by
Kristofer.Pettersson@naruto
Browse files
Options
Browse Files
Download
Plain Diff
Merge naruto.:C:/cpp/bug20777/my50-bug20777
into naruto.:C:/cpp/bug20777/my51-bug20777
parents
f97d10d2
05bef788
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
318 additions
and
185 deletions
+318
-185
mysql-test/r/sp.result
mysql-test/r/sp.result
+88
-0
mysql-test/t/sp.test
mysql-test/t/sp.test
+56
-4
sql/item_func.cc
sql/item_func.cc
+157
-167
sql/item_func.h
sql/item_func.h
+17
-14
No files found.
mysql-test/r/sp.result
View file @
ab23aa25
...
@@ -5832,4 +5832,92 @@ END|
...
@@ -5832,4 +5832,92 @@ END|
CALL bug24117()|
CALL bug24117()|
DROP PROCEDURE bug24117|
DROP PROCEDURE bug24117|
DROP TABLE t3|
DROP TABLE t3|
drop function if exists bug20777|
drop table if exists examplebug20777|
create function bug20777(f1 bigint unsigned) returns bigint unsigned
begin
set f1 = (f1 - 10); set f1 = (f1 + 10);
return f1;
end|
select bug20777(9223372036854775803) as '9223372036854775803 2**63-5';
9223372036854775803 2**63-5
9223372036854775803
select bug20777(9223372036854775804) as '9223372036854775804 2**63-4';
9223372036854775804 2**63-4
9223372036854775804
select bug20777(9223372036854775805) as '9223372036854775805 2**63-3';
9223372036854775805 2**63-3
9223372036854775805
select bug20777(9223372036854775806) as '9223372036854775806 2**63-2';
9223372036854775806 2**63-2
9223372036854775806
select bug20777(9223372036854775807) as '9223372036854775807 2**63-1';
9223372036854775807 2**63-1
9223372036854775807
select bug20777(9223372036854775808) as '9223372036854775808 2**63+0';
9223372036854775808 2**63+0
9223372036854775808
select bug20777(9223372036854775809) as '9223372036854775809 2**63+1';
9223372036854775809 2**63+1
9223372036854775809
select bug20777(9223372036854775810) as '9223372036854775810 2**63+2';
9223372036854775810 2**63+2
9223372036854775810
select bug20777(-9223372036854775808) as 'lower bounds signed bigint';
lower bounds signed bigint
0
select bug20777(9223372036854775807) as 'upper bounds signed bigint';
upper bounds signed bigint
9223372036854775807
select bug20777(0) as 'lower bounds unsigned bigint';
lower bounds unsigned bigint
0
select bug20777(18446744073709551615) as 'upper bounds unsigned bigint';
upper bounds unsigned bigint
18446744073709551615
select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1';
upper bounds unsigned bigint + 1
18446744073709551615
select bug20777(-1) as 'lower bounds unsigned bigint - 1';
lower bounds unsigned bigint - 1
0
select bug20777(1.84e+19) as 'submitter value, 1.84e19';
submitter value, 1.84e19
9223372036854775808
create table examplebug20777 as select
0 as 'i',
bug20777(9223372036854775806) as '2**63-2',
bug20777(9223372036854775807) as '2**63-1',
bug20777(9223372036854775808) as '2**63',
bug20777(9223372036854775809) as '2**63+1',
bug20777(18446744073709551614) as '2**64-2',
bug20777(18446744073709551615) as '2**64-1',
bug20777(18446744073709551616) as '2**64',
bug20777(0) as '0',
bug20777(-1) as '-1';
insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1);
show create table examplebug20777;
Table Create Table
examplebug20777 CREATE TABLE `examplebug20777` (
`i` int(1) NOT NULL default '0',
`2**63-2` bigint(20) unsigned default NULL,
`2**63-1` bigint(20) unsigned default NULL,
`2**63` bigint(20) unsigned default NULL,
`2**63+1` bigint(20) unsigned default NULL,
`2**64-2` bigint(20) unsigned default NULL,
`2**64-1` bigint(20) unsigned default NULL,
`2**64` bigint(20) unsigned default NULL,
`0` bigint(20) unsigned default NULL,
`-1` bigint(20) unsigned default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
select * from examplebug20777 order by i;
i 2**63-2 2**63-1 2**63 2**63+1 2**64-2 2**64-1 2**64 0 -1
0 9223372036854775806 9223372036854775807 9223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 18446744073709551615 0 0
1 9223372036854775806 9223372036854775807 223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 8446744073709551616 0 0
drop table examplebug20777;
select bug20777(18446744073709551613)+1;
bug20777(18446744073709551613)+1
18446744073709551614
drop function bug20777;
End of 5.0 tests.
drop table t1,t2;
drop table t1,t2;
mysql-test/t/sp.test
View file @
ab23aa25
...
@@ -6803,9 +6803,56 @@ DROP PROCEDURE bug24117|
...
@@ -6803,9 +6803,56 @@ DROP PROCEDURE bug24117|
DROP TABLE t3|
DROP TABLE t3|
#
#
# NOTE: The delimiter is `
|
`, and not `
;
`. It is changed to `
;
`
# Bug#20777: Function w BIGINT UNSIGNED shows diff. behaviour --ps-protocol
# at the end of the file!
#
#
--disable_warnings
drop function if exists bug20777|
drop table if exists examplebug20777|
--enabled_warnings
create function bug20777(f1 bigint unsigned) returns bigint unsigned
begin
set f1 = (f1 - 10); set f1 = (f1 + 10);
return f1;
end|
delimiter ;|
select bug20777(9223372036854775803) as '9223372036854775803 2**63-5';
select bug20777(9223372036854775804) as '9223372036854775804 2**63-4';
select bug20777(9223372036854775805) as '9223372036854775805 2**63-3';
select bug20777(9223372036854775806) as '9223372036854775806 2**63-2';
select bug20777(9223372036854775807) as '9223372036854775807 2**63-1';
select bug20777(9223372036854775808) as '9223372036854775808 2**63+0';
select bug20777(9223372036854775809) as '9223372036854775809 2**63+1';
select bug20777(9223372036854775810) as '9223372036854775810 2**63+2';
select bug20777(-9223372036854775808) as 'lower bounds signed bigint';
select bug20777(9223372036854775807) as 'upper bounds signed bigint';
select bug20777(0) as 'lower bounds unsigned bigint';
select bug20777(18446744073709551615) as 'upper bounds unsigned bigint';
select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1';
select bug20777(-1) as 'lower bounds unsigned bigint - 1';
select bug20777(1.84e+19) as 'submitter value, 1.84e19';
create table examplebug20777 as select
0 as 'i',
bug20777(9223372036854775806) as '2**63-2',
bug20777(9223372036854775807) as '2**63-1',
bug20777(9223372036854775808) as '2**63',
bug20777(9223372036854775809) as '2**63+1',
bug20777(18446744073709551614) as '2**64-2',
bug20777(18446744073709551615) as '2**64-1',
bug20777(18446744073709551616) as '2**64',
bug20777(0) as '0',
bug20777(-1) as '-1';
insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1);
show create table examplebug20777;
select * from examplebug20777 order by i;
drop table examplebug20777;
select bug20777(18446744073709551613)+1;
drop function bug20777;
delimiter |;
###
--echo End of 5.0 tests.
#
#
# BUG#NNNN: New bug synopsis
# BUG#NNNN: New bug synopsis
...
@@ -6814,8 +6861,13 @@ DROP TABLE t3|
...
@@ -6814,8 +6861,13 @@ DROP TABLE t3|
#drop procedure if exists bugNNNN|
#drop procedure if exists bugNNNN|
#--enable_warnings
#--enable_warnings
#create procedure bugNNNN...
#create procedure bugNNNN...
#
# Add bugs above this line. Use existing tables t1 and t2 when
# Add bugs above this line. Use existing tables t1 and t2 when
# practical, or create table t3, t4 etc temporarily (and drop them).
# practical, or create table t3,t4 etc temporarily (and drop them).
# NOTE: The delimiter is `
|
`, and not `
;
`. It is changed to `
;
`
# at the end of the file!
#
delimiter
;
|
delimiter
;
|
drop
table
t1
,
t2
;
drop
table
t1
,
t2
;
sql/item_func.cc
View file @
ab23aa25
...
@@ -4979,10 +4979,8 @@ longlong Item_func_row_count::val_int()
...
@@ -4979,10 +4979,8 @@ longlong Item_func_row_count::val_int()
}
}
Item_func_sp
::
Item_func_sp
(
Name_resolution_context
*
context_arg
,
Item_func_sp
::
Item_func_sp
(
Name_resolution_context
*
context_arg
,
sp_name
*
name
)
sp_name
*
name_arg
)
:
Item_func
(),
context
(
context_arg
),
m_name
(
name
),
m_sp
(
NULL
),
sp_result_field
(
NULL
)
:
Item_func
(),
context
(
context_arg
),
m_name
(
name_arg
),
m_sp
(
NULL
),
result_field
(
NULL
)
{
{
maybe_null
=
1
;
maybe_null
=
1
;
m_name
->
init_qname
(
current_thd
);
m_name
->
init_qname
(
current_thd
);
...
@@ -4992,9 +4990,8 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
...
@@ -4992,9 +4990,8 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
Item_func_sp
::
Item_func_sp
(
Name_resolution_context
*
context_arg
,
Item_func_sp
::
Item_func_sp
(
Name_resolution_context
*
context_arg
,
sp_name
*
name_arg
,
List
<
Item
>
&
list
)
sp_name
*
name
,
List
<
Item
>
&
list
)
:
Item_func
(
list
),
context
(
context_arg
),
m_name
(
name_arg
),
m_sp
(
NULL
),
:
Item_func
(
list
),
context
(
context_arg
),
m_name
(
name
),
m_sp
(
NULL
),
sp_result_field
(
NULL
)
result_field
(
NULL
)
{
{
maybe_null
=
1
;
maybe_null
=
1
;
m_name
->
init_qname
(
current_thd
);
m_name
->
init_qname
(
current_thd
);
...
@@ -5006,13 +5003,13 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
...
@@ -5006,13 +5003,13 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
void
void
Item_func_sp
::
cleanup
()
Item_func_sp
::
cleanup
()
{
{
if
(
result_field
)
if
(
sp_
result_field
)
{
{
delete
result_field
;
delete
sp_
result_field
;
result_field
=
NULL
;
sp_
result_field
=
NULL
;
}
}
m_sp
=
NULL
;
m_sp
=
NULL
;
dummy_table
->
alia
s
=
NULL
;
dummy_table
->
s
=
NULL
;
Item_func
::
cleanup
();
Item_func
::
cleanup
();
}
}
...
@@ -5038,81 +5035,117 @@ Item_func_sp::func_name() const
...
@@ -5038,81 +5035,117 @@ Item_func_sp::func_name() const
}
}
Field
*
Item_func_sp
::
sp_result_field
(
void
)
const
/**
@brief Initialize the result field by creating a temporary dummy table
and assign it to a newly created field object. Meta data used to
create the field is fetched from the sp_head belonging to the stored
proceedure found in the stored procedure functon cache.
@note This function should be called from fix_fields to init the result
field. It is some what related to Item_field.
@see Item_field
@param thd A pointer to the session and thread context.
@return Function return error status.
@retval TRUE is returned on an error
@retval FALSE is returned on success.
*/
bool
Item_func_sp
::
init_result_field
(
THD
*
thd
)
{
{
Field
*
field
;
DBUG_ENTER
(
"Item_func_sp::init_result_field"
);
DBUG_ENTER
(
"Item_func_sp::sp_result_field"
);
DBUG_PRINT
(
"info"
,
(
"sp: %s, flags: %x, level: %lu"
,
char
*
empty_name
=
(
char
*
)
""
;
(
m_sp
?
"YES"
:
"NO"
),
TABLE_SHARE
*
share
;
(
m_sp
?
m_sp
->
m_flags
:
(
uint
)
0
),
(
m_sp
?
m_sp
->
m_recursion_level
:
(
ulong
)
0
)));
DBUG_ASSERT
(
m_sp
==
NULL
);
DBUG_ASSERT
(
sp_result_field
==
NULL
);
DBUG_ASSERT
(
dummy_table
->
s
==
NULL
);
if
(
!
m_sp
)
{
THD
*
thd
=
current_thd
;
if
(
!
(
m_sp
=
sp_find_routine
(
thd
,
TYPE_ENUM_FUNCTION
,
m_name
,
if
(
!
(
m_sp
=
sp_find_routine
(
thd
,
TYPE_ENUM_FUNCTION
,
m_name
,
&
thd
->
sp_func_cache
,
TRUE
)))
&
thd
->
sp_func_cache
,
TRUE
)))
{
{
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"FUNCTION"
,
m_name
->
m_qname
.
str
);
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"FUNCTION"
,
m_name
->
m_qname
.
str
);
DBUG_RETURN
(
0
);
context
->
process_error
(
thd
);
DBUG_RETURN
(
TRUE
);
}
}
/*
A Field need to be attached to a Table.
Below we "create" a dummy table by initializing
the needed pointers.
*/
dummy_table
->
s
=
share
=
&
dummy_table
->
share_not_to_be_used
;
dummy_table
->
alias
=
empty_name
;
dummy_table
->
maybe_null
=
maybe_null
;
dummy_table
->
in_use
=
thd
;
dummy_table
->
copy_blobs
=
TRUE
;
share
->
table_cache_key
=
empty_name
;
share
->
table_name
=
empty_name
;
if
(
!
(
sp_result_field
=
m_sp
->
create_result_field
(
max_length
,
name
,
dummy_table
)))
{
DBUG_RETURN
(
TRUE
);
}
}
if
(
!
dummy_table
->
alias
)
if
(
sp_result_field
->
pack_length
()
>
sizeof
(
result_buf
))
{
{
char
*
empty_name
=
(
char
*
)
""
;
sp_result_field
->
move_field
(
sql_alloc
(
sp_result_field
->
pack_length
()));
dummy_table
->
alias
=
empty_name
;
}
else
{
dummy_table
->
maybe_null
=
maybe_null
;
sp_result_field
->
move_field
(
result_buf
);
dummy_table
->
in_use
=
current_thd
;
dummy_table
->
copy_blobs
=
TRUE
;
dummy_table
->
s
->
table_cache_key
.
str
=
empty_name
;
dummy_table
->
s
->
table_name
.
str
=
empty_name
;
dummy_table
->
s
->
db
.
str
=
empty_name
;
}
}
if
(
!
(
field
=
m_sp
->
create_result_field
(
max_length
,
name
,
dummy_table
)))
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
DBUG_RETURN
(
field
);
sp_result_field
->
null_ptr
=
(
uchar
*
)
&
null_value
;
sp_result_field
->
null_bit
=
1
;
DBUG_RETURN
(
FALSE
);
}
}
/**
@brief Initialize local members with values from the Field interface.
/*
@note called from Item::fix_fields.
Execute function & store value in field
*/
void
Item_func_sp
::
fix_length_and_dec
()
{
DBUG_ENTER
(
"Item_func_sp::fix_length_and_dec"
);
RETURN
DBUG_ASSERT
(
sp_result_field
);
0 value <> NULL
decimals
=
sp_result_field
->
decimals
();
1 value = NULL or error
max_length
=
sp_result_field
->
field_length
;
collation
.
set
(
sp_result_field
->
charset
());
maybe_null
=
1
;
unsigned_flag
=
test
(
sp_result_field
->
flags
&
UNSIGNED_FLAG
);
DBUG_VOID_RETURN
;
}
/**
@brief Execute function & store value in field.
@return Function returns error status.
@retval FALSE on success.
@retval TRUE if an error occurred.
*/
*/
bool
bool
Item_func_sp
::
execute
(
Field
**
flp
)
Item_func_sp
::
execute
()
{
{
THD
*
thd
=
current_thd
;
THD
*
thd
=
current_thd
;
Field
*
f
;
/*
/*
Get field in virtual tmp table to store result. Create the field if
Get field in virtual tmp table to store result. Create the field if
invoked first time.
invoked first time.
*/
*/
if
(
!
(
f
=
*
flp
))
{
if
(
!
(
*
flp
=
f
=
sp_result_field
()))
{
/* Error set by sp_result_field() */
null_value
=
1
;
return
TRUE
;
}
f
->
move_field
((
f
->
pack_length
()
>
sizeof
(
result_buf
))
?
sql_alloc
(
f
->
pack_length
())
:
result_buf
);
f
->
null_ptr
=
(
uchar
*
)
&
null_value
;
f
->
null_bit
=
1
;
}
/* Execute function and store the return value in the field. */
/* Execute function and store the return value in the field. */
if
(
execute_impl
(
thd
,
f
))
if
(
execute_impl
(
thd
))
{
{
null_value
=
1
;
null_value
=
1
;
context
->
process_error
(
thd
);
context
->
process_error
(
thd
);
...
@@ -5121,14 +5154,24 @@ Item_func_sp::execute(Field **flp)
...
@@ -5121,14 +5154,24 @@ Item_func_sp::execute(Field **flp)
/* Check that the field (the value) is not NULL. */
/* Check that the field (the value) is not NULL. */
null_value
=
f
->
is_null
();
null_value
=
sp_result_field
->
is_null
();
return
null_value
;
return
null_value
;
}
}
/**
@brief Execute function and store the return value in the field.
@note This function was intended to be the concrete implementation of
the interface function execute. This was never realized.
@return The error state.
@retval FALSE on success
@retval TRUE if an error occurred.
*/
bool
bool
Item_func_sp
::
execute_impl
(
THD
*
thd
,
Field
*
return_value_fld
)
Item_func_sp
::
execute_impl
(
THD
*
thd
)
{
{
bool
err_status
=
TRUE
;
bool
err_status
=
TRUE
;
Sub_statement_state
statement_state
;
Sub_statement_state
statement_state
;
...
@@ -5145,7 +5188,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
...
@@ -5145,7 +5188,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
thd
->
security_ctx
=
context
->
security_ctx
;
thd
->
security_ctx
=
context
->
security_ctx
;
}
}
#endif
#endif
if
(
find_and
_check_access
(
thd
))
if
(
sp
_check_access
(
thd
))
goto
error
;
goto
error
;
/*
/*
...
@@ -5166,7 +5209,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
...
@@ -5166,7 +5209,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
function call into binlog.
function call into binlog.
*/
*/
thd
->
reset_sub_statement_state
(
&
statement_state
,
SUB_STMT_FUNCTION
);
thd
->
reset_sub_statement_state
(
&
statement_state
,
SUB_STMT_FUNCTION
);
err_status
=
m_sp
->
execute_function
(
thd
,
args
,
arg_count
,
return_value_fld
);
err_status
=
m_sp
->
execute_function
(
thd
,
args
,
arg_count
,
sp_result_field
);
thd
->
restore_sub_statement_state
(
&
statement_state
);
thd
->
restore_sub_statement_state
(
&
statement_state
);
error:
error:
...
@@ -5181,15 +5224,9 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
...
@@ -5181,15 +5224,9 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
void
void
Item_func_sp
::
make_field
(
Send_field
*
tmp_field
)
Item_func_sp
::
make_field
(
Send_field
*
tmp_field
)
{
{
Field
*
field
;
DBUG_ENTER
(
"Item_func_sp::make_field"
);
DBUG_ENTER
(
"Item_func_sp::make_field"
);
if
((
field
=
sp_result_field
()))
DBUG_ASSERT
(
sp_result_field
);
{
sp_result_field
->
make_field
(
tmp_field
);
field
->
make_field
(
tmp_field
);
delete
field
;
DBUG_VOID_RETURN
;
}
init_make_field
(
tmp_field
,
MYSQL_TYPE_VARCHAR
);
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -5197,67 +5234,20 @@ Item_func_sp::make_field(Send_field *tmp_field)
...
@@ -5197,67 +5234,20 @@ Item_func_sp::make_field(Send_field *tmp_field)
enum
enum_field_types
enum
enum_field_types
Item_func_sp
::
field_type
()
const
Item_func_sp
::
field_type
()
const
{
{
Field
*
field
;
DBUG_ENTER
(
"Item_func_sp::field_type"
);
DBUG_ENTER
(
"Item_func_sp::field_type"
);
DBUG_ASSERT
(
sp_result_field
);
if
(
result_field
)
DBUG_RETURN
(
sp_result_field
->
type
());
DBUG_RETURN
(
result_field
->
type
());
if
((
field
=
sp_result_field
()))
{
enum_field_types
result
=
field
->
type
();
delete
field
;
DBUG_RETURN
(
result
);
}
DBUG_RETURN
(
MYSQL_TYPE_VARCHAR
);
}
}
Item_result
Item_result
Item_func_sp
::
result_type
()
const
Item_func_sp
::
result_type
()
const
{
{
Field
*
field
;
DBUG_ENTER
(
"Item_func_sp::result_type"
);
DBUG_ENTER
(
"Item_func_sp::result_type"
);
DBUG_PRINT
(
"info"
,
(
"m_sp: 0x%lx"
,
(
long
)
m_sp
));
DBUG_PRINT
(
"info"
,
(
"m_sp = %p"
,
m_sp
));
DBUG_ASSERT
(
sp_result_field
);
if
(
result_field
)
DBUG_RETURN
(
sp_result_field
->
result_type
());
DBUG_RETURN
(
result_field
->
result_type
());
if
((
field
=
sp_result_field
()))
{
Item_result
result
=
field
->
result_type
();
delete
field
;
DBUG_RETURN
(
result
);
}
DBUG_RETURN
(
STRING_RESULT
);
}
void
Item_func_sp
::
fix_length_and_dec
()
{
Field
*
field
;
DBUG_ENTER
(
"Item_func_sp::fix_length_and_dec"
);
if
(
result_field
)
{
decimals
=
result_field
->
decimals
();
max_length
=
result_field
->
field_length
;
collation
.
set
(
result_field
->
charset
());
DBUG_VOID_RETURN
;
}
if
(
!
(
field
=
sp_result_field
()))
{
context
->
process_error
(
current_thd
);
DBUG_VOID_RETURN
;
}
decimals
=
field
->
decimals
();
max_length
=
field
->
field_length
;
collation
.
set
(
field
->
charset
());
maybe_null
=
1
;
delete
field
;
DBUG_VOID_RETURN
;
}
}
longlong
Item_func_found_rows
::
val_int
()
longlong
Item_func_found_rows
::
val_int
()
{
{
DBUG_ASSERT
(
fixed
==
1
);
DBUG_ASSERT
(
fixed
==
1
);
...
@@ -5268,57 +5258,39 @@ longlong Item_func_found_rows::val_int()
...
@@ -5268,57 +5258,39 @@ longlong Item_func_found_rows::val_int()
Field
*
Field
*
Item_func_sp
::
tmp_table_field
(
TABLE
*
t_arg
)
Item_func_sp
::
tmp_table_field
(
TABLE
*
t_arg
)
{
{
Field
*
field
=
0
;
DBUG_ENTER
(
"Item_func_sp::tmp_table_field"
);
DBUG_ENTER
(
"Item_func_sp::tmp_table_field"
);
if
(
m_sp
)
DBUG_ASSERT
(
sp_result_field
);
field
=
m_sp
->
create_result_field
(
max_length
,
(
const
char
*
)
name
,
t_arg
);
DBUG_RETURN
(
sp_result_field
);
if
(
!
field
)
field
=
Item_func
::
tmp_table_field
(
t_arg
);
if
(
!
field
)
my_message
(
ER_OUT_OF_RESOURCES
,
ER
(
ER_OUT_OF_RESOURCES
),
MYF
(
0
));
DBUG_RETURN
(
field
);
}
}
/*
/**
Find the function and check access rights to the function
@brief Checks if requested access to function can be granted to user.
SYNOPSIS
find_and_check_access()
thd thread handler
RETURN
FALSE Access granted
TRUE Requested access can't be granted or function doesn't exists
NOTES
Checks if requested access to function can be granted to user.
If function isn't found yet, it searches function first.
If function isn't found yet, it searches function first.
If function can't be found or user don't have requested access
If function can't be found or user don't have requested access
error is raised.
error is raised.
@param thd thread handler
@return Indication if the access was granted or not.
@retval FALSE Access is granted.
@retval TRUE Requested access can't be granted or function doesn't exists.
*/
*/
bool
bool
Item_func_sp
::
find_and
_check_access
(
THD
*
thd
)
Item_func_sp
::
sp
_check_access
(
THD
*
thd
)
{
{
if
(
!
m_sp
&&
!
(
m_sp
=
sp_find_routine
(
thd
,
TYPE_ENUM_FUNCTION
,
m_name
,
DBUG_ENTER
(
"Item_func_sp::sp_check_access"
);
&
thd
->
sp_func_cache
,
TRUE
)))
DBUG_ASSERT
(
m_sp
);
{
my_error
(
ER_SP_DOES_NOT_EXIST
,
MYF
(
0
),
"FUNCTION"
,
m_name
->
m_qname
.
str
);
return
TRUE
;
}
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
if
(
check_routine_access
(
thd
,
EXECUTE_ACL
,
if
(
check_routine_access
(
thd
,
EXECUTE_ACL
,
m_sp
->
m_db
.
str
,
m_sp
->
m_name
.
str
,
0
,
FALSE
))
m_sp
->
m_db
.
str
,
m_sp
->
m_name
.
str
,
0
,
FALSE
))
return
TRUE
;
DBUG_RETURN
(
TRUE
)
;
#endif
#endif
return
FALSE
;
DBUG_RETURN
(
FALSE
)
;
}
}
...
@@ -5326,9 +5298,25 @@ bool
...
@@ -5326,9 +5298,25 @@ bool
Item_func_sp
::
fix_fields
(
THD
*
thd
,
Item
**
ref
)
Item_func_sp
::
fix_fields
(
THD
*
thd
,
Item
**
ref
)
{
{
bool
res
;
bool
res
;
DBUG_ENTER
(
"Item_func_sp::fix_fields"
);
DBUG_ASSERT
(
fixed
==
0
);
DBUG_ASSERT
(
fixed
==
0
);
/*
We must call init_result_field before Item_func::fix_fields()
to make m_sp and result_field members available to fix_length_and_dec(),
which is called from Item_func::fix_fields().
*/
res
=
init_result_field
(
thd
);
if
(
res
)
DBUG_RETURN
(
res
);
res
=
Item_func
::
fix_fields
(
thd
,
ref
);
res
=
Item_func
::
fix_fields
(
thd
,
ref
);
if
(
!
res
&&
thd
->
lex
->
view_prepare_mode
)
if
(
res
)
DBUG_RETURN
(
res
);
if
(
thd
->
lex
->
view_prepare_mode
)
{
{
/*
/*
Here we check privileges of the stored routine only during view
Here we check privileges of the stored routine only during view
...
@@ -5340,15 +5328,17 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
...
@@ -5340,15 +5328,17 @@ Item_func_sp::fix_fields(THD *thd, Item **ref)
good idea especially if the view has SQL SECURITY DEFINER and
good idea especially if the view has SQL SECURITY DEFINER and
the used stored procedure has SQL SECURITY DEFINER.
the used stored procedure has SQL SECURITY DEFINER.
*/
*/
res
=
find_and
_check_access
(
thd
);
res
=
sp
_check_access
(
thd
);
#ifndef NO_EMBEDDED_ACCESS_CHECKS
#ifndef NO_EMBEDDED_ACCESS_CHECKS
/*
Try to set and restore the security context to see whether it's valid
*/
Security_context
*
save_secutiry_ctx
;
Security_context
*
save_secutiry_ctx
;
if
(
!
res
&&
!
(
res
=
set_routine_security_ctx
(
thd
,
m_sp
,
false
,
res
=
set_routine_security_ctx
(
thd
,
m_sp
,
false
,
&
save_secutiry_ctx
);
&
save_secutiry_ctx
)))
if
(
!
res
)
{
sp_restore_security_context
(
thd
,
save_secutiry_ctx
);
sp_restore_security_context
(
thd
,
save_secutiry_ctx
);
}
#endif
/* ! NO_EMBEDDED_ACCESS_CHECKS */
#endif
/* ! NO_EMBEDDED_ACCESS_CHECKS */
}
}
return
res
;
DBUG_RETURN
(
res
)
;
}
}
sql/item_func.h
View file @
ab23aa25
...
@@ -1434,12 +1434,15 @@ class Item_func_sp :public Item_func
...
@@ -1434,12 +1434,15 @@ class Item_func_sp :public Item_func
sp_name
*
m_name
;
sp_name
*
m_name
;
mutable
sp_head
*
m_sp
;
mutable
sp_head
*
m_sp
;
TABLE
*
dummy_table
;
TABLE
*
dummy_table
;
Field
*
result_field
;
char
result_buf
[
64
];
char
result_buf
[
64
];
/*
The result field of the concrete stored function.
*/
Field
*
sp_result_field
;
bool
execute
(
Field
**
flp
);
bool
execute
();
bool
execute_impl
(
THD
*
thd
,
Field
*
return_value_fld
);
bool
execute_impl
(
THD
*
thd
);
Field
*
sp_result_field
(
void
)
const
;
bool
init_result_field
(
THD
*
thd
)
;
public:
public:
...
@@ -1465,23 +1468,23 @@ class Item_func_sp :public Item_func
...
@@ -1465,23 +1468,23 @@ class Item_func_sp :public Item_func
longlong
val_int
()
longlong
val_int
()
{
{
if
(
execute
(
&
result_field
))
if
(
execute
())
return
(
longlong
)
0
;
return
(
longlong
)
0
;
return
result_field
->
val_int
();
return
sp_
result_field
->
val_int
();
}
}
double
val_real
()
double
val_real
()
{
{
if
(
execute
(
&
result_field
))
if
(
execute
())
return
0.0
;
return
0.0
;
return
result_field
->
val_real
();
return
sp_
result_field
->
val_real
();
}
}
my_decimal
*
val_decimal
(
my_decimal
*
dec_buf
)
my_decimal
*
val_decimal
(
my_decimal
*
dec_buf
)
{
{
if
(
execute
(
&
result_field
))
if
(
execute
())
return
NULL
;
return
NULL
;
return
result_field
->
val_decimal
(
dec_buf
);
return
sp_
result_field
->
val_decimal
(
dec_buf
);
}
}
String
*
val_str
(
String
*
str
)
String
*
val_str
(
String
*
str
)
...
@@ -1490,7 +1493,7 @@ class Item_func_sp :public Item_func
...
@@ -1490,7 +1493,7 @@ class Item_func_sp :public Item_func
char
buff
[
20
];
char
buff
[
20
];
buf
.
set
(
buff
,
20
,
str
->
charset
());
buf
.
set
(
buff
,
20
,
str
->
charset
());
buf
.
length
(
0
);
buf
.
length
(
0
);
if
(
execute
(
&
result_field
))
if
(
execute
())
return
NULL
;
return
NULL
;
/*
/*
result_field will set buf pointing to internal buffer
result_field will set buf pointing to internal buffer
...
@@ -1498,7 +1501,7 @@ class Item_func_sp :public Item_func
...
@@ -1498,7 +1501,7 @@ class Item_func_sp :public Item_func
when SP is executed. In order to prevent occasional
when SP is executed. In order to prevent occasional
corruption of returned value, we make here a copy.
corruption of returned value, we make here a copy.
*/
*/
result_field
->
val_str
(
&
buf
);
sp_
result_field
->
val_str
(
&
buf
);
str
->
copy
(
buf
);
str
->
copy
(
buf
);
return
str
;
return
str
;
}
}
...
@@ -1506,11 +1509,11 @@ class Item_func_sp :public Item_func
...
@@ -1506,11 +1509,11 @@ class Item_func_sp :public Item_func
virtual
bool
change_context_processor
(
byte
*
cntx
)
virtual
bool
change_context_processor
(
byte
*
cntx
)
{
context
=
(
Name_resolution_context
*
)
cntx
;
return
FALSE
;
}
{
context
=
(
Name_resolution_context
*
)
cntx
;
return
FALSE
;
}
void
fix_length_and_dec
();
bool
sp_check_access
(
THD
*
thd
);
bool
find_and_check_access
(
THD
*
thd
);
virtual
enum
Functype
functype
()
const
{
return
FUNC_SP
;
}
virtual
enum
Functype
functype
()
const
{
return
FUNC_SP
;
}
bool
fix_fields
(
THD
*
thd
,
Item
**
ref
);
bool
fix_fields
(
THD
*
thd
,
Item
**
ref
);
void
fix_length_and_dec
(
void
);
bool
is_expensive
()
{
return
1
;
}
bool
is_expensive
()
{
return
1
;
}
};
};
...
...
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