diff --git a/src/gausskernel/optimizer/commands/indexcmds.cpp b/src/gausskernel/optimizer/commands/indexcmds.cpp index 5115a89bb..64911467a 100755 --- a/src/gausskernel/optimizer/commands/indexcmds.cpp +++ b/src/gausskernel/optimizer/commands/indexcmds.cpp @@ -456,6 +456,35 @@ static bool CheckIndexIncludingParams(IndexStmt* stmt) return (nparams > 0); } +static bool CheckLedgerIndex_walker(Node* node, int* context) +{ + if (IsA(node, Var)) { + Var *var = (Var*)node; + if (var->varattno == *context) + return true; + } + if (IsA(node, IndexElem)) { + IndexElem *elem = (IndexElem *)node; + if (elem->name && strcmp(elem->name, "hash") == 0) + return true; + if (elem->expr) + return CheckLedgerIndex_walker(elem->expr, context); + + return false; + } + return expression_tree_walker(node, (bool (*)())CheckLedgerIndex_walker, context); +} + +/* index expression of ledger user table is not support "hash" column */ +static bool CheckLedgerIndex(Relation rel, Node *node) +{ + int hash_attrno = user_hash_attrno(rel->rd_att); + + hash_attrno = hash_attrno + 1; /* in Var, attrno start at 1 */ + + return CheckLedgerIndex_walker(node, &hash_attrno); +} + void SetPartionIndexType(IndexStmt* stmt, Relation rel, bool is_alter_table) { if (!RELATION_IS_PARTITIONED(rel)) { @@ -770,6 +799,12 @@ Oid DefineIndex(Oid relationId, IndexStmt* stmt, Oid indexRelationId, bool is_al errmsg("not supported to create a functional index on this table."))); } + if (rel->rd_isblockchain && CheckLedgerIndex(rel, (Node*)stmt->indexParams)) { + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("index of ledger user talbe can not contain \"hash\" column."))); + } + SetPartionIndexType(stmt, rel, is_alter_table); if (stmt->isGlobal && DISABLE_MULTI_NODES_GPI) { diff --git a/src/test/regress/input/ledger_table_case.source b/src/test/regress/input/ledger_table_case.source index 91e830693..89187b3e9 100644 --- a/src/test/regress/input/ledger_table_case.source +++ b/src/test/regress/input/ledger_table_case.source @@ -537,6 +537,35 @@ CREATE TYPE bc_compress_type AS (name text, salary numeric); CREATE TABLE ledgernsp.bad_tb(a bc_compress_type); DROP TYPE bc_compress_type; +---------------------------------------------------------------------- +-- TEST CASE 016. index can not contain "hash" column. -- +---------------------------------------------------------------------- +create table ledgernsp.t_col_hash(id int, "Hash" int, unique (hash)); -- error +create table ledgernsp.t_col_hash(id int, "Hash" int, unique ((textin(hash16out(HASH))))); -- error +create table ledgernsp.t_col_hash(id int, "Hash" int, unique ("Hash")); +create table ledgernsp.t_col_hash2(id int, "Hash" int, unique ((int4_text("Hash")))); +create table ledgernsp.t_col_hash3(id int, "Hash" int); + +create index ledgernsp.i_t_col_hash on ledgernsp.t_col_hash(((HASH))); -- error +create index ledgernsp.i_t_col_hash on ledgernsp.t_col_hash(textin(hash16out(HASH))); -- error +create index ledgernsp.i_t_col_hash3 on ledgernsp.t_col_hash3((("HASH"))); -- error +create index ledgernsp.i_t_col_hash3 on ledgernsp.t_col_hash3((("Hash"))); +create index ledgernsp.i_t_col_hash3_2 on ledgernsp.t_col_hash3(int4_text("Hash")); + +\d ledgernsp.t_col_hash +\d ledgernsp.t_col_hash2 +\d ledgernsp.t_col_hash3 + +INSERT INTO ledgernsp.t_col_hash3 VALUES (1,1); +INSERT INTO ledgernsp.t_col_hash3 VALUES (2,2), (3,NULL), (NULL,NULL); +update ledgernsp.t_col_hash3 set "Hash" = "Hash" + 1; +delete from ledgernsp.t_col_hash3 where id = 3; +select *, hash from ledgernsp.t_col_hash3; + +drop table if exists ledgernsp.t_col_hash; +drop table if exists ledgernsp.t_col_hash2; +drop table if exists ledgernsp.t_col_hash3; + ---------------------------------------------------------------------- -- clear enviroment. -- ---------------------------------------------------------------------- diff --git a/src/test/regress/output/ledger_table_case.source b/src/test/regress/output/ledger_table_case.source index 9647f81ec..55374220b 100644 --- a/src/test/regress/output/ledger_table_case.source +++ b/src/test/regress/output/ledger_table_case.source @@ -1113,6 +1113,70 @@ CREATE TABLE ledgernsp.bad_tb(a bc_compress_type); ERROR: Unsupport column type "bc_compress_type" of ledger user table. DROP TYPE bc_compress_type; ---------------------------------------------------------------------- +-- TEST CASE 016. index can not contain "hash" column. -- +---------------------------------------------------------------------- +create table ledgernsp.t_col_hash(id int, "Hash" int, unique (hash)); -- error +ERROR: index of ledger user talbe can not contain "hash" column. +create table ledgernsp.t_col_hash(id int, "Hash" int, unique ((textin(hash16out(HASH))))); -- error +ERROR: expression is supported only in B-format database. +LINE 1: ... ledgernsp.t_col_hash(id int, "Hash" int, unique ((textin(ha... + ^ +create table ledgernsp.t_col_hash(id int, "Hash" int, unique ("Hash")); +NOTICE: CREATE TABLE / UNIQUE will create implicit index "t_col_hash_Hash_key" for table "t_col_hash" +create table ledgernsp.t_col_hash2(id int, "Hash" int, unique ((int4_text("Hash")))); +ERROR: expression is supported only in B-format database. +LINE 1: ...ledgernsp.t_col_hash2(id int, "Hash" int, unique ((int4_text... + ^ +create table ledgernsp.t_col_hash3(id int, "Hash" int); +create index ledgernsp.i_t_col_hash on ledgernsp.t_col_hash(((HASH))); -- error +ERROR: index of ledger user talbe can not contain "hash" column. +create index ledgernsp.i_t_col_hash on ledgernsp.t_col_hash(textin(hash16out(HASH))); -- error +ERROR: index of ledger user talbe can not contain "hash" column. +create index ledgernsp.i_t_col_hash3 on ledgernsp.t_col_hash3((("HASH"))); -- error +ERROR: column "HASH" does not exist +LINE 1: ...edgernsp.i_t_col_hash3 on ledgernsp.t_col_hash3((("HASH"))); + ^ +create index ledgernsp.i_t_col_hash3 on ledgernsp.t_col_hash3((("Hash"))); +create index ledgernsp.i_t_col_hash3_2 on ledgernsp.t_col_hash3(int4_text("Hash")); +\d ledgernsp.t_col_hash + Table "ledgernsp.t_col_hash" + Column | Type | Modifiers +--------+---------+----------- + id | integer | + Hash | integer | + hash | hash16 | +Indexes: + "t_col_hash_Hash_key" UNIQUE CONSTRAINT, btree ("Hash") TABLESPACE pg_default + +\d ledgernsp.t_col_hash2 +\d ledgernsp.t_col_hash3 +Table "ledgernsp.t_col_hash3" + Column | Type | Modifiers +--------+---------+----------- + id | integer | + Hash | integer | + hash | hash16 | +Indexes: + "i_t_col_hash3" btree ("Hash") TABLESPACE pg_default + "i_t_col_hash3_2" btree (int4_text("Hash")) TABLESPACE pg_default + +INSERT INTO ledgernsp.t_col_hash3 VALUES (1,1); +INSERT INTO ledgernsp.t_col_hash3 VALUES (2,2), (3,NULL), (NULL,NULL); +update ledgernsp.t_col_hash3 set "Hash" = "Hash" + 1; +delete from ledgernsp.t_col_hash3 where id = 3; +select *, hash from ledgernsp.t_col_hash3; + id | Hash | hash +----+------+------------------ + 1 | 2 | 2371ff151e8194d1 + 2 | 3 | 3e9ed67f492416b7 + | | 8f00b204e9800998 +(3 rows) + +drop table if exists ledgernsp.t_col_hash; +drop table if exists ledgernsp.t_col_hash2; +NOTICE: table "t_col_hash2" does not exist, skipping +drop table if exists ledgernsp.t_col_hash3; +---------------------------------------------------------------------- -- clear enviroment. -- ---------------------------------------------------------------------- DROP SCHEMA IF EXISTS ledgernsp CASCADE;