0

I'm pretty new to Postgres and SQL as a whole and could use a bit of help with a function here.

I have this table:

CREATE TABLE car_rentals(
plate       varchar(10)     NOT NULL,
start_date  date            NOT NULL,
end_date    date            NOT NULL,
license_nr  varchar(10)     NOT NULL,
CONSTRAINT unq_car_rentals_start UNIQUE (plate, start_date),
CONSTRAINT unq_car_rentals_end UNIQUE (plate, end_date));

What i need is for a function to take as input plate, start date and end date and throw an error if the table contains any row with the same plate where the rental period is different from but overlaps with the given period.

I found this document on reporting errors but I'm not sure how to properly format the function in order to implement what I need. https://www.postgresql.org/docs/9.6/plpgsql-errors-and-messages.html

2
  • 1
    You don't need a function you need this Range Constraint. Look at btree_gist example and adapt to your table. Commented Apr 6, 2021 at 22:47
  • 1
    You want a trigger that fires before insert and throws an exception if there’s an overlap. Commented Apr 7, 2021 at 7:25

2 Answers 2

3

You don't need a trigger to achieve this. Postgres supports so called exclusion constraints exactly for this purpose:

create table car_rentals
(
  plate       varchar(10)     NOT NULL,
  start_date  date            NOT NULL,
  end_date    date            NOT NULL,
  license_nr  varchar(10)     NOT NULL,
  constraint no_overlapping_ranges 
     exclude using gist (plate with =, daterange(start_date, end_date, '[]') with &&)
);

The constraint definition in details:

  • plate with = for rows with the same plate number
  • daterange(start_date, end_date, '[]') with && - fail if there are rows with an overlapping range.

As the constraint includes the = operator, you need to install the extension btree_gist in order to create the above constraint:

As a superuser run:

create extension btree_gist;

in the database where you want to create the car_rentals database (you only need to do this once).

Online example

Sign up to request clarification or add additional context in comments.

Comments

1

The WHERE condition of a query you could use in a trigger could be:

WHERE daterange(start_date, end_date, '[]') && daterange($1, $2, '[]')  -- overlaps
  AND (start_date <> $1 OR end_date <> $2)  -- is not equal
  AND plate = $3

Here $1, $2 and $3 are placeholders for the data against which you want to check, and the query becomes simple by using the "overlaps" range operator &&.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.