diff --git a/src/common/backend/catalog/system_views.sql b/src/common/backend/catalog/system_views.sql index 760df349f..e34f8f79e 100644 --- a/src/common/backend/catalog/system_views.sql +++ b/src/common/backend/catalog/system_views.sql @@ -1656,8 +1656,8 @@ AS $$ SELECT CAST(float8out($1) AS VARCHAR2) $$ LANGUAGE SQL STRICT IMMUTABLE NOT FENCED; CREATE OR REPLACE FUNCTION to_char(TEXT) -RETURNS TEXT -AS $$ SELECT $1 $$ +RETURNS varchar +AS $$ SELECT $1::varchar(10485760) $$ LANGUAGE SQL STRICT IMMUTABLE NOT FENCED; CREATE OR REPLACE FUNCTION to_number(TEXT) diff --git a/src/common/backend/utils/adt/varchar.cpp b/src/common/backend/utils/adt/varchar.cpp index f36e49319..b3298d0bb 100755 --- a/src/common/backend/utils/adt/varchar.cpp +++ b/src/common/backend/utils/adt/varchar.cpp @@ -572,6 +572,12 @@ Datum varchar(PG_FUNCTION_ARGS) /* only reach here if string is too long... */ + if (len > MaxAttrSize) { + ereport(ERROR, + (errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION), + errmsg("value too long for type character varying maxlen(%d) input_len(%d)", MaxAttrSize, len))); + } + /* truncate multibyte string preserving multibyte boundary */ max_mb_len = pg_mbcharcliplen(s_data, len, max_len); diff --git a/src/test/regress/expected/varchar.out b/src/test/regress/expected/varchar.out index dc6474cc2..2759e06a2 100644 --- a/src/test/regress/expected/varchar.out +++ b/src/test/regress/expected/varchar.out @@ -108,3 +108,14 @@ SELECT '' AS four, * FROM VARCHAR_TBL ORDER BY f1; | abcd (4 rows) +select char_length(to_char(lpad('abc', 1024 * 1024 *10, 'x'))); + char_length +------------- + 10485760 +(1 row) + +select char_length(to_char(lpad('abc', 1024 * 1024 *10 + 1, 'x'))); +ERROR: value too long for type character varying maxlen(10485760) input_len(10485761) +CONTEXT: referenced column: varchar +SQL function "to_char" statement 1 +referenced column: char_length \ No newline at end of file diff --git a/src/test/regress/sql/varchar.sql b/src/test/regress/sql/varchar.sql index f6daf1aca..7cfbb6bde 100644 --- a/src/test/regress/sql/varchar.sql +++ b/src/test/regress/sql/varchar.sql @@ -64,3 +64,7 @@ INSERT INTO VARCHAR_TBL (f1) VALUES ('abcde'); INSERT INTO VARCHAR_TBL (f1) VALUES ('abcd '); SELECT '' AS four, * FROM VARCHAR_TBL ORDER BY f1; + +select char_length(to_char(lpad('abc', 1024 * 1024 *10, 'x'))); + +select char_length(to_char(lpad('abc', 1024 * 1024 *10 + 1, 'x')));