Uglified to work with PostgreSQL 8.1, 8.2

If these show noticeable performance difference then we'll add
some version dependency checking and load different functions
for the older database.
This commit is contained in:
Andrew McMillan 2009-04-15 00:05:15 +12:00
parent c813609384
commit 3230f90541
2 changed files with 126 additions and 78 deletions

View File

@ -33,9 +33,9 @@ CREATE TYPE rrule_parts AS (
freq TEXT,
count INT,
interval INT,
-- bysecond INT[],
-- byminute INT[],
-- byhour INT[],
bysecond INT[],
byminute INT[],
byhour INT[],
bymonthday INT[],
byyearday INT[],
byweekno INT[],
@ -64,17 +64,17 @@ BEGIN
/**
* We can do the array conversion as a simple cast, since the strings are simple numbers, with no commas
*/
result.byday := ('{' || substring(repeatrule from 'BYDAY=(([+-]?[0-9]{0,2}(MO|TU|WE|TH|FR|SA|SU),?)+)(;|$)') || '}')::text[];
result.byday := string_to_array( substring(repeatrule from 'BYDAY=(([+-]?[0-9]{0,2}(MO|TU|WE|TH|FR|SA|SU),?)+)(;|$)'), ',');
result.byyearday := ('{' || substring(repeatrule from 'BYYEARDAY=([0-9,+-]+)(;|$)') || '}')::int[];
result.byweekno := ('{' || substring(repeatrule from 'BYWEEKNO=([0-9,+-]+)(;|$)') || '}')::int[];
result.bymonthday := ('{' || substring(repeatrule from 'BYMONTHDAY=([0-9,+-]+)(;|$)') || '}')::int[];
result.bymonth := ('{' || substring(repeatrule from 'BYMONTH=(([+-]?[0-1]?[0-9],?)+)(;|$)') || '}')::int[];
result.bysetpos := ('{' || substring(repeatrule from 'BYSETPOS=(([+-]?[0-9]{1,3},?)+)(;|$)') || '}')::int[];
result.byyearday := string_to_array(substring(repeatrule from 'BYYEARDAY=([0-9,+-]+)(;|$)'), ',');
result.byweekno := string_to_array(substring(repeatrule from 'BYWEEKNO=([0-9,+-]+)(;|$)'), ',');
result.bymonthday := string_to_array(substring(repeatrule from 'BYMONTHDAY=([0-9,+-]+)(;|$)'), ',');
result.bymonth := string_to_array(substring(repeatrule from 'BYMONTH=(([+-]?[0-1]?[0-9],?)+)(;|$)'), ',');
result.bysetpos := string_to_array(substring(repeatrule from 'BYSETPOS=(([+-]?[0-9]{1,3},?)+)(;|$)'), ',');
-- result.bysecond := list_to_array(substring(repeatrule from 'BYSECOND=([0-9,]+)(;|$)'))::int[];
-- result.byminute := list_to_array(substring(repeatrule from 'BYMINUTE=([0-9,]+)(;|$)'))::int[];
-- result.byhour := list_to_array(substring(repeatrule from 'BYHOUR=([0-9,]+)(;|$)'))::int[];
result.bysecond := string_to_array(substring(repeatrule from 'BYSECOND=([0-9,]+)(;|$)'), ',');
result.byminute := string_to_array(substring(repeatrule from 'BYMINUTE=([0-9,]+)(;|$)'), ',');
result.byhour := string_to_array(substring(repeatrule from 'BYHOUR=([0-9,]+)(;|$)'), ',');
RETURN result;
END;
@ -102,6 +102,13 @@ BEGIN
RETURN;
END IF;
-- It seems that the array needs to be initialised to non-null values in PostgreSQL 8.1
-- The date chosen is the earliest valid date in PostgreSQL 8.1, and nobody should be
-- scheduling appointments for then!
FOR i IN 1..31 LOOP
results[i] := '4713-01-01 00:00:00 BC'::timestamp;
END LOOP;
i := 1;
dayrule := byday[i];
WHILE dayrule IS NOT NULL LOOP
@ -145,9 +152,11 @@ BEGIN
ELSE
-- Return all such days that are within the given month
WHILE date_part('month', each_day) = this_month LOOP
results[date_part('day',each_day)] := each_day;
each_day := each_day + '1 week'::interval;
index := date_part('day',each_day);
-- RAISE NOTICE 'Adding "%" to list[%] for %', each_day, index, dayrule;
results[index] := each_day;
-- RAISE NOTICE 'Added "%" to list for %', each_day, dayrule;
each_day := each_day + '1 week'::interval;
END LOOP;
END IF;
@ -156,7 +165,7 @@ BEGIN
END LOOP;
FOR i IN 1..31 LOOP
IF results[i] IS NOT NULL THEN
IF results[i] > '4713-01-01 00:00:00 BC'::timestamp THEN
RETURN NEXT results[i];
END IF;
END LOOP;
@ -308,10 +317,6 @@ $$ LANGUAGE 'plpgsql' IMMUTABLE;
------------------------------------------------------------------------------------------------------
-- Given a cursor into a set, process the set returning the subset matching the BYSETPOS
--
-- Note that this function *requires* PostgreSQL 8.3 or later for the cursor handling syntax
-- to work. I guess we could do it with an array, instead, for compatibility with earlier
-- releases, since there's a maximum of 366 positions in a set.
------------------------------------------------------------------------------------------------------
CREATE or REPLACE FUNCTION rrule_bysetpos_filter( REFCURSOR, INT[] ) RETURNS SETOF TIMESTAMP WITH TIME ZONE AS $$
DECLARE
@ -319,6 +324,8 @@ DECLARE
bysetpos ALIAS FOR $2;
valid_date TIMESTAMP WITH TIME ZONE;
i INT;
setsize INT;
ourset TIMESTAMP WITH TIME ZONE[];
BEGIN
IF bysetpos IS NULL THEN
@ -328,13 +335,22 @@ BEGIN
RETURN NEXT valid_date;
END LOOP;
ELSE
setsize := 0;
FOR i IN 1..366 LOOP
FETCH curse INTO valid_date;
EXIT WHEN NOT FOUND;
ourset[i] := valid_date;
setsize = setsize + 1;
END LOOP;
-- RAISE NOTICE 'We have % in our set.', setsize;
FOR i IN 1..366 LOOP
EXIT WHEN bysetpos[i] IS NULL;
IF bysetpos[i] > 0 THEN
FETCH ABSOLUTE bysetpos[i] FROM curse INTO valid_date;
valid_date := ourset[bysetpos[i]];
-- RAISE NOTICE 'Extracted % from position %.', valid_date, bysetpos[i];
ELSE
MOVE LAST IN curse;
FETCH RELATIVE (bysetpos[i] + 1) FROM curse INTO valid_date;
valid_date := ourset[ setsize + bysetpos[i] + 1 ];
-- RAISE NOTICE 'Extracted % from position (% % + 1) = %.', valid_date, setsize, bysetpos[i], setsize + bysetpos[i] + 1;
END IF;
IF valid_date IS NOT NULL THEN
RETURN NEXT valid_date;
@ -396,7 +412,7 @@ CREATE or REPLACE FUNCTION weekly_set( TIMESTAMP WITH TIME ZONE, rrule_parts ) R
DECLARE
after ALIAS FOR $1;
rrule ALIAS FOR $2;
valid_date TIMESTAMP WITH TIME ZONE;
rowvar RECORD;
curse REFCURSOR;
weekno INT;
i INT;
@ -409,8 +425,10 @@ BEGIN
END IF;
END IF;
OPEN curse SCROLL FOR SELECT r FROM rrule_week_byday_set(after, rrule.byday ) r;
RETURN QUERY SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d;
OPEN curse FOR SELECT r FROM rrule_week_byday_set(after, rrule.byday ) r;
FOR rowvar IN SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d LOOP
RETURN NEXT rowvar.d;
END LOOP;
END;
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
@ -423,7 +441,7 @@ CREATE or REPLACE FUNCTION monthly_set( TIMESTAMP WITH TIME ZONE, rrule_parts )
DECLARE
after ALIAS FOR $1;
rrule ALIAS FOR $2;
valid_date TIMESTAMP WITH TIME ZONE;
rowvar RECORD;
curse REFCURSOR;
setpos INT;
i INT;
@ -444,16 +462,18 @@ BEGIN
* My guess is that this means 'INTERSECT'
*/
IF rrule.byday IS NOT NULL AND rrule.bymonthday IS NOT NULL THEN
OPEN curse SCROLL FOR SELECT r FROM rrule_month_byday_set(after, rrule.byday ) r
OPEN curse FOR SELECT r FROM rrule_month_byday_set(after, rrule.byday ) r
INTERSECT SELECT r FROM rrule_month_bymonthday_set(after, rrule.bymonthday ) r
ORDER BY 1;
ELSIF rrule.bymonthday IS NOT NULL THEN
OPEN curse SCROLL FOR SELECT r FROM rrule_month_bymonthday_set(after, rrule.bymonthday ) r ORDER BY 1;
OPEN curse FOR SELECT r FROM rrule_month_bymonthday_set(after, rrule.bymonthday ) r ORDER BY 1;
ELSE
OPEN curse SCROLL FOR SELECT r FROM rrule_month_byday_set(after, rrule.byday ) r ORDER BY 1;
OPEN curse FOR SELECT r FROM rrule_month_byday_set(after, rrule.byday ) r ORDER BY 1;
END IF;
RETURN QUERY SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d;
FOR rowvar IN SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d LOOP
RETURN NEXT rowvar.d;
END LOOP;
END;
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
@ -461,12 +481,14 @@ $$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;
------------------------------------------------------------------------------------------------------
-- If this is YEARLY;BYMONTH, abuse MONTHLY;BYMONTH for everything except the BYSETPOS
-- FIXME: it is wrong to abuse MONTHLY;BYMONTH in this way. We should write YEARLY;BYMONTH properly.
------------------------------------------------------------------------------------------------------
CREATE or REPLACE FUNCTION rrule_yearly_bymonth_set( TIMESTAMP WITH TIME ZONE, rrule_parts ) RETURNS SETOF TIMESTAMP WITH TIME ZONE AS $$
DECLARE
after ALIAS FOR $1;
rrule ALIAS FOR $2;
current_base TIMESTAMP WITH TIME ZONE;
rowvar RECORD;
rr rrule_parts;
i INT;
BEGIN
@ -478,7 +500,9 @@ BEGIN
FOR i IN 1..12 LOOP
EXIT WHEN rr.bymonth[i] IS NULL;
current_base := date_trunc( 'year', after ) + ((rr.bymonth[i] - 1)::text || ' months')::interval + (after::time)::interval;
RETURN QUERY SELECT r FROM monthly_set(current_base,rr) r;
FOR rowvar IN SELECT d FROM monthly_set(current_base,rr) d LOOP
RETURN NEXT rowvar.d;
END LOOP;
END LOOP;
ELSE
-- We don't yet implement byweekno, byblah
@ -497,15 +521,16 @@ DECLARE
after ALIAS FOR $1;
rrule ALIAS FOR $2;
current_base TIMESTAMP WITH TIME ZONE;
rowvar RECORD;
curse REFCURSOR;
curser REFCURSOR;
i INT;
BEGIN
IF rrule.bymonth IS NOT NULL THEN
OPEN curse SCROLL FOR SELECT r FROM rrule_yearly_bymonth_set(after, rrule ) r;
FOR current_base IN SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d LOOP
current_base := date_trunc( 'day', current_base ) + (after::time)::interval;
OPEN curse FOR SELECT r FROM rrule_yearly_bymonth_set(after, rrule ) r;
FOR rowvar IN SELECT d FROM rrule_bysetpos_filter(curse,rrule.bysetpos) d LOOP
current_base := date_trunc( 'day', rowvar.d ) + (after::time)::interval;
RETURN NEXT current_base;
END LOOP;
ELSE
@ -532,6 +557,7 @@ DECLARE
base_day TIMESTAMP WITH TIME ZONE;
current_base TIMESTAMP WITH TIME ZONE;
current TIMESTAMP WITH TIME ZONE;
rowvar RECORD;
rrule rrule_parts%ROWTYPE;
BEGIN
loopcount := 0;
@ -547,7 +573,8 @@ BEGIN
base_day := date_trunc('day',basedate);
WHILE loopcount < loopmax AND current_base <= maxdate LOOP
IF rrule.freq = 'DAILY' THEN
FOR current IN SELECT d FROM daily_set(current_base,rrule) d WHERE d >= base_day LOOP
FOR rowvar IN SELECT d FROM daily_set(current_base,rrule) d WHERE d >= base_day LOOP
current := rowvar.d;
-- IF test_byday_rule(current,rrule.byday) AND test_bymonthday_rule(current,rrule.bymonthday) AND test_bymonth_rule(current,rrule.bymonth) THEN
EXIT WHEN rrule.until IS NOT NULL AND current > rrule.until;
IF current >= mindate THEN
@ -559,7 +586,8 @@ BEGIN
END LOOP;
current_base := current_base + (rrule.interval::text || ' days')::interval;
ELSIF rrule.freq = 'WEEKLY' THEN
FOR current IN SELECT w FROM weekly_set(current_base,rrule) w WHERE w >= base_day LOOP
FOR rowvar IN SELECT d FROM weekly_set(current_base,rrule) d WHERE d >= base_day LOOP
current := rowvar.d;
IF test_byyearday_rule(current,rrule.byyearday)
AND test_bymonthday_rule(current,rrule.bymonthday)
AND test_bymonth_rule(current,rrule.bymonth)
@ -574,7 +602,8 @@ BEGIN
END LOOP;
current_base := current_base + (rrule.interval::text || ' weeks')::interval;
ELSIF rrule.freq = 'MONTHLY' THEN
FOR current IN SELECT m FROM monthly_set(current_base,rrule) m WHERE m >= base_day LOOP
FOR rowvar IN SELECT d FROM monthly_set(current_base,rrule) d WHERE d >= base_day LOOP
current := rowvar.d;
-- IF /* test_byyearday_rule(current,rrule.byyearday)
-- AND */ test_bymonth_rule(current,rrule.bymonth)
-- THEN
@ -588,7 +617,8 @@ BEGIN
END LOOP;
current_base := current_base + (rrule.interval::text || ' months')::interval;
ELSIF rrule.freq = 'YEARLY' THEN
FOR current IN SELECT y FROM yearly_set(current_base,rrule) y WHERE y >= base_day LOOP
FOR rowvar IN SELECT d FROM yearly_set(current_base,rrule) d WHERE d >= base_day LOOP
current := rowvar.d;
EXIT WHEN rrule.until IS NOT NULL AND current > rrule.until;
IF current >= mindate THEN
RETURN NEXT current;
@ -617,8 +647,11 @@ DECLARE
basedate ALIAS FOR $1;
repeatrule ALIAS FOR $2;
maxdate TIMESTAMP WITH TIME ZONE;
rowvar RECORD;
BEGIN
maxdate := current_date + '10 years'::interval;
RETURN QUERY SELECT d FROM rrule_event_instances_range( basedate, repeatrule, basedate, maxdate, 300 ) d;
FOR rowvar IN SELECT d FROM rrule_event_instances_range( basedate, repeatrule, basedate, maxdate, 300 ) d LOOP
RETURN NEXT rowvar.d;
END LOOP;
END;
$$ LANGUAGE 'plpgsql' IMMUTABLE STRICT;

View File

@ -9,7 +9,7 @@
-- RRULE:FREQ=DAILY;COUNT=10
--
-- ==> (1997 9:00 AM EDT)September 2-11
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;COUNT=10' ) LIMIT 20;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;COUNT=10' );
--
-- --------------------------------------------------------------------
-- Daily until December 24, 1997:
@ -19,7 +19,7 @@
--
-- ==> (1997 9:00 AM EDT)September 2-30;October 1-25
-- (1997 9:00 AM EST)October 26-31;November 1-30;December 1-23
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;UNTIL=19971224T000000' ) LIMIT 500;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;UNTIL=19971224T000000' );
--
-- --------------------------------------------------------------------
-- Every other day - forever:
@ -31,7 +31,7 @@
-- (1997 9:00 AM EST)October 26,28,30;November 1,3,5,7...25,27,29;
-- Dec 1,3,...
--
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;INTERVAL=2' ) LIMIT 20;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;INTERVAL=2' ) LIMIT 50;
-- --------------------------------------------------------------------
-- Every 10 days, 5 occurrences:
--
@ -40,7 +40,7 @@
--
-- ==> (1997 9:00 AM EDT)September 2,12,22;October 2,12
--
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;INTERVAL=10;COUNT=5' ) LIMIT 500;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;INTERVAL=10;COUNT=5' );
-- --------------------------------------------------------------------
-- Everyday in January, for 3 years:
--
@ -54,7 +54,10 @@
-- (1999 9:00 AM EDT)January 1-31
-- (2000 9:00 AM EDT)January 1-31
--
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1' ) LIMIT 500;
--- ? No instance on January 31, since 9:00am EDT is after 2000-01-31 09:00:00 UTC. I think that is correct.
--- ? SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19980101T090000', 'FREQ=YEARLY;UNTIL=20000131T090000Z;BYMONTH=1;BYDAY=SU,MO,TU,WE,TH,FR,SA' );
--- ? No instance on January 31, since 9:00am EDT is after 2000-01-31 09:00:00 UTC. I think that is correct.
--- ? SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19980101T090000', 'FREQ=DAILY;UNTIL=20000131T090000Z;BYMONTH=1' );
-- --------------------------------------------------------------------
-- Weekly for 10 occurrences
--
@ -63,7 +66,7 @@
--
-- ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
-- (1997 9:00 AM EST)October 28;November 4
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;COUNT=10' ) LIMIT 500;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;COUNT=10' );
--
-- --------------------------------------------------------------------
-- Weekly until December 24, 1997
@ -74,7 +77,7 @@
-- ==> (1997 9:00 AM EDT)September 2,9,16,23,30;October 7,14,21
-- (1997 9:00 AM EST)October 28;November 4,11,18,25;
-- December 2,9,16,23
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;UNTIL=19971224T000000Z' ) LIMIT 500;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;UNTIL=19971224T000000Z' );
--
-- --------------------------------------------------------------------
-- Every other week - forever:
@ -84,9 +87,9 @@
--
-- ==> (1997 9:00 AM EDT)September 2,16,30;October 14
-- (1997 9:00 AM EST)October 28;November 11,25;December 9,23
-- (1998 9:00 AM EST)January 6,20;February
-- (1998 9:00 AM EST)January 6,20;February 3, 17
-- ...
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;INTERVAL=2;WKST=SU' ) LIMIT 12;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;INTERVAL=2;WKST=SU' ) LIMIT 13;
--
-- --------------------------------------------------------------------
-- Weekly on Tuesday and Thursday for 5 weeks:
@ -97,8 +100,8 @@
-- RRULE:FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH
--
-- ==> (1997 9:00 AM EDT)September 2,4,9,11,16,18,23,25,30;October 2
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH' ) LIMIT 500;
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH' ) LIMIT 500;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;UNTIL=19971007T000000Z;WKST=SU;BYDAY=TU,TH' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;COUNT=10;WKST=SU;BYDAY=TU,TH' );
--
-- --------------------------------------------------------------------
-- Every other week on Monday, Wednesday and Friday until December 24,
@ -111,7 +114,8 @@
-- 1,3,13,15,17
-- (1997 9:00 AM EST)October 27,29,31;November 10,12,14,24,26,28;
-- December 8,10,12,22
--- !!! SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;BYDAY=MO,WE,FR' );
-- !!! This is challenging, because it starts on DTSTART even though DTSTART fails the repeat criteria. In fact no known provide a UI that allows data like this to be created.
--- !!! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;INTERVAL=2;UNTIL=19971224T000000Z;WKST=SU;BYDAY=MO,WE,FR' );
--
-- --------------------------------------------------------------------
-- Every other week on Tuesday and Thursday, for 8 occurrences:
@ -120,7 +124,7 @@
-- RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH
--
-- ==> (1997 9:00 AM EDT)September 2,4,16,18,30;October 2,14,16
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH' );
--
-- --------------------------------------------------------------------
-- Monthly on the 1st Friday for ten occurrences:
@ -132,7 +136,7 @@
-- (1997 9:00 AM EST)November 7;Dec 5
-- (1998 9:00 AM EST)January 2;February 6;March 6;April 3
-- (1998 9:00 AM EDT)May 1;June 5
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;COUNT=10;BYDAY=1FR' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970905T090000', 'FREQ=MONTHLY;COUNT=10;BYDAY=1FR' );
--
-- --------------------------------------------------------------------
-- Monthly on the 1st Friday until December 24, 1997:
@ -142,7 +146,7 @@
--
-- ==> (1997 9:00 AM EDT)September 5;October 3
-- (1997 9:00 AM EST)November 7;December 5
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970905T090000', 'FREQ=MONTHLY;UNTIL=19971224T000000Z;BYDAY=1FR' );
--
-- --------------------------------------------------------------------
-- Every other month on the 1st and last Sunday of the month for 10
@ -155,7 +159,7 @@
-- (1997 9:00 AM EST)November 2,30
-- (1998 9:00 AM EST)January 4,25;March 1,29
-- (1998 9:00 AM EDT)May 3,31
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970907T090000', 'FREQ=MONTHLY;INTERVAL=2;COUNT=10;BYDAY=1SU,-1SU' );
--
-- --------------------------------------------------------------------
-- Monthly on the second to last Monday of the month for 6 months:
@ -166,7 +170,7 @@
-- ==> (1997 9:00 AM EDT)September 22;October 20
-- (1997 9:00 AM EST)November 17;December 22
-- (1998 9:00 AM EST)January 19;February 16
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;COUNT=6;BYDAY=-2MO' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;COUNT=6;BYDAY=-2MO' );
--
-- --------------------------------------------------------------------
-- Monthly on the third to the last day of the month, forever:
@ -178,7 +182,7 @@
-- (1997 9:00 AM EST)October 29;November 28;December 29
-- (1998 9:00 AM EST)January 29;February 26
-- ...
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;BYMONTHDAY=-3' ) LIMIT 30;
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;BYMONTHDAY=-3' ) LIMIT 6;
--
-- --------------------------------------------------------------------
-- Monthly on the 2nd and 15th of the month for 10 occurrences:
@ -189,7 +193,7 @@
-- ==> (1997 9:00 AM EDT)September 2,15;October 2,15
-- (1997 9:00 AM EST)November 2,15;December 2,15
-- (1998 9:00 AM EST)January 2,15
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;COUNT=10;BYMONTHDAY=2,15' );
--
-- --------------------------------------------------------------------
-- Monthly on the first and last day of the month for 10 occurrences:
@ -200,7 +204,7 @@
-- ==> (1997 9:00 AM EDT)September 30;October 1
-- (1997 9:00 AM EST)October 31;November 1,30;December 1,31
-- (1998 9:00 AM EST)January 1,31;February 1
--- SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970930T090000', 'FREQ=MONTHLY;COUNT=10;BYMONTHDAY=1,-1' );
--
-- --------------------------------------------------------------------
-- Every 18 months on the 10th thru 15th of the month for 10
@ -212,7 +216,7 @@
--
-- ==> (1997 9:00 AM EDT)September 10,11,12,13,14,15
-- (1999 9:00 AM EST)March 10,11,12,13
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970910T090000', 'FREQ=MONTHLY;INTERVAL=18;COUNT=10;BYMONTHDAY=10,11,12,13,14,15' );
--
-- --------------------------------------------------------------------
-- Every Tuesday, every other month:
@ -224,7 +228,7 @@
-- (1997 9:00 AM EST)November 4,11,18,25
-- (1998 9:00 AM EST)January 6,13,20,27;March 3,10,17,24,31
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;INTERVAL=2;BYDAY=TU' ) LIMIT 18;
--
-- --------------------------------------------------------------------
-- Yearly in June and July for 10 occurrences:
@ -238,7 +242,8 @@
-- (2001 9:00 AM EDT)June 10;July 10
-- Note: Since none of the BYDAY, BYMONTHDAY or BYYEARDAY components
-- are specified, the day is gotten from DTSTART
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- !!! We miss the first instance in June. Busted.
--- !!! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970610T090000', 'FREQ=YEARLY;COUNT=10;BYMONTH=6,7' );
--
-- --------------------------------------------------------------------
-- Every other year on January, February, and March for 10 occurrences:
@ -250,7 +255,8 @@
-- (1999 9:00 AM EST)January 10;February 10;March 10
-- (2001 9:00 AM EST)January 10;February 10;March 10
-- (2003 9:00 AM EST)January 10;February 10;March 10
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- !!! We miss the first instance in March. Busted.
--- !!! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970310T090000', 'FREQ=YEARLY;INTERVAL=2;COUNT=10;BYMONTH=1,2,3' );
--
-- --------------------------------------------------------------------
-- Every 3rd year on the 1st, 100th and 200th day for 10 occurrences:
@ -265,7 +271,8 @@
-- (2003 9:00 AM EST)January 1
-- (2003 9:00 AM EDT)April 10;July 19
-- (2006 9:00 AM EST)January 1
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- ! We don't support BYYEARDAY yet.
--- ! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970101T090000', 'FREQ=YEARLY;INTERVAL=3;COUNT=10;BYYEARDAY=1,100,200' );
--
-- --------------------------------------------------------------------
-- Every 20th Monday of the year, forever:
@ -276,7 +283,8 @@
-- (1998 9:00 AM EDT)May 18
-- (1999 9:00 AM EDT)May 17
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- ! We don't support BYDAY for yearly events. We don't support YEARLY at all well, TBH
--- ! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970519T090000', 'FREQ=YEARLY;BYDAY=20MO' ) LIMIT 3;
--
-- --------------------------------------------------------------------
-- Monday of week number 20 (where the default start of the week is
@ -289,7 +297,8 @@
-- (1998 9:00 AM EDT)May 11
-- (1999 9:00 AM EDT)May 17
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- ! We don't support BYWEEKNO at all yet.
--- ! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970512T090000', 'FREQ=YEARLY;BYWEEKNO=20;BYDAY=MO' ) LIMIT 3;
--
-- --------------------------------------------------------------------
-- Every Thursday in March, forever:
@ -301,7 +310,7 @@
-- (1998 9:00 AM EST)March 5,12,19,26
-- (1999 9:00 AM EST)March 4,11,18,25
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970313T090000', 'FREQ=YEARLY;BYMONTH=3;BYDAY=TH' ) LIMIT 11;
--
-- --------------------------------------------------------------------
-- Every Thursday, but only during June, July, and August, forever:
@ -316,7 +325,7 @@
-- (1999 9:00 AM EDT)June 3,10,17,24;July 1,8,15,22,29;
-- August 5,12,19,26
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970605T090000', 'FREQ=YEARLY;BYDAY=TH;BYMONTH=6,7,8' ) LIMIT 39;
--
-- --------------------------------------------------------------------
-- Every Friday the 13th, forever:
@ -329,7 +338,7 @@
-- (1999 9:00 AM EDT)August 13
-- (2000 9:00 AM EDT)October 13
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=MONTHLY;BYDAY=FR;BYMONTHDAY=13' ) LIMIT 35;
--
-- --------------------------------------------------------------------
-- The first Saturday that follows the first Sunday of the month,
@ -343,7 +352,7 @@
-- (1998 9:00 AM EST)January 10;February 7;March 7
-- (1998 9:00 AM EDT)April 11;May 9;June 13...
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970913T090000', 'FREQ=MONTHLY;BYDAY=SA;BYMONTHDAY=7,8,9,10,11,12,13' ) LIMIT 10;
--
-- --------------------------------------------------------------------
-- Every four years, the first Tuesday after a Monday in November,
@ -357,7 +366,7 @@
-- (2000 9:00 AM EST)November 7
-- (2004 9:00 AM EST)November 2
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19961105T090000', 'FREQ=YEARLY;INTERVAL=4;BYMONTH=11;BYDAY=TU;BYMONTHDAY=2,3,4,5,6,7,8' ) LIMIT 6;
--
-- --------------------------------------------------------------------
-- The 3rd instance into the month of one of Tuesday, Wednesday or
@ -368,7 +377,7 @@
--
-- ==> (1997 9:00 AM EDT)September 4;October 7
-- (1997 9:00 AM EST)November 6
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970904T090000', 'FREQ=MONTHLY;COUNT=3;BYDAY=TU,WE,TH;BYSETPOS=3' );
--
-- --------------------------------------------------------------------
-- The 2nd to last weekday of the month:
@ -380,7 +389,7 @@
-- (1997 9:00 AM EST)October 30;November 27;December 30
-- (1998 9:00 AM EST)January 29;February 26;March 30
-- ...
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970929T090000', 'FREQ=MONTHLY;BYDAY=MO,TU,WE,TH,FR;BYSETPOS=-2' ) LIMIT 8;
--
-- --------------------------------------------------------------------
-- Every 3 hours from 9:00 AM to 5:00 PM on a specific day:
@ -389,7 +398,8 @@
-- RRULE:FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z
--
-- ==> (September 2, 1997 EDT)09:00,12:00,15:00
--- !! SELECT * FROM event_instances('19970902T090000', '' );
--- !! FREQ=HOURLY Not implemented
--- !! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=HOURLY;INTERVAL=3;UNTIL=19970902T170000Z' );
--
-- --------------------------------------------------------------------
-- Every 15 minutes for 6 occurrences:
@ -398,7 +408,8 @@
-- RRULE:FREQ=MINUTELY;INTERVAL=15;COUNT=6
--
-- ==> (September 2, 1997 EDT)09:00,09:15,09:30,09:45,10:00,10:15
--- !! SELECT * FROM event_instances('19970902T090000', '' );
--- !! FREQ=MINUTELY Not implemented
--- !! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('', '' );
--
-- --------------------------------------------------------------------
-- Every hour and a half for 4 occurrences:
@ -407,7 +418,8 @@
-- RRULE:FREQ=MINUTELY;INTERVAL=90;COUNT=4
--
-- ==> (September 2, 1997 EDT)09:00,10:30;12:00;13:30
--- !! SELECT * FROM event_instances('19970902T090000', '' );
--- !! FREQ=HOURLY Not implemented
--- !! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('', '' );
--
-- --------------------------------------------------------------------
-- Every 20 minutes from 9:00 AM to 4:40 PM every day:
@ -422,7 +434,8 @@
-- (September 3, 1997 EDT)9:00,9:20,9:40,10:00,10:20,
-- ...16:00,16:20,16:40
-- ...
---- !! SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40' ) LIMIT 500;
--- !! FREQ=MINUTELY and/or BYHOUR Not implemented
--- !! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970902T090000', 'FREQ=DAILY;BYHOUR=9,10,11,12,13,14,15,16;BYMINUTE=0,20,40' ) LIMIT 500;
--
-- --------------------------------------------------------------------
-- An example where the days generated makes a difference because of
@ -439,5 +452,7 @@
-- RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU
-- ==> (1997 EDT)August 5,17,19,31
--
--- ! SELECT * FROM event_instances('19970902T090000', '' );
--- !! WKST Not implemented. The second one works fine because WKST == SU in all our code.
--- !! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970805T090000', 'FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=MO' );
--- !! SET timezone TO 'US/Eastern'; SELECT * FROM event_instances('19970805T090000', 'FREQ=WEEKLY;INTERVAL=2;COUNT=4;BYDAY=TU,SU;WKST=SU' );
--