diff --git a/src/bin/psql/describe.cpp b/src/bin/psql/describe.cpp index ab382d77d..91618c52d 100644 --- a/src/bin/psql/describe.cpp +++ b/src/bin/psql/describe.cpp @@ -19,6 +19,8 @@ #include "catalog/pg_namespace.h" #include "catalog/pg_default_acl.h" #include "catalog/pg_attrdef.h" +#include "catalog/pg_collation.h" +#include "securec.h" #include "common.h" #include "describe.h" #include "dumputils.h" @@ -1870,13 +1872,41 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation if (!PQgetisnull(res, i, 6)) { if (tmpbuf.len > 0) appendPQExpBufferStr(&tmpbuf, " "); - appendPQExpBuffer(&tmpbuf, _("collate %s"), PQgetvalue(res, i, 6)); + char* collate = PQgetvalue(res, i, 6); + PQExpBufferData charsetbuf; + initPQExpBuffer(&charsetbuf); + appendPQExpBuffer(&charsetbuf, _("select oid,collencoding from pg_collation where collname = '%s';"), collate); + PGresult* charset_res = PSQLexec(charsetbuf.data, false); + int collid = atoi(PQgetvalue(charset_res, 0, 0)); + if (COLLATION_IN_B_FORMAT(collid)) { + int charset = atoi(PQgetvalue(charset_res, 0, 1)); + const char* encoding = pg_encoding_to_char(charset); + appendPQExpBuffer(&tmpbuf, _("character set %s collate %s"), encoding, collate); + } else { + appendPQExpBuffer(&tmpbuf, _("collate %s"), collate); + } + termPQExpBuffer(&charsetbuf); + PQclear(charset_res); } } else { if (!PQgetisnull(res, i, 5)) { if (tmpbuf.len > 0) appendPQExpBufferStr(&tmpbuf, " "); - appendPQExpBuffer(&tmpbuf, _("collate %s"), PQgetvalue(res, i, 5)); + char* collate = PQgetvalue(res, i, 5); + PQExpBufferData charsetbuf; + initPQExpBuffer(&charsetbuf); + appendPQExpBuffer(&charsetbuf, _("select oid,collencoding from pg_collation where collname = '%s';"), collate); + PGresult* charset_res = PSQLexec(charsetbuf.data, false); + int collid = atoi(PQgetvalue(charset_res, 0, 0)); + if (COLLATION_IN_B_FORMAT(collid)) { + int charset = atoi(PQgetvalue(charset_res, 0, 1)); + const char* encoding = pg_encoding_to_char(charset); + appendPQExpBuffer(&tmpbuf, _("character set %s collate %s"), encoding, collate); + } else { + appendPQExpBuffer(&tmpbuf, _("collate %s"), collate); + } + termPQExpBuffer(&charsetbuf); + PQclear(charset_res); } } @@ -3114,6 +3144,31 @@ static bool describeOneTableDetails(const char* schemaname, const char* relation printfPQExpBuffer(&buf, "%s: %s", t, tableinfo.reloptions); printTableAddFooter(&cont, buf.data); + + char* p = strstr(tableinfo.reloptions, "collate="); + if (p != NULL) { + char coll_str[B_FORMAT_COLLATION_STR_LEN + 1] = {0}; + errno_t rc = memcpy_s(coll_str, sizeof(coll_str), p + strlen("collate="), B_FORMAT_COLLATION_STR_LEN); + securec_check_c(rc, "\0", "\0"); + int collid = atoi(coll_str); + if (COLLATION_IN_B_FORMAT(collid)) { + PQExpBufferData charsetbuf; + initPQExpBuffer(&charsetbuf); + appendPQExpBuffer(&charsetbuf, _("select collname,collencoding from pg_collation where oid = %s;"), coll_str); + PGresult* charset_res = PSQLexec(charsetbuf.data, false); + + char* collname = PQgetvalue(charset_res, 0, 0); + int charset = atoi(PQgetvalue(charset_res, 0, 1)); + const char* encoding = pg_encoding_to_char(charset); + + resetPQExpBuffer(&charsetbuf); + appendPQExpBuffer(&charsetbuf, _("Character Set: %s\nCollate: %s"), encoding, collname); + printTableAddFooter(&cont, charsetbuf.data); + + termPQExpBuffer(&charsetbuf); + PQclear(charset_res); + } + } } /* if rel in blockchain schema */ diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h index 73ff69fe8..fc3633379 100644 --- a/src/include/catalog/pg_collation.h +++ b/src/include/catalog/pg_collation.h @@ -127,6 +127,7 @@ DESCR("gb18030_bin collation"); #define GB18030_BIN_COLLATION_OID 1801 #define B_FORMAT_COLLATION_OID_MAX 10000 +#define B_FORMAT_COLLATION_STR_LEN 4 #define COLLATION_IN_B_FORMAT(colloid) \ ((colloid) > B_FORMAT_COLLATION_OID_MIN && (colloid) < B_FORMAT_COLLATION_OID_MAX) diff --git a/src/test/regress/expected/test_b_format_collate.out b/src/test/regress/expected/test_b_format_collate.out index de358e300..14d0d6b74 100644 --- a/src/test/regress/expected/test_b_format_collate.out +++ b/src/test/regress/expected/test_b_format_collate.out @@ -94,13 +94,13 @@ create table t_collate(id int, f1 text collate "utf8mb4_general_ci"); alter table t_collate add column f2 text collate "utf8mb4_unicode_ci",add column f3 varchar collate "utf8mb4_general_ci"; alter table t_collate alter f1 type text collate "utf8mb4_bin"; \d+ t_collate - Table "public.t_collate" - Column | Type | Modifiers | Storage | Stats target | Description ---------+-------------------+----------------------------+----------+--------------+------------- - id | integer | | plain | | - f1 | text | collate utf8mb4_bin | extended | | - f2 | text | collate utf8mb4_unicode_ci | extended | | - f3 | character varying | collate utf8mb4_general_ci | extended | | + Table "public.t_collate" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-------------------+-----------------------------------------------+----------+--------------+------------- + id | integer | | plain | | + f1 | text | character set UTF8 collate utf8mb4_bin | extended | | + f2 | text | character set UTF8 collate utf8mb4_unicode_ci | extended | | + f3 | character varying | character set UTF8 collate utf8mb4_general_ci | extended | | Has OIDs: no Options: orientation=row, compression=no diff --git a/src/test/regress/output/charset_b_format.source b/src/test/regress/output/charset_b_format.source index 83da88afd..ebca7b093 100755 --- a/src/test/regress/output/charset_b_format.source +++ b/src/test/regress/output/charset_b_format.source @@ -817,12 +817,14 @@ select pg_get_tabledef('s_t_charset_6'); create table s_t_charset_7 as table s_t_charset_1; \d+ s_t_charset_7; - Table "s_charset_1.s_t_charset_7" - Column | Type | Modifiers | Storage | Stats target | Description ---------+-----------------------+----------------------------+----------+--------------+------------- - s1 | character varying(20) | collate utf8mb4_general_ci | extended | | + Table "s_charset_1.s_t_charset_7" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------------------------------------------+----------+--------------+------------- + s1 | character varying(20) | character set UTF8 collate utf8mb4_general_ci | extended | | Has OIDs: no Options: orientation=row, compression=no, collate=1537 +Character Set: UTF8 +Collate: utf8mb4_general_ci create table s_t_charset_8 as select '123'; \d+ s_t_charset_8; @@ -832,6 +834,8 @@ create table s_t_charset_8 as select '123'; ?column? | text | | extended | | Has OIDs: no Options: orientation=row, compression=no, collate=1537 +Character Set: UTF8 +Collate: utf8mb4_general_ci alter session set current_schema = s_charset_12; create table s_t_charset_9(s1 varchar(20) charset utf8mb4); @@ -875,16 +879,18 @@ select * from p_charset_1; (1 row) \d+ p_charset_1; - Table "s_charset_1.p_charset_1" - Column | Type | Modifiers | Storage | Stats target | Description ---------+-----------------------+----------------------------+----------+--------------+------------- - c1 | character varying(20) | collate utf8mb4_general_ci | extended | | - c2 | character varying(20) | collate utf8mb4_general_ci | extended | | - c3 | integer | | plain | | + Table "s_charset_1.p_charset_1" + Column | Type | Modifiers | Storage | Stats target | Description +--------+-----------------------+-----------------------------------------------+----------+--------------+------------- + c1 | character varying(20) | character set UTF8 collate utf8mb4_general_ci | extended | | + c2 | character varying(20) | character set UTF8 collate utf8mb4_general_ci | extended | | + c3 | integer | | plain | | Partition By HASH(c1) Number of partitions: 2 (View pg_partition to check each partition range.) Has OIDs: no Options: orientation=row, compression=no, collate=1538 +Character Set: UTF8 +Collate: utf8mb4_unicode_ci -- temporary table create temporary table tem_charset_1(c1 varchar(20),c2 varchar(20),c3 int) character set = utf8mb4;