From 08387b9b50194ffb4c0e5effb2616aaf208ba3dd Mon Sep 17 00:00:00 2001 From: wangfeihuo Date: Sun, 7 Apr 2024 21:06:21 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E6=A0=87=E9=A2=98=E3=80=91:=20?= =?UTF-8?q?=E5=9B=9E=E5=90=88https://gitee.com/opengauss/openGauss-server/?= =?UTF-8?q?pulls/4694/=E4=BF=AE=E5=A4=8D=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=90=8Ecore=E7=9A=84=E9=97=AE=E9=A2=98.=20?= =?UTF-8?q?=E3=80=90=E5=AE=9E=E7=8E=B0=E5=86=85=E5=AE=B9=E3=80=91:=20?= =?UTF-8?q?=E5=9B=9E=E5=90=88https://gitee.com/opengauss/openGauss-server/?= =?UTF-8?q?pulls/4694/=E4=BF=AE=E5=A4=8D=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=90=8Ecore=E7=9A=84=E9=97=AE=E9=A2=98=20?= =?UTF-8?q?=E3=80=90=E6=A0=B9=E5=9B=A0=E5=88=86=E6=9E=90=E3=80=91:=20?= =?UTF-8?q?=E5=9B=9E=E5=90=88https://gitee.com/opengauss/openGauss-server/?= =?UTF-8?q?pulls/4694/=E4=BF=AE=E5=A4=8D=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=90=8Ecore=E7=9A=84=E9=97=AE=E9=A2=98=20?= =?UTF-8?q?=E3=80=90=E5=AE=9E=E7=8E=B0=E6=96=B9=E6=A1=88=E3=80=91:=20?= =?UTF-8?q?=E5=9B=9E=E5=90=88https://gitee.com/opengauss/openGauss-server/?= =?UTF-8?q?pulls/4694/=E4=BF=AE=E5=A4=8D=E8=A1=A8=E5=A2=9E=E5=8A=A0?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=90=8Ecore=E7=9A=84=E9=97=AE=E9=A2=98=20?= =?UTF-8?q?=E3=80=90=E5=85=B3=E8=81=94=E9=9C=80=E6=B1=82=E6=88=96issue?= =?UTF-8?q?=E3=80=91:=20https://e.gitee.com/opengaussorg/dashboard=3Fissue?= =?UTF-8?q?=3DI9C345?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/parse_coerce.cpp | 2 +- src/common/backend/parser/parse_collate.cpp | 2 +- src/common/backend/parser/parse_node.cpp | 2 +- src/common/backend/utils/mb/mbutils.cpp | 2 +- .../expected/test_b_format_collate2.out | 114 ++++++++++++++++ src/test/regress/parallel_schedule0A | 2 +- .../regress/sql/test_b_format_collate2.sql | 123 ++++++++++++++++++ 7 files changed, 242 insertions(+), 5 deletions(-) create mode 100644 src/test/regress/expected/test_b_format_collate2.out create mode 100644 src/test/regress/sql/test_b_format_collate2.sql diff --git a/src/common/backend/parser/parse_coerce.cpp b/src/common/backend/parser/parse_coerce.cpp index b2803a9cf..54660cf7a 100644 --- a/src/common/backend/parser/parse_coerce.cpp +++ b/src/common/backend/parser/parse_coerce.cpp @@ -524,7 +524,7 @@ Node* coerce_type(ParseState* pstate, Node* node, Oid inputTypeId, Oid targetTyp newcon->consttype = baseTypeId; newcon->consttypmod = inputTypeMod; - if (OidIsValid(GetCollationConnection()) && + if (!DB_IS_CMPT(B_FORMAT) && OidIsValid(GetCollationConnection()) && IsSupportCharsetType(baseTypeId)) { newcon->constcollid = GetCollationConnection(); } else { diff --git a/src/common/backend/parser/parse_collate.cpp b/src/common/backend/parser/parse_collate.cpp index 306a30d33..07a89eeac 100644 --- a/src/common/backend/parser/parse_collate.cpp +++ b/src/common/backend/parser/parse_collate.cpp @@ -136,7 +136,7 @@ FORCE_INLINE static void get_valid_collation(Oid& collation, CollateStrength& st strength = context.strength; location = context.location; derivation = context.derivation; - } else if (ENABLE_MULTI_CHARSET && + } else if (!DB_IS_CMPT(B_FORMAT) && ENABLE_MULTI_CHARSET && context.strength == COLLATE_NONE && (OidIsValid(GetCollationConnection()) || context.derivation == DERIVATION_SYSCONST)) { /* collation of version() is UTF8_GENERAL_CI */ diff --git a/src/common/backend/parser/parse_node.cpp b/src/common/backend/parser/parse_node.cpp index 800c77d35..b87da89de 100644 --- a/src/common/backend/parser/parse_node.cpp +++ b/src/common/backend/parser/parse_node.cpp @@ -520,7 +520,7 @@ Const* make_const(ParseState* pstate, Value* value, int location) typid = UNKNOWNOID; /* will be coerced later */ typelen = -2; /* cstring-style varwidth type */ typebyval = false; - if (OidIsValid(GetCollationConnection())) { + if (!DB_IS_CMPT(B_FORMAT) && OidIsValid(GetCollationConnection())) { collid = GetCollationConnection(); } break; diff --git a/src/common/backend/utils/mb/mbutils.cpp b/src/common/backend/utils/mb/mbutils.cpp index 85663c196..aa7747f82 100644 --- a/src/common/backend/utils/mb/mbutils.cpp +++ b/src/common/backend/utils/mb/mbutils.cpp @@ -1218,7 +1218,7 @@ const char* GetCharsetConnectionName(void) Oid GetCollationConnection(void) { - if (!ENABLE_MULTI_CHARSET) { + if (!ENABLE_MULTI_CHARSET || !DB_IS_CMPT(B_FORMAT)) { return InvalidOid; } return u_sess->mb_cxt.collation_connection; diff --git a/src/test/regress/expected/test_b_format_collate2.out b/src/test/regress/expected/test_b_format_collate2.out new file mode 100644 index 000000000..23ed4523c --- /dev/null +++ b/src/test/regress/expected/test_b_format_collate2.out @@ -0,0 +1,114 @@ +CREATE DATABASE test_collate_A4 with dbcompatibility 'b' ENCODING='SQL_ASCII' LC_COLLATE='C' LC_CTYPE='C'; +\c test_collate_A4 +set b_format_behavior_compat_options = 'default_collation,enable_multi_charset'; +create or replace function pg_catalog.get_index_columns(OUT namespace name, OUT indexrelid oid, OUT indrelid oid, OUT indisunique bool, OUT indisusable bool, OUT seq_in_index int2, OUT attrnum int2, OUT collation int2) returns setof record +as $$ +declare +query_str text; +item int2; +row_data record; +begin +query_str := 'select n.nspname, i.indexrelid, i.indrelid, i.indisunique, i.indisusable, i.indkey, i.indoption, i.indnkeyatts + from pg_catalog.pg_index i + left join pg_class c on c.oid = i.indexrelid + left join pg_catalog.pg_namespace n on n.oid = c.relnamespace + where n.nspname <> ''pg_catalog'' + and n.nspname <> ''db4ai'' + and n.nspname <> ''information_schema'' + and n.nspname !~ ''^pg_toast'''; +for row_data in EXECUTE(query_str) LOOP + for item in 0..row_data.indnkeyatts - 1 loop + namespace := row_data.nspname; + indexrelid := row_data.indexrelid; + indrelid := row_data.indrelid; + indisunique := row_data.indisunique; + indisusable := row_data.indisusable; + seq_in_index := item + 1; + attrnum := row_data.indkey[item]; + collation := row_data.indoption[item]; + return next; + end loop; +end loop; +end; $$ +LANGUAGE 'plpgsql'; +create view public.index_statistic as +select + i.namespace as "namespace", + (select relname from pg_class tc where tc.oid = i.indrelid) as "table", + not i.indisunique as "non_unique", + c.relname as "key_name", + i.seq_in_index as "seq_in_index", + a.attname as "column_name", + (case when m.amcanorder + then ( + case when i.collation & 1 then 'D' else 'A' END + ) else null end + ) as "collation", + (select + (case when ts.stadistinct = 0 + then NULL else ( + case when ts.stadistinct > 0 then ts.stadistinct else ts.stadistinct * tc.reltuples * -1 end + ) end + ) + from pg_class tc + left join pg_statistic ts on tc.oid = ts.starelid + where + tc.oid = i.indrelid + and ts.staattnum = i.attrnum + ) as "cardinality", + null as "sub_part", + null as "packed", + (case when a.attnotnull then '' else 'YES' end) as "null", + m.amname as "index_type", + (case when i.indisusable then '' else 'disabled' end) as "comment", + (select description from pg_description where objoid = i.indexrelid) as "index_comment" +from + (select * from get_index_columns()) i + left join pg_class c on c.oid = i.indexrelid + left join pg_attribute a on a.attrelid = i.indrelid + and a.attnum = i.attrnum + left join pg_am m on m.oid = c.relam +order by + c.relname; +CREATE OR REPLACE FUNCTION pg_catalog.pg_get_nonstrict_basic_value(typename text) +RETURNS text +AS +$$ +BEGIN + IF typename = 'timestamp' then + return 'now'; + elsif typename = 'time' or typename = 'timetz' or typename = 'interval' or typename = 'reltime' then + return '00:00:00'; + elsif typename = 'date' then + return '1970-01-01'; + elsif typename = 'smalldatetime' then + return '1970-01-01 08:00:00'; + elsif typename = 'abstime' then + return '1970-01-01 08:00:00+08'; + elsif typename = 'uuid' then + return '00000000-0000-0000-0000-000000000000'; + elsif typename = 'bool' then + return 'false'; + elsif typename = 'point' or typename = 'polygon' then + return '(0,0)'; + elsif typename = 'path' then + return '((0,0))'; + elsif typename = 'circle' then + return '(0,0),0'; + elsif typename = 'lseg' or typename = 'box' then + return '(0,0),(0,0)'; + elsif typename = 'tinterval' then + return '["1970-01-01 00:00:00+08" "1970-01-01 00:00:00+08"]'; + else + return '0 or empty'; + end if; +end; +$$ +LANGUAGE plpgsql; +CREATE VIEW public.pg_type_nonstrict_basic_value AS + SELECT + t.typname As typename, + pg_get_nonstrict_basic_value(t.typname) As basic_value + FROM pg_type t; +\c postgres +DROP DATABASE IF EXISTS test_collate_A4; diff --git a/src/test/regress/parallel_schedule0A b/src/test/regress/parallel_schedule0A index ed813acef..d0ac1b06d 100644 --- a/src/test/regress/parallel_schedule0A +++ b/src/test/regress/parallel_schedule0A @@ -98,7 +98,7 @@ test: event_dump_audit test: single_node_sha #test b format collation -test: test_b_format_collate charset_b_format +test: test_b_format_collate charset_b_format test_b_format_collate2 # test subpartition test: hw_subpartition_createtable hw_subpartition_scan hw_subpartition_select hw_subpartition_split hw_subpartition_truncate hw_subpartition_update hw_subpartition_gpi hw_subpartition_analyze_vacuum hw_subpartition_alter_table hw_subpartition_index hw_subpartition_add_drop_partition hw_subpartition_tablespace hw_subpartition_ddl_index hw_subpartition_size diff --git a/src/test/regress/sql/test_b_format_collate2.sql b/src/test/regress/sql/test_b_format_collate2.sql new file mode 100644 index 000000000..abe1544b7 --- /dev/null +++ b/src/test/regress/sql/test_b_format_collate2.sql @@ -0,0 +1,123 @@ +CREATE DATABASE test_collate_A4 with dbcompatibility 'b' ENCODING='SQL_ASCII' LC_COLLATE='C' LC_CTYPE='C'; +\c test_collate_A4 + +set b_format_behavior_compat_options = 'default_collation,enable_multi_charset'; + +create or replace function pg_catalog.get_index_columns(OUT namespace name, OUT indexrelid oid, OUT indrelid oid, OUT indisunique bool, OUT indisusable bool, OUT seq_in_index int2, OUT attrnum int2, OUT collation int2) returns setof record +as $$ +declare +query_str text; +item int2; +row_data record; +begin +query_str := 'select n.nspname, i.indexrelid, i.indrelid, i.indisunique, i.indisusable, i.indkey, i.indoption, i.indnkeyatts + from pg_catalog.pg_index i + left join pg_class c on c.oid = i.indexrelid + left join pg_catalog.pg_namespace n on n.oid = c.relnamespace + where n.nspname <> ''pg_catalog'' + and n.nspname <> ''db4ai'' + and n.nspname <> ''information_schema'' + and n.nspname !~ ''^pg_toast'''; +for row_data in EXECUTE(query_str) LOOP + for item in 0..row_data.indnkeyatts - 1 loop + namespace := row_data.nspname; + indexrelid := row_data.indexrelid; + indrelid := row_data.indrelid; + indisunique := row_data.indisunique; + indisusable := row_data.indisusable; + seq_in_index := item + 1; + attrnum := row_data.indkey[item]; + collation := row_data.indoption[item]; + return next; + end loop; +end loop; +end; $$ +LANGUAGE 'plpgsql'; + +create view public.index_statistic as +select + i.namespace as "namespace", + (select relname from pg_class tc where tc.oid = i.indrelid) as "table", + not i.indisunique as "non_unique", + c.relname as "key_name", + i.seq_in_index as "seq_in_index", + a.attname as "column_name", + (case when m.amcanorder + then ( + case when i.collation & 1 then 'D' else 'A' END + ) else null end + ) as "collation", + (select + (case when ts.stadistinct = 0 + then NULL else ( + case when ts.stadistinct > 0 then ts.stadistinct else ts.stadistinct * tc.reltuples * -1 end + ) end + ) + from pg_class tc + left join pg_statistic ts on tc.oid = ts.starelid + where + tc.oid = i.indrelid + and ts.staattnum = i.attrnum + ) as "cardinality", + null as "sub_part", + null as "packed", + (case when a.attnotnull then '' else 'YES' end) as "null", + m.amname as "index_type", + (case when i.indisusable then '' else 'disabled' end) as "comment", + (select description from pg_description where objoid = i.indexrelid) as "index_comment" +from + (select * from get_index_columns()) i + left join pg_class c on c.oid = i.indexrelid + left join pg_attribute a on a.attrelid = i.indrelid + and a.attnum = i.attrnum + left join pg_am m on m.oid = c.relam +order by + c.relname; + + +CREATE OR REPLACE FUNCTION pg_catalog.pg_get_nonstrict_basic_value(typename text) +RETURNS text +AS +$$ +BEGIN + IF typename = 'timestamp' then + return 'now'; + elsif typename = 'time' or typename = 'timetz' or typename = 'interval' or typename = 'reltime' then + return '00:00:00'; + elsif typename = 'date' then + return '1970-01-01'; + elsif typename = 'smalldatetime' then + return '1970-01-01 08:00:00'; + elsif typename = 'abstime' then + return '1970-01-01 08:00:00+08'; + elsif typename = 'uuid' then + return '00000000-0000-0000-0000-000000000000'; + elsif typename = 'bool' then + return 'false'; + elsif typename = 'point' or typename = 'polygon' then + return '(0,0)'; + elsif typename = 'path' then + return '((0,0))'; + elsif typename = 'circle' then + return '(0,0),0'; + elsif typename = 'lseg' or typename = 'box' then + return '(0,0),(0,0)'; + elsif typename = 'tinterval' then + return '["1970-01-01 00:00:00+08" "1970-01-01 00:00:00+08"]'; + else + return '0 or empty'; + end if; +end; +$$ +LANGUAGE plpgsql; + +CREATE VIEW public.pg_type_nonstrict_basic_value AS + SELECT + t.typname As typename, + pg_get_nonstrict_basic_value(t.typname) As basic_value + + FROM pg_type t; + + +\c postgres +DROP DATABASE IF EXISTS test_collate_A4; \ No newline at end of file