PERIODS AND SYSTEM- PERIODS AND SYSTEM- VERSIONED TABLES VERSIONED - - PowerPoint PPT Presentation

periods and system periods and system versioned tables
SMART_READER_LITE
LIVE PREVIEW

PERIODS AND SYSTEM- PERIODS AND SYSTEM- VERSIONED TABLES VERSIONED - - PowerPoint PPT Presentation

PERIODS AND SYSTEM- PERIODS AND SYSTEM- VERSIONED TABLES VERSIONED TABLES Vik Fearing February 1, 2019 FOSDEM PGDay, Brussels VIK FEARING VIK FEARING https://www.2ndQuadrant.fr/ PERIODS PERIODS WHAT IS A PERIOD? WHAT IS A PERIOD? Wait.


slide-1
SLIDE 1

PERIODS AND SYSTEM- PERIODS AND SYSTEM- VERSIONED TABLES VERSIONED TABLES

Vik Fearing February 1, 2019 FOSDEM PGDay, Brussels

slide-2
SLIDE 2

VIK FEARING VIK FEARING

https://www.2ndQuadrant.fr/

slide-3
SLIDE 3

PERIODS PERIODS

slide-4
SLIDE 4

WHAT IS A PERIOD? WHAT IS A PERIOD?

Wait. Please do not interrupt me to talk about range types.

slide-5
SLIDE 5

WHAT IS A PERIOD? WHAT IS A PERIOD?

SQL:2011 A starting value: not null, inclusive An ending value: not null, exclusive A constraint: start < end Same namespace as columns

slide-6
SLIDE 6

SCHEDULING SCHEDULING

CREATE TABLE reservations ( guest text NOT NULL, room_number integer NOT NULL, checkin date NOT NULL, checkout date NOT NULL, PERIOD FOR stay (checkin, checkout) ); ALTER TABLE reservations ADD PRIMARY KEY (room_number, stay WITHOUT OVERLAPS);

slide-7
SLIDE 7

SCHEDULING SCHEDULING

Guest Room Check In Check Out Alice 112 2018-10-08 2018-10-11 ERROR

INSERT INTO reservations VALUES ('Bob', 112, '2018-10-10', '2018-10-12');

slide-8
SLIDE 8

PERIOD PREDICATES PERIOD PREDICATES

slide-9
SLIDE 9

PERIOD PREDICATES PERIOD PREDICATES

OVERLAPS p1 OVERLAPS p2 EQUALS p1 EQUALS p2 CONTAINS p1 CONTAINS p2 p1 CONTAINS value

slide-10
SLIDE 10

PERIOD PREDICATES PERIOD PREDICATES

PRECEDES p1 PRECEDES p2 SUCCEEDS p1 SUCCEEDS p2 IMMEDIATELY PRECEDES p1 IMMEDIATELY PRECEDES p2 IMMEDIATELY SUCCEEDS p1 IMMEDIATELY SUCCEEDS p2

slide-11
SLIDE 11

SALES TAX RATES SALES TAX RATES

CREATE TABLE vat ( start_date date NOT NULL, end_date date NOT NULL, rate percentage NOT NULL, PERIOD FOR validity (start_date, end_date), PRIMARY KEY (validity WITHOUT OVERLAPS) );

slide-12
SLIDE 12

SALES TAX RATES SALES TAX RATES

for Switzerland Start End Rate

  • innity

2011 7.6% 2011 2018 8% 2018 innity 7.7%

SELECT * FROM invoices JOIN vat ON vat.validity CONTAINS invoices.invoice_date;

slide-13
SLIDE 13

NON-TEMPORAL NON-TEMPORAL PERIODS PERIODS

(not in the SQL standard)

slide-14
SLIDE 14

PRICING STRATEGIES PRICING STRATEGIES

CREATE TABLE pricing ( product_name text NOT NULL, unit_price numeric NOT NULL, min_quantity integer NOT NULL, max_quantity integer NOT NULL, PERIOD FOR quantity_range (min_quantity, max_quantity), CHECK (min_quantity > 0), PRIMARY KEY (product_name, quantity_range WITHOUT OVERLAPS) );

slide-15
SLIDE 15

PRICING STRATEGIES PRICING STRATEGIES

