修复隐式转换丢失字符序的问题
This commit is contained in:
@ -212,20 +212,23 @@ Node* coerce_to_target_type(ParseState* pstate, Node* expr, Oid exprtype, Oid ta
|
||||
(cformat != COERCE_IMPLICIT_CAST),
|
||||
(result != expr && !IsA(result, Const)));
|
||||
}
|
||||
#ifdef PGXC
|
||||
/* Do not need to do that on local Coordinator */
|
||||
if (IsConnFromCoord())
|
||||
#endif
|
||||
if (expr != origexpr) {
|
||||
/* Reinstall top CollateExpr */
|
||||
CollateExpr* coll = (CollateExpr*)origexpr;
|
||||
CollateExpr* newcoll = makeNode(CollateExpr);
|
||||
|
||||
newcoll->arg = (Expr*)result;
|
||||
newcoll->collOid = coll->collOid;
|
||||
newcoll->location = coll->location;
|
||||
result = (Node*)newcoll;
|
||||
}
|
||||
if (expr != origexpr && (
|
||||
#ifdef PGXC
|
||||
/* Do not need to do that on local Coordinator */
|
||||
IsConnFromCoord() ||
|
||||
#endif
|
||||
type_is_collatable(targettype))) {
|
||||
|
||||
/* Reinstall top CollateExpr */
|
||||
CollateExpr* coll = (CollateExpr*)origexpr;
|
||||
CollateExpr* newcoll = makeNode(CollateExpr);
|
||||
|
||||
newcoll->arg = (Expr*)result;
|
||||
newcoll->collOid = coll->collOid;
|
||||
newcoll->location = coll->location;
|
||||
result = (Node*)newcoll;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -371,6 +371,63 @@ SELECT '高斯' COLLATE "binary"; -- ERROR
|
||||
ERROR: COLLATION "binary" is not valid for CHARACTER SET "UTF8"
|
||||
LINE 1: SELECT '高斯' COLLATE "binary";
|
||||
^
|
||||
-- test CollateExpr
|
||||
CREATE TABLE t_collate_expr(
|
||||
ftext text collate utf8mb4_bin,
|
||||
fbytea bytea,
|
||||
fvbit varbit(8),
|
||||
fint int
|
||||
);
|
||||
-- -- test INSERT
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate "binary"); -- ERROR
|
||||
ERROR: COLLATION "binary" is not valid for CHARACTER SET "UTF8"
|
||||
LINE 1: ...SERT INTO t_collate_expr(ftext) VALUES('01100001' collate "b...
|
||||
^
|
||||
CONTEXT: referenced column: ftext
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate gbk_bin); -- ERROR
|
||||
ERROR: COLLATION "gbk_bin" is not valid for CHARACTER SET "UTF8"
|
||||
LINE 1: ...SERT INTO t_collate_expr(ftext) VALUES('01100001' collate gb...
|
||||
^
|
||||
CONTEXT: referenced column: ftext
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- only reserve top collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate "binary"); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate "binary"); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate "binary"); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate utf8mb4_general_ci collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate utf8mb4_general_ci collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate utf8mb4_general_ci collate gbk_bin); -- do not check collate
|
||||
-- -- test limit
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate "binary");
|
||||
?column?
|
||||
----------
|
||||
(0 rows)
|
||||
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate gbk_bin);
|
||||
?column?
|
||||
----------
|
||||
(0 rows)
|
||||
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate utf8mb4_unicode_ci);
|
||||
?column?
|
||||
----------
|
||||
(0 rows)
|
||||
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
?column?
|
||||
----------
|
||||
(0 rows)
|
||||
|
||||
DROP TABLE t_collate_expr;
|
||||
-- 中文 const charset
|
||||
SELECT CAST('高斯' AS bytea);
|
||||
bytea
|
||||
@ -2287,18 +2344,16 @@ EXECUTE test_merge_collation(_utf8mb4'高斯DB'); -- $1 use collation_connection
|
||||
高斯DB高斯DB | utf8mb4_general_ci
|
||||
(1 row)
|
||||
|
||||
EXECUTE test_merge_collation(_utf8mb4'高斯DB' collate gbk_chinese_ci); -- explicit noneffective, utf8_gen
|
||||
result | pg_collation_for
|
||||
--------------+--------------------
|
||||
高斯DB高斯DB | utf8mb4_general_ci
|
||||
(1 row)
|
||||
|
||||
EXECUTE test_merge_collation(_gbk'高斯DB'); -- _gbk noneffective, utf8_gen
|
||||
result | pg_collation_for
|
||||
--------------+--------------------
|
||||
高斯DB高斯DB | utf8mb4_general_ci
|
||||
(1 row)
|
||||
|
||||
EXECUTE test_merge_collation(_utf8mb4'高斯DB' collate gbk_chinese_ci); -- implicit type cast, keep explicit collation and check it, ERROR
|
||||
ERROR: COLLATION "gbk_chinese_ci" is not valid for CHARACTER SET "UTF8"
|
||||
LINE 1: EXECUTE test_merge_collation(_utf8mb4'高斯DB' collate gbk_ch...
|
||||
^
|
||||
DEALLOCATE test_merge_collation;
|
||||
-- -- -- -- PBE with explicit collation,
|
||||
PREPARE test_merge_collation(text) AS
|
||||
|
@ -91,6 +91,42 @@ SELECT '高斯' COLLATE "gbk_chinese_ci"; -- ERROR
|
||||
SELECT '高斯' COLLATE "gb18030_chinese_ci"; -- ERROR
|
||||
SELECT '高斯' COLLATE "binary"; -- ERROR
|
||||
|
||||
-- test CollateExpr
|
||||
CREATE TABLE t_collate_expr(
|
||||
ftext text collate utf8mb4_bin,
|
||||
fbytea bytea,
|
||||
fvbit varbit(8),
|
||||
fint int
|
||||
);
|
||||
-- -- test INSERT
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate "binary"); -- ERROR
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate gbk_bin); -- ERROR
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(ftext) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- only reserve top collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate "binary"); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate "binary"); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate "binary"); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate utf8mb4_unicode_ci);
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fbytea) VALUES('01100001' collate utf8mb4_general_ci collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fvbit) VALUES('01100001' collate utf8mb4_general_ci collate gbk_bin); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
INSERT INTO t_collate_expr(fint) VALUES('01100001' collate utf8mb4_general_ci collate gbk_bin); -- do not check collate
|
||||
|
||||
-- -- test limit
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate "binary");
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate gbk_bin);
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate utf8mb4_unicode_ci);
|
||||
select 1 from t_collate_expr limit(to_hex('11') collate gbk_bin collate utf8mb4_unicode_ci); -- do not check collate
|
||||
|
||||
DROP TABLE t_collate_expr;
|
||||
|
||||
-- 中文 const charset
|
||||
SELECT CAST('高斯' AS bytea);
|
||||
SELECT CAST(_binary'高斯' AS bytea);
|
||||
@ -544,8 +580,8 @@ DEALLOCATE test_merge_collation;
|
||||
PREPARE test_merge_collation(text) AS
|
||||
SELECT CONCAT($1, fgbk_bin) result, collation for(result) FROM t_diff_charset_columns;
|
||||
EXECUTE test_merge_collation(_utf8mb4'高斯DB'); -- $1 use collation_connection, utf8_gen
|
||||
EXECUTE test_merge_collation(_utf8mb4'高斯DB' collate gbk_chinese_ci); -- explicit noneffective, utf8_gen
|
||||
EXECUTE test_merge_collation(_gbk'高斯DB'); -- _gbk noneffective, utf8_gen
|
||||
EXECUTE test_merge_collation(_utf8mb4'高斯DB' collate gbk_chinese_ci); -- implicit type cast, keep explicit collation and check it, ERROR
|
||||
DEALLOCATE test_merge_collation;
|
||||
-- -- -- -- PBE with explicit collation,
|
||||
PREPARE test_merge_collation(text) AS
|
||||
|
Reference in New Issue
Block a user