mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-12533 sql_mode=ORACLE: Add support for database qualified sequence names in NEXTVAL and CURRVAL
This commit is contained in:
@ -58,3 +58,20 @@ View Create View character_set_client collation_connection
|
|||||||
v1 CREATE VIEW "v1" AS select lastval("test"."s1") AS "a" latin1 latin1_swedish_ci
|
v1 CREATE VIEW "v1" AS select lastval("test"."s1") AS "a" latin1 latin1_swedish_ci
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP SEQUENCE s1;
|
DROP SEQUENCE s1;
|
||||||
|
#
|
||||||
|
# MDEV-12533 sql_mode=ORACLE: Add support for database qualified sequence names in NEXTVAL and CURRVAL
|
||||||
|
#
|
||||||
|
CREATE SEQUENCE s1;
|
||||||
|
SELECT test.s1.nextval;
|
||||||
|
test.s1.nextval
|
||||||
|
1
|
||||||
|
SELECT test.s1.currval;
|
||||||
|
test.s1.currval
|
||||||
|
1
|
||||||
|
SELECT .s1.nextval;
|
||||||
|
.s1.nextval
|
||||||
|
2
|
||||||
|
SELECT .s1.currval;
|
||||||
|
.s1.currval
|
||||||
|
2
|
||||||
|
DROP SEQUENCE s1;
|
||||||
|
@ -31,3 +31,13 @@ SELECT * FROM v1;
|
|||||||
SHOW CREATE VIEW v1;
|
SHOW CREATE VIEW v1;
|
||||||
DROP VIEW v1;
|
DROP VIEW v1;
|
||||||
DROP SEQUENCE s1;
|
DROP SEQUENCE s1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-12533 sql_mode=ORACLE: Add support for database qualified sequence names in NEXTVAL and CURRVAL
|
||||||
|
--echo #
|
||||||
|
CREATE SEQUENCE s1;
|
||||||
|
SELECT test.s1.nextval;
|
||||||
|
SELECT test.s1.currval;
|
||||||
|
SELECT .s1.nextval;
|
||||||
|
SELECT .s1.currval;
|
||||||
|
DROP SEQUENCE s1;
|
||||||
|
104
sql/sql_lex.cc
104
sql/sql_lex.cc
@ -6387,6 +6387,53 @@ my_var *LEX::create_outvar(THD *thd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident)
|
||||||
|
{
|
||||||
|
TABLE_LIST *table;
|
||||||
|
if (!(table= current_select->add_table_to_list(thd, table_ident, 0,
|
||||||
|
TL_OPTION_SEQUENCE,
|
||||||
|
TL_WRITE_ALLOW_WRITE,
|
||||||
|
MDL_SHARED_WRITE)))
|
||||||
|
return NULL;
|
||||||
|
return new (thd->mem_root) Item_func_nextval(thd, table);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *LEX::create_item_func_lastval(THD *thd, Table_ident *table_ident)
|
||||||
|
{
|
||||||
|
TABLE_LIST *table;
|
||||||
|
if (!(table= current_select->add_table_to_list(thd, table_ident, 0,
|
||||||
|
TL_OPTION_SEQUENCE,
|
||||||
|
TL_READ,
|
||||||
|
MDL_SHARED_READ)))
|
||||||
|
return NULL;
|
||||||
|
return new (thd->mem_root) Item_func_lastval(thd, table);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *LEX::create_item_func_nextval(THD *thd,
|
||||||
|
const LEX_STRING &db,
|
||||||
|
const LEX_STRING &name)
|
||||||
|
{
|
||||||
|
Table_ident *table_ident;
|
||||||
|
if (!(table_ident= new (thd->mem_root) Table_ident(thd, db, name, false)))
|
||||||
|
return NULL;
|
||||||
|
return create_item_func_nextval(thd, table_ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *LEX::create_item_func_lastval(THD *thd,
|
||||||
|
const LEX_STRING &db,
|
||||||
|
const LEX_STRING &name)
|
||||||
|
{
|
||||||
|
Table_ident *table_ident;
|
||||||
|
if (!(table_ident= new (thd->mem_root) Table_ident(thd, db, name, false)))
|
||||||
|
return NULL;
|
||||||
|
return create_item_func_lastval(thd, table_ident);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Item *LEX::create_item_ident(THD *thd,
|
Item *LEX::create_item_ident(THD *thd,
|
||||||
const LEX_STRING &a,
|
const LEX_STRING &a,
|
||||||
const LEX_STRING &b,
|
const LEX_STRING &b,
|
||||||
@ -6401,37 +6448,50 @@ Item *LEX::create_item_ident(THD *thd,
|
|||||||
if (!my_strnncoll(system_charset_info,
|
if (!my_strnncoll(system_charset_info,
|
||||||
(const uchar *) b.str, 7,
|
(const uchar *) b.str, 7,
|
||||||
(const uchar *) "NEXTVAL", 7))
|
(const uchar *) "NEXTVAL", 7))
|
||||||
{
|
return create_item_func_nextval(thd, null_lex_str, a);
|
||||||
TABLE_LIST *table;
|
|
||||||
Table_ident *table_ident;
|
|
||||||
if (!(table_ident= new (thd->mem_root) Table_ident(a)) ||
|
|
||||||
!(table= current_select->add_table_to_list(thd, table_ident, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_WRITE_ALLOW_WRITE,
|
|
||||||
MDL_SHARED_WRITE)))
|
|
||||||
return NULL;
|
|
||||||
return new (thd->mem_root) Item_func_nextval(thd, table);
|
|
||||||
}
|
|
||||||
else if (!my_strnncoll(system_charset_info,
|
else if (!my_strnncoll(system_charset_info,
|
||||||
(const uchar *) b.str, 7,
|
(const uchar *) b.str, 7,
|
||||||
(const uchar *) "CURRVAL", 7))
|
(const uchar *) "CURRVAL", 7))
|
||||||
{
|
return create_item_func_lastval(thd, null_lex_str, a);
|
||||||
TABLE_LIST *table;
|
|
||||||
Table_ident *table_ident;
|
|
||||||
if (!(table_ident= new (thd->mem_root) Table_ident(a)) ||
|
|
||||||
!(table= current_select->add_table_to_list(thd, table_ident, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_READ,
|
|
||||||
MDL_SHARED_READ)))
|
|
||||||
return NULL;
|
|
||||||
return new (thd->mem_root) Item_func_lastval(thd, table);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return create_item_ident_nospvar(thd, a, b);
|
return create_item_ident_nospvar(thd, a, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item *LEX::create_item_ident(THD *thd,
|
||||||
|
const LEX_STRING &a,
|
||||||
|
const LEX_STRING &b,
|
||||||
|
const LEX_STRING &c)
|
||||||
|
{
|
||||||
|
const char *schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ?
|
||||||
|
NullS : a.str);
|
||||||
|
|
||||||
|
if ((thd->variables.sql_mode & MODE_ORACLE) && c.length == 7)
|
||||||
|
{
|
||||||
|
if (!my_strnncoll(system_charset_info,
|
||||||
|
(const uchar *) c.str, 7,
|
||||||
|
(const uchar *) "NEXTVAL", 7))
|
||||||
|
return create_item_func_nextval(thd, a, b);
|
||||||
|
else if (!my_strnncoll(system_charset_info,
|
||||||
|
(const uchar *) c.str, 7,
|
||||||
|
(const uchar *) "CURRVAL", 7))
|
||||||
|
return create_item_func_lastval(thd, a, b);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (current_select->no_table_names_allowed)
|
||||||
|
{
|
||||||
|
my_error(ER_TABLENAME_NOT_ALLOWED_HERE, MYF(0), b.str, thd->where);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (current_select->parsing_place != IN_HAVING ||
|
||||||
|
current_select->get_in_sum_expr() > 0)
|
||||||
|
return new (thd->mem_root) Item_field(thd, current_context(),
|
||||||
|
schema, b.str, c.str);
|
||||||
|
return new (thd->mem_root) Item_ref(thd, current_context(),
|
||||||
|
schema, b.str, c.str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Item *LEX::create_item_limit(THD *thd,
|
Item *LEX::create_item_limit(THD *thd,
|
||||||
const LEX_STRING &a,
|
const LEX_STRING &a,
|
||||||
|
@ -3239,6 +3239,35 @@ public:
|
|||||||
const LEX_STRING &a,
|
const LEX_STRING &a,
|
||||||
const LEX_STRING &b,
|
const LEX_STRING &b,
|
||||||
uint pos_in_q, uint length_in_q);
|
uint pos_in_q, uint length_in_q);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create an item from its qualified name.
|
||||||
|
Depending on context, it can be a table field, a table field reference,
|
||||||
|
or a sequence NEXTVAL and CURRVAL.
|
||||||
|
@param thd - THD, for mem_root
|
||||||
|
@param a - the first name
|
||||||
|
@param b - the second name
|
||||||
|
@param c - the third name
|
||||||
|
@retval - NULL on error, or a pointer to a new Item.
|
||||||
|
*/
|
||||||
|
Item *create_item_ident(THD *thd,
|
||||||
|
const LEX_STRING &a,
|
||||||
|
const LEX_STRING &b,
|
||||||
|
const LEX_STRING &c);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Create an item for "NEXT VALUE FOR sequence_name"
|
||||||
|
*/
|
||||||
|
Item *create_item_func_nextval(THD *thd, Table_ident *ident);
|
||||||
|
Item *create_item_func_nextval(THD *thd, const LEX_STRING &db,
|
||||||
|
const LEX_STRING &name);
|
||||||
|
/*
|
||||||
|
Create an item for "PREVIOUS VALUE FOR sequence_name"
|
||||||
|
*/
|
||||||
|
Item *create_item_func_lastval(THD *thd, Table_ident *ident);
|
||||||
|
Item *create_item_func_lastval(THD *thd, const LEX_STRING &db,
|
||||||
|
const LEX_STRING &name);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Create an item for a name in LIMIT clause: LIMIT var
|
Create an item for a name in LIMIT clause: LIMIT var
|
||||||
@param THD - THD, for mem_root
|
@param THD - THD, for mem_root
|
||||||
|
@ -9353,46 +9353,22 @@ column_default_non_parenthesized_expr:
|
|||||||
}
|
}
|
||||||
| NEXT_SYM VALUE_SYM FOR_SYM table_ident
|
| NEXT_SYM VALUE_SYM FOR_SYM table_ident
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_nextval(thd, $4)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $4, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_WRITE_ALLOW_WRITE,
|
|
||||||
MDL_SHARED_WRITE)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_nextval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| NEXTVAL_SYM '(' table_ident ')'
|
| NEXTVAL_SYM '(' table_ident ')'
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_nextval(thd, $3)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $3, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_WRITE_ALLOW_WRITE,
|
|
||||||
MDL_SHARED_WRITE)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_nextval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident
|
| PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_lastval(thd, $4)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $4, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_READ,
|
|
||||||
MDL_SHARED_READ)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_lastval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| LASTVAL_SYM '(' table_ident ')'
|
| LASTVAL_SYM '(' table_ident ')'
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_lastval(thd, $3)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $3, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_READ,
|
|
||||||
MDL_SHARED_WRITE)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_lastval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -14165,53 +14141,12 @@ simple_ident_q:
|
|||||||
simple_ident_q2:
|
simple_ident_q2:
|
||||||
'.' ident '.' ident
|
'.' ident '.' ident
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (!($$= Lex->create_item_ident(thd, null_lex_str, $2, $4)))
|
||||||
SELECT_LEX *sel= lex->current_select;
|
|
||||||
if (sel->no_table_names_allowed)
|
|
||||||
{
|
|
||||||
my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
|
|
||||||
MYF(0), $2.str, thd->where);
|
|
||||||
}
|
|
||||||
if ((sel->parsing_place != IN_HAVING) ||
|
|
||||||
(sel->get_in_sum_expr() > 0))
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_field(thd, Lex->current_context(),
|
|
||||||
NullS, $2.str, $4.str);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_ref(thd, Lex->current_context(),
|
|
||||||
NullS, $2.str, $4.str);
|
|
||||||
}
|
|
||||||
if ($$ == NULL)
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| ident '.' ident '.' ident
|
| ident '.' ident '.' ident
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (!($$= Lex->create_item_ident(thd, $1, $3, $5)))
|
||||||
SELECT_LEX *sel= lex->current_select;
|
|
||||||
const char* schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ?
|
|
||||||
NullS : $1.str);
|
|
||||||
if (sel->no_table_names_allowed)
|
|
||||||
{
|
|
||||||
my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
|
|
||||||
MYF(0), $3.str, thd->where);
|
|
||||||
}
|
|
||||||
if ((sel->parsing_place != IN_HAVING) ||
|
|
||||||
(sel->get_in_sum_expr() > 0))
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_field(thd, Lex->current_context(),
|
|
||||||
schema,
|
|
||||||
$3.str, $5.str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_ref(thd, Lex->current_context(),
|
|
||||||
schema,
|
|
||||||
$3.str, $5.str);
|
|
||||||
}
|
|
||||||
if ($$ == NULL)
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
@ -9441,46 +9441,22 @@ column_default_non_parenthesized_expr:
|
|||||||
}
|
}
|
||||||
| NEXT_SYM VALUE_SYM FOR_SYM table_ident
|
| NEXT_SYM VALUE_SYM FOR_SYM table_ident
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_nextval(thd, $4)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $4, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_WRITE_ALLOW_WRITE,
|
|
||||||
MDL_SHARED_WRITE)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_nextval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| NEXTVAL_SYM '(' table_ident ')'
|
| NEXTVAL_SYM '(' table_ident ')'
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_nextval(thd, $3)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $3, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_WRITE_ALLOW_WRITE,
|
|
||||||
MDL_SHARED_WRITE)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_nextval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident
|
| PREVIOUS_SYM VALUE_SYM FOR_SYM table_ident
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_lastval(thd, $4)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $4, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_READ,
|
|
||||||
MDL_SHARED_READ)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_lastval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| LASTVAL_SYM '(' table_ident ')'
|
| LASTVAL_SYM '(' table_ident ')'
|
||||||
{
|
{
|
||||||
TABLE_LIST *table;
|
if (!($$= Lex->create_item_func_lastval(thd, $3)))
|
||||||
if (!(table= Select->add_table_to_list(thd, $3, 0,
|
|
||||||
TL_OPTION_SEQUENCE,
|
|
||||||
TL_READ,
|
|
||||||
MDL_SHARED_WRITE)))
|
|
||||||
MYSQL_YYABORT;
|
|
||||||
if (!($$= new (thd->mem_root) Item_func_lastval(thd, table)))
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
@ -14319,53 +14295,12 @@ simple_ident_q2:
|
|||||||
}
|
}
|
||||||
| '.' ident '.' ident
|
| '.' ident '.' ident
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (!($$= Lex->create_item_ident(thd, null_lex_str, $2, $4)))
|
||||||
SELECT_LEX *sel= lex->current_select;
|
|
||||||
if (sel->no_table_names_allowed)
|
|
||||||
{
|
|
||||||
my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
|
|
||||||
MYF(0), $2.str, thd->where);
|
|
||||||
}
|
|
||||||
if ((sel->parsing_place != IN_HAVING) ||
|
|
||||||
(sel->get_in_sum_expr() > 0))
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_field(thd, Lex->current_context(),
|
|
||||||
NullS, $2.str, $4.str);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_ref(thd, Lex->current_context(),
|
|
||||||
NullS, $2.str, $4.str);
|
|
||||||
}
|
|
||||||
if ($$ == NULL)
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
| ident '.' ident '.' ident
|
| ident '.' ident '.' ident
|
||||||
{
|
{
|
||||||
LEX *lex= thd->lex;
|
if (!($$= Lex->create_item_ident(thd, $1, $3, $5)))
|
||||||
SELECT_LEX *sel= lex->current_select;
|
|
||||||
const char* schema= (thd->client_capabilities & CLIENT_NO_SCHEMA ?
|
|
||||||
NullS : $1.str);
|
|
||||||
if (sel->no_table_names_allowed)
|
|
||||||
{
|
|
||||||
my_error(ER_TABLENAME_NOT_ALLOWED_HERE,
|
|
||||||
MYF(0), $3.str, thd->where);
|
|
||||||
}
|
|
||||||
if ((sel->parsing_place != IN_HAVING) ||
|
|
||||||
(sel->get_in_sum_expr() > 0))
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_field(thd, Lex->current_context(),
|
|
||||||
schema,
|
|
||||||
$3.str, $5.str);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$$= new (thd->mem_root) Item_ref(thd, Lex->current_context(),
|
|
||||||
schema,
|
|
||||||
$3.str, $5.str);
|
|
||||||
}
|
|
||||||
if ($$ == NULL)
|
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
Reference in New Issue
Block a user