Commit af59a318 authored by Yuchen Pei's avatar Yuchen Pei

wip wip wip Adding unsigned by making fields Longlong_hybrid

parent 87cdc8f8
...@@ -86,6 +86,11 @@ Type_handler const *sequence_definition::value_type_handler() ...@@ -86,6 +86,11 @@ Type_handler const *sequence_definition::value_type_handler()
return Type_handler::get_handler_by_field_type(value_type); return Type_handler::get_handler_by_field_type(value_type);
} }
bool sequence_definition::is_unsigned() const
{
return value_type_handler()->is_unsigned();
}
longlong sequence_definition::value_type_max() longlong sequence_definition::value_type_max()
{ {
return ~ value_type_min(); return ~ value_type_min();
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#define ROUND_FIELD_NO 7 #define ROUND_FIELD_NO 7
#include "mysql_com.h" #include "mysql_com.h"
#include "sql_type_int.h"
class Create_field; class Create_field;
class Type_handler; class Type_handler;
...@@ -61,22 +62,26 @@ class sequence_definition :public Sql_alloc ...@@ -61,22 +62,26 @@ class sequence_definition :public Sql_alloc
{ {
public: public:
sequence_definition(): sequence_definition():
min_value(1), max_value(LONGLONG_MAX-1), start(1), increment(1), reserved_until(0, false), min_value(1, false), max_value(LONGLONG_MAX-1, false), start(1, false),
cache(1000), round(0), restart(0), cycle(0), used_fields(0), value_type(MYSQL_TYPE_LONGLONG) increment(1), cache(1000), round(0), restart(0, false), cycle(0),
used_fields(0), value_type(MYSQL_TYPE_LONGLONG),
next_free_value(0, false)
{} {}
longlong reserved_until; Longlong_hybrid reserved_until;
longlong min_value; Longlong_hybrid min_value;
longlong max_value; Longlong_hybrid max_value;
longlong start; Longlong_hybrid start;
longlong increment; longlong increment;
longlong cache; longlong cache; // cache size
ulonglong round; ulonglong round;
longlong restart; // alter sequence restart value Longlong_hybrid restart; // alter sequence restart value
bool cycle; bool cycle;
uint used_fields; // Which fields where used in CREATE uint used_fields; // Which fields where used or specified in CREATE
enum_field_types value_type; // value type of the sequence enum enum_field_types value_type; // value type of the sequence
Type_handler const *value_type_handler(); Type_handler const *value_type_handler();
// Whether the sequence is unsigned.
bool is_unsigned() const;
// max value for the value type, e.g. 32767 for smallint. // max value for the value type, e.g. 32767 for smallint.
longlong value_type_max(); longlong value_type_max();
// min value for the value type, e.g. -32768 for smallint. // min value for the value type, e.g. -32768 for smallint.
...@@ -87,7 +92,7 @@ class sequence_definition :public Sql_alloc ...@@ -87,7 +92,7 @@ class sequence_definition :public Sql_alloc
int write_initial_sequence(TABLE *table); int write_initial_sequence(TABLE *table);
int write(TABLE *table, bool all_fields); int write(TABLE *table, bool all_fields);
/* This must be called after sequence data has been updated */ /* This must be called after sequence data has been updated */
void adjust_values(longlong next_value); void adjust_values(Longlong_hybrid next_value);
inline void print_dbug() inline void print_dbug()
{ {
DBUG_PRINT("sequence", ("reserved: %lld start: %lld increment: %lld min_value: %lld max_value: %lld cache: %lld round: %lld", DBUG_PRINT("sequence", ("reserved: %lld start: %lld increment: %lld min_value: %lld max_value: %lld cache: %lld round: %lld",
...@@ -103,7 +108,7 @@ class sequence_definition :public Sql_alloc ...@@ -103,7 +108,7 @@ class sequence_definition :public Sql_alloc
merged with global auto_increment_offset and auto_increment_increment merged with global auto_increment_offset and auto_increment_increment
*/ */
longlong real_increment; longlong real_increment;
longlong next_free_value; Longlong_hybrid next_free_value;
}; };
/** /**
...@@ -142,11 +147,15 @@ class SEQUENCE :public sequence_definition ...@@ -142,11 +147,15 @@ class SEQUENCE :public sequence_definition
{ {
if (real_increment > 0) if (real_increment > 0)
{ {
if (value > max_value - real_increment || // here we have an issue where there's no subtraction operator
value + real_increment > max_value) // for Longlong_hybrid. How do we design subtraction operator?
// what if the two operands are of different signedness? That's
// a further design issue.
if (value > max_value - Longlong_hybrid(real_increment, is_unsigned()) ||
value + Longlong_hybrid(real_increment, is_unsigned()) > max_value)
value= max_value + 1; value= max_value + 1;
else else
value+= real_increment; value+= Longlong_hybrid(real_increment, is_unsigned());
} }
else else
{ {
...@@ -175,7 +184,7 @@ class SEQUENCE_LAST_VALUE ...@@ -175,7 +184,7 @@ class SEQUENCE_LAST_VALUE
{ {
public: public:
SEQUENCE_LAST_VALUE(uchar *key_arg, uint length_arg) SEQUENCE_LAST_VALUE(uchar *key_arg, uint length_arg)
:key(key_arg), length(length_arg) :key(key_arg), length(length_arg), value(0, false)
{} {}
~SEQUENCE_LAST_VALUE() ~SEQUENCE_LAST_VALUE()
{ my_free((void*) key); } { my_free((void*) key); }
...@@ -186,7 +195,7 @@ class SEQUENCE_LAST_VALUE ...@@ -186,7 +195,7 @@ class SEQUENCE_LAST_VALUE
const uchar *key; const uchar *key;
uint length; uint length;
bool null_value; bool null_value;
longlong value; Longlong_hybrid value;
uchar table_version[MY_UUID_SIZE]; uchar table_version[MY_UUID_SIZE];
}; };
......
...@@ -2608,13 +2608,18 @@ sequence_defs: ...@@ -2608,13 +2608,18 @@ sequence_defs:
| sequence_defs sequence_def | sequence_defs sequence_def
; ;
sequence_def: sequence_def:
AS int_type AS int_type field_options
{ {
if (unlikely(Lex->create_info.seq_create_info->used_fields & if (unlikely(Lex->create_info.seq_create_info->used_fields &
seq_field_used_as)) seq_field_used_as))
my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "AS")); my_yyabort_error((ER_DUP_ARGUMENT, MYF(0), "AS"));
Lex->create_info.seq_create_info->value_type = $2->field_type(); if ($3 & ZEROFILL_FLAG)
my_yyabort_error((ER_NOT_SUPPORTED_YET, MYF(0), "ZEROFILL is not supported as a sequence value type option"));
Type_handler handler = $2;
if ($3 & UNSIGNED_FLAG)
handler = $2->type_handler_unsigned();
Lex->create_info.seq_create_info->value_type = handler->field_type();
} }
| MINVALUE_SYM opt_equal ulonglong_num | MINVALUE_SYM opt_equal 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