Skip to content

Commit 3a8974c

Browse files
committed
Bug#36226080: wl16142-Mysqld failure-String::c_ptr_safe
Step 2: Add ROUTINE_FIELD_ITEM type code. Add this new type code and let class Item_splocal return it. Also eliminated local variables m_type and m_result_type, the latter can be derived at runtime from data_type(). This also made it possible to remove the redundant functions sp_map_result_type() and sp_map_item_type(). Added some extra regression tests for use of LIMIT, NTILE, LEAD and LAG with stored procedures, since there is now a different type code for procedure variables and parameters that must be of integer type. Change-Id: I1206c889407ac88982325ab508cbedb89b27e707
1 parent b1c4393 commit 3a8974c

11 files changed

+207
-60
lines changed

mysql-test/r/sp.result

+11
Original file line numberDiff line numberDiff line change
@@ -7344,6 +7344,17 @@ set a = (select count(*) from t1 limit a, b);
73447344
return a;
73457345
end|
73467346
ERROR 42000: Undeclared variable: b
7347+
# Variables used in LIMIT and OFFSET must be of integer type
7348+
create function f1() returns integer
7349+
begin
7350+
declare a integer;
7351+
declare b, c real;
7352+
set a = (select count(*) from t1 limit a, b);
7353+
return a;
7354+
end|
7355+
ERROR 42000: The variable "b" has a non-integer based type near 'b);
7356+
return a;
7357+
end' at line 5
73477358
create function f1()
73487359
returns int
73497360
begin

mysql-test/r/window_functions.result

+80-1
Original file line numberDiff line numberDiff line change
@@ -9461,10 +9461,89 @@ DO LEAD(1, 18446744073709551615) OVER();
94619461
ERROR HY000: Incorrect arguments to lead
94629462
DO NTILE(18446744073709551615) OVER();
94639463
ERROR HY000: Incorrect arguments to ntile
9464-
CREATE PROCEDURE p1(n INT) DO NTILE(n) OVER();
9464+
CREATE PROCEDURE p1(n INTEGER) DO NTILE(n) OVER();
94659465
CALL p1(NULL);
94669466
ERROR HY000: Incorrect arguments to ntile
94679467
DROP PROCEDURE p1;
9468+
CREATE PROCEDURE p1(n INTEGER) DO LEAD('x', n) OVER();
9469+
CALL p1(NULL);
9470+
ERROR HY000: Incorrect arguments to lead
9471+
CALL p1(0);
9472+
CALL p1(-1);
9473+
ERROR HY000: Incorrect arguments to lead
9474+
DROP PROCEDURE p1;
9475+
CREATE PROCEDURE p1(n INTEGER) DO LAG('x', n) OVER();
9476+
CALL p1(NULL);
9477+
ERROR HY000: Incorrect arguments to lag
9478+
CALL p1(0);
9479+
CALL p1(-1);
9480+
ERROR HY000: Incorrect arguments to lag
9481+
DROP PROCEDURE p1;
9482+
CREATE PROCEDURE p1(n DATE) DO NTILE(n) OVER();
9483+
ERROR 42000: The variable "n" has a non-integer based type near 'n) OVER()' at line 1
9484+
CREATE PROCEDURE p1()
9485+
BEGIN
9486+
DECLARE d DATE;
9487+
DO NTILE(d) OVER();
9488+
END
9489+
//
9490+
ERROR 42000: The variable "d" has a non-integer based type near 'd) OVER();
9491+
END' at line 4
9492+
CREATE PROCEDURE p2()
9493+
BEGIN
9494+
DECLARE d DATE;
9495+
DO LEAD('x', d) OVER();
9496+
END
9497+
//
9498+
ERROR 42000: The variable "d" has a non-integer based type near 'd) OVER();
9499+
END' at line 4
9500+
CREATE PROCEDURE p3()
9501+
BEGIN
9502+
DECLARE d DATE;
9503+
DO LAG('x', d) OVER();
9504+
END
9505+
//
9506+
ERROR 42000: The variable "d" has a non-integer based type near 'd) OVER();
9507+
END' at line 4
9508+
CREATE PROCEDURE p1(n INTEGER)
9509+
BEGIN
9510+
DECLARE i INTEGER;
9511+
SET i = n;
9512+
DO NTILE(i) OVER();
9513+
END
9514+
//
9515+
CREATE PROCEDURE p2(n INTEGER)
9516+
BEGIN
9517+
DECLARE i INTEGER;
9518+
SET i = n;
9519+
DO LEAD('x', i) OVER();
9520+
END
9521+
//
9522+
CREATE PROCEDURE p3(n INTEGER)
9523+
BEGIN
9524+
DECLARE i INTEGER;
9525+
SET i = n;
9526+
DO LAG('x', i) OVER();
9527+
END
9528+
//
9529+
CALL p1(NULL);
9530+
ERROR HY000: Incorrect arguments to ntile
9531+
CALL p1(0);
9532+
ERROR HY000: Incorrect arguments to ntile
9533+
CALL p1(1);
9534+
CALL p2(NULL);
9535+
ERROR HY000: Incorrect arguments to lead
9536+
CALL p2(0);
9537+
CALL p2(-1);
9538+
ERROR HY000: Incorrect arguments to lead
9539+
CALL p3(NULL);
9540+
ERROR HY000: Incorrect arguments to lag
9541+
CALL p3(0);
9542+
CALL p3(-1);
9543+
ERROR HY000: Incorrect arguments to lag
9544+
DROP PROCEDURE p1;
9545+
DROP PROCEDURE p2;
9546+
DROP PROCEDURE p3;
94689547
SET @v = NULL;
94699548
PREPARE stmt FROM 'DO NTILE(?) OVER()';
94709549
EXECUTE stmt USING @v;

