aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2022-12-30 20:47:57 +0900
committerMichael Paquier <michael@paquier.xyz>2022-12-30 20:47:57 +0900
commit7aa81c61ec8f68212570192f3088544dbfa43cb9 (patch)
tree5af49de71f755bb7dd199881b6233bd3454e4e6f /src
parent1f605b82ba66ece8b421b10d41094dd2e3c0c48b (diff)
downloadpostgresql-7aa81c61ec8f68212570192f3088544dbfa43cb9.tar.gz
postgresql-7aa81c61ec8f68212570192f3088544dbfa43cb9.zip
Fix precision handling for some COERCE_SQL_SYNTAX functions
f193883 has been incorrectly setting up the precision used in the timestamp compilations returned by the following functions: - LOCALTIME - LOCALTIMESTAMP - CURRENT_TIME - CURRENT_TIMESTAMP Specifying an out-of-range precision for CURRENT_TIMESTAMP and LOCALTIMESTAMP was raising a WARNING without adjusting the precision, leading to a subsequent error. LOCALTIME and CURRENT_TIME raised a WARNING without an error, still the precision given to the internal routines was not correct, so let's be clean. Ian has reported the problems in timestamp.c, while I have noticed the ones in date.c. Regression tests are added for all of them with precisions high enough to provide coverage for the warnings, something that went missing up to this commit. Author: Ian Lawrence Barwick, Michael Paquier Discussion: https://postgr.es/m/CAB8KJ=jQEnn9sYG+N752spt68wMrhmT-ocHCh4oeNmHF82QMWA@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/date.c10
-rw-r--r--src/backend/utils/adt/timestamp.c10
-rw-r--r--src/test/regress/expected/expressions.out31
-rw-r--r--src/test/regress/sql/expressions.sql7
4 files changed, 40 insertions, 18 deletions
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 1cf7c7652d7..e70cf4bdcff 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -347,10 +347,7 @@ current_time(PG_FUNCTION_ARGS)
int32 typmod = -1;
if (!PG_ARGISNULL(0))
- {
- typmod = PG_GETARG_INT32(0);
- anytime_typmod_check(true, typmod);
- }
+ typmod = anytime_typmod_check(true, PG_GETARG_INT32(0));
GetCurrentTimeUsec(tm, &fsec, &tz);
@@ -375,10 +372,7 @@ sql_localtime(PG_FUNCTION_ARGS)
int32 typmod = -1;
if (!PG_ARGISNULL(0))
- {
- typmod = PG_GETARG_INT32(0);
- anytime_typmod_check(false, typmod);
- }
+ typmod = anytime_typmod_check(false, PG_GETARG_INT32(0));
GetCurrentTimeUsec(tm, &fsec, &tz);
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 3f2508c0c4a..b23cce11362 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -1606,10 +1606,7 @@ current_timestamp(PG_FUNCTION_ARGS)
int32 typmod = -1;
if (!PG_ARGISNULL(0))
- {
- typmod = PG_GETARG_INT32(0);
- anytimestamp_typmod_check(true, typmod);
- }
+ typmod = anytimestamp_typmod_check(true, PG_GETARG_INT32(0));
ts = GetCurrentTransactionStartTimestamp();
if (typmod >= 0)
@@ -1627,10 +1624,7 @@ sql_localtimestamp(PG_FUNCTION_ARGS)
int32 typmod = -1;
if (!PG_ARGISNULL(0))
- {
- typmod = PG_GETARG_INT32(0);
- anytimestamp_typmod_check(false, typmod);
- }
+ typmod = anytimestamp_typmod_check(false, PG_GETARG_INT32(0));
ts = timestamptz2timestamp(GetCurrentTransactionStartTimestamp());
if (typmod >= 0)
diff --git a/src/test/regress/expected/expressions.out b/src/test/regress/expected/expressions.out
index 28a20900f19..df432d4c927 100644
--- a/src/test/regress/expected/expressions.out
+++ b/src/test/regress/expected/expressions.out
@@ -36,7 +36,7 @@ SELECT now()::time(3)::text = localtime(3)::text;
t
(1 row)
--- current_timestamp / localtimestamp (always matches because of transactional behaviour)
+-- current_time[stamp]/ localtime[stamp] (always matches because of transactional behaviour)
SELECT current_timestamp = NOW();
?column?
----------
@@ -57,6 +57,35 @@ SELECT now()::timestamp::text = localtimestamp::text;
t
(1 row)
+-- precision overflow
+SELECT current_time = current_time(7);
+WARNING: TIME(7) WITH TIME ZONE precision reduced to maximum allowed, 6
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT current_timestamp = current_timestamp(7);
+WARNING: TIMESTAMP(7) WITH TIME ZONE precision reduced to maximum allowed, 6
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT localtime = localtime(7);
+WARNING: TIME(7) precision reduced to maximum allowed, 6
+ ?column?
+----------
+ t
+(1 row)
+
+SELECT localtimestamp = localtimestamp(7);
+WARNING: TIMESTAMP(7) precision reduced to maximum allowed, 6
+ ?column?
+----------
+ t
+(1 row)
+
-- current_role/user/user is tested in rolnames.sql
-- current database / catalog
SELECT current_catalog = current_database();
diff --git a/src/test/regress/sql/expressions.sql b/src/test/regress/sql/expressions.sql
index f9a0299d17b..fea5358d252 100644
--- a/src/test/regress/sql/expressions.sql
+++ b/src/test/regress/sql/expressions.sql
@@ -17,12 +17,17 @@ SELECT now()::timetz(4)::text = current_time(4)::text;
SELECT now()::time::text = localtime::text;
SELECT now()::time(3)::text = localtime(3)::text;
--- current_timestamp / localtimestamp (always matches because of transactional behaviour)
+-- current_time[stamp]/ localtime[stamp] (always matches because of transactional behaviour)
SELECT current_timestamp = NOW();
-- precision
SELECT length(current_timestamp::text) >= length(current_timestamp(0)::text);
-- localtimestamp
SELECT now()::timestamp::text = localtimestamp::text;
+-- precision overflow
+SELECT current_time = current_time(7);
+SELECT current_timestamp = current_timestamp(7);
+SELECT localtime = localtime(7);
+SELECT localtimestamp = localtimestamp(7);
-- current_role/user/user is tested in rolnames.sql