mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-06 15:24:56 +08:00
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
This commit is contained in:
parent
1f605b82ba
commit
7aa81c61ec
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user