mysql-test/t/sp.test

+10
Original file line numberDiff line numberDiff line change
@@ -8461,6 +8461,16 @@ begin
84618461
return a;
84628462
end|
84638463

8464+
--echo # Variables used in LIMIT and OFFSET must be of integer type
8465+
--error ER_PARSE_ERROR
8466+
create function f1() returns integer
8467+
begin
8468+
declare a integer;
8469+
declare b, c real;
8470+
set a = (select count(*) from t1 limit a, b);
8471+
return a;
8472+
end|
8473+
84648474
create function f1()
84658475
returns int
84668476
begin

mysql-test/t/window_functions.test

+93-1
Original file line numberDiff line numberDiff line change
@@ -4231,11 +4231,103 @@ DO NTILE(18446744073709551615) OVER();
42314231

42324232
# Negative coverage tests for some non-literal arguments:
42334233

4234-
CREATE PROCEDURE p1(n INT) DO NTILE(n) OVER();
4234+
CREATE PROCEDURE p1(n INTEGER) DO NTILE(n) OVER();
42354235
--error ER_WRONG_ARGUMENTS
42364236
CALL p1(NULL);
42374237
DROP PROCEDURE p1;
42384238

4239+
CREATE PROCEDURE p1(n INTEGER) DO LEAD('x', n) OVER();
4240+
--error ER_WRONG_ARGUMENTS
4241+
CALL p1(NULL);
4242+
CALL p1(0);
4243+
--error ER_WRONG_ARGUMENTS
4244+
CALL p1(-1);
4245+
DROP PROCEDURE p1;
4246+
4247+
CREATE PROCEDURE p1(n INTEGER) DO LAG('x', n) OVER();
4248+
--error ER_WRONG_ARGUMENTS
4249+
CALL p1(NULL);
4250+
CALL p1(0);
4251+
--error ER_WRONG_ARGUMENTS
4252+
CALL p1(-1);
4253+
DROP PROCEDURE p1;
4254+
4255+
--error ER_PARSE_ERROR
4256+
CREATE PROCEDURE p1(n DATE) DO NTILE(n) OVER();
4257+
4258+
delimiter //;
4259+
--error ER_PARSE_ERROR
4260+
CREATE PROCEDURE p1()
4261+
BEGIN
4262+
DECLARE d DATE;
4263+
DO NTILE(d) OVER();
4264+
END
4265+
//
4266+
4267+
--error ER_PARSE_ERROR
4268+
CREATE PROCEDURE p2()
4269+
BEGIN
4270+
DECLARE d DATE;
4271+
DO LEAD('x', d) OVER();
4272+
END
4273+
//
4274+
4275+
--error ER_PARSE_ERROR
4276+
CREATE PROCEDURE p3()
4277+
BEGIN
4278+
DECLARE d DATE;
4279+
DO LAG('x', d) OVER();
4280+
END
4281+
//
4282+
4283+
CREATE PROCEDURE p1(n INTEGER)
4284+
BEGIN
4285+
DECLARE i INTEGER;
4286+
SET i = n;
4287+
DO NTILE(i) OVER();
4288+
END
4289+
//
4290+
4291+
CREATE PROCEDURE p2(n INTEGER)
4292+
BEGIN
4293+
DECLARE i INTEGER;
4294+
SET i = n;
4295+
DO LEAD('x', i) OVER();
4296+
END
4297+
//
4298+
4299+
CREATE PROCEDURE p3(n INTEGER)
4300+
BEGIN
4301+
DECLARE i INTEGER;
4302+
SET i = n;
4303+
DO LAG('x', i) OVER();
4304+
END
4305+
//
4306+
4307+
delimiter ;//
4308+
4309+
--error ER_WRONG_ARGUMENTS
4310+
CALL p1(NULL);
4311+
--error ER_WRONG_ARGUMENTS
4312+
CALL p1(0);
4313+
CALL p1(1);
4314+
4315+
--error ER_WRONG_ARGUMENTS
4316+
CALL p2(NULL);
4317+
CALL p2(0);
4318+
--error ER_WRONG_ARGUMENTS
4319+
CALL p2(-1);
4320+
4321+
--error ER_WRONG_ARGUMENTS
4322+
CALL p3(NULL);
4323+
CALL p3(0);
4324+
--error ER_WRONG_ARGUMENTS
4325+
CALL p3(-1);
4326+
4327+
DROP PROCEDURE p1;
4328+
DROP PROCEDURE p2;
4329+
DROP PROCEDURE p3;
4330+
42394331
SET @v = NULL;
42404332

