2017-11-02 10:06:02 +01:00
|
|
|
/* Copyright (c) 2017, MariaDB
|
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
|
|
|
|
|
2017-06-29 14:32:17 +02:00
|
|
|
#ifndef SQL_TVC_INCLUDED
|
|
|
|
#define SQL_TVC_INCLUDED
|
|
|
|
#include "sql_type.h"
|
|
|
|
|
|
|
|
typedef List<Item> List_item;
|
MDEV-14347 CREATE PROCEDURE returns no error when using an unknown variable
CREATE PROCEDURE did not detect unknown SP variables in assignments like this:
SET var=a_long_var_name_with_a_typo;
The error happened only during the SP execution time, and only of the control
flow reaches the erroneous statement.
Fixing most expressions to detect unknown identifiers.
This includes simple subqueries without tables:
- Query specification: SELECT list, WHERE,
HAVING (inside aggregate functions) clauses, e.g.
SET var= (SELECT unknown_ident+1);
SET var= (SELECT 1 WHERE unknown_identifier);
SET var= (SELECT 1 HAVING SUM(unknown_identifier);
- Table value constructor: VALUES clause, e.g.:
SET var= (VALUES(unknown_ident));
Note, in some more complex subquery cases unknown variables are still not detected
(this will be fixed separately):
- Derived tables:
SET a=(SELECT unknown_ident FROM (SELECT 1 AS alias) t1);
SET res=(SELECT * FROM t1 LEFT OUTER JOIN (SELECT unknown_ident) t2 USING (c1));
- CTE:
SET a=(WITH cte1 (a) AS (SELECT unknown_ident) SELECT * FROM cte1);
SET a=(WITH cte1 (a,b) AS (VALUES (unknown,2),(3,4)) SELECT * FROM cte1);
SET a=(WITH cte1 (a,b) AS (VALUES (1,2),(3,4)) SELECT unknown_ident FROM cte1);
- SELECT .. GROUP BY unknown_identifier
- SELECT .. ORDER BY unknown_identifier
- HAVING with an unknown identifier outside of any aggregate functions:
SELECT .. HAVING unknown_identifier;
2020-06-09 21:03:08 +02:00
|
|
|
typedef bool (Item::*Item_processor) (void *arg);
|
2017-06-29 14:32:17 +02:00
|
|
|
class select_result;
|
2017-08-29 02:32:39 +02:00
|
|
|
class Explain_select;
|
|
|
|
class Explain_query;
|
|
|
|
class Item_func_in;
|
2017-11-22 07:01:43 +01:00
|
|
|
class st_select_lex_unit;
|
|
|
|
typedef class st_select_lex SELECT_LEX;
|
2023-09-24 04:02:52 +02:00
|
|
|
class Type_holder;
|
2017-08-29 02:32:39 +02:00
|
|
|
|
2017-06-29 14:32:17 +02:00
|
|
|
/**
|
|
|
|
@class table_value_constr
|
|
|
|
@brief Definition of a Table Value Construction(TVC)
|
|
|
|
|
2017-08-29 02:32:39 +02:00
|
|
|
It contains a list of lists of values which this TVC is defined by and
|
|
|
|
reference on SELECT where this TVC is defined.
|
2017-06-29 14:32:17 +02:00
|
|
|
*/
|
|
|
|
class table_value_constr : public Sql_alloc
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
List<List_item> lists_of_values;
|
|
|
|
select_result *result;
|
2017-08-29 02:32:39 +02:00
|
|
|
SELECT_LEX *select_lex;
|
2023-09-24 04:02:52 +02:00
|
|
|
Type_holder *type_holders;
|
2017-08-29 02:32:39 +02:00
|
|
|
|
|
|
|
enum { QEP_NOT_PRESENT_YET, QEP_AVAILABLE} have_query_plan;
|
|
|
|
|
|
|
|
Explain_select *explain;
|
|
|
|
ulonglong select_options;
|
2017-06-29 14:32:17 +02:00
|
|
|
|
2017-08-29 02:32:39 +02:00
|
|
|
table_value_constr(List<List_item> tvc_values, SELECT_LEX *sl,
|
|
|
|
ulonglong select_options_arg) :
|
2023-09-24 04:02:52 +02:00
|
|
|
lists_of_values(tvc_values), result(0), select_lex(sl), type_holders(0),
|
2017-08-29 02:32:39 +02:00
|
|
|
have_query_plan(QEP_NOT_PRESENT_YET), explain(0),
|
|
|
|
select_options(select_options_arg)
|
|
|
|
{ };
|
2018-08-19 07:57:20 +02:00
|
|
|
|
|
|
|
ha_rows get_records() { return lists_of_values.elements; }
|
2017-06-30 12:54:33 +02:00
|
|
|
|
2017-06-29 14:32:17 +02:00
|
|
|
bool prepare(THD *thd_arg, SELECT_LEX *sl,
|
2017-08-29 02:32:39 +02:00
|
|
|
select_result *tmp_result,
|
|
|
|
st_select_lex_unit *unit_arg);
|
|
|
|
|
2019-05-08 09:08:09 +02:00
|
|
|
bool to_be_wrapped_as_with_tail();
|
|
|
|
|
2017-08-29 02:32:39 +02:00
|
|
|
int save_explain_data_intern(THD *thd_arg,
|
|
|
|
Explain_query *output);
|
2017-11-14 06:47:58 +01:00
|
|
|
bool optimize(THD *thd_arg);
|
2017-08-29 02:32:39 +02:00
|
|
|
bool exec(SELECT_LEX *sl);
|
2017-06-29 14:32:17 +02:00
|
|
|
|
2017-08-29 02:32:39 +02:00
|
|
|
void print(THD *thd_arg, String *str, enum_query_type query_type);
|
MDEV-14347 CREATE PROCEDURE returns no error when using an unknown variable
CREATE PROCEDURE did not detect unknown SP variables in assignments like this:
SET var=a_long_var_name_with_a_typo;
The error happened only during the SP execution time, and only of the control
flow reaches the erroneous statement.
Fixing most expressions to detect unknown identifiers.
This includes simple subqueries without tables:
- Query specification: SELECT list, WHERE,
HAVING (inside aggregate functions) clauses, e.g.
SET var= (SELECT unknown_ident+1);
SET var= (SELECT 1 WHERE unknown_identifier);
SET var= (SELECT 1 HAVING SUM(unknown_identifier);
- Table value constructor: VALUES clause, e.g.:
SET var= (VALUES(unknown_ident));
Note, in some more complex subquery cases unknown variables are still not detected
(this will be fixed separately):
- Derived tables:
SET a=(SELECT unknown_ident FROM (SELECT 1 AS alias) t1);
SET res=(SELECT * FROM t1 LEFT OUTER JOIN (SELECT unknown_ident) t2 USING (c1));
- CTE:
SET a=(WITH cte1 (a) AS (SELECT unknown_ident) SELECT * FROM cte1);
SET a=(WITH cte1 (a,b) AS (VALUES (unknown,2),(3,4)) SELECT * FROM cte1);
SET a=(WITH cte1 (a,b) AS (VALUES (1,2),(3,4)) SELECT unknown_ident FROM cte1);
- SELECT .. GROUP BY unknown_identifier
- SELECT .. ORDER BY unknown_identifier
- HAVING with an unknown identifier outside of any aggregate functions:
SELECT .. HAVING unknown_identifier;
2020-06-09 21:03:08 +02:00
|
|
|
bool walk_values(Item_processor processor, bool walk_subquery, void *arg);
|
2017-08-29 02:32:39 +02:00
|
|
|
};
|
2019-05-08 09:08:09 +02:00
|
|
|
|
|
|
|
st_select_lex *wrap_tvc_with_tail(THD *thd, st_select_lex *tvc_sl);
|
|
|
|
|
2017-11-02 10:06:02 +01:00
|
|
|
#endif /* SQL_TVC_INCLUDED */
|