Historically, something like to_date('2009-06-40','YYYY-MM-DD') would
return '2009-07-10' because there was no prohibition on out-of-range
month or day numbers. This has been widely panned, and it also turns
out that Oracle throws an error in such cases. Since these functions
are nominally Oracle-compatibility features, let's change that.
There's no particular restriction on year (modulo the fact that the
scanner may not believe that more than 4 digits are year digits,
a matter to be addressed separately if at all). But we now check month,
day, hour, minute, second, and fractional-second fields, as well as
day-of-year and second-of-day fields if those are used.
Currently, no checks are made on ISO-8601-style week numbers or day
numbers; it's not very clear what the appropriate rules would be there,
and they're probably so little used that it's not worth sweating over.
Artur Zakirov, reviewed by Amul Sul, further adjustments by me
Discussion: <1873520224.1784572.1465833145330.JavaMail.yahoo@mail.yahoo.com>
See-Also: <57786490.9010201@wars-nicht.de>
When there are consecutive spaces (or other non-format-code characters) in
the format, we should advance over exactly that many characters of input.
The previous coding mistakenly did a "skip whitespace" action between such
characters, possibly allowing more input to be skipped than the user
intended. We only need to skip whitespace just before an actual field.
This is really a bug fix, but given the minimal number of field complaints
and the risk of breaking applications coded to expect the old behavior,
let's not back-patch it.
Jeevan Chalke
Formerly, when using a SQL-spec timezone setting with a fixed GMT offset
(called a "brute force" timezone in the code), the session_timezone
variable was not updated to match the nominal timezone; rather, all code
was expected to ignore session_timezone if HasCTZSet was true. This is
of course obviously fragile, though a search of the code finds only
timeofday() failing to honor the rule. A bigger problem was that
DetermineTimeZoneOffset() supposed that if its pg_tz parameter was
pointer-equal to session_timezone, then HasCTZSet should override the
parameter. This would cause datetime input containing an explicit zone
name to be treated as referencing the brute-force zone instead, if the
zone name happened to match the session timezone that had prevailed
before installing the brute-force zone setting (as reported in bug #8572).
The same malady could affect AT TIME ZONE operators.
To fix, set up session_timezone so that it matches the brute-force zone
specification, which we can do using the POSIX timezone definition syntax
"<abbrev>offset", and get rid of the bogus lookaside check in
DetermineTimeZoneOffset(). Aside from fixing the erroneous behavior in
datetime parsing and AT TIME ZONE, this will cause the timeofday() function
to print its result in the user-requested time zone rather than some
previously-set zone. It might also affect results in third-party
extensions, if there are any that make use of session_timezone without
considering HasCTZSet, but in all cases the new behavior should be saner
than before.
Back-patch to all supported branches.
Further experimentation reveals that my previous change didn't fix the
issue entirely: these tests would still fail at the spring-forward DST
transition. There doesn't seem to be any great value in testing this
specific issue for both timestamp and timestamptz, so just lose the
latter tests.
Previously, 'yesterday 04:00:00'::timestamp didn't do the same thing as
'04:00:00 yesterday'::timestamp, and the return value from the latter
was midnight rather than the specified time.
Dean Rasheed, with some stylistic changes
This was unintentionally broken in 8.4 while tightening up checking of
ordinary non-Julian date inputs to forbid references to "year zero".
Per bug #5672 from Benjamin Gigot.
even when not in FM mode. This improves compatibility with Oracle and with
our pre-8.4 behavior, as per bug #4862.
Brendan Jurd
Add a couple of regression test cases for this. In passing, get rid of the
labeling of the individual test cases; doesn't seem to be good for anything
except causing extra work when inserting a test...
Tom Lane
configuration files that can be altered by a DBA. The australian_timezones
GUC setting disappears, replaced by a timezone_abbreviations setting (set this
to 'Australia' to get the effect of australian_timezones). The list of zone
names defined by default has undergone a bit of cleanup, too. Documentation
still needs some work --- in particular, should we fix Table B-4, or just get
rid of it? Joachim Wieland, with some editorializing by moi.
tests for the new interval->day changes. I added tests for
justify_hours() and justify_days() to interval.sql, as they take
interval input and produce interval output. If there's a more
appropriate place for them, please let me know.
Michael Glaesemann
in UPDATE. We also now issue a NOTICE if a query has _any_ implicit
range table entries -- in the past, we would only warn about implicit
RTEs in SELECTs with at least one explicit RTE.
As a result of the warning change, 25 of the regression tests had to
be updated. I also took the opportunity to remove some bogus whitespace
differences between some of the float4 and float8 variants. I believe
I have correctly updated all the platform-specific variants, but let
me know if that's not the case.
Original patch for DELETE ... USING from Euler Taveira de Oliveira,
reworked by Neil Conway.
better SQL compliance in this area, per recent discussion. Mark related
operators as commutators where possible. (The system doesn't actually care
about commutator marking for operators not returning boolean, at the moment,
but this seems forward-thinking and besides it made it easier to verify
that we hadn't missed any.)
Also, remove interval-minus-time and interval-minus-timetz operators.
I'm not sure how these got in, but they are nonstandard and had very
obviously broken behavior. (minus is not commutative in anyone's book.)
I doubt anyone had ever used 'em, because we'd surely have gotten a bug
report about it if so.
heuristic determination of day vs month in date/time input. Add the
ability to specify that input is interpreted as yy-mm-dd order (which
formerly worked, but only for yy greater than 31). DateStyle's input
component now has the preferred spellings DMY, MDY, or YMD; the older
keywords European and US are now aliases for the first two of these.
Per recent discussions on pgsql-general.
what is capable using integer-datatime timestamps. It does attempt
to exercise the maximum allowable timestamp range.
Also is a small error check when converting a timestamp from external
to internal format that prevents out of range timestamps from being
entered.
Files patched:
Index: src/backend/utils/adt/timestamp.c
Added range check to prevent out of range timestamps
from being used.
Index: src/test/regress/sql/horology.sql
Index: src/test/regress/expected/horology-no-DST-before-1970.out
Index: src/test/regress/expected/horology-solaris-1947.out
Limited range of timestamps being checked to
Jan 1, 4713 BC to Dec 31, 294276
In creating this patch, I have seen some definite problems with integer
timestamps and how they react when used near their limits. For example,
the following statement gives the correct result:
SELECT timestamp without time zone 'Jan 1, 4713 BC'
+ interval '109203489 days' AS "Dec 31, 294276";
However, this statement which is the logical inverse of the above
gives incorrect results:
SELECT timestamp without time zone '12/31/294276'
- timestamp without time zone 'Jan 1, 4713 BC' AS "109203489 Days";
John Cochran
functions which limited the maximum date for a timestamp to AD 1465001.
The new limit is AD 5874897.
The files affected are:
doc/src/sgml/datatype.sgml:
Documentation change due to patch. Included is a notice about
the reduced range when using an eight-byte integer for timestamps.
src/backend/utils/adt/datetime.c:
Replacement functions for j2date() and date2j() functions.
src/include/utils/datetime.h:
Corrected a bug with the limit on the earliest possible date,
Nov 23,-4713 has a Julian day count of -1. The earliest possible
date should be Nov 24, -4713 with a day count of 0.
src/test/regress/expected/horology-no-DST-before-1970.out:
src/test/regress/expected/horology-solaris-1947.out:
src/test/regress/expected/horology.out:
Copies of expected output for regression testing.
Note: Only horology.out has been physically tested. I do not have access
to a Solaris box and I don't know how to provoke the "pre-1970" test.
src/test/regress/sql/horology.sql:
Added some test cases to check extended range.
John Cochran
for type 'time without time zone', as we already did for type
'timestamp without time zone'. This patch was proposed by Tom Lockhart
on 7-Nov-02, but he never got around to applying it. Adjust regression
tests and documentation to match.
to be flexible about assignment casts without introducing ambiguity in
operator/function resolution. Introduce a well-defined promotion hierarchy
for numeric datatypes (int2->int4->int8->numeric->float4->float8).
Change make_const to initially label numeric literals as int4, int8, or
numeric (never float8 anymore).
Explicitly mark Func and RelabelType nodes to indicate whether they came
from a function call, explicit cast, or implicit cast; use this to do
reverse-listing more accurately and without so many heuristics.
Explicit casts to char, varchar, bit, varbit will truncate or pad without
raising an error (the pre-7.2 behavior), while assigning to a column without
any explicit cast will still raise an error for wrong-length data like 7.3.
This more nearly follows the SQL spec than 7.2 behavior (we should be
reporting a 'completion condition' in the explicit-cast cases, but we have
no mechanism for that, so just do silent truncation).
Fix some problems with enforcement of typmod for array elements;
it didn't work at all in 'UPDATE ... SET array[n] = foo', for example.
Provide a generalized array_length_coerce() function to replace the
specialized per-array-type functions that used to be needed (and were
missing for NUMERIC as well as all the datetime types).
Add missing conversions int8<->float4, text<->numeric, oid<->int8.
initdb forced.
Use "--enable-integer-datetimes" in configuration to use this rather
than the original float8 storage. I would recommend the integer-based
storage for any platform on which it is available. We perhaps should
make this the default for the production release.
Change timezone(timestamptz) results to return timestamp rather than
a character string. Formerly, we didn't have a way to represent
timestamps with an explicit time zone other than freezing the info into
a string. Now, we can reasonably omit the explicit time zone from the
result and return a timestamp with values appropriate for the specified
time zone. Much cleaner, and if you need the time zone in the result
you can put it into a character string pretty easily anyway.
Allow fractional seconds in date/time types even for dates prior to 1BC.
Limit timestamp data types to 6 decimal places of precision. Just right
for a micro-second storage of int8 date/time types, and reduces the
number of places ad-hoc rounding was occuring for the float8-based types.
Use lookup tables for precision/rounding calculations for timestamp and
interval types. Formerly used pow() to calculate the desired value but
with a more limited range there is no reason to not type in a lookup
table. Should be *much* better performance, though formerly there were
some optimizations to help minimize the number of times pow() was called.
Define a HAVE_INT64_TIMESTAMP variable. Based on the configure option
"--enable-integer-datetimes" and the existing internal INT64_IS_BUSTED.
Add explicit date/interval operators and functions for addition and
subtraction. Formerly relied on implicit type promotion from date to
timestamp with time zone.
Change timezone conversion functions for the timetz type from "timetz()"
to "timezone()". This is consistant with other time zone coersion
functions for other types.
Bump the catalog version to 200204201.
Fix up regression tests to reflect changes in fractional seconds
representation for date/times in BC eras.
All regression tests pass on my Linux box.
Thanks to Bruce for spotting it and Tom Lane for diagnosing it.
Since horology test output is changing anyway, add some date/time input
tests to horology.sql. Some of these should move to the tests for the
individual data types, and we perhaps should add an entire new test
for "timezone" to allow manipulating the current time zone without
risking damage to the results of other tests.
Modified the parser and the SET handlers to use full Node structures
rather than simply a character string argument.
Implement INTERVAL() YEAR TO MONTH (etc) syntax per SQL99.
Does not yet accept the goofy string format that goes along with, but
this should be fairly straight forward to fix now as a bug or later
as a feature.
Implement precision for the INTERVAL() type.
Use the typmod mechanism for both of INTERVAL features.
Fix the INTERVAL syntax in the parser:
opt_interval was in the wrong place.
INTERVAL is now a reserved word, otherwise we get reduce/reduce errors.
Implement an explicit date_part() function for TIMETZ.
Should fix coersion problem with INTERVAL reported by Peter E.
Fix up some error messages for date/time types.
Use all caps for type names within message.
Fix recently introduced side-effect bug disabling 'epoch' as a recognized
field for date_part() etc. Reported by Peter E. (??)
Bump catalog version number.
Rename "microseconds" current transaction time field
from ...Msec to ...Usec. Duh!
date/time regression tests updated for reference platform, but a few
changes will be necessary for others.
time zones.
SQL99 spec requires a default of zero (round to seconds) which is set
in gram.y as typmod is set in the parse tree. We *could* change to a
default of either 6 (for internal compatibility with previous versions)
or 2 (for external compatibility with previous versions).
Evaluate entries in pg_proc wrt the iscachable attribute for timestamp and
other date/time types. Try to recognize cases where side effects like the
current time zone setting may have an effect on results to decide whether
something is cachable or not.
(which failed miserably during DST) to just compare against a time
derived from a timestamp value.
Certainly not a direct check for a correct result, but should work
at any time of year.
Allow some operator-like tokens to be used as function names.
Flesh out support for time, timetz, and interval operators
and interactions.
Regression tests pass, but non-reference-platform horology test results
will need to be updated.
regression tests for specific types, and move a few others to the
cross-type "horology" test.
Rearrange the test order slightly, and move the abstime test to the
"parallel safe" area.
Hand-patch the results for "1947" and for "solaris", so those may not
be exactly correct.
Implement "date/time grand unification".
Transform datetime and timespan into timestamp and interval.
Deprecate datetime and timespan, though translate to new types in gram.y.
Transform all datetime and timespan catalog entries into new types.
Make "INTERVAL" reserved word allowed as a column identifier in gram.y.
Remove dt.h, dt.c files, and retarget datetime.h, datetime.c as utility
routines for all date/time types.
date.{h,c} now deals with date, time types.
timestamp.{h,c} now deals with timestamp, interval types.
nabstime.{h,c} now deals with abstime, reltime, tinterval types.
Make NUMERIC a known native type for purposes of type coersion. Not tested.