42414333
PREPARE stmt FROM 'DO NTILE(?) OVER()';

sql/item.cc

+2-5
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
#include "sql/protocol.h"
7777
#include "sql/query_options.h"
7878
#include "sql/select_lex_visitor.h"
79-
#include "sql/sp.h" // sp_map_item_type
79+
#include "sql/sp.h" // sp_prepare_func_item
8080
#include "sql/sp_rcontext.h" // sp_rcontext
8181
#include "sql/sql_base.h" // view_ref_found
8282
#include "sql/sql_bitmap.h"
@@ -1961,10 +1961,7 @@ Item_splocal::Item_splocal(const Name_string sp_var_name, uint sp_var_idx,
19611961
len_in_query(len_in_q) {
19621962
set_nullable(true);
19631963

1964-
sp_var_type = real_type_to_type(sp_var_type);
1965-
m_type = sp_map_item_type(sp_var_type);
1966-
set_data_type(sp_var_type);
1967-
m_result_type = sp_map_result_type(sp_var_type);
1964+
set_data_type(real_type_to_type(sp_var_type));
19681965
}
19691966

19701967
Item *Item_splocal::this_item() {

sql/item.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -986,6 +986,7 @@ class Item : public Parse_tree_node {
986986
CACHE_ITEM, ///< An internal item used to cache values.
987987
TYPE_HOLDER_ITEM, ///< An internal item used to help aggregate a type.
988988
PARAM_ITEM, ///< A dynamic parameter used in a prepared statement.
989+
ROUTINE_FIELD_ITEM, ///< A variable inside a routine (proc, func, trigger)
989990
TRIGGER_FIELD_ITEM, ///< An OLD or NEW field, used in trigger definitions.
990991
XPATH_NODESET_ITEM, ///< Used in XPATH expressions.
991992
VALUES_COLUMN_ITEM ///< A value from a VALUES clause.
@@ -3896,9 +3897,6 @@ class Item_splocal final : public Item_sp_variable,
38963897
private Settable_routine_parameter {
38973898
uint m_var_idx;
38983899

3899-
Type m_type;
3900-
Item_result m_result_type;
3901-
39023900
public:
39033901
/*
39043902
If this variable is a parameter in LIMIT clause.
@@ -3941,10 +3939,12 @@ class Item_splocal final : public Item_sp_variable,
39413939
enum_query_type query_type) const override;
39423940

39433941
public:
3944-
inline uint get_var_idx() const { return m_var_idx; }
3942+
uint get_var_idx() const { return m_var_idx; }
39453943

3946-
inline enum Type type() const override { return m_type; }
3947-
inline Item_result result_type() const override { return m_result_type; }
3944+
Type type() const override { return ROUTINE_FIELD_ITEM; }
3945+
Item_result result_type() const override {
3946+
return type_to_result(data_type());
3947+
}
39483948
bool val_json(Json_wrapper *result) override;
39493949

39503950
private:

sql/item_func.h

+1
Original file line numberDiff line numberDiff line change
@@ -3206,6 +3206,7 @@ class user_var_entry {
32063206
/* Routines to access the value and its type */
32073207
const char *ptr() const { return m_ptr; }
32083208
size_t length() const { return m_length; }
3209+
/// The data type of this variable.
32093210
Item_result type() const { return m_type; }
32103211
/* Item-alike routines to access the value */
32113212
double val_real(bool *null_value) const;

sql/parse_tree_items.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,9 @@ bool PTI_int_splocal::do_itemize(Parse_context *pc, Item **res) {
693693
if (v == nullptr) {
694694
return true; // undefined variable or OOM
695695
}
696-
if (v->type() != Item::INT_ITEM) {
696+
// Data type for a routine field is resolved during parsing, so this is OK:
697+
if (v->type() == Item::ROUTINE_FIELD_ITEM &&
698+
!is_integer_type(v->data_type())) {
697699
pc->thd->syntax_error_at(m_location, ER_SPVAR_NONINTEGER_TYPE, m_name.str);
698700
return true;
699701
}

sql/sp.cc

-44
Original file line numberDiff line numberDiff line change
@@ -2279,50 +2279,6 @@ void sp_finish_parsing(THD *thd) {
22792279
sp->m_parser_data.finish_parsing_sp_body(thd);
22802280
}
22812281

2282-
/// @return Item_result code corresponding to the RETURN-field type code.
2283-
Item_result sp_map_result_type(enum enum_field_types type) {
2284-
switch (type) {
2285-
case MYSQL_TYPE_BIT:
2286-
case MYSQL_TYPE_BOOL:
2287-
case MYSQL_TYPE_TINY:
2288-
case MYSQL_TYPE_SHORT:
2289-
case MYSQL_TYPE_LONG:
2290-
case MYSQL_TYPE_LONGLONG:
2291-
case MYSQL_TYPE_INT24:
2292-
return INT_RESULT;
2293-
case MYSQL_TYPE_DECIMAL:
2294-
case MYSQL_TYPE_NEWDECIMAL:
2295-
return DECIMAL_RESULT;
2296-
case MYSQL_TYPE_FLOAT:
2297-
case MYSQL_TYPE_DOUBLE:
2298-
return REAL_RESULT;
2299-
default:
2300-
return STRING_RESULT;
2301-
}
2302-
}
2303-
2304-
/// @return Item::Type code corresponding to the RETURN-field type code.
2305-
Item::Type sp_map_item_type(enum enum_field_types type) {
2306-
switch (type) {
2307-
case MYSQL_TYPE_BIT:
2308-
case MYSQL_TYPE_BOOL:
2309-
case MYSQL_TYPE_TINY:
2310-
case MYSQL_TYPE_SHORT:
2311-
case MYSQL_TYPE_LONG:
2312-
case MYSQL_TYPE_LONGLONG:
2313-
case MYSQL_TYPE_INT24:
2314-
return Item::INT_ITEM;
2315-
case MYSQL_TYPE_DECIMAL:
2316-
case MYSQL_TYPE_NEWDECIMAL:
2317-
return Item::DECIMAL_ITEM;
2318-
case MYSQL_TYPE_FLOAT:
2319-
case MYSQL_TYPE_DOUBLE:
2320-
return Item::REAL_ITEM;
2321-
default:
2322-
return Item::STRING_ITEM;
2323-
}
2324-
}
2325-
23262282
/**
23272283
@param lex LEX-object, representing an SQL-statement inside SP.
23282284

sql/sp.h

-2
Original file line numberDiff line numberDiff line change
@@ -399,8 +399,6 @@ void sp_finish_parsing(THD *thd);
399399

400400
///////////////////////////////////////////////////////////////////////////
401401

402-
Item_result sp_map_result_type(enum enum_field_types type);
403-
Item::Type sp_map_item_type(enum enum_field_types type);
404402
uint sp_get_flags_for_command(LEX *lex);
405403

406404
bool sp_check_name(LEX_STRING *ident);

sql/sql_tmp_table.cc

+1
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ Field *create_tmp_field(THD *thd, TABLE *table, Item *item, Item::Type type,
472472
case Item::NULL_ITEM:
473473
case Item::HEX_BIN_ITEM:
474474
case Item::PARAM_ITEM:
475+
case Item::ROUTINE_FIELD_ITEM:
475476
case Item::SUM_FUNC_ITEM:
476477
if (type == Item::SUM_FUNC_ITEM && !is_wf) {
477478
Item_sum *item_sum = down_cast<Item_sum *>(item);

0 commit comments

Comments
 (0)