Product Unit Price Min Max Trinket €1000 1 10 Trinket €800 10 500 Trinket €600 500 1000 Trinket €250 1000 10000

SELECT * FROM pricing WHERE quantity_range CONTAINS 42;

slide-16
SLIDE 16

PORTIONS PORTIONS

slide-17
SLIDE 17

DELETE DELETE

CREATE TABLE vacation ( employee text NOT NULL, start_date date NOT NULL, end_date date NOT NULL, PERIOD FOR dates (start_date, end_date), PRIMARY KEY (employee, dates WITHOUT OVERLAPS) );

slide-18
SLIDE 18

DELETE DELETE

Employee Start End Charlotte 2018-08-01 2018-09-01 Employee Start End Charlotte 2018-08-01 2018-08-10 Charlotte 2018-08-11 2018-09-01

DELETE FROM vacation FOR PORTION OF dates FROM '2018-08-10' TO '2018-08-11' WHERE employee = 'Charlotte';

slide-19
SLIDE 19

UPDATE UPDATE

CREATE TABLE products ( name text NOT NULL,

  • pening date NOT NULL,

closing date NOT NULL, price numeric NOT NULL, PERIOD FOR season (opening, closing), PRIMARY KEY (name, season WITHOUT OVERLAPS) );

slide-20
SLIDE 20

UPDATE UPDATE

Product Open Close Price Trinket 2018-01-01 2019-01-01 €894.85

UPDATE products FOR PORTION OF season FROM '2018-12-01' TO '2018-12-23' SET price = 100;

slide-21
SLIDE 21

UPDATE UPDATE

Product Open Close Price Trinket 2018-01-01 2018-12-01 €894.85 Trinket 2018-12-01 2019-12-23 €100.00 Trinket 2018-12-23 2019-01-01 €894.85

slide-22
SLIDE 22

SYSTEM-VERSIONED SYSTEM-VERSIONED TABLES TABLES

(must be timestamp with time zone)

slide-23
SLIDE 23

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

CREATE TABLE clients ( id bigint PRIMARY KEY, name text NOT NULL, email text NOT NULL, sys_start timestamptz, sys_end timestamptz, PERIOD FOR SYSTEM_TIME (sys_start, sys_end) );

slide-24
SLIDE 24

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

CREATE TABLE clients ( id bigint PRIMARY KEY, name text NOT NULL, email text NOT NULL, sys_start timestamptz GENERATED ALWAYS AS ROW START, sys_end timestamptz GENERATED ALWAYS AS ROW END, PERIOD FOR SYSTEM_TIME (sys_start, sys_end) );

slide-25
SLIDE 25

NOTHING CHANGES! NOTHING CHANGES!

slide-26
SLIDE 26

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. alice@gadgets.com 2018-10-01 09:53+02 'innity'

SELECT * FROM clients;

slide-27
SLIDE 27

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. bob@gadgets.com 2018-10-09 15:47+02 'innity'

UPDATE clients SET email = 'bob@gadgets.com' WHERE id = 3784; SELECT * FROM clients;

slide-28
SLIDE 28

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. carla@gadgets.com 2018-10-11 12:04+02 'innity'

UPDATE clients SET email = 'carla@gadgets.com' WHERE id = 3784; SELECT * FROM clients;

slide-29
SLIDE 29

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. alice@gadgets.com 2018-10-01 09:53+02 2018-10-09 15:47+02 3784 Gadgets Inc. bob@gadgets.com 2018-10-09 15:47+02 2018-10-11 12:04+02 3784 Gadgets Inc. carla@gadgets.com 2018-10-11 12:04+02 'innity'

SELECT * FROM clients FOR SYSTEM_TIME FROM '-infinity' TO 'infinity';

slide-30
SLIDE 30

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. alice@gadgets.com 2018-10-01 09:53+02 2018-10-09 15:47+02

SELECT * FROM clients FOR SYSTEM_TIME AS OF '2018-10-07 12:00+02';

slide-31
SLIDE 31

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

AS OF ts FROM ts1 TO ts2 BETWEEN ts1 AND ts2 BETWEEN SYMMETRIC ts1 AND ts2

slide-32
SLIDE 32

IMPLEMENTATION IN IMPLEMENTATION IN POSTGRESQL POSTGRESQL

slide-33
SLIDE 33

WHAT IS A PERIOD? WHAT IS A PERIOD?

A starting value: not null, inclusive An ending value: not null, exclusive A constraint: start < end Same namespace as columns

slide-34
SLIDE 34

WHAT IS A RANGE TYPE? WHAT IS A RANGE TYPE?

A starting value An ending value A constraint: start <= end

BUT! BUT!

Bounds can be either inclusive or exclusive Bounds can be null Ranges can be empty

slide-35
SLIDE 35

SCHEDULING SCHEDULING

CREATE TABLE reservations ( guest text NOT NULL, room_number integer NOT NULL, checkin date NOT NULL, checkout date NOT NULL, PERIOD FOR stay (checkin, checkout) ); ALTER TABLE reservations ADD PRIMARY KEY (room_number, stay WITHOUT OVERLAPS);

slide-36
SLIDE 36

SCHEDULING SCHEDULING

CREATE TABLE reservations ( guest text NOT NULL, room_number integer NOT NULL, stay daterange NOT NULL ); ALTER TABLE reservations ADD PRIMARY KEY (room_number, stay); CREATE EXTENSION btree_gist; ALTER TABLE reservations ADD EXCLUDE USING gist (room_number WITH =, stay WITH &&);

slide-37
SLIDE 37

SCHEDULING SCHEDULING

Guest Room Check In Check Out Alice 112 2018-10-08 2018-10-11 ERROR

INSERT INTO reservations VALUES ('Bob', 112, '2018-10-10', '2018-10-12');

slide-38
SLIDE 38

SCHEDULING SCHEDULING

Guest Room Stay Alice 112 [2018-10-08,2018-10-11) ERROR

INSERT INTO reservations VALUES ('Bob', 112, '[2018-10-10,2018-10-12)');

slide-39
SLIDE 39

PERIOD PREDICATES PERIOD PREDICATES

OVERLAPS p1 OVERLAPS p2 p1 && p2 EQUALS p1 EQUALS p2 p1 = p2 CONTAINS p1 CONTAINS p2 p1 CONTAINS value p1 @> p2 p1 @> value

slide-40
SLIDE 40

PERIOD PREDICATES PERIOD PREDICATES

PRECEDES p1 PRECEDES p2 p1 << p2 SUCCEEDS p1 SUCCEEDS p2 p1 >> p2

slide-41
SLIDE 41

PERIOD PREDICATES PERIOD PREDICATES

IMMEDIATELY PRECEDES p1 IMMEDIATELY PRECEDES p2 p1 << p2 and p1 -|- p2 IMMEDIATELY SUCCEEDS p1 IMMEDIATELY SUCCEEDS p2 p1 >> p2 and p1 -|- p2

Two new operators, <| and |>, would be useful outside

  • f this.
slide-42
SLIDE 42

PRICING STRATEGIES PRICING STRATEGIES

CREATE TABLE pricing ( product_name text NOT NULL, unit_price numeric NOT NULL, min_quantity integer NOT NULL, max_quantity integer NOT NULL, PERIOD FOR quantity_range (min_quantity, max_quantity), CHECK (min_quantity > 0), PRIMARY KEY (product_name, quantity_range WITHOUT OVERLAPS) );

slide-43
SLIDE 43

PRICING STRATEGIES PRICING STRATEGIES

CREATE TABLE pricing ( product_name text NOT NULL, unit_price numeric NOT NULL, quantity_range int4range NOT NULL, CHECK (lower(quantity_range) > 0), PRIMARY KEY (product_name, quantity_range), EXCLUDE USING gist (product_name WITH =, quantity_range WITH &&) );

slide-44
SLIDE 44

PRICING STRATEGIES PRICING STRATEGIES

Product Unit Price Min Max Trinket €1000 1 10 Trinket €800 10 500 Trinket €600 500 1000 Trinket €250 1000 10000

SELECT * FROM pricing WHERE quantity_range CONTAINS 42;

slide-45
SLIDE 45

PRICING STRATEGIES PRICING STRATEGIES

Product Unit Price Quantities Trinket €1000 [1,10) Trinket €800 [10,500) Trinket €600 [500,1000) Trinket €250 [1000,10000)

SELECT * FROM pricing WHERE quantity_range @> 42;

slide-46
SLIDE 46

NON-TEMPORAL NON-TEMPORAL PERIODS PERIODS

(not in the SQL standard) (range types aren't either so ¯\_(ツ)_/¯)

slide-47
SLIDE 47

SALES TAX RATES SALES TAX RATES

Start End Rate

  • innity

2011 7.6% 2011 2018 8% 2018 innity 7.7%

SELECT * FROM invoices JOIN vat ON vat.validity CONTAINS invoices.invoice_date;

slide-48
SLIDE 48

SALES TAX RATES SALES TAX RATES

Validity Rate [-innity,2011) 7.6% [2011,2018) 8% [2018,innity) 7.7%

SELECT * FROM invoices JOIN vat ON vat.validity @> invoices.invoice_date;

slide-49
SLIDE 49

This can't be done with an extension.

DELETE FROM vacation FOR PORTION OF dates FROM '2018-08-10' TO '2018-08-11' WHERE employee = 'Charlotte'; UPDATE products FOR PORTION OF season FROM '2018-12-01' TO '2018-12-23' SET price = 100;

slide-50
SLIDE 50

SYSTEM-VERSIONED SYSTEM-VERSIONED TABLES TABLES

CREATE EXTENSION sysver;

https://github.com/xocolatl/sysver

slide-51
SLIDE 51

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

CREATE TABLE clients ( id bigint PRIMARY KEY, name text NOT NULL, email text NOT NULL, );

slide-52
SLIDE 52

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

Two columns: sysver_start and sysver_end NOT NULL constraints CHECK (sysver_start < sysver_end) BEFORE trigger for GENERATED ALWAYS AFTER trigger for historization

SELECT sysver.sysver_register('clients');

slide-53
SLIDE 53

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

clients_history table, same structure clients_with_history view to combine them Several functions

SELECT sysver.sysver_register('clients');

slide-54
SLIDE 54

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. carla@gadgets.com 2018-10-11 12:04+02 'innity'

SELECT * FROM clients;

slide-55
SLIDE 55

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. alice@gadgets.com 2018-10-01 09:53+02 2018-10-09 15:47+02 3784 Gadgets Inc. bob@gadgets.com 2018-10-09 15:47+02 2018-10-11 12:04+02 3784 Gadgets Inc. carla@gadgets.com 2018-10-11 12:04+02 'innity'

SELECT * FROM clients FOR SYSTEM_TIME FROM '-infinity' TO 'infinity'; SELECT * FROM clients__from_to('-infinity', 'infinity');

slide-56
SLIDE 56

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

ID Client Email SysStart SysEnd 3784 Gadgets Inc. alice@gadgets.com 2018-10-01 09:53+02 2018-10-09 15:47+02

SELECT * FROM clients__as_of('2018-10-07 12:00+02');

slide-57
SLIDE 57

SYSTEM-VERSIONED TABLES SYSTEM-VERSIONED TABLES

AS OF ts table__as_of(ts) FROM ts1 TO ts2 table__from_to(ts1, ts2) BETWEEN ts1 AND ts2 table__between(ts1, ts2) BETWEEN SYMMETRIC ts1 AND ts2 table__between_symmetric(ts1, ts2)

slide-58
SLIDE 58

BETWEEN SYMMETRIC BETWEEN SYMMETRIC

commit 6f19a8c41f976236310a272bb646d3411759e18d Author: Tom Lane Date: Sun Dec 30 13:42:04 2018 -0500 Teach eval_const_expressions to constant-fold LEAST/GREATEST expressions. Doing this requires an assumption that the invoked btree comparison function is immutable. We could check that explicitly, but in other places such as contain_mutable_functions we just assume that it's true, so we may as well do likewise here. (If the comparison function's behavior isn't immutable, the sort order in indexes built with it would be unstable, so it seems certainly wrong for it not to be so.) Vik Fearing

slide-59
SLIDE 59

IMPLEMENTATION IN IMPLEMENTATION IN POSTGRESQL POSTGRESQL

(for real)

slide-60
SLIDE 60

IMPLEMENTATION IN POSTGRESQL IMPLEMENTATION IN POSTGRESQL

WIP Patch posted to -hackers on May 26, 2018 Almost complete infrastructure for periods Incomplete support for table inheritance Incomplete support for pg_dump None of the other features mentioned in this presentation

slide-61
SLIDE 61

QUESTIONS? QUESTIONS?