From 4b683deb02b0f28a26a944239374e4d96556d741 Mon Sep 17 00:00:00 2001 From: wangfeihuo Date: Tue, 22 Apr 2025 16:43:11 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Ddbcc=20new=20valud=20?= =?UTF-8?q?=E8=8C=83=E5=9B=B4=E4=B8=8D=E5=AF=B9=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/shark/dbcc.cpp | 27 ++++-- contrib/shark/expected/test_dbcc.out | 95 +++++++++++++++++++ contrib/shark/shark--1.0.sql | 2 +- contrib/shark/sql/test_dbcc.sql | 28 ++++++ .../backend_parser/gram-tsql-epilogue.y.cpp | 2 +- .../shark/src/backend_parser/gram-tsql-rule.y | 4 +- .../optimizer/commands/sequence/sequence.cpp | 35 +++++-- src/include/commands/sequence.h | 4 +- 8 files changed, 171 insertions(+), 26 deletions(-) diff --git a/contrib/shark/dbcc.cpp b/contrib/shark/dbcc.cpp index c62ec02cbd..2f8d567877 100644 --- a/contrib/shark/dbcc.cpp +++ b/contrib/shark/dbcc.cpp @@ -6,9 +6,10 @@ #define DBCC_RESULT_MAX_LENGTH 256 +#define MAX_INT16_LEN 45 -extern void get_last_value_and_max_value(text* txt, int64* last_value, int64* current_max_value); -extern int64 get_and_reset_last_value(text* txt, int64 new_value, bool need_reseed); +extern void get_last_value_and_max_value(text* txt, int128* last_value, int128* current_max_value); +extern int128 get_and_reset_last_value(text* txt, int128 new_value, bool need_reseed); extern "C" Datum dbcc_check_ident_no_reseed(PG_FUNCTION_ARGS); extern "C" Datum dbcc_check_ident_reseed(PG_FUNCTION_ARGS); @@ -52,8 +53,8 @@ bool is_relation_empty(text* txt) Datum dbcc_check_ident_no_reseed(PG_FUNCTION_ARGS) { - int64 last_value = 0; - int64 current_max_value = 0; + int128 last_value = 0; + int128 current_max_value = 0; text* txt = PG_GETARG_TEXT_P(0); char result[DBCC_RESULT_MAX_LENGTH] = {0}; errno_t rc = EOK; @@ -85,9 +86,13 @@ Datum dbcc_check_ident_no_reseed(PG_FUNCTION_ARGS) rc = snprintf_s(result, DBCC_RESULT_MAX_LENGTH, DBCC_RESULT_MAX_LENGTH - 1, "Checking identity information: current identity value 'NULL', current column value 'NULL'."); } else { + char buf_last_value[MAX_INT16_LEN + 1]; + char buf_current_max_value[MAX_INT16_LEN + 1]; + pg_i128toa(last_value, buf_last_value, MAX_INT16_LEN + 1); + pg_i128toa(current_max_value, buf_current_max_value, MAX_INT16_LEN + 1); rc = snprintf_s(result, DBCC_RESULT_MAX_LENGTH, DBCC_RESULT_MAX_LENGTH - 1, - "Checking identity information: current identity value '%lld', current column value '%lld'.", - last_value, current_max_value); + "Checking identity information: current identity value '%s', current column value '%s'.", + buf_last_value, buf_current_max_value); } securec_check_ss(rc, "\0", "\0"); @@ -100,8 +105,8 @@ Datum dbcc_check_ident_no_reseed(PG_FUNCTION_ARGS) Datum dbcc_check_ident_reseed(PG_FUNCTION_ARGS) { - int64 last_value = 0; - int64 new_seed = 0; + int128 last_value = 0; + int128 new_seed = 0; errno_t rc = EOK; char result[DBCC_RESULT_MAX_LENGTH]; bool withmsg = true; @@ -113,7 +118,7 @@ Datum dbcc_check_ident_reseed(PG_FUNCTION_ARGS) text* txt = PG_GETARG_TEXT_P(0); bool need_reseed = !fcinfo->argnull[1]; if (need_reseed) { - new_seed = PG_GETARG_INT64(1); + new_seed = PG_GETARG_INT128(1); } if(!fcinfo->argnull[2]) { @@ -134,8 +139,10 @@ Datum dbcc_check_ident_reseed(PG_FUNCTION_ARGS) rc = snprintf_s(result, DBCC_RESULT_MAX_LENGTH, DBCC_RESULT_MAX_LENGTH - 1, "Checking identity information: current identity value 'NULL'."); } else { + char buf_last_value[MAX_INT16_LEN + 1]; + pg_i128toa(last_value, buf_last_value, MAX_INT16_LEN + 1); rc = snprintf_s(result, DBCC_RESULT_MAX_LENGTH, DBCC_RESULT_MAX_LENGTH - 1, - "Checking identity information: current identity value '%lld'.", last_value); + "Checking identity information: current identity value '%s'.", buf_last_value); } securec_check_ss(rc, "\0", "\0"); diff --git a/contrib/shark/expected/test_dbcc.out b/contrib/shark/expected/test_dbcc.out index c56f76a987..dcab6f2906 100644 --- a/contrib/shark/expected/test_dbcc.out +++ b/contrib/shark/expected/test_dbcc.out @@ -379,6 +379,101 @@ PL/pgSQL function test_procedure_test(integer) line 2 at PERFORM drop table Employees; drop procedure test_procedure_test(int); +-- newreseed value range +drop table if exists Employees; +NOTICE: table "employees" does not exist, skipping +CREATE TABLE Employees (EmployeeID serial ,Name VARCHAR(100) NOT NULL); +NOTICE: CREATE TABLE will create implicit sequence "employees_employeeid_seq" for serial column "employees.employeeid" +insert into Employees(Name) values ('zhangsan'); +insert into Employees(Name) values ('lisi'); +ALTER SEQUENCE employees_employeeid_seq MINVALUE -9223372036854775808; +DBCC CHECKIDENT ('Employees', RESEED, 9223372036854775806); +NOTICE: "Checking identity information: current identity value '2'." +CONTEXT: referenced column: dbcc_check_ident_reseed + dbcc_check_ident_reseed +------------------------------------------------------------ + Checking identity information: current identity value '2'. +(1 row) + +DBCC CHECKIDENT ('Employees', NORESEED); +NOTICE: "Checking identity information: current identity value '9223372036854775806', current column value '2'." +CONTEXT: referenced column: dbcc_check_ident_no_reseed + dbcc_check_ident_no_reseed +-------------------------------------------------------------------------------------------------------- + Checking identity information: current identity value '9223372036854775806', current column value '2'. +(1 row) + +DBCC CHECKIDENT ('Employees', RESEED, 9223372036854775807); +NOTICE: "Checking identity information: current identity value '9223372036854775806'." +CONTEXT: referenced column: dbcc_check_ident_reseed + dbcc_check_ident_reseed +------------------------------------------------------------------------------ + Checking identity information: current identity value '9223372036854775806'. +(1 row) + +DBCC CHECKIDENT ('Employees', NORESEED); +NOTICE: "Checking identity information: current identity value '9223372036854775807', current column value '2'." +CONTEXT: referenced column: dbcc_check_ident_no_reseed + dbcc_check_ident_no_reseed +-------------------------------------------------------------------------------------------------------- + Checking identity information: current identity value '9223372036854775807', current column value '2'. +(1 row) + +DBCC CHECKIDENT ('Employees', RESEED, 9223372036854775808); +ERROR: setval: value 9223372036854775808 is out of bounds for sequence "employees_employeeid_seq" (-9223372036854775808..9223372036854775807) +CONTEXT: referenced column: dbcc_check_ident_reseed +DBCC CHECKIDENT ('Employees', NORESEED); +NOTICE: "Checking identity information: current identity value '9223372036854775807', current column value '2'." +CONTEXT: referenced column: dbcc_check_ident_no_reseed + dbcc_check_ident_no_reseed +-------------------------------------------------------------------------------------------------------- + Checking identity information: current identity value '9223372036854775807', current column value '2'. +(1 row) + +DBCC CHECKIDENT ('Employees', RESEED, -9223372036854775807); +NOTICE: "Checking identity information: current identity value '9223372036854775807'." +CONTEXT: referenced column: dbcc_check_ident_reseed + dbcc_check_ident_reseed +------------------------------------------------------------------------------ + Checking identity information: current identity value '9223372036854775807'. +(1 row) + +DBCC CHECKIDENT ('Employees', NORESEED); +NOTICE: "Checking identity information: current identity value '-9223372036854775807', current column value '2'." +CONTEXT: referenced column: dbcc_check_ident_no_reseed + dbcc_check_ident_no_reseed +--------------------------------------------------------------------------------------------------------- + Checking identity information: current identity value '-9223372036854775807', current column value '2'. +(1 row) + +DBCC CHECKIDENT ('Employees', RESEED, -9223372036854775808); +NOTICE: "Checking identity information: current identity value '-9223372036854775807'." +CONTEXT: referenced column: dbcc_check_ident_reseed + dbcc_check_ident_reseed +------------------------------------------------------------------------------- + Checking identity information: current identity value '-9223372036854775807'. +(1 row) + +DBCC CHECKIDENT ('Employees', NORESEED); +NOTICE: "Checking identity information: current identity value '-9223372036854775808', current column value '2'." +CONTEXT: referenced column: dbcc_check_ident_no_reseed + dbcc_check_ident_no_reseed +--------------------------------------------------------------------------------------------------------- + Checking identity information: current identity value '-9223372036854775808', current column value '2'. +(1 row) + +DBCC CHECKIDENT ('Employees', RESEED, -9223372036854775809); +ERROR: setval: value -9223372036854775809 is out of bounds for sequence "employees_employeeid_seq" (-9223372036854775808..9223372036854775807) +CONTEXT: referenced column: dbcc_check_ident_reseed +DBCC CHECKIDENT ('Employees', NORESEED); +NOTICE: "Checking identity information: current identity value '-9223372036854775808', current column value '2'." +CONTEXT: referenced column: dbcc_check_ident_no_reseed + dbcc_check_ident_no_reseed +--------------------------------------------------------------------------------------------------------- + Checking identity information: current identity value '-9223372036854775808', current column value '2'. +(1 row) + +drop table if exists Employees; -- some error case -- no serial col CREATE TABLE Employees_no ( diff --git a/contrib/shark/shark--1.0.sql b/contrib/shark/shark--1.0.sql index dd91971d4f..c25b4382e3 100644 --- a/contrib/shark/shark--1.0.sql +++ b/contrib/shark/shark--1.0.sql @@ -52,7 +52,7 @@ RETURNS INT AS LANGUAGE C STABLE; CREATE FUNCTION dbcc_check_ident_no_reseed(varchar, boolean, boolean) RETURNS varchar as 'MODULE_PATHNAME', 'dbcc_check_ident_no_reseed' LANGUAGE C STRICT STABLE; -CREATE FUNCTION dbcc_check_ident_reseed(varchar, bigint, boolean) RETURNS varchar as 'MODULE_PATHNAME', 'dbcc_check_ident_reseed' LANGUAGE C STABLE; +CREATE FUNCTION dbcc_check_ident_reseed(varchar, int16, boolean) RETURNS varchar as 'MODULE_PATHNAME', 'dbcc_check_ident_reseed' LANGUAGE C STABLE; create function fetch_status() returns int as 'MODULE_PATHNAME' language C; diff --git a/contrib/shark/sql/test_dbcc.sql b/contrib/shark/sql/test_dbcc.sql index 1bed7f0bdb..c2f5ddbeb4 100644 --- a/contrib/shark/sql/test_dbcc.sql +++ b/contrib/shark/sql/test_dbcc.sql @@ -179,6 +179,34 @@ call test_procedure_test(1); drop table Employees; drop procedure test_procedure_test(int); + +-- newreseed value range +drop table if exists Employees; +CREATE TABLE Employees (EmployeeID serial ,Name VARCHAR(100) NOT NULL); +insert into Employees(Name) values ('zhangsan'); +insert into Employees(Name) values ('lisi'); +ALTER SEQUENCE employees_employeeid_seq MINVALUE -9223372036854775808; + +DBCC CHECKIDENT ('Employees', RESEED, 9223372036854775806); +DBCC CHECKIDENT ('Employees', NORESEED); + +DBCC CHECKIDENT ('Employees', RESEED, 9223372036854775807); +DBCC CHECKIDENT ('Employees', NORESEED); + +DBCC CHECKIDENT ('Employees', RESEED, 9223372036854775808); +DBCC CHECKIDENT ('Employees', NORESEED); + +DBCC CHECKIDENT ('Employees', RESEED, -9223372036854775807); +DBCC CHECKIDENT ('Employees', NORESEED); + +DBCC CHECKIDENT ('Employees', RESEED, -9223372036854775808); +DBCC CHECKIDENT ('Employees', NORESEED); + +DBCC CHECKIDENT ('Employees', RESEED, -9223372036854775809); +DBCC CHECKIDENT ('Employees', NORESEED); + +drop table if exists Employees; + -- some error case -- no serial col diff --git a/contrib/shark/src/backend_parser/gram-tsql-epilogue.y.cpp b/contrib/shark/src/backend_parser/gram-tsql-epilogue.y.cpp index fdf977b494..64d1de3bec 100644 --- a/contrib/shark/src/backend_parser/gram-tsql-epilogue.y.cpp +++ b/contrib/shark/src/backend_parser/gram-tsql-epilogue.y.cpp @@ -52,7 +52,7 @@ static List* make_no_reseed_func(char* table_name, bool with_no_msgs, bool resee static List* make_reseed_func(char* table_name, Node* new_seed, bool with_no_msgs) { List* funcname = list_make1(makeString("dbcc_check_ident_reseed")); - Node* cast_node = makeTypeCast(new_seed, SystemTypeName("int8"), NULL, NULL, NULL, ((A_Const*)new_seed)->location); + Node* cast_node = makeTypeCast(new_seed, SystemTypeName("int16"), NULL, NULL, NULL, ((A_Const*)new_seed)->location); List* args = list_make3(makeStringConst(table_name, -1), cast_node, makeBoolConst(with_no_msgs, false)); return make_func_call_func(funcname, args); } diff --git a/contrib/shark/src/backend_parser/gram-tsql-rule.y b/contrib/shark/src/backend_parser/gram-tsql-rule.y index 2c11055c81..8945e6a965 100644 --- a/contrib/shark/src/backend_parser/gram-tsql-rule.y +++ b/contrib/shark/src/backend_parser/gram-tsql-rule.y @@ -539,11 +539,11 @@ DBCCCheckIdentStmt: n->windowClause = NIL; $$ = (Node*)n; } - | DBCC CHECKIDENT '(' ColId_or_Sconst ',' RESEED ',' SignedIconst ')' opt_with_no_infomsgs + | DBCC CHECKIDENT '(' ColId_or_Sconst ',' RESEED ',' NumericOnly ')' opt_with_no_infomsgs { SelectStmt *n = makeNode(SelectStmt); n->distinctClause = NIL; - n->targetList = make_reseed_func(quote_identifier_wrapper($4, yyscanner), (Node*)makeIntConst($8, @8), $10); + n->targetList = make_reseed_func(quote_identifier_wrapper($4, yyscanner), makeAConst($8, @8), $10); n->intoClause = NULL; n->fromClause = NIL; n->whereClause = NULL; diff --git a/src/gausskernel/optimizer/commands/sequence/sequence.cpp b/src/gausskernel/optimizer/commands/sequence/sequence.cpp index edb1a5f49b..cf3cd52cb5 100644 --- a/src/gausskernel/optimizer/commands/sequence/sequence.cpp +++ b/src/gausskernel/optimizer/commands/sequence/sequence.cpp @@ -3113,7 +3113,6 @@ static char* Int8or16Out(T_Int num) return ret; } - template T_Int GetColumnMaxOrMinValue(char* column_name, char* full_table_name, bool is_min) { @@ -3270,13 +3269,14 @@ char* get_serial_column_and_seq_table(List* range_var, char* table_name, Oid* se } -void get_last_value_and_max_value(text* txt, int64* last_value, int64* current_max_value) +void get_last_value_and_max_value(text* txt, int128* last_value, int128* current_max_value) { - int64 increasement_by = 0; + int128 increasement_by = 0; Oid relid = 0; SeqTable elm = NULL; Relation seqrel; char* serial_column_name = NULL; + char relkind; char* table_name = TextDatumGetCString(txt); List* range_var = textToQualifiedNameList(txt); @@ -3284,12 +3284,17 @@ void get_last_value_and_max_value(text* txt, int64* last_value, int64* current_m /* open and lock sequence */ init_sequence(relid, &elm, &seqrel); - *last_value = GetLastAndIncrementValue(elm, seqrel, &increasement_by); + relkind = RelationGetRelkind(seqrel); + if (relkind == RELKIND_SEQUENCE) { + *last_value = GetLastAndIncrementValue(elm, seqrel, &increasement_by); + } else { + *last_value = GetLastAndIncrementValue(elm, seqrel, &increasement_by); + } relation_close(seqrel, NoLock); /* get current max value by execute select max (xx) from xxx */ bool is_min = increasement_by < 0 ? true : false; - *current_max_value = GetColumnMaxOrMinValue(serial_column_name, table_name, is_min); + *current_max_value = GetColumnMaxOrMinValue(serial_column_name, table_name, is_min); pfree(serial_column_name); pfree(table_name); @@ -3297,14 +3302,15 @@ void get_last_value_and_max_value(text* txt, int64* last_value, int64* current_m } -int64 get_and_reset_last_value(text* txt, int64 new_value, bool need_reseed) +int128 get_and_reset_last_value(text* txt, int128 new_value, bool need_reseed) { - int64 last_value = 0; + int128 last_value = 0; Oid relid = 0; - int64 increasement_by = 0; + int128 increasement_by = 0; SeqTable elm = NULL; Relation seqrel; char* serial_column_name = NULL; + char relkind; List* range_var = textToQualifiedNameList(txt); char* table_name = TextDatumGetCString(txt); @@ -3313,12 +3319,21 @@ int64 get_and_reset_last_value(text* txt, int64 new_value, bool need_reseed) /* open and lock sequence */ init_sequence(relid, &elm, &seqrel); - last_value = GetLastAndIncrementValue(elm, seqrel, &increasement_by); + relkind = RelationGetRelkind(seqrel); + if (relkind == RELKIND_SEQUENCE) { + last_value = GetLastAndIncrementValue(elm, seqrel, &increasement_by); + } else { + last_value = GetLastAndIncrementValue(elm, seqrel, &increasement_by); + } relation_close(seqrel, NoLock); // set new reseed if (need_reseed) { - do_setval(relid, new_value, true, true); + if (relkind == RELKIND_SEQUENCE) { + do_setval(relid, new_value, true, true); + } else { + do_setval(relid, new_value, true, true); + } } pfree(serial_column_name); diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h index 66d8655f76..0beb3e1902 100644 --- a/src/include/commands/sequence.h +++ b/src/include/commands/sequence.h @@ -230,8 +230,8 @@ typedef enum { #define FULL_TABLE_NAME_MAX_LENGTH 256 -extern void get_last_value_and_max_value(text* txt, int64* last_value, int64* current_max_value); -extern int64 get_and_reset_last_value(text* txt, int64 new_value, bool need_reseed); +extern void get_last_value_and_max_value(text* txt, int128* last_value, int128* current_max_value); +extern int128 get_and_reset_last_value(text* txt, int128 new_value, bool need_reseed); extern void delete_global_seq(Oid relid, Relation seqrel); -- Gitee