Commit 3758c111 authored by Yuchen Pei's avatar Yuchen Pei

MDEV-28152 wip wip wip sequence support for unsigned types

Works: create, alter (except types), next, etc.
Passing tests in the sql_sequence suites.
parent 86de48ae
......@@ -22,6 +22,20 @@ select * from s2;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1 1 9223372036854775806 1 1 1000 0 0
DROP SEQUENCE s1, s2;
#
# MDEV-28152 Features for sequence
#
CREATE SEQUENCE s1 as mediumint unsigned ENGINE=InnoDB;
PREPARE stmt FROM "CREATE TABLE s2 LIKE s1";
execute stmt;
drop table s2;
execute stmt;
drop table s2;
execute stmt;
select * from s2;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1 1 16777214 1 1 1000 0 0
DROP SEQUENCE s1, s2;
CREATE SEQUENCE s1 ENGINE=InnoDB;
connect con1,localhost,root,,test;
CREATE TABLE s2 LIKE s1;;
......
......@@ -38,6 +38,20 @@ execute stmt;
select * from s2;
DROP SEQUENCE s1, s2;
--echo #
--echo # MDEV-28152 Features for sequence
--echo #
CREATE SEQUENCE s1 as mediumint unsigned ENGINE=InnoDB;
PREPARE stmt FROM "CREATE TABLE s2 LIKE s1";
execute stmt;
drop table s2;
execute stmt;
drop table s2;
execute stmt;
select * from s2;
DROP SEQUENCE s1, s2;
#
# MDEV-15117 Server crashes in in open_and_process_table or ASAN
# heap-use-after-free in is_temporary_table upon creating/flushing sequences
......
This diff is collapsed.
......@@ -71,56 +71,9 @@ create or replace sequence t1 start with 10 minvalue=-10 maxvalue=11 cache=10 cy
show create sequence t1;
select * from t1;
# Truncating out-of-bound numbers for minvalue and maxvalue
create or replace sequence t1 minvalue -999999999999999999999;
show create sequence t1;
create or replace sequence t1 minvalue -9223372036854775808;
show create sequence t1;
create or replace sequence t1 minvalue -9223372036854775807;
show create sequence t1;
create or replace sequence t1 minvalue 9223372036854775805;
show create sequence t1;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9223372036854775806;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9223372036854775807;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9223372036854775808;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9999999999999999999999;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 maxvalue -999999999999999999999 increment by -1;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 maxvalue -9223372036854775808 increment by -1;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 maxvalue -9223372036854775807 increment by -1;
create or replace sequence t1 maxvalue -9223372036854775806 increment by -1;
show create sequence t1;
create or replace sequence t1 maxvalue 9223372036854775806;
show create sequence t1;
create or replace sequence t1 maxvalue 9223372036854775807;
show create sequence t1;
create or replace sequence t1 maxvalue 9223372036854775808;
show create sequence t1;
create or replace sequence t1 maxvalue 9999999999999999999999;
show create sequence t1;
# NO MINVALUE, NO MAXVALUE
create or replace sequence t1 start with 10 NO MAXVALUE NO MINVALUE;
# Create with value types
create or replace sequence t1 as tinyint;
show create sequence t1;
create or replace sequence t1 as smallint;
show create sequence t1;
create or replace sequence t1 as mediumint;
show create sequence t1;
create or replace sequence t1 as int;
show create sequence t1;
create or replace sequence t1 as bigint;
show create sequence t1;
# Some edge cases
create or replace sequence t1 start with 10 maxvalue 10;
create or replace sequence t1 start with 10 minvalue 10;
......@@ -594,3 +547,147 @@ CREATE TRIGGER s1 BEFORE UPDATE ON seq1 FOR EACH ROW SET @a= 5;
DROP SEQUENCE seq1;
--echo # End of 10.4 test
--echo #
--echo # MDEV-28152 Features for sequence
--echo #
--echo -----
--echo Truncating out-of-bound numbers for minvalue and maxvalue
--echo -----
create or replace sequence t1 minvalue -999999999999999999999;
show create sequence t1;
create or replace sequence t1 minvalue -9223372036854775808;
show create sequence t1;
create or replace sequence t1 minvalue -9223372036854775807;
show create sequence t1;
create or replace sequence t1 minvalue 9223372036854775805;
show create sequence t1;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9223372036854775806;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9223372036854775807;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9223372036854775808;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 minvalue 9999999999999999999999;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 maxvalue -999999999999999999999 increment by -1;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 maxvalue -9223372036854775808 increment by -1;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 maxvalue -9223372036854775807 increment by -1;
create or replace sequence t1 maxvalue -9223372036854775806 increment by -1;
show create sequence t1;
create or replace sequence t1 maxvalue 9223372036854775806;
show create sequence t1;
create or replace sequence t1 maxvalue 9223372036854775807;
show create sequence t1;
create or replace sequence t1 maxvalue 9223372036854775808;
show create sequence t1;
create or replace sequence t1 maxvalue 9999999999999999999999;
show create sequence t1;
--echo -----
--echo Create with value types
--echo -----
create or replace sequence t1 as tinyint;
show create sequence t1;
show create table t1;
create or replace sequence t1 as smallint;
show create sequence t1;
show create table t1;
create or replace sequence t1 as mediumint;
show create sequence t1;
show create table t1;
create or replace sequence t1 as int;
show create sequence t1;
show create table t1;
create or replace sequence t1 as bigint;
show create sequence t1;
show create table t1;
create or replace sequence t1 as tinyint unsigned;
show create sequence t1;
show create table t1;
create or replace sequence t1 as smallint unsigned;
show create sequence t1;
show create table t1;
create or replace sequence t1 as mediumint unsigned;
show create sequence t1;
show create table t1;
create or replace sequence t1 as int unsigned;
show create sequence t1;
show create table t1;
create or replace sequence t1 as bigint unsigned;
show create sequence t1;
show create table t1;
#zerofill is not supported
--error ER_NOT_SUPPORTED_YET
create or replace sequence t1 as tinyint zerofill;
#an unsigned sequence has to have positive increment
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 as mediumint unsigned increment by -1;
#start with a number between longlong_max and ulonglong_max
create or replace sequence t1 as bigint unsigned start with 12345678901234567890;
show create sequence t1;
show create table t1;
--echo -----
--echo value types + truncating
--echo -----
create or replace sequence t1 minvalue -23 maxvalue 9999 as tinyint unsigned;
show create sequence t1;
show create table t1;
create or replace sequence t1 minvalue -32768 maxvalue 32767 as smallint;
show create sequence t1;
show create table t1;
create or replace sequence t1 minvalue 0 maxvalue 65535 as smallint unsigned;
show create sequence t1;
show create table t1;
create or replace sequence t1 minvalue -12345678901234 as mediumint unsigned maxvalue 12345678901234;
show create sequence t1;
show create table t1;
create or replace sequence t1 as bigint unsigned minvalue -12345678901234 maxvalue 12345678901234;
show create sequence t1;
show create table t1;
--echo -----
--echo indistinguishable values during parsing if we did not pass back Longlong_hybrid from the parser.
--echo -----
#signed, -1: no truncation. Note that we need a negative increment because this is a nagative sequence
create or replace sequence t1 as bigint maxvalue -1 increment by -1;
show create sequence t1;
show create table t1;
#signed, ulonglong_max: turncating to longlong_max-1
create or replace sequence t1 as bigint maxvalue 18446744073709551615;
show create sequence t1;
show create table t1;
#unsigned, -1: truncation and invalid data (max_value truncated to 1 which is equal to min_value)
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 as bigint unsigned maxvalue -1;
#unsigned, ulonglong_max: truncating to ulonglong_max-1
create or replace sequence t1 as bigint unsigned maxvalue 18446744073709551615;
show create sequence t1;
show create table t1;
--echo -----
--echo value types + out of range start
--echo -----
--error ER_PARSE_ERROR
create or replace sequence t1 start with -123456789012345678901 as tinyint unsigned;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 start with -1 as tinyint unsigned;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 start with 0 as tinyint unsigned;
show create sequence t1;
create or replace sequence t1 start with 1 as tinyint unsigned;
show create sequence t1;
create or replace sequence t1 start with 254 as tinyint unsigned;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 start with 255 as tinyint unsigned;
--error ER_SEQUENCE_INVALID_DATA
create or replace sequence t1 start with 256 as tinyint unsigned;
--error ER_PARSE_ERROR
create or replace sequence t1 start with 123456789012345678901 as tinyint unsigned;
drop sequence t1;
......@@ -548,3 +548,92 @@ SELECT SETVAL (v,0);
ERROR 42S02: 'test.v' is not a SEQUENCE
UNLOCK TABLES;
DROP VIEW v;
#
# MDEV-28152 Features for sequence
#
create or replace sequence t1 as tinyint unsigned minvalue 1 maxvalue 2;
show create sequence t1;
Table Create Table
t1 CREATE SEQUENCE `t1` as tiny unsigned start with 1 minvalue 1 maxvalue 2 increment by 1 cache 1000 nocycle ENGINE=MyISAM
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`next_not_cached_value` tinyint(5) unsigned NOT NULL,
`minimum_value` tinyint(5) unsigned NOT NULL,
`maximum_value` tinyint(5) unsigned NOT NULL,
`start_value` tinyint(5) unsigned NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache_size` bigint(21) unsigned NOT NULL,
`cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed',
`cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=MyISAM SEQUENCE=1
select * from t1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1 1 2 1 1 1000 0 0
select next value for t1;
next value for t1
1
select next value for t1;
next value for t1
2
select next value for t1;
ERROR HY000: Sequence 'test.t1' has run out
create or replace sequence t1 as tinyint unsigned minvalue 1 maxvalue 2 cycle;
show create sequence t1;
Table Create Table
t1 CREATE SEQUENCE `t1` as tiny unsigned start with 1 minvalue 1 maxvalue 2 increment by 1 cache 1000 cycle ENGINE=MyISAM
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`next_not_cached_value` tinyint(5) unsigned NOT NULL,
`minimum_value` tinyint(5) unsigned NOT NULL,
`maximum_value` tinyint(5) unsigned NOT NULL,
`start_value` tinyint(5) unsigned NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache_size` bigint(21) unsigned NOT NULL,
`cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed',
`cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=MyISAM SEQUENCE=1
select * from t1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
1 1 2 1 1 1000 1 0
select next value for t1;
next value for t1
1
select next value for t1;
next value for t1
2
select next value for t1;
next value for t1
1
create or replace sequence t1 minvalue -23 maxvalue 99999 as tinyint;
Warnings:
Note 1292 Truncated incorrect INTEGER value: 'MAXVALUE'
show create sequence t1;
Table Create Table
t1 CREATE SEQUENCE `t1` as tinyint start with -23 minvalue -23 maxvalue 126 increment by 1 cache 1000 nocycle ENGINE=MyISAM
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`next_not_cached_value` tinyint(5) NOT NULL,
`minimum_value` tinyint(5) NOT NULL,
`maximum_value` tinyint(5) NOT NULL,
`start_value` tinyint(5) NOT NULL COMMENT 'start value when sequences is created or value if RESTART is used',
`increment` bigint(21) NOT NULL COMMENT 'increment value',
`cache_size` bigint(21) unsigned NOT NULL,
`cycle_option` tinyint(1) unsigned NOT NULL COMMENT '0 if no cycles are allowed, 1 if the sequence should begin a new cycle when maximum_value is passed',
`cycle_count` bigint(21) NOT NULL COMMENT 'How many cycles have been done'
) ENGINE=MyISAM SEQUENCE=1
select * from t1;
next_not_cached_value minimum_value maximum_value start_value increment cache_size cycle_option cycle_count
-23 -23 126 -23 1 1000 0 0
select next value for t1;
next value for t1
-23
select next value for t1;
next value for t1
-22
select next value for t1;
next value for t1
-21
drop sequence t1;
......@@ -297,3 +297,34 @@ SELECT SETVAL (v,0);
UNLOCK TABLES;
DROP VIEW v;
--echo #
--echo # MDEV-28152 Features for sequence
--echo #
create or replace sequence t1 as tinyint unsigned minvalue 1 maxvalue 2;
show create sequence t1;
show create table t1;
select * from t1;
select next value for t1;
select next value for t1;
--error ER_SEQUENCE_RUN_OUT
select next value for t1;
create or replace sequence t1 as tinyint unsigned minvalue 1 maxvalue 2 cycle;
show create sequence t1;
show create table t1;
select * from t1;
select next value for t1;
select next value for t1;
select next value for t1;
create or replace sequence t1 minvalue -23 maxvalue 99999 as tinyint;
show create sequence t1;
show create table t1;
select * from t1;
select next value for t1;
select next value for t1;
select next value for t1;
drop sequence t1;
This diff is collapsed.
......@@ -35,6 +35,7 @@
#define ROUND_FIELD_NO 7
#include "mysql_com.h"
#include "sql_type_int.h"
class Create_field;
class Type_handler;
......@@ -61,20 +62,31 @@ class sequence_definition :public Sql_alloc
{
public:
sequence_definition():
min_value(1), max_value(LONGLONG_MAX-1), start(1), increment(1),
cache(1000), round(0), restart(0), cycle(0), used_fields(0), value_type(MYSQL_TYPE_LONGLONG)
min_value_from_parser(1, false),
max_value_from_parser(LONGLONG_MAX-1, false), start_from_parser(1, false),
increment(1), cache(1000), round(0), restart_from_parser(0, false), cycle(0), used_fields(0),
// We use value type and is_unsigned instead of a handler because
// Type_handler is incomplete, which we cannot initialise here
// with &type_handler_slonglong.
value_type(MYSQL_TYPE_LONGLONG), is_unsigned(false)
{}
longlong reserved_until;
longlong min_value;
longlong max_value;
longlong start;
Longlong_hybrid min_value_from_parser;
Longlong_hybrid max_value_from_parser;
Longlong_hybrid start_from_parser;
longlong increment;
longlong cache;
ulonglong round;
// TODO: allow unsigned in restart
longlong restart; // alter sequence restart value
Longlong_hybrid restart_from_parser;
bool cycle;
uint used_fields; // Which fields where used in CREATE
enum_field_types value_type; // value type of the sequence
bool is_unsigned;
Type_handler const *value_type_handler();
// max value for the value type, e.g. 32767 for smallint.
......@@ -88,6 +100,7 @@ class sequence_definition :public Sql_alloc
int write(TABLE *table, bool all_fields);
/* This must be called after sequence data has been updated */
void adjust_values(longlong next_value);
longlong truncate_value(const Longlong_hybrid& original);
inline void print_dbug()
{
DBUG_PRINT("sequence", ("reserved: %lld start: %lld increment: %lld min_value: %lld max_value: %lld cache: %lld round: %lld",
......@@ -138,24 +151,54 @@ class SEQUENCE :public sequence_definition
longlong next_value(TABLE *table, bool second_round, int *error);
int set_value(TABLE *table, longlong next_value, ulonglong round_arg,
bool is_used);
longlong increment_value(longlong value)
bool within_bounds(const longlong value, const longlong upper, const longlong lower, bool increasing)
{
if (real_increment > 0)
return
(is_unsigned && increasing && (ulonglong) value < (ulonglong) upper) ||
(is_unsigned && !increasing && (ulonglong) value > (ulonglong) lower) ||
(!is_unsigned && increasing && value < upper) ||
(!is_unsigned && !increasing && value > lower);
}
longlong increment_value(longlong value, const longlong increment)
{
if (is_unsigned)
{
if (value > max_value - real_increment ||
value + real_increment > max_value)
value= max_value + 1;
if (increment > 0)
{
// in case value + increment overflows
if ((ulonglong) value > (ulonglong) max_value - (ulonglong) increment ||
// in case max_value - increment underflows
(ulonglong) value + (ulonglong) increment > (ulonglong) max_value)
value= max_value + 1;
else
value+= increment;
}
else
value+= real_increment;
}
else
{
if (value + real_increment < min_value ||
value < min_value - real_increment)
value= min_value - 1;
{
if ((ulonglong) value - (ulonglong) (-increment) < (ulonglong) min_value ||
(ulonglong) value < (ulonglong) min_value + (ulonglong) (- increment))
value= min_value - 1;
else
value+= increment;
}
} else
if (increment > 0)
{
if (value > max_value - increment ||
value + increment > max_value)
value= max_value + 1;
else
value+= increment;
}
else
value+= real_increment;
}
{
if (value + increment < min_value ||
value < min_value - increment)
value= min_value - 1;
else
value+= increment;
}
return value;
}
......
......@@ -2697,11 +2697,20 @@ static int show_create_sequence(THD *thd, TABLE_LIST *table_list,
packet->append(STRING_WITH_LEN(" as "));
packet->append(seq->value_type_handler()->name().lex_cstring());
packet->append(STRING_WITH_LEN(" start with "));
packet->append_longlong(seq->start);
if (seq->is_unsigned)
packet->append_ulonglong(seq->start);
else
packet->append_longlong(seq->start);
packet->append(STRING_WITH_LEN(" minvalue "));
packet->append_longlong(seq->min_value);
if (seq->is_unsigned)
packet->append_ulonglong(seq->min_value);
else
packet->append_longlong(seq->min_value);
packet->append(STRING_WITH_LEN(" maxvalue "));
packet->append_longlong(seq->max_value);
if (seq->is_unsigned)
packet->append_ulonglong(seq->max_value);
else
packet->append_longlong(seq->max_value);
packet->append(STRING_WITH_LEN(" increment by "));
packet->append_longlong(seq->increment);
if (seq->cache)
......
......@@ -200,6 +200,9 @@ void _CONCAT_UNDERSCORED(turn_parser_debug_on,yyparse)()
ulonglong ulonglong_number;
longlong longlong_number;
uint sp_instr_addr;
// Longlong_hybrid does not have a default constructor, hence the
// default value below.
Longlong_hybrid longlong_hybrid_number= Longlong_hybrid(0, false);
/* structs */
LEX_CSTRING lex_str;
......@@ -1466,7 +1469,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize);
ulonglong_num real_ulonglong_num
%type <longlong_number>
sequence_value_num sequence_truncated_value_num
sequence_value_num
%type <longlong_hybrid_number>
sequence_value_hybrid_num sequence_truncated_value_hybrid_num
%type <choice> choice
......@@ -2605,19 +2611,23 @@ sequence_defs:
;
sequence_def:
AS int_type
AS int_type field_options
{
if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_as))
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "AS"));
if ($3 & ZEROFILL_FLAG)
my_yyabort_error((ER_NOT_SUPPORTED_YET, MYF(0), "ZEROFILL as a sequence value type option"));
Lex->create_info.seq_create_info->value_type = $2->field_type();
Lex->create_info.seq_create_info->is_unsigned = $3 & UNSIGNED_FLAG ? true : false;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_as;
}
| MINVALUE_SYM opt_equal sequence_truncated_value_num
| MINVALUE_SYM opt_equal sequence_truncated_value_hybrid_num
{
if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_min_value))
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
Lex->create_info.seq_create_info->min_value= $3;
Lex->create_info.seq_create_info->min_value_from_parser= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
Lex->create_info.seq_create_info->used_fields|= seq_field_specified_min_value;
}
......@@ -2633,12 +2643,12 @@ sequence_def:
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MINVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| MAXVALUE_SYM opt_equal sequence_truncated_value_num
| MAXVALUE_SYM opt_equal sequence_truncated_value_hybrid_num
{
if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_max_value))
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->max_value= $3;
Lex->create_info.seq_create_info->max_value_from_parser= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
Lex->create_info.seq_create_info->used_fields|= seq_field_specified_max_value;
}
......@@ -2654,12 +2664,12 @@ sequence_def:
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "MAXVALUE"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| START_SYM opt_with sequence_value_num
| START_SYM opt_with sequence_value_hybrid_num
{
if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_start))
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "START"));
Lex->create_info.seq_create_info->start= $3;
Lex->create_info.seq_create_info->start_from_parser= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_start;
}
| INCREMENT_SYM opt_by sequence_value_num
......@@ -2714,7 +2724,7 @@ sequence_def:
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart;
}
| RESTART_SYM opt_with sequence_value_num
| RESTART_SYM opt_with sequence_value_hybrid_num
{
if (unlikely(Lex->sql_command != SQLCOM_ALTER_SEQUENCE))
{
......@@ -2724,7 +2734,7 @@ sequence_def:
if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_restart))
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "RESTART"));
Lex->create_info.seq_create_info->restart= $3;
Lex->create_info.seq_create_info->restart_from_parser= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value;
}
;
......@@ -12572,6 +12582,7 @@ real_ulong_num:
| dec_num_error { MYSQL_YYABORT; }
;
// For simple sequence metadata values that are signed and do not need truncation
sequence_value_num:
opt_plus NUM { int error; $$= (longlong) my_strtoll10($2.str, (char**) 0, &error); }
| opt_plus LONG_NUM { int error; $$= (longlong) my_strtoll10($2.str, (char**) 0, &error); }
......@@ -12588,15 +12599,74 @@ sequence_value_num:
}
;
sequence_truncated_value_num:
opt_plus NUM { int error; $$= (longlong) my_strtoll10($2.str, (char**) 0, &error); }
| opt_plus LONG_NUM { int error; $$= (longlong) my_strtoll10($2.str, (char**) 0, &error); }
| opt_plus ULONGLONG_NUM { $$= LONGLONG_MAX; }
| opt_plus DECIMAL_NUM { $$= LONGLONG_MAX; }
| '-' NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); }
| '-' LONG_NUM { int error; $$= -(longlong) my_strtoll10($2.str, (char**) 0, &error); }
| '-' ULONGLONG_NUM { $$= LONGLONG_MIN; }
| '-' DECIMAL_NUM { $$= LONGLONG_MIN; }
// For sequence metadata values that may be unsigned but do not need truncation (start, restart)
sequence_value_hybrid_num:
opt_plus NUM
{
int error;
$$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error), false);
}
| opt_plus LONG_NUM
{
int error;
$$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error), false);
}
| opt_plus ULONGLONG_NUM
{
int error;
$$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error), true);
}
| '-' NUM
{
int error;
$$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error), false);
}
| '-' LONG_NUM
{
int error;
$$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error), false);
}
| '-' ULONGLONG_NUM
{
int error;
const ulonglong abs= my_strtoll10($2.str, (char**) 0, &error);
if (abs == 1 + (ulonglong) LONGLONG_MAX)
$$= Longlong_hybrid(LONGLONG_MIN, false);
else
thd->parse_error(ER_DATA_OUT_OF_RANGE);
}
;
// For sequence metadata values that may be unsigned and need truncation (maxvalue, minvalue)
sequence_truncated_value_hybrid_num:
opt_plus NUM
{
int error;
$$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error), false);
}
| opt_plus LONG_NUM
{
int error;
$$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error), false);
}
| opt_plus ULONGLONG_NUM
{
int error;
$$= Longlong_hybrid(my_strtoll10($2.str, (char**) 0, &error), true);
}
| opt_plus DECIMAL_NUM { $$= Longlong_hybrid(ULONGLONG_MAX, true); }
| '-' NUM
{
int error;
$$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error), false);
}
| '-' LONG_NUM
{
int error;
$$= Longlong_hybrid(- my_strtoll10($2.str, (char**) 0, &error), false);
}
| '-' ULONGLONG_NUM { $$= Longlong_hybrid(LONGLONG_MIN, false); }
| '-' DECIMAL_NUM { $$= Longlong_hybrid(LONGLONG_MIN, false); }
;
ulonglong_num:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment