Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The smallest unit that supports pg_cron is the granularity of seconds… #149

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
42 changes: 21 additions & 21 deletions expected/pg_cron-test.out
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ SELECT extversion FROM pg_extension WHERE extname='pg_cron';
(1 row)

-- Vacuum every day at 10:00am (GMT)
SELECT cron.schedule('0 10 * * *', 'VACUUM');
SELECT cron.schedule('0 0 10 * * *', 'VACUUM');
schedule
----------
1
Expand All @@ -39,45 +39,45 @@ SELECT cron.schedule('@restart', 'ALTER EXTENSION pg_cron UPDATE');
(1 row)

-- Vacuum every day at 10:00am (GMT)
SELECT cron.schedule('myvacuum', '0 10 * * *', 'VACUUM');
SELECT cron.schedule('myvacuum', '0 0 10 * * *', 'VACUUM');
schedule
----------
3
(1 row)

SELECT jobid, jobname, schedule, command FROM cron.job ORDER BY jobid;
jobid | jobname | schedule | command
-------+----------+------------+--------------------------------
2 | | @restart | ALTER EXTENSION pg_cron UPDATE
3 | myvacuum | 0 10 * * * | VACUUM
jobid | jobname | schedule | command
-------+----------+--------------+--------------------------------
2 | | @restart | ALTER EXTENSION pg_cron UPDATE
3 | myvacuum | 0 0 10 * * * | VACUUM
(2 rows)

-- Make that 11:00am (GMT)
SELECT cron.schedule('myvacuum', '0 11 * * *', 'VACUUM');
SELECT cron.schedule('myvacuum', '0 0 11 * * *', 'VACUUM');
schedule
----------
3
(1 row)

SELECT jobid, jobname, schedule, command FROM cron.job ORDER BY jobid;
jobid | jobname | schedule | command
-------+----------+------------+--------------------------------
2 | | @restart | ALTER EXTENSION pg_cron UPDATE
3 | myvacuum | 0 11 * * * | VACUUM
jobid | jobname | schedule | command
-------+----------+--------------+--------------------------------
2 | | @restart | ALTER EXTENSION pg_cron UPDATE
3 | myvacuum | 0 0 11 * * * | VACUUM
(2 rows)

-- Make that VACUUM FULL
SELECT cron.schedule('myvacuum', '0 11 * * *', 'VACUUM FULL');
SELECT cron.schedule('myvacuum', '0 0 11 * * *', 'VACUUM FULL');
schedule
----------
3
(1 row)

SELECT jobid, jobname, schedule, command FROM cron.job ORDER BY jobid;
jobid | jobname | schedule | command
-------+----------+------------+--------------------------------
2 | | @restart | ALTER EXTENSION pg_cron UPDATE
3 | myvacuum | 0 11 * * * | VACUUM FULL
jobid | jobname | schedule | command
-------+----------+--------------+--------------------------------
2 | | @restart | ALTER EXTENSION pg_cron UPDATE
3 | myvacuum | 0 0 11 * * * | VACUUM FULL
(2 rows)

-- Stop scheduling a job
Expand Down Expand Up @@ -109,27 +109,27 @@ revoke connect on database pgcron_dbno from public;
create user pgcron_cront with password 'pwd';
GRANT USAGE ON SCHEMA cron TO pgcron_cront;
-- Schedule a job for this user on the database that does not accept connections
SELECT cron.schedule(job_name:='can not connect', schedule:='0 11 * * *', command:='VACUUM',database:='pgcron_dbno',username:='pgcron_cront');
SELECT cron.schedule(job_name:='can not connect', schedule:='0 0 11 * * *', command:='VACUUM',database:='pgcron_dbno',username:='pgcron_cront');
ERROR: User pgcron_cront does not have CONNECT privilege on pgcron_dbno
-- Create a database that does allow connections
create database pgcron_dbyes;
-- Schedule a job on the database that does accept connections for a non existing user
SELECT cron.schedule(job_name:='user does not exist', schedule:='0 11 * * *', command:='VACUUM',database:='pgcron_dbyes',username:='pgcron_useraqwxszedc');
SELECT cron.schedule(job_name:='user does not exist', schedule:='0 0 11 * * *', command:='VACUUM',database:='pgcron_dbyes',username:='pgcron_useraqwxszedc');
ERROR: role "pgcron_useraqwxszedc" does not exist
-- Alter an existing job on a database that does not accept connections
SELECT cron.alter_job(job_id:=2,database:='pgcron_dbno',username:='pgcron_cront');
ERROR: User pgcron_cront does not have CONNECT privilege on pgcron_dbno
-- Second as non superuser
SET SESSION AUTHORIZATION pgcron_cront;
-- Create a job
SELECT cron.schedule('My vacuum', '0 11 * * *', 'VACUUM');
SELECT cron.schedule('My vacuum', '0 0 11 * * *', 'VACUUM');
schedule
----------
6
(1 row)

-- Create a job for another user
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 11 * * *', command:='VACUUM',username:='anotheruser');
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 0 11 * * *', command:='VACUUM',username:='anotheruser');
ERROR: must be superuser to create a job for another role
-- Change the username of an existing job that the user own
select cron.alter_job(job_id:=6,username:='anotheruser');
Expand Down Expand Up @@ -175,7 +175,7 @@ SELECT username FROM cron.job where jobid=2;
(1 row)

-- Create a job for another user
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 11 * * *', command:='VACUUM',username:='pgcron_cront');
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 0 11 * * *', command:='VACUUM',username:='pgcron_cront');
schedule
----------
7
Expand Down
10 changes: 8 additions & 2 deletions include/cron.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ typedef int time_min;

#define SECONDS_PER_MINUTE 60

#define FIRST_SECOND 0
#define LAST_SECOND 59
#define SECOND_COUNT (LAST_SECOND - FIRST_SECOND + 1)

#define FIRST_MINUTE 0
#define LAST_MINUTE 59
#define MINUTE_COUNT (LAST_MINUTE - FIRST_MINUTE + 1)
Expand Down Expand Up @@ -160,6 +164,7 @@ typedef struct _entry {
gid_t gid;
char **envp;
char *cmd;
bitstr_t bit_decl(second, SECOND_COUNT);
bitstr_t bit_decl(minute, MINUTE_COUNT);
bitstr_t bit_decl(hour, HOUR_COUNT);
bitstr_t bit_decl(dom, DOM_COUNT);
Expand All @@ -169,8 +174,9 @@ typedef struct _entry {
#define DOM_STAR 0x01
#define DOW_STAR 0x02
#define WHEN_REBOOT 0x04
#define MIN_STAR 0x08
#define HR_STAR 0x10
#define SEC_STAR 0x08
#define MIN_STAR 0x10
#define HR_STAR 0x20
} entry;

/* the crontab database will be a list of the
Expand Down
18 changes: 9 additions & 9 deletions sql/pg_cron-test.sql
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ ALTER EXTENSION pg_cron UPDATE TO '1.4';
SELECT extversion FROM pg_extension WHERE extname='pg_cron';

-- Vacuum every day at 10:00am (GMT)
SELECT cron.schedule('0 10 * * *', 'VACUUM');
SELECT cron.schedule('0 0 10 * * *', 'VACUUM');

-- Stop scheduling a job
SELECT cron.unschedule(1);
Expand All @@ -18,17 +18,17 @@ SELECT cron.schedule('@restar', 'ALTER EXTENSION pg_cron UPDATE');
SELECT cron.schedule('@restart', 'ALTER EXTENSION pg_cron UPDATE');

-- Vacuum every day at 10:00am (GMT)
SELECT cron.schedule('myvacuum', '0 10 * * *', 'VACUUM');
SELECT cron.schedule('myvacuum', '0 0 10 * * *', 'VACUUM');

SELECT jobid, jobname, schedule, command FROM cron.job ORDER BY jobid;

-- Make that 11:00am (GMT)
SELECT cron.schedule('myvacuum', '0 11 * * *', 'VACUUM');
SELECT cron.schedule('myvacuum', '0 0 11 * * *', 'VACUUM');

SELECT jobid, jobname, schedule, command FROM cron.job ORDER BY jobid;

-- Make that VACUUM FULL
SELECT cron.schedule('myvacuum', '0 11 * * *', 'VACUUM FULL');
SELECT cron.schedule('myvacuum', '0 0 11 * * *', 'VACUUM FULL');

SELECT jobid, jobname, schedule, command FROM cron.job ORDER BY jobid;

Expand All @@ -55,13 +55,13 @@ create user pgcron_cront with password 'pwd';
GRANT USAGE ON SCHEMA cron TO pgcron_cront;

-- Schedule a job for this user on the database that does not accept connections
SELECT cron.schedule(job_name:='can not connect', schedule:='0 11 * * *', command:='VACUUM',database:='pgcron_dbno',username:='pgcron_cront');
SELECT cron.schedule(job_name:='can not connect', schedule:='0 0 11 * * *', command:='VACUUM',database:='pgcron_dbno',username:='pgcron_cront');

-- Create a database that does allow connections
create database pgcron_dbyes;

-- Schedule a job on the database that does accept connections for a non existing user
SELECT cron.schedule(job_name:='user does not exist', schedule:='0 11 * * *', command:='VACUUM',database:='pgcron_dbyes',username:='pgcron_useraqwxszedc');
SELECT cron.schedule(job_name:='user does not exist', schedule:='0 0 11 * * *', command:='VACUUM',database:='pgcron_dbyes',username:='pgcron_useraqwxszedc');

-- Alter an existing job on a database that does not accept connections
SELECT cron.alter_job(job_id:=2,database:='pgcron_dbno',username:='pgcron_cront');
Expand All @@ -70,10 +70,10 @@ SELECT cron.alter_job(job_id:=2,database:='pgcron_dbno',username:='pgcron_cront'
SET SESSION AUTHORIZATION pgcron_cront;

-- Create a job
SELECT cron.schedule('My vacuum', '0 11 * * *', 'VACUUM');
SELECT cron.schedule('My vacuum', '0 0 11 * * *', 'VACUUM');

-- Create a job for another user
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 11 * * *', command:='VACUUM',username:='anotheruser');
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 0 11 * * *', command:='VACUUM',username:='anotheruser');

-- Change the username of an existing job that the user own
select cron.alter_job(job_id:=6,username:='anotheruser');
Expand All @@ -97,7 +97,7 @@ select cron.alter_job(job_id:=2,username:='pgcron_cront');
SELECT username FROM cron.job where jobid=2;

-- Create a job for another user
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 11 * * *', command:='VACUUM',username:='pgcron_cront');
SELECT cron.schedule(job_name:='his vacuum', schedule:='0 0 11 * * *', command:='VACUUM',username:='pgcron_cront');
SELECT username FROM cron.job where jobid=7;

-- cleaning
Expand Down
16 changes: 15 additions & 1 deletion src/entry.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@


typedef enum ecode {
e_none, e_minute, e_hour, e_dom, e_month, e_dow,
e_none, e_second, e_minute, e_hour, e_dom, e_month, e_dow,
e_cmd, e_timespec, e_username, e_cmd_len
} ecode_e;

Expand Down Expand Up @@ -126,33 +126,38 @@ parse_cron_entry(char *schedule)
if (!strcmp("reboot", cmd) || !strcmp("restart", cmd)) {
e->flags |= WHEN_REBOOT;
} else if (!strcmp("yearly", cmd) || !strcmp("annually", cmd)){
bit_set(e->second, 0);
bit_set(e->minute, 0);
bit_set(e->hour, 0);
bit_set(e->dom, 0);
bit_set(e->month, 0);
bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
e->flags |= DOW_STAR;
} else if (!strcmp("monthly", cmd)) {
bit_set(e->second, 0);
bit_set(e->minute, 0);
bit_set(e->hour, 0);
bit_set(e->dom, 0);
bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
e->flags |= DOW_STAR;
} else if (!strcmp("weekly", cmd)) {
bit_set(e->second, 0);
bit_set(e->minute, 0);
bit_set(e->hour, 0);
bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
e->flags |= DOM_STAR;
bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
bit_nset(e->dow, 0,0);
} else if (!strcmp("daily", cmd) || !strcmp("midnight", cmd)) {
bit_set(e->second, 0);
bit_set(e->minute, 0);
bit_set(e->hour, 0);
bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
bit_nset(e->month, 0, (LAST_MONTH-FIRST_MONTH+1));
bit_nset(e->dow, 0, (LAST_DOW-FIRST_DOW+1));
} else if (!strcmp("hourly", cmd)) {
bit_set(e->second, 0);
bit_set(e->minute, 0);
bit_nset(e->hour, 0, (LAST_HOUR-FIRST_HOUR+1));
bit_nset(e->dom, 0, (LAST_DOM-FIRST_DOM+1));
Expand All @@ -166,6 +171,15 @@ parse_cron_entry(char *schedule)
} else {
Debug(DPARS, ("load_entry()...about to parse numerics\n"))

if (ch == '*')
e->flags |= SEC_STAR;
ch = get_list(e->second, FIRST_SECOND, LAST_SECOND,
PPC_NULL, ch, file);
if (ch == EOF) {
ecode = e_second;
goto eof;
}

if (ch == '*')
e->flags |= MIN_STAR;
ch = get_list(e->minute, FIRST_MINUTE, LAST_MINUTE,
Expand Down