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
c5d94db3
Commit
c5d94db3
authored
Apr 21, 2005
by
acurtis@xiphis.org
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
564eb3dc
f6750758
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
280 additions
and
50 deletions
+280
-50
mysql-test/r/sp.result
mysql-test/r/sp.result
+43
-0
mysql-test/t/sp.test
mysql-test/t/sp.test
+56
-0
sql/item_func.cc
sql/item_func.cc
+48
-14
sql/item_func.h
sql/item_func.h
+18
-32
sql/mysql_priv.h
sql/mysql_priv.h
+1
-0
sql/protocol.cc
sql/protocol.cc
+1
-0
sql/sp_head.cc
sql/sp_head.cc
+30
-2
sql/sql_table.cc
sql/sql_table.cc
+71
-0
sql/sql_yacc.yy
sql/sql_yacc.yy
+12
-2
No files found.
mysql-test/r/sp.result
View file @
c5d94db3
...
...
@@ -2967,4 +2967,47 @@ begin end;
goto label1;
end|
drop procedure bug6898|
drop function if exists bug9102|
create function bug9102() returns blob return 'a'|
select bug9102()|
bug9102()
a
drop function bug9102|
drop function if exists bug7648|
create function bug7648() returns bit(8) return 'a'|
select bug7648()|
bug7648()
a
drop function bug7648|
drop function if exists bug9775|
create function bug9775(v1 char(1)) returns enum('a','b') return v1|
select bug9775('a'),bug9775('b'),bug9775('c')|
bug9775('a') bug9775('b') bug9775('c')
a b
drop function bug9775|
create function bug9775(v1 int) returns enum('a','b') return v1|
select bug9775(1),bug9775(2),bug9775(3)|
bug9775(1) bug9775(2) bug9775(3)
a b
drop function bug9775|
create function bug9775(v1 char(1)) returns set('a','b') return v1|
select bug9775('a'),bug9775('b'),bug9775('a,b'),bug9775('c')|
bug9775('a') bug9775('b') bug9775('a,b') bug9775('c')
a b a,b
drop function bug9775|
create function bug9775(v1 int) returns set('a','b') return v1|
select bug9775(1),bug9775(2),bug9775(3),bug9775(4)|
bug9775(1) bug9775(2) bug9775(3) bug9775(4)
a b a,b
drop function bug9775|
drop function if exists bug8861|
create function bug8861(v1 int) returns year return v1|
select bug8861(05)|
bug8861(05)
2005
set @x = bug8861(05)|
select @x|
@x
2005
drop function bug8861|
drop table t1,t2;
mysql-test/t/sp.test
View file @
c5d94db3
...
...
@@ -3644,6 +3644,62 @@ end|
drop
procedure
bug6898
|
#
# BUG#9102: Stored proccedures: function which returns blob causes crash
#
--
disable_warnings
drop
function
if
exists
bug9102
|
--
enable_warnings
create
function
bug9102
()
returns
blob
return
'a'
|
select
bug9102
()
|
drop
function
bug9102
|
#
# BUG#7648: Stored procedure crash when invoking a function that returns a bit
#
--
disable_warnings
drop
function
if
exists
bug7648
|
--
enable_warnings
create
function
bug7648
()
returns
bit
(
8
)
return
'a'
|
select
bug7648
()
|
drop
function
bug7648
|
#
# BUG#9775: crash if create function that returns enum or set
#
--
disable_warnings
drop
function
if
exists
bug9775
|
--
enable_warnings
create
function
bug9775
(
v1
char
(
1
))
returns
enum
(
'a'
,
'b'
)
return
v1
|
select
bug9775
(
'a'
),
bug9775
(
'b'
),
bug9775
(
'c'
)
|
drop
function
bug9775
|
create
function
bug9775
(
v1
int
)
returns
enum
(
'a'
,
'b'
)
return
v1
|
select
bug9775
(
1
),
bug9775
(
2
),
bug9775
(
3
)
|
drop
function
bug9775
|
create
function
bug9775
(
v1
char
(
1
))
returns
set
(
'a'
,
'b'
)
return
v1
|
select
bug9775
(
'a'
),
bug9775
(
'b'
),
bug9775
(
'a,b'
),
bug9775
(
'c'
)
|
drop
function
bug9775
|
create
function
bug9775
(
v1
int
)
returns
set
(
'a'
,
'b'
)
return
v1
|
select
bug9775
(
1
),
bug9775
(
2
),
bug9775
(
3
),
bug9775
(
4
)
|
drop
function
bug9775
|
#
# BUG#8861: If Return is a YEAR data type, value is not shown in year format
#
--
disable_warnings
drop
function
if
exists
bug8861
|
--
enable_warnings
create
function
bug8861
(
v1
int
)
returns
year
return
v1
|
select
bug8861
(
05
)
|
set
@
x
=
bug8861
(
05
)
|
select
@
x
|
drop
function
bug8861
|
#
# BUG#NNNN: New bug synopsis
#
...
...
sql/item_func.cc
View file @
c5d94db3
...
...
@@ -4461,7 +4461,7 @@ longlong Item_func_row_count::val_int()
Item_func_sp
::
Item_func_sp
(
sp_name
*
name
)
:
Item_func
(),
m_name
(
name
),
m_sp
(
NULL
)
:
Item_func
(),
m_name
(
name
),
m_sp
(
NULL
)
,
result_field
(
NULL
)
{
maybe_null
=
1
;
m_name
->
init_qname
(
current_thd
);
...
...
@@ -4470,7 +4470,7 @@ Item_func_sp::Item_func_sp(sp_name *name)
Item_func_sp
::
Item_func_sp
(
sp_name
*
name
,
List
<
Item
>
&
list
)
:
Item_func
(
list
),
m_name
(
name
),
m_sp
(
NULL
)
:
Item_func
(
list
),
m_name
(
name
),
m_sp
(
NULL
)
,
result_field
(
NULL
)
{
maybe_null
=
1
;
m_name
->
init_qname
(
current_thd
);
...
...
@@ -4526,6 +4526,29 @@ Item_func_sp::sp_result_field(void) const
}
int
Item_func_sp
::
execute
(
Field
**
flp
)
{
Item
*
it
;
Field
*
f
;
if
(
execute
(
&
it
))
{
null_value
=
1
;
return
1
;
}
if
(
!
(
f
=
*
flp
))
{
*
flp
=
f
=
sp_result_field
();
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
;
}
it
->
save_in_field
(
f
,
1
);
return
f
->
is_null
();
}
int
Item_func_sp
::
execute
(
Item
**
itp
)
{
...
...
@@ -4601,6 +4624,8 @@ Item_func_sp::field_type() const
Field
*
field
=
0
;
DBUG_ENTER
(
"Item_func_sp::field_type"
);
if
(
result_field
)
DBUG_RETURN
(
result_field
->
type
());
if
(
!
m_sp
)
m_sp
=
sp_find_function
(
current_thd
,
m_name
,
TRUE
);
// cache only
if
((
field
=
sp_result_field
()))
...
...
@@ -4621,6 +4646,8 @@ Item_func_sp::result_type() const
DBUG_ENTER
(
"Item_func_sp::result_type"
);
DBUG_PRINT
(
"info"
,
(
"m_sp = %p"
,
m_sp
));
if
(
result_field
)
DBUG_RETURN
(
result_field
->
result_type
());
if
(
!
m_sp
)
m_sp
=
sp_find_function
(
current_thd
,
m_name
,
TRUE
);
// cache only
if
((
field
=
sp_result_field
()))
...
...
@@ -4636,8 +4663,16 @@ Item_func_sp::result_type() const
void
Item_func_sp
::
fix_length_and_dec
()
{
Field
*
field
=
result_field
;
DBUG_ENTER
(
"Item_func_sp::fix_length_and_dec"
);
if
(
result_field
)
{
decimals
=
result_field
->
decimals
();
max_length
=
result_field
->
representation_length
();
DBUG_VOID_RETURN
;
}
if
(
!
m_sp
)
m_sp
=
sp_find_function
(
current_thd
,
m_name
,
TRUE
);
// cache only
if
(
!
m_sp
)
...
...
@@ -4646,29 +4681,28 @@ Item_func_sp::fix_length_and_dec()
}
else
{
switch
(
result_type
())
{
if
(
!
field
)
field
=
sp_result_field
();
decimals
=
field
->
decimals
();
max_length
=
field
->
representation_length
();
switch
(
field
->
result_type
())
{
case
STRING_RESULT
:
maybe_null
=
1
;
max_length
=
MAX_BLOB_WIDTH
;
break
;
case
REAL_RESULT
:
decimals
=
NOT_FIXED_DEC
;
max_length
=
float_length
(
decimals
);
break
;
case
INT_RESULT
:
decimals
=
0
;
max_length
=
21
;
break
;
case
DECIMAL_RESULT
:
// TODO: where to find real precision and scale?
decimals
=
min
(
DECIMAL_MAX_LENGTH
/
2
,
NOT_FIXED_DEC
-
1
);
max_length
=
DECIMAL_MAX_LENGTH
;
break
;
case
ROW_RESULT
:
default:
// This case should never be chosen
DBUG_ASSERT
(
0
);
break
;
}
if
(
field
!=
result_field
)
delete
field
;
}
DBUG_VOID_RETURN
;
}
...
...
sql/item_func.h
View file @
c5d94db3
...
...
@@ -1283,8 +1283,11 @@ class Item_func_sp :public Item_func
sp_name
*
m_name
;
mutable
sp_head
*
m_sp
;
TABLE
*
dummy_table
;
Field
*
result_field
;
char
result_buf
[
64
];
int
execute
(
Item
**
itp
);
int
execute
(
Field
**
flp
);
Field
*
sp_result_field
(
void
)
const
;
public:
...
...
@@ -1296,6 +1299,12 @@ class Item_func_sp :public Item_func
virtual
~
Item_func_sp
()
{}
void
cleanup
()
{
Item_func
::
cleanup
();
result_field
=
NULL
;
}
const
char
*
func_name
()
const
;
enum
enum_field_types
field_type
()
const
;
...
...
@@ -1308,53 +1317,30 @@ class Item_func_sp :public Item_func
longlong
val_int
()
{
return
(
longlong
)
Item_func_sp
::
val_real
();
if
(
execute
(
&
result_field
))
return
0LL
;
return
result_field
->
val_int
();
}
double
val_real
()
{
Item
*
it
;
double
d
;
if
(
execute
(
&
it
))
{
null_value
=
1
;
if
(
execute
(
&
result_field
))
return
0.0
;
}
d
=
it
->
val_real
();
null_value
=
it
->
null_value
;
return
d
;
return
result_field
->
val_real
();
}
my_decimal
*
val_decimal
(
my_decimal
*
dec_buf
)
{
Item
*
it
;
my_decimal
*
result
;
if
(
execute
(
&
it
))
{
null_value
=
1
;
if
(
execute
(
&
result_field
))
return
NULL
;
}
result
=
it
->
val_decimal
(
dec_buf
);
null_value
=
it
->
null_value
;
return
result
;
return
result_field
->
val_decimal
(
dec_buf
);
}
String
*
val_str
(
String
*
str
)
{
Item
*
it
;
String
*
s
;
if
(
execute
(
&
it
))
{
null_value
=
1
;
if
(
execute
(
&
result_field
))
return
NULL
;
}
s
=
it
->
val_str
(
str
);
null_value
=
it
->
null_value
;
return
s
;
return
result_field
->
val_str
(
str
);
}
void
fix_length_and_dec
();
...
...
sql/mysql_priv.h
View file @
c5d94db3
...
...
@@ -647,6 +647,7 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
Item
***
copy_func
,
Field
**
from_field
,
bool
group
,
bool
modify_item
,
uint
convert_blob_length
);
void
sp_prepare_create_field
(
THD
*
thd
,
create_field
*
sql_field
);
int
prepare_create_field
(
create_field
*
sql_field
,
uint
*
blob_columns
,
int
*
timestamps
,
int
*
timestamps_with_niladic
,
...
...
sql/protocol.cc
View file @
c5d94db3
...
...
@@ -774,6 +774,7 @@ bool Protocol_simple::store(const char *from, uint length,
#ifndef DEBUG_OFF
DBUG_ASSERT
(
field_types
==
0
||
field_types
[
field_pos
]
==
MYSQL_TYPE_DECIMAL
||
field_types
[
field_pos
]
==
MYSQL_TYPE_YEAR
||
field_types
[
field_pos
]
==
MYSQL_TYPE_BIT
||
field_types
[
field_pos
]
==
MYSQL_TYPE_NEWDECIMAL
||
(
field_types
[
field_pos
]
>=
MYSQL_TYPE_ENUM
&&
...
...
sql/sp_head.cc
View file @
c5d94db3
...
...
@@ -370,6 +370,7 @@ TYPELIB *
sp_head
::
create_typelib
(
List
<
String
>
*
src
)
{
TYPELIB
*
result
=
NULL
;
CHARSET_INFO
*
cs
=
m_returns_cs
;
DBUG_ENTER
(
"sp_head::clone_typelib"
);
if
(
src
->
elements
)
{
...
...
@@ -377,12 +378,39 @@ sp_head::create_typelib(List<String> *src)
result
->
count
=
src
->
elements
;
result
->
name
=
""
;
if
(
!
(
result
->
type_names
=
(
const
char
**
)
alloc_root
(
mem_root
,
sizeof
(
char
*
)
*
(
result
->
count
+
1
))))
alloc_root
(
mem_root
,
(
sizeof
(
char
*
)
+
sizeof
(
int
)
)
*
(
result
->
count
+
1
))))
return
0
;
result
->
type_lengths
=
(
unsigned
int
*
)(
result
->
type_names
+
result
->
count
+
1
);
List_iterator
<
String
>
it
(
*
src
);
String
conv
,
*
tmp
;
uint32
dummy
;
for
(
uint
i
=
0
;
i
<
result
->
count
;
i
++
)
result
->
type_names
[
i
]
=
strdup_root
(
mem_root
,
(
it
++
)
->
c_ptr
());
{
tmp
=
it
++
;
if
(
String
::
needs_conversion
(
tmp
->
length
(),
tmp
->
charset
(),
cs
,
&
dummy
))
{
uint
cnv_errs
;
conv
.
copy
(
tmp
->
ptr
(),
tmp
->
length
(),
tmp
->
charset
(),
cs
,
&
cnv_errs
);
char
*
buf
=
(
char
*
)
alloc_root
(
mem_root
,
conv
.
length
()
+
1
);
memcpy
(
buf
,
conv
.
ptr
(),
conv
.
length
());
buf
[
conv
.
length
()]
=
'\0'
;
result
->
type_names
[
i
]
=
buf
;
result
->
type_lengths
[
i
]
=
conv
.
length
();
}
else
{
result
->
type_names
[
i
]
=
strdup_root
(
mem_root
,
tmp
->
c_ptr
());
result
->
type_lengths
[
i
]
=
tmp
->
length
();
}
// Strip trailing spaces.
uint
lengthsp
=
cs
->
cset
->
lengthsp
(
cs
,
result
->
type_names
[
i
],
result
->
type_lengths
[
i
]);
result
->
type_lengths
[
i
]
=
lengthsp
;
((
uchar
*
)
result
->
type_names
[
i
])[
lengthsp
]
=
'\0'
;
}
result
->
type_names
[
result
->
count
]
=
0
;
result
->
type_lengths
[
result
->
count
]
=
0
;
}
return
result
;
}
...
...
sql/sql_table.cc
View file @
c5d94db3
...
...
@@ -1351,6 +1351,77 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
}
/*
Preparation of create_field for SP function return values.
Based on code used in the inner loop of mysql_prepare_table() above
SYNOPSIS
sp_prepare_create_field()
thd Thread object
sql_field Field to prepare
DESCRIPTION
Prepares the field structures for field creation.
*/
void
sp_prepare_create_field
(
THD
*
thd
,
create_field
*
sql_field
)
{
if
(
sql_field
->
sql_type
==
FIELD_TYPE_SET
||
sql_field
->
sql_type
==
FIELD_TYPE_ENUM
)
{
uint32
field_length
,
dummy
;
if
(
sql_field
->
sql_type
==
FIELD_TYPE_SET
)
{
calculate_interval_lengths
(
sql_field
->
charset
,
sql_field
->
interval
,
&
dummy
,
&
field_length
);
sql_field
->
length
=
field_length
+
(
sql_field
->
interval
->
count
-
1
);
}
else
/* FIELD_TYPE_ENUM */
{
calculate_interval_lengths
(
sql_field
->
charset
,
sql_field
->
interval
,
&
field_length
,
&
dummy
);
sql_field
->
length
=
field_length
;
}
set_if_smaller
(
sql_field
->
length
,
MAX_FIELD_WIDTH
-
1
);
}
if
(
sql_field
->
sql_type
==
FIELD_TYPE_BIT
)
{
sql_field
->
pack_flag
=
FIELDFLAG_NUMBER
|
FIELDFLAG_TREAT_BIT_AS_CHAR
;
}
sql_field
->
create_length_to_internal_length
();
if
(
sql_field
->
length
>
MAX_FIELD_VARCHARLENGTH
&&
!
(
sql_field
->
flags
&
BLOB_FLAG
))
{
/* Convert long VARCHAR columns to TEXT or BLOB */
char
warn_buff
[
MYSQL_ERRMSG_SIZE
];
sql_field
->
sql_type
=
FIELD_TYPE_BLOB
;
sql_field
->
flags
|=
BLOB_FLAG
;
sprintf
(
warn_buff
,
ER
(
ER_AUTO_CONVERT
),
sql_field
->
field_name
,
"VARCHAR"
,
(
sql_field
->
charset
==
&
my_charset_bin
)
?
"BLOB"
:
"TEXT"
);
push_warning
(
thd
,
MYSQL_ERROR
::
WARN_LEVEL_NOTE
,
ER_AUTO_CONVERT
,
warn_buff
);
}
if
((
sql_field
->
flags
&
BLOB_FLAG
)
&&
sql_field
->
length
)
{
if
(
sql_field
->
sql_type
==
FIELD_TYPE_BLOB
)
{
/* The user has given a length to the blob column */
sql_field
->
sql_type
=
get_blob_type_from_length
(
sql_field
->
length
);
sql_field
->
pack_length
=
calc_pack_length
(
sql_field
->
sql_type
,
0
);
}
sql_field
->
length
=
0
;
// Probably from an item
}
}
/*
Create a table
...
...
sql/sql_yacc.yy
View file @
c5d94db3
...
...
@@ -1407,6 +1407,16 @@ create_function_tail:
lex->uint_geom_type)))
YYABORT;
sp->m_returns_cs= new_field->charset;
if (new_field->sql_type == FIELD_TYPE_SET ||
new_field->sql_type == FIELD_TYPE_ENUM)
{
new_field->interval=
sp->create_typelib(&new_field->interval_list);
}
sp_prepare_create_field(YYTHD, new_field);
if (prepare_create_field(new_field, &unused1, &unused2, &unused2,
0))
YYABORT;
...
...
@@ -1415,8 +1425,8 @@ create_function_tail:
sp->m_returns_cs= new_field->charset;
sp->m_returns_len= new_field->length;
sp->m_returns_pack= new_field->pack_flag;
sp->m_returns_typelib=
sp->create_typelib(&new_field->interval_list)
;
sp->m_returns_typelib= new_field->interval;
new_field->interval= NULL
;
bzero((char *)&lex->sp_chistics, sizeof(st_sp_chistics));
}
...
...
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