From 386e9e10b67977f16d3c37d43cd66f89d8a17edb Mon Sep 17 00:00:00 2001 From: lukeman Date: Mon, 14 Apr 2025 21:14:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A4=84=E7=90=86issue=EF=BC=9AD=E5=85=BC?= =?UTF-8?q?=E5=AE=B9=E6=80=A7=E7=94=9F=E6=88=90=E8=AE=A1=E7=AE=97=E5=88=97?= =?UTF-8?q?=EF=BC=8C=E5=9C=A8=E8=A1=A8=E4=B8=AD=E6=96=B0=E5=A2=9E=E7=94=9F?= =?UTF-8?q?=E6=88=90=E8=AE=A1=E7=AE=97=E5=88=97=E6=97=B6=EF=BC=8C=E6=8A=A5?= =?UTF-8?q?=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- contrib/shark/expected/test_ddl_and_dml.out | 39 +++++++++++++++---- contrib/shark/sql/test_ddl_and_dml.sql | 13 ++++++- contrib/shark/src/tablecmds.cpp | 22 ++++++++++- .../optimizer/commands/ddldeparse.cpp | 34 +++++++++++----- 4 files changed, 88 insertions(+), 20 deletions(-) diff --git a/contrib/shark/expected/test_ddl_and_dml.out b/contrib/shark/expected/test_ddl_and_dml.out index 7080a14698..8fca83f243 100644 --- a/contrib/shark/expected/test_ddl_and_dml.out +++ b/contrib/shark/expected/test_ddl_and_dml.out @@ -21,13 +21,13 @@ select * from Products; (2 rows) \d+ Products - Table "test_ddl_and_dml.products" - Column | Type | Modifiers | Storage | Stats target | Description -----------------+----------+-----------------------------------------------------------------------+---------+--------------+------------- - qtyavailable | smallint | | plain | | - unitprice | money | | plain | | - inventoryvalue | money | as ((qtyavailable * unitprice)) persisted | plain | | - retailvalue | money | as (((qtyavailable * unitprice) * (1.5)::double precision)) persisted | plain | | + Table "test_ddl_and_dml.products" + Column | Type | Modifiers | Storage | Stats target | Description +----------------+----------+---------------------------------------------------------------------------------------+---------+--------------+------------- + qtyavailable | smallint | | plain | | + unitprice | money | | plain | | + inventoryvalue | money | collate default as ((qtyavailable * unitprice)) persisted | plain | | + retailvalue | money | collate default as (((qtyavailable * unitprice) * (1.5)::double precision)) persisted | plain | | Has OIDs: no Options: orientation=row, compression=no @@ -48,6 +48,31 @@ ALTER TABLE Products DROP COLUMN UnitPrice; ERROR: cannot drop a column used by a generated column DETAIL: Column "unitprice" is used by generated column "inventoryvalue". DROP TABLE IF EXISTS Products; +-- test for issue #IC13WR +drop table if exists ttb16; +NOTICE: table "ttb16" does not exist, skipping +create table ttb16(str1 varchar(20),str2 varchar(20),str3 as (str1 || str2)); +NOTICE: The virtual computed columns (non-persisted) are currently ignored and behave the same as persisted columns. +insert into ttb16 values('hello ','world'); +insert into ttb16 values('runoob'); +select * from ttb16; + str1 | str2 | str3 +--------+-------+------------- + hello | world | hello world + runoob | | +(2 rows) + +--- expect success +alter table ttb16 add column str4 as (str1 || str2); +NOTICE: The virtual computed columns (non-persisted) are currently ignored and behave the same as persisted columns. +select * from ttb16; + str1 | str2 | str3 | str4 +--------+-------+-------------+------------- + hello | world | hello world | hello world + runoob | | | +(2 rows) + +drop table ttb16; -- case2: top clause DROP TABLE IF EXISTS Products; NOTICE: table "products" does not exist, skipping diff --git a/contrib/shark/sql/test_ddl_and_dml.sql b/contrib/shark/sql/test_ddl_and_dml.sql index 4935303c50..45a2a82aaf 100644 --- a/contrib/shark/sql/test_ddl_and_dml.sql +++ b/contrib/shark/sql/test_ddl_and_dml.sql @@ -31,6 +31,17 @@ ALTER TABLE Products DROP COLUMN UnitPrice; DROP TABLE IF EXISTS Products; +-- test for issue #IC13WR +drop table if exists ttb16; +create table ttb16(str1 varchar(20),str2 varchar(20),str3 as (str1 || str2)); +insert into ttb16 values('hello ','world'); +insert into ttb16 values('runoob'); +select * from ttb16; +--- expect success +alter table ttb16 add column str4 as (str1 || str2); +select * from ttb16; +drop table ttb16; + -- case2: top clause DROP TABLE IF EXISTS Products; CREATE TABLE Products(QtyAvailable smallint, UnitPrice money, InventoryValue AS (QtyAvailable * UnitPrice)); @@ -732,4 +743,4 @@ SELECT 1 YES; SELECT 1 ZONE; reset current_schema; -drop schema if exists test_ddl_and_dml cascade; \ No newline at end of file +drop schema if exists test_ddl_and_dml cascade; diff --git a/contrib/shark/src/tablecmds.cpp b/contrib/shark/src/tablecmds.cpp index ba08c75248..d8b68042c6 100644 --- a/contrib/shark/src/tablecmds.cpp +++ b/contrib/shark/src/tablecmds.cpp @@ -257,7 +257,25 @@ static void pltsql_PreAddConstraintsHook(Relation rel, ParseState *pstate, List attTup->atttypid = targettype; attTup->atttypmod = targettypmod; - attTup->attcollation = 0; + /* + * The target column should already be having a collation associated + * with it due to explicit COLLATE clause If suppose collation is not + * valid or there is no explicit COLLATE clause, we try to find column + * collation from finished expession. + */ + if (!OidIsValid(attTup->attcollation)) { + Oid targetcollid; + + /* take care of collations in the finished expression */ + assign_expr_collations(pstate, expr); + targetcollid = exprCollation(expr); + + if (OidIsValid(targetcollid)) { + attTup->attcollation = targetcollid; + } else { + attTup->attcollation = tform->typcollation; + } + } attTup->attndims = tform->typndims; attTup->attlen = tform->typlen; @@ -386,4 +404,4 @@ static bool check_nested_computed_column(Node *node, void *context) } return raw_expression_tree_walker(node, (bool (*)())check_nested_computed_column, (void*)context); -} \ No newline at end of file +} diff --git a/src/gausskernel/optimizer/commands/ddldeparse.cpp b/src/gausskernel/optimizer/commands/ddldeparse.cpp index 394ac06399..ea70189752 100644 --- a/src/gausskernel/optimizer/commands/ddldeparse.cpp +++ b/src/gausskernel/optimizer/commands/ddldeparse.cpp @@ -1718,6 +1718,16 @@ static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool compo "name", ObjTypeString, coldef->colname, "coltype", ObjTypeObject, new_objtree_for_type(typid, typmod)); + + tmp_obj = new_objtree("COLLATE"); + if (OidIsValid(typcollation)) { + append_object_object(tmp_obj, "%{name}D", + new_objtree_for_qualname_id(CollationRelationId, + typcollation)); + } else { + append_not_present(tmp_obj, "%{name}D"); + } + append_object_object(ret, "%{collation}s", tmp_obj); } else { ObjTree* dummy = new_objtree_VA(NULL, numFour, "schemaname", ObjTypeString, "", @@ -1730,15 +1740,6 @@ static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool compo "name", ObjTypeString, coldef->colname, "coltype", ObjTypeObject, dummy); } - tmp_obj = new_objtree("COLLATE"); - if (OidIsValid(typcollation)) { - append_object_object(tmp_obj, "%{name}D", - new_objtree_for_qualname_id(CollationRelationId, - typcollation)); - } else { - append_not_present(tmp_obj, "%{name}D"); - } - append_object_object(ret, "%{collation}s", tmp_obj); if (!composite) { /* @@ -1858,6 +1859,19 @@ static ObjTree* deparse_ColumnDef(Relation relation, List *dpcontext, bool compo append_not_present(tmp_obj, "(%{generation_expr}s) STORED"); } append_object_object(ret, "%{generated_column}s", tmp_obj); + + if (coldef->generatedCol == ATTRIBUTE_GENERATED_PERSISTED) { + /* A generated column of the PERSISTED type requires adding COLLATE after the expression. */ + tmp_obj = new_objtree("COLLATE"); + if (OidIsValid(typcollation)) { + append_object_object(tmp_obj, "%{name}D", + new_objtree_for_qualname_id(CollationRelationId, + typcollation)); + } else { + append_not_present(tmp_obj, "%{name}D"); + } + append_object_object(ret, "%{collation}s", tmp_obj); + } } ReleaseSysCache(attrTup); @@ -5943,4 +5957,4 @@ static ObjTree* deparse_CreateTrigStmt(Oid objectId, Node *parsetree) table_close(pg_trigger, AccessShareLock); return ret; -} \ No newline at end of file +} -- Gitee