Timestamp berechnung läuft unter 9.3 aber nicht unter 13?

Hallo PG Community,

ich habe eine PostgreSQL Funktion die unter PostgreSQL 9.3 läuft aber nicht unter PostgreSQL 13.

declare returnedDate timestamp with time zone;
declare returnedDate2 timestamp with time zone;
declare returnedDate3 timestamp with time zone;
declare cDay integer;
declare cMonth integer;
declare cYear integer;

	BEGIN
		cYear:=2021;
		cMonth:=10;
		cDay:=-1;

		returnedDate:=to_timestamp(cYear || '-' || cMonth || '-' ||
							cDay, 'YYYY-MM-DD');
						
		cYear:=2021;
		cMonth:=22;
		cDay:=1;

		returnedDate2:=to_timestamp(cYear || '-' || cMonth || '-' ||
							cDay, 'YYYY-MM-DD');
						
		cYear:=2021;
		cMonth:=15;
		cDay:=43;

		returnedDate3:=to_timestamp(cYear || '-' || cMonth || '-' ||
							cDay, 'YYYY-MM-DD');
							
		
		RAISE NOTICE 'Ausgabe 1: %', returnedDate;
		RAISE NOTICE 'Ausgabe 2: %', returnedDate2;
		RAISE NOTICE 'Ausgabe 3: %', returnedDate3;
		
	END;

Wie ihr bemerkt habt, ist cDay -1 beim ersten und cMonth 22 beim zweiten und cMonth 15, cDay 43. Werte die so nicht gibt, was aber kein Problem bei 9.3 ist.
Diese Funktion läuft ohne Fehlermeldung bei 9.3, berechnet Automatisch und gibt auch neue Werte aus.
Leider funktioniert es nicht mehr mit der 13 Version.

SQL-Fehler [22008]: ERROR: date/time field value out of range: "2021-10--1"
....

Was mir nicht klar und nachvollziehbar ist, wieso das in 9.3 funktioniert und in 13 nicht???
Kennt jemand eine ähnliche Funktion was mit den neueren PostgreSQL läuft?

Auf Hinweise wurde ich mich freuen.

VG pg0ne.

Diese Änderung wurde bereits mit Postgres 10 eingführt:

Make to_timestamp() and to_date() reject out-of-range input fields (Artur Zakirov)


Übrigens: declare startet einen Block in dem alle Variablen definiert werden können. Es ist nicht notwendig jede Variable in einem neuen declare block zu packen.

Du kannst Dir auch das Leben etwas leichter machen, indem Du make_date(year => cyear, month => cmonth, day => cday) verwendest anstatt einen String zu basteln. Aber auch das wird ein invalides Datum zurückweisen

1 „Gefällt mir“

Hallo castorp,

danke für diese Wichtige Information.
Ich habe ein altes Projekt bekommen und bin ganz Neu in PostgreSQL und PG Funktionen.
Lerne gerne immer dazu.

Also kann ich soweit keine Berechnung machen, da reject out-of-range input fields.
Werde mir make_date genauer anschauen.

Viele Dank.

Du kannst Dir natürlich eine Funktion schreiben, die auch ungültige Werte akzeptiert und irgendeinen Default-Wert zurückliefert. Die Frage ist welches Datum soll zurückgeliefert werden wenn Du das z.B. mit 2021-50-80 aufrufst?

Sinnvoller wäre es meiner Meinung nach, gleich gültige Werte zu verwenden. Oder eventuell mit Intervallen arbeiten. Also z.B. ein Interval (mit Tagen, Monaten, Wochen, Minuten usw) zu einem Basisdatum addieren. Aber das hängt natürlich davon ab, was genau Du da machen willst.

Ja das stimmt.
Ich denke es geht kein weg an eigenen Funktion vorbei.
Gültige Werte, das ist natürlich richtig und wichtig,
aber wenn es wie in dein Beispiel 2021-50-01 kommt,
dann muss die 50 irgendwie in ein gültigen Wert umgestellt werden
und der Rest in Jahren.

Werde mir alles mal genauer anschauen.

Eine Motivation das Verhalten von to_date() und to_timestamp() zu ändern, war (glaube ich!) die Tatsache, dass Oracle bei diesen Funktionen auch einen Fehler wirft, wenn keine gültigen Werte enthalten sind. Und diese Funktionen sind ja denen in Oracle nachempfunden.

Ich meine mich an ein paar Diskussionen erinnern zu können, in denen Benutzer bei Migrationen Probleme bekommen haben, weil Postgres eben keinen Fehler geworfen hat, deren Code aber darauf vertraut hat.