Project: YugabyteDB (App Definition and Development / Database)
File: test-date-time-subtraction-overloads.md

title: Test the date-time subtraction overloads [YSQL] headerTitle: Test the date-time subtraction overloads linkTitle: Test subtraction overloads description: Presents code that tests the date-time subtraction overloads. [YSQL] menu: v2.18: identifier: test-date-time-subtraction-overloads parent: date-time-operators weight: 30 type: docs The of the overall date-time section explains why timetz is not covered. So there are five date-time data types to consider here and therefore twenty-five overloads to test. The following code implements all of the tests. The design of the code (it tests the legal subtractions and the illegal subtractions separately) was informed by ad hoc tests during its development. Try this: ```plpgsql drop function if exists typefromdatetimesubtraction_overload(text) cascade; create function typefromdatetimesubtraction_overload(i in text) returns regtype language plpgsql as $body$ declare d1 constant date not null := '01-01-2020'; d2 constant date not null := '02-01-2020'; t1 constant time not null := '12:00:00'; t2 constant time not null := '13:00:00'; ts1 constant timestamp not null := '01-01-2020 12:00:00'; ts2 constant timestamp not null := '02-01-2020 12:00:00'; tstz1 constant timestamptz not null := '01-01-2020 12:00:00 UTC'; tstz2 constant timestamptz not null := '02-01-2020 12:00:00 UTC'; i1 constant interval not null := '12 hours'; i2 constant interval not null := '13 hours'; t regtype not null := pg_typeof(d1); begin case i -- "date" row. when 'date-date' then t := pg_typeof(d1 - d2); when 'date-time' then t := pg_typeof(d1 - t2); when 'date-ts' then t := pg_typeof(d1 - ts2); when 'date-tstz' then t := pg_typeof(d1 - tstz2); when 'date-interval' then t := pg_typeof(d1 - i2); -- "time" row. when 'time-date' then t := pg_typeof(t1 - d2); when 'time-time' then t := pg_typeof(t1 - t2); when 'time-ts' then t := pg_typeof(t1 - ts2); when 'time-tstz' then t := pg_typeof(t1 - tstz2); when 'time-interval' then t := pg_typeof(t1 - i2); -- Plain "timestamp" row. when 'ts-date' then t := pg_typeof(ts1 - d2); when 'ts-time' then t := pg_typeof(ts1 - t2); when 'ts-ts' then t := pg_typeof(ts1 - ts2); when 'ts-tstz' then t := pg_typeof(ts1 - tstz2); when 'ts-interval' then t := pg_typeof(ts1 - i2); -- "timestamptz"

when 'tstz-date' then t := pg_typeof(tstz1 - d2); when 'tstz-time' then t := pg_typeof(tstz1 - t2); when 'tstz-ts' then t := pg_typeof(tstz1 - ts2); when 'tstz-tstz' then t := pg_typeof(tstz1 - tstz2); when 'tstz-interval' then t := pg_typeof(tstz1 - i2); -- "interval" row. when 'interval-date' then t := pg_typeof(i1 - d2); when 'interval-time' then t := pg_typeof(i1 - t2); when 'interval-ts' then t := pg_typeof(i1 - ts2); when 'interval-tstz' then t := pg_typeof(i1 - tstz2); when 'interval-interval' then t := pg_typeof(i1 - i2); end case; return t; end; $body$; drop procedure if exists confirmexpected42883(text) cascade; create procedure confirmexpected42883(i in text) language plpgsql as $body$ declare t regtype; begin t := typefromdatetimesubtraction_overload(i); assert false, 'Unexpected'; -- 42883: operator does not exist... exception when undefined_function then null; end; $body$; drop procedure if exists confirmexpected42725(text) cascade; create procedure confirmexpected42725(i in text) language plpgsql as $body$ declare t regtype; begin t := typefromdatetimesubtraction_overload(i); assert false, 'Unexpected'; -- 42725: operator is not unique... exception when ambiguous_function then null; end; $body$; drop function if exists datetimesubtractionoverloadsreport() cascade; create function datetimesubtractionoverloadsreport() returns table(z text) language plpgsql as $body$ begin -- 19 legal subtractions in all. z := 'date-date: '||typefromdatetimesubtraction_overload('date-date')::text; return next; z := 'date-time: '||typefromdatetimesubtraction_overload('date-time')::text; return next; z := 'date-ts: '||typefromdatetimesubtraction_overload('date-ts')::text; return next; z := 'date-tstz: '||typefromdatetimesubtraction_overload('date-tstz')::text; return next; z := 'date-interval: '||typefromdatetimesubtraction_overload('date-interval')::text; return next; z := ''; return next; z := 'time-time: '||typefromdatetimesubtraction_overload('time-time')::text; return next; z := 'time-interval: '||typefromdatetimesubtraction_overload('time-interval')::text; return next; z := ''; return next; z := 'ts-date: '||typefromdatetimesubtraction_overload('ts-date')::text; return next; z := 'ts-time: '||typefromdatetimesubtraction_overload('ts-time')::text; return next; z := 'ts-ts: '||typefromdatetimesubtraction_overload('ts-ts')::text; return next; z := 'ts-tstz: '||typefromdatetimesubtraction_overload('ts-tstz')::text; return next; z := 'ts-interval: '||typefromdatetimesubtraction_overload('ts-interval')::text; return next; z := ''; return next; z := 'tstz-date: '||typefromdatetimesubtraction_overload('tstz-date')::text; return next; z := 'tstz-time: '||typefromdatetimesubtraction_overload('tstz-time')::text; return next; z := 'tstz-ts: '||typefromdatetimesubtraction_overload('tstz-ts')::text; return next; z := 'tstz-tstz: '||typefromdatetimesubtraction_overload('tstz-tstz')::text; return next; z := 'tstz-interval: '||typefromdatetimesubtraction_overload('tstz-interval')::text; return next; z := ''; return next; z := 'interval-time: '||typefromdatetimesubtraction_overload('interval-time')::text; return next; z := 'interval-interval: '||typefromdatetimesubtraction_overload('interval-interval')::text; return next; -- 6 illegal subtractions in all. call confirmexpected42883('time-date'); call confirmexpected42883('time-ts'); call confirmexpected42883('time-tstz'); call confirmexpected42883('interval-date'); call confirmexpected42883('interval-ts'); call confirmexpected42883('interval-tstz'); end; $body$; select z from datetimesubtractionoverloadsreport(); ``` This is the result: ```output date-date: integer date-time: timestamp without time zone date-ts: interval date-tstz: interval date-interval: timestamp without time zone time-time: interval time-interval: time without time zone ts-date: interval ts-time: timestamp without time zone ts-ts: interval ts-tstz: interval ts-interval: timestamp without time zone tstz-date: interval tstz-time: timestamp with time zone tstz-ts: interval tstz-tstz: interval tstz-interval: timestamp with time zone interval-time: interval interval-interval: interval ```