Processing Data Inside PostgreSQL - Bruce Momjian
Transcript of Processing Data Inside PostgreSQL - Bruce Momjian
![Page 1: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/1.jpg)
Data Processing Inside PostgreSQL
BRUCE MOMJIAN
There are indisputable advantages of doing data processing in the database
rather than in each application. This presentation explores the ability to
push data processing into the database using SQL, functions, triggers, and
the object-relational features of POSTGRESQL.
Creative Commons Attribution License http://momjian.us/presentations
Last updated: February, 2019
1 / 88
![Page 2: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/2.jpg)
Pre-SQL Data Access
No one wants to return to this era:
◮ Complex cross-table access
◮ Single index
◮ No optimizer
◮ Simple WHERE processing
◮ No aggregation
https://www.flickr.com/photos/jmazzola1/
2 / 88
![Page 3: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/3.jpg)
SQL Data Access
You probably take these for granted:
◮ Easy cross-table access, with optimizer assistance
◮ Complex WHERE processing
◮ Transaction Control
◮ Concurrency
◮ Portable language (SQL)
3 / 88
![Page 4: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/4.jpg)
Post-Ingres
Welcome to thenext generationof data storage.
https://www.flickr.com/photos/mtshaw/
4 / 88
![Page 5: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/5.jpg)
Contents
1. SQL
2. Functions and Triggers
3. Customizing Database Features
5 / 88
![Page 6: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/6.jpg)
1. SQL
Make full use of theSQL tools available.
6 / 88
![Page 7: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/7.jpg)
2. Functions and Triggers
Put your programsin the database.
https://www.flickr.com/photos/23204800@N08/
7 / 88
![Page 8: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/8.jpg)
3. Customizing Database Features
Change thedatabase features.
https://www.flickr.com/photos/alpima/
8 / 88
![Page 9: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/9.jpg)
1. SQL
https://www.flickr.com/photos/ajc1/
9 / 88
![Page 10: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/10.jpg)
Table ConstraintsTable creation requires concentration.
https://www.flickr.com/photos/dsykes34/
10 / 88
![Page 11: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/11.jpg)
Unique Test in an Application
BEGIN;LOCK tab;SELECT ... WHERE col = key;if not found
INSERT (or UPDATE)COMMIT;
11 / 88
![Page 12: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/12.jpg)
UNIQUE Constraint
CREATE TABLE tab(
col ... UNIQUE);
CREATE TABLE customer (id INTEGER UNIQUE);
12 / 88
![Page 13: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/13.jpg)
Preventing NULLs
if (col != NULL)INSERT/UPDATE;
13 / 88
![Page 14: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/14.jpg)
NOT NULL Constraint
CREATE TABLE tab(
col ... NOT NULL );CREATE TABLE customer (name TEXT NOT NULL);
14 / 88
![Page 15: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/15.jpg)
Primary Key Constraint
◮ UNIQUE
◮ NOT NULL
CREATE TABLE customer (id INTEGER PRIMARY KEY);
15 / 88
![Page 16: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/16.jpg)
Ensuring Table Linkage
Foreign —> Primary
BEGIN; SELECT *FROM primaryWHERE key = colFOR UPDATE; if foundINSERT (or UPDATE) INTO foreign;COMMIT;
16 / 88
![Page 17: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/17.jpg)
Ensuring Table Linkage
Primary —> Foreign
BEGIN;SELECT *FROM foreign WHERE col = key FOR UPDATE;if found ? UPDATE/DELETE primary;COMMIT;
17 / 88
![Page 18: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/18.jpg)
Ensuring Table Linkage
Example
CREATE TABLE statename (code CHAR(2) PRIMARY KEY,name VARCHAR(30)
);
CREATE TABLE customer(
customer_id INTEGER,name VARCHAR(30),telephone VARCHAR(20),street VARCHAR(40),city VARCHAR(25),state CHAR(2) REFERENCES statename,zipcode CHAR(10),country VARCHAR(20)
);
18 / 88
![Page 19: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/19.jpg)
Ensuring Table Linkage, Larger Example
CREATE TABLE customer(
customer_id INTEGER PRIMARY KEY,name VARCHAR(30),telephone VARCHAR(20),street VARCHAR(40),city VARCHAR(25),state CHAR(2),zipcode CHAR(10),country VARCHAR(20)
);
CREATE TABLE employee(
employee_id INTEGER PRIMARY KEY,name VARCHAR(30),hire_date DATE
);
CREATE TABLE part (part_id INTEGER PRIMARY KEY,name VARCHAR(30),cost NUMERIC(8,2),weight FLOAT
);
CREATE TABLE salesorder (order_id INTEGER,customer_id INTEGER REFERENCES customer,employee_id INTEGER REFERENCES employee,part_id INTEGER REFERENCES part,order_date DATE,
19 / 88
![Page 20: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/20.jpg)
Ensuring Table Linkage
Prevent Change to Primary
BEGIN;SELECT ... FROM foreign WHERE col = keyFOR UPDATE; IF found
ABORT;
UPDATE/DELETE primary;COMMIT;
20 / 88
![Page 21: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/21.jpg)
Ensuring Table Linkage
REFERENCES Constraint
NO ACTION/RESTRICT (default)
CREATE TABLE foreign( col ... REFERENCES primary (col)ON UPDATE NO ACTION -- not requiredON DELETE NO ACTION -- not required );
21 / 88
![Page 22: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/22.jpg)
Ensuring Table Linkage
Cascade Change to Primary
BEGIN; SELECT ... FROM foreign WHERE col = keyFOR UPDATE;IF found
UPDATE/DELETE foreign;
UPDATE/DELETE primary;COMMIT;
22 / 88
![Page 23: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/23.jpg)
Ensuring Table Linkage
REFERENCES Constraint
CASCADE
CREATE TABLE foreign (col ... REFERENCES primary (col)
ON UPDATE CASCADEON DELETE CASCADE
);
23 / 88
![Page 24: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/24.jpg)
Ensuring Table Linkage
Set Foreign to NULL on Change to Primary
BEGIN;SELECT ...FROM foreignWHERE col = keyFOR UPDATE;IF found
UPDATE foreign SET col = NULL;
UPDATE/DELETE primary;COMMIT;
24 / 88
![Page 25: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/25.jpg)
Ensuring Table Linkage
REFERENCES Constraint
SET NULL
CREATE TABLE foreign(
col ... REFERENCES primary (col)ON UPDATE SET NULLON DELETE SET NULL
);
25 / 88
![Page 26: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/26.jpg)
Ensuring Table Linkage
Set Foreign to DEFAULT on Change to Primary
BEGIN;SELECT ...FROM foreignWHERE col = keyFOR UPDATE;IF found
UPDATE foreign SET col = DEFAULT;
UPDATE/DELETE primary;COMMIT;
26 / 88
![Page 27: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/27.jpg)
Ensuring Table Linkage
REFERENCES Constraint
SET DEFAULT
CREATE TABLE foreign(
col ... REFERENCES primary (col)ON UPDATE SET DEFAULTON DELETE SET DEFAULT
);
CREATE TABLE order (cust_id INTEGER REFERENCES customer (id));
27 / 88
![Page 28: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/28.jpg)
Controlling Data
if col > 0 ...(col = 2 OR col = 7) ...length(col) < 10 ...INSERT/UPDATE tab;
28 / 88
![Page 29: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/29.jpg)
CHECK Constraint
CREATE TABLE tab(
col ... CHECK (col > 0 ...);
CREATE TABLE customer (age INTEGER CHECK (age >= 0));
29 / 88
![Page 30: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/30.jpg)
Check Constraint Example
CREATE TABLE friend2 (firstname VARCHAR(15),lastname VARCHAR(20),city VARCHAR(15),state CHAR(2) CHECK (length(trim(state)) = 2),age INTEGER CHECK (age >= 0),gender CHAR(1) CHECK (gender IN (’M’,’F’)),last_met DATE CHECK (last_met BETWEEN ’1950-01-01’
AND CURRENT_DATE),CHECK (upper(trim(firstname)) != ’ED’ OR
upper(trim(lastname)) != ’RIVERS’));
INSERT INTO friend2VALUES (’Ed’, ’Rivers’, ’Wibbleville’, ’J’, -35, ’S’, ’1931-09-23’);
ERROR: ExecAppend: rejected due to CHECK constraint friend2_last_met
30 / 88
![Page 31: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/31.jpg)
Default Column Values
if col not specifiedcol = DEFAULT;
INSERT/UPDATE tab;
31 / 88
![Page 32: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/32.jpg)
DEFAULT Constraint
CREATE TABLE tab(
quantity ... DEFAULT 1);
CREATE TABLE customer (created timestamp DEFAULT CURRENT_TIMESTAMP);
32 / 88
![Page 33: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/33.jpg)
Auto-numbering Column
CREATE TABLE counter (curr INTEGER);INSERT INTO counter VALUES (1);...BEGIN;val = SELECT curr FROM counter FOR UPDATE;UPDATE counter SET curr = curr + 1;COMMIT;INSERT INTO tab VALUES (... val ...);
33 / 88
![Page 34: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/34.jpg)
SERIAL/Sequence
CREATE TABLE tab(
col SERIAL);
CREATE TABLE tab(
col INTEGER DEFAULT nextval(’tab_col_seq’));
CREATE TABLE customer (id SERIAL);
CREATE SEQUENCE customer_id_seq;CREATE TABLE customer (id INTEGER DEFAULT nextval(’customer_id_seq’));
34 / 88
![Page 35: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/35.jpg)
Constraint Macros
DOMAIN
CREATE DOMAIN phone ASCHAR(12) CHECK (VALUE ˜ ’^[0-9]{3}-[0-9]{3}-[0-9]{4}$’);
CREATE TABLE company ( ... phnum phone, ...);
35 / 88
![Page 36: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/36.jpg)
Using
SELECT’s
Featureshttps://www.flickr.com/photos/umnak/
36 / 88
![Page 37: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/37.jpg)
ANSI Outer Joins - LEFT OUTER
SELECT *FROM tab1, tab2WHERE tab1.col = tab2.colUNIONSELECT *FROM tab1WHERE col NOT IN(
SELECT tab2.colFROM tab2
);
SELECT *FROM tab1 LEFT JOIN tab2 ON tab1.col = tab2.col;
37 / 88
![Page 38: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/38.jpg)
ANSI Outer Joins - RIGHT OUTER
SELECT *FROM tab1, tab2WHERE tab1.col = tab2.colUNIONSELECT *FROM tab2WHERE col NOT IN(
SELECT tab1.colFROM tab1
);
SELECT *FROM tab1 RIGHT JOIN tab2 ON tab1.col = tab2.col;
38 / 88
![Page 39: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/39.jpg)
ANSI Outer Joins - FULL OUTER
SELECT *FROM tab1, tab2WHERE tab1.col = tab2.colUNIONSELECT *FROM tab1WHERE col NOT IN(
SELECT tab2.colFROM tab2
)UNIONSELECT *FROM tab2WHERE col NOT IN(
SELECT tab1.colFROM tab1
);
SELECT *FROM tab1 FULL JOIN tab2 ON tab1.col = tab2.col;
39 / 88
![Page 40: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/40.jpg)
ANSI Outer Join Example
SELECT *FROM customer LEFT JOIN order ON customer.id = order.cust_id;
40 / 88
![Page 41: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/41.jpg)
Aggregates
SUM()
total = 0FOREACH val IN set
total = total + val;END FOREACH
SELECT SUM(val) FROM tab;
41 / 88
![Page 42: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/42.jpg)
Aggregates
MAX()
max = MIN_VAL;FOREACH val IN set
if (val > max)max = val;
END FOREACH
SELECT MAX(val) FROM tab;
SELECT MAX(cost) FROM part;
42 / 88
![Page 43: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/43.jpg)
Aggregates
GROUP BY SUM()
qsort(set)
save = ’’;total = 0;FOREACH val IN set
if val != save and save != ’’{
print save, total;save = val;total = 0;
}total = total + amt;
END FOREACHif save != ’’
print save, total;
SELECT val, SUM(amt) FROM tab GROUP BY val;43 / 88
![Page 44: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/44.jpg)
Aggregates
GROUP BY MAX()
save = ’’;max = MIN_VAL;FOREACH val IN set
if val != save and save != ’’{
print save, max;save = val;max = MIN_VAL;
}if (amt > max)
max = amt;END FOREACHif save != ’’
print save, max;
SELECT val, MAX(amt) FROM tab GROUP BY val;
44 / 88
![Page 45: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/45.jpg)
Aggregates
GROUP BY Examples
SELECT part, COUNT(*)FROM orderORDER BY part;
SELECT cust_id, SUM(due)FROM orderGROUP BY cust_idORDER BY 2 DESC;
45 / 88
![Page 46: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/46.jpg)
Merging SELECTs
UNION
SELECT * INTO TEMP out FROM ...INSERT INTO TEMP out SELECT ...INSERT INTO TEMP out SELECT ...SELECT DISTINCT ...
SELECT *UNIONSELECT *UNIONSELECT *;
46 / 88
![Page 47: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/47.jpg)
Joining SELECTs
INTERSECT
SELECT * INTO TEMP out;DELETE FROM out WHERE out.* NOT IN (SELECT ...);DELETE FROM out WHERE out.* NOT IN (SELECT ...);
SELECT *INTERSECTSELECT *INTERSECTSELECT *;
47 / 88
![Page 48: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/48.jpg)
Subtracting SELECTs
EXCEPT
SELECT * INTO TEMP out;DELETE FROM out WHERE out.* IN (SELECT ...);DELETE FROM out WHERE out.* IN (SELECT ...);
SELECT *EXCEPTSELECT *EXCEPTSELECT *;
48 / 88
![Page 49: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/49.jpg)
Controlling Rows Returned
LIMIT/OFFSET
DECLARE limdemo CURSOR FOR SELECT ...FOR i = 1 to 5
FETCH IN limdemoEND FOR
SELECT *LIMIT 5;
DECLARE limdemo CURSOR FOR SELECT ...MOVE 20 IN limdemoFOR i = 1 to 5
FETCH IN limdemo;END FOR
SELECT *OFFSET 20 LIMIT 5;
49 / 88
![Page 50: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/50.jpg)
Controlling Rows Returned
LIMIT/OFFSET Example
SELECT order_id, balanceFROM orderORDER BY balance DESCLIMIT 10;
50 / 88
![Page 51: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/51.jpg)
Locking SELECT Rows
FOR UPDATE
BEGIN;LOCK tab;SELECT * FROM CUSTOMER WHERE id = 4452;UPDATE customer SET balance = 0 WHERE id = 4452;COMMIT;
BEGIN;SELECT *FROM customerWHERE id = 4452FOR UPDATE;...UPDATE customerSET balance = 0WHERE id = 4452;COMMIT; 51 / 88
![Page 52: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/52.jpg)
Temporary Tables
CREATE TABLE tab (...);...DROP TABLE tab;
CREATE TEMP TABLE tab (...);
SELECT *INTO TEMPORARY holdFROM tab1, tab2, tab3WHERE ...
52 / 88
![Page 53: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/53.jpg)
Automatically Modify SELECT
VIEW - One Column
SELECT col4FROM tab;
CREATE VIEW view1 ASSELECT col4FROM tab;
SELECT * FROM view1;
53 / 88
![Page 54: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/54.jpg)
Automatically Modify SELECT
VIEW - One Row
SELECT *FROM tabWHERE col = ’ISDN’;
CREATE VIEW view2 ASSELECT *FROM tabWHERE col = ’ISDN’;
SELECT * FROM view2;
54 / 88
![Page 55: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/55.jpg)
Automatically Modify SELECT
VIEW - One Field
SELECT col4FROM tabWHERE col = ’ISDN’;
CREATE VIEW view3 ASSELECT col4FROM tabWHERE col = ’ISDN’;
SELECT * FROM view3;
55 / 88
![Page 56: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/56.jpg)
Automatically Modify
INSERT/UPDATE/DELETE
Rules
INSERT INTO tab1 VALUES (...);INSERT INTO tab2 VALUES (...);
CREATE RULE insert_tab1 AS ON INSERT TO tab1 DOINSERT INTO tab2 VALUES (...);
INSERT INTO tab1 VALUES (...);
56 / 88
![Page 57: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/57.jpg)
Automatically Modify
INSERT/UPDATE/DELETE
Rules Example
CREATE TABLE service_request(
customer_id INTEGER,description text,
cre_user text DEFAULT CURRENT_USER,cre_timestamp timestamp DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE service_request_log(
customer_id INTEGER,description text,mod_type char(1),mod_user text DEFAULT CURRENT_USER,
mod_timestamp timestamp DEFAULT CURRENT_TIMESTAMP);
57 / 88
![Page 58: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/58.jpg)
Rules Example - Rule Definition
CREATE RULE service_request_update AS -- UPDATE ruleON UPDATE TO service_requestDO
INSERT INTO service_request_log (customer_id, description, mod_type)VALUES (old.customer_id, old.description, ’U’);
CREATE RULE service_request_delete AS -- DELETE ruleON DELETE TO service_requestDO
INSERT INTO service_request_log (customer_id, description, mod_type)VALUES (old.customer_id, old.description, ’D’);
58 / 88
![Page 59: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/59.jpg)
Multi-User Consistency
◮ Atomic Changes
◮ Atomic Visibility
◮ Atomic Consistency
◮ Reliability
User 1 User 2 Description
BEGIN WORK User 1 starts a transaction
UPDATE acct SET balance = balance - 100 WHERE acctno = 53224 remove 100 from an account
UPDATE acct SET balance = balance + 100 WHERE acctno = 94913 add 100 to an account
SELECT * FROM acct sees both changes
SELECT * FROM acct sees no changes
COMMIT WORK
SELECT * FROM acct sees both changes
59 / 88
![Page 60: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/60.jpg)
Notification
LISTEN/NOTIFY
signal()/kill()
LISTEN myevent;NOTIFY myevent;
60 / 88
![Page 61: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/61.jpg)
Application Walk-through
https://www.flickr.com/photos/guerito/
61 / 88
![Page 62: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/62.jpg)
2. Functions and Triggers
Placing Code
Into the Database:
Server-Side Functions
https://www.flickr.com/photos/momboleum/
62 / 88
![Page 63: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/63.jpg)
Single-Parameter Built-In Functions/Operator
SELECT factorial(10);factorial-----------3628800
SELECT 10!;?column?----------3628800
63 / 88
![Page 64: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/64.jpg)
Two-Parameter Built-in Function/Operator
SELECT date_mi(’2003-05-20’::date, ’2001-10-13’::date);date_mi---------584
SELECT ’2003-05-20’::date - ’2001-10-13’::date;?column?----------584
psql \dfSpsql \doS
64 / 88
![Page 65: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/65.jpg)
Custom Server-Side Functions
◮ Create function
◮ Call function, manually or automatically
65 / 88
![Page 66: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/66.jpg)
Compute Sales Tax
total = cost * 1.06;INSERT ... VALUES ( ... total ... );
INSERT ... VALUES ( ... cost * 1.06, ... );
CREATE FUNCTION total(float)RETURNS floatAS ’SELECT $1 * 1.06;’LANGUAGE ’sql’;
INSERT ... VALUES ( ... total(cost) ... )
66 / 88
![Page 67: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/67.jpg)
Convert Fahrenheit to Centigrade
cent = (faren - 32.0) * 5.0 / 9.0INSERT ... VALUES ( ... cent ... )
INSERT ... VALUES ( ... (faren - 32.0) * 5.0 / 9.0, ... )
CREATE FUNCTION ftoc(float)RETURNS floatAS ’SELECT ($1 - 32.0) * 5.0 / 9.0;’LANGUAGE ’sql’;
INSERT ... VALUES ( ... ftoc(faren) ... )
67 / 88
![Page 68: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/68.jpg)
Compute Shipping Cost
if cost < 2shipping = 3.00
else if cost < 4shipping = 5.00
else shipping = 6.00
INSERT ... VALUES ( ... cost + shipping ... );
68 / 88
![Page 69: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/69.jpg)
Shipping Cost Function
CREATE FUNCTION shipping(numeric)RETURNS numericAS ’SELECT CASE
WHEN $1 < 2 THEN CAST(3.00 AS numeric(8,2))WHEN $1 >= 2 AND $1 < 4 THEN CAST(5.00 AS numeric(8,2))WHEN $1 >= 4 THEN CAST(6.00 AS numeric(8,2))
END;’LANGUAGE ’sql’;
INSERT ... VALUES ( ... cost + shipping(cost) ... );
69 / 88
![Page 70: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/70.jpg)
String Processing — PL/pgSQL
CREATE FUNCTION spread(text)RETURNS textAS $$DECLARE
str text;ret text;i integer;len integer;
BEGINstr := upper($1);ret := ’’; -- start with zero lengthi := 1;len := length(str);WHILE i <= len LOOP
ret := ret || substr(str, i, 1) || ’ ’;i := i + 1;
END LOOP;RETURN ret;
END;$$LANGUAGE ’plpgsql’;
SELECT spread(’Major Financial Report’);spread
----------------------------------------------M A J O R F I N A N C I A L R E P O R T
70 / 88
![Page 71: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/71.jpg)
State Name Lookup
SQL Language Function
SELECT nameFROM statenameWHERE code = ’AL’;
CREATE FUNCTION getstatename(text)RETURNS textAS ’SELECT name
FROM statenameWHERE code = $1;’
LANGUAGE ’sql’;
SELECT getstatename(’AL’);
71 / 88
![Page 72: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/72.jpg)
State Name Lookup From String
PL/pgSQL Language Function
CREATE FUNCTION getstatecode(text)RETURNS textAS $$DECLARE
state_str statename.name%TYPE;statename_rec record;i integer;len integer;matches record;search_str text;
BEGINstate_str := initcap($1); -- capitalization match columnlen := length(trim($1));i := 2;SELECT INTO statename_rec * -- first try for an exact matchFROM statenameWHERE name = state_str;IF FOUNDTHEN RETURN statename_rec.code;END IF;
72 / 88
![Page 73: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/73.jpg)
State Name Lookup From String
PL/pgSQL Language Function (Cont.)
WHILE i <= len LOOP -- test 2,4,6,... chars for matchsearch_str = trim(substr(state_str, 1, i)) || ’%’;SELECT INTO matches COUNT(*)FROM statenameWHERE name LIKE search_str;IF matches.count = 0 -- no matches, failureTHEN RETURN NULL;END IF;IF matches.count = 1 -- exactly one match, return itTHEN
SELECT INTO statename_rec *FROM statenameWHERE name LIKE search_str;IF FOUNDTHEN RETURN statename_rec.code;END IF;
END IF;i := i + 2; -- >1 match, try 2 more chars
END LOOP;RETURN ’’;
END;$$LANGUAGE ’plpgsql’; 73 / 88
![Page 74: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/74.jpg)
State Name Maintenance
CREATE FUNCTION change_statename(char(2), char(30))RETURNS booleanAS $$DECLARE
state_code ALIAS FOR $1;state_name ALIAS FOR $2;statename_rec RECORD;
BEGINIF length(state_code) = 0 -- no state code, failureTHEN RETURN ’f’;ELSE
IF length(state_name) != 0 -- is INSERT or UPDATE?THEN
SELECT INTO statename_rec *FROM statenameWHERE code = state_code;IF NOT FOUND -- is state not in table?THEN INSERT INTO statename
VALUES (state_code, state_name);ELSE UPDATE statename
SET name = state_nameWHERE code = state_code;
END IF;RETURN ’t’;
74 / 88
![Page 75: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/75.jpg)
State Name Maintenance (Cont.)
ELSE -- is DELETESELECT INTO statename_rec *FROM statenameWHERE code = state_code;IF FOUNDTHEN DELETE FROM statename
WHERE code = state_code;RETURN ’t’;
ELSE RETURN ’f’;END IF;
END IF;END IF;
END;$$LANGUAGE ’plpgsql’;
SELECT change_statename(’AL’,’Alabama’);SELECT change_statename(’AL’,’Bermuda’);SELECT change_statename(’AL’,’’);SELECT change_statename(’AL’,’’); -- row was already deleted
75 / 88
![Page 76: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/76.jpg)
SELECT Inside FROM
SELECT *FROM (SELECT * FROM tab) AS tab;
SELECT *FROM ( SELECT 1,2,3,4,5 UNION
SELECT 6,7,8,9,10 UNIONSELECT 11,12,13,14,15) AS tab15;
col| col| col| col| col---+----+----+----+----1 | 2 | 3 | 4 | 56 | 7 | 8 | 9 | 1011 | 12 | 13 | 14 | 15
76 / 88
![Page 77: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/77.jpg)
Function Returning
Multiple Values
CREATE FUNCTION func5() RETURNSTABLE (x1 INT, x2 INT, x3 INT, x4 INT, x5 INT) AS’SELECT 1,2,3,4,5;’LANGUAGE SQL;
SELECT * FROM func5();x1 | x2 | x3 | x4 | x5----+----+----+----+----
1 | 2 | 3 | 4 | 5
77 / 88
![Page 78: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/78.jpg)
Function Returning
a Table Result
CREATE FUNCTION func15() RETURNSTABLE (x1 INT, x2 INT, x3 INT, x4 INT, x5 INT) AS’ SELECT 1,2,3,4,5 UNION
SELECT 6,7,8,9,10 UNIONSELECT 11,12,13,14,15;’
LANGUAGE SQL;
SELECT * FROM func15() ORDER BY x1;x1 | x2 | x3 | x4 | x5----+----+----+----+----
1 | 2 | 3 | 4 | 56 | 7 | 8 | 9 | 10
11 | 12 | 13 | 14 | 15
78 / 88
![Page 79: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/79.jpg)
Automatic Function Calls
Trigger
◮ BEFORE/AFTER ROW
◮ INSERT/UPDATE/DELETE
◮ OLD/NEW
79 / 88
![Page 80: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/80.jpg)
Trigger on Statename
CREATE FUNCTION trigger_insert_update_statename()RETURNS triggerAS $$BEGIN
IF new.code !˜ ’^[A-Za-z][A-Za-z]$’THEN RAISE EXCEPTION ’State code must be two alphabetic characters.’;END IF;IF new.name !˜ ’^[A-Za-z ]*$’THEN RAISE EXCEPTION ’State name must be only alphabetic characters.’;END IF;IF length(trim(new.name)) < 3THEN RAISE EXCEPTION ’State name must longer than two characters.’;END IF;new.code = upper(new.code); -- uppercase statename.codenew.name = initcap(new.name); -- capitalize statename.nameRETURN new;
END;$$LANGUAGE ’plpgsql’;
80 / 88
![Page 81: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/81.jpg)
Install Trigger
On Statename
CREATE TRIGGER trigger_statenameBEFORE INSERT OR UPDATEON statenameFOR EACH ROWEXECUTE PROCEDURE trigger_insert_update_statename();
INSERT INTO statename VALUES (’a’, ’alabama’);INSERT INTO statename VALUES (’al’, ’alabama2’);INSERT INTO statename VALUES (’al’, ’al’);INSERT INTO statename VALUES (’al’, ’alabama’);
81 / 88
![Page 82: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/82.jpg)
Function Languages
◮ SQL
◮ PL/pgSQL
◮ PL/Perl
◮ PL/Python
◮ PL/Java
◮ PL/TCL
◮ PL/sh
◮ C
82 / 88
![Page 83: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/83.jpg)
Function Examples
◮ /contrib/earthdistance
◮ /contrib/fuzzystringmatch
◮ /contrib/pgcrypto
https://www.flickr.com/photos/brapke/
83 / 88
![Page 84: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/84.jpg)
3. Customizing Database Features
Adding New
Data and Indexing
Featureshttps://www.flickr.com/photos/biggreymare/
84 / 88
![Page 85: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/85.jpg)
Creation
◮ CREATE FUNCTIONS in C
◮ CREATE TYPE
◮ CREATE OPERATOR
◮ CREATE OPERATOR CLASS (index type)
85 / 88
![Page 86: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/86.jpg)
Create New Data Type
With Operator and Index Support
◮ Write input/output functions
◮ Register input/output functions with CREATE FUNCTION
◮ Register type with CREATE TYPE
◮ Write comparison functions
◮ Register comparison functions with CREATE FUNCTION
◮ Register comparison functions with CREATE OPERATOR
◮ Register operator class for indexes with CREATE OPERATOR
CLASS
86 / 88
![Page 87: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/87.jpg)
Create New Data Type
Examples
◮ /contrib/chkpass
◮ /contrib/isn
◮ /contrib/cube
◮ /contrib/ltree
◮ /src/backend/utils/adt
https://www.flickr.com/photos/rueful/
87 / 88
![Page 88: Processing Data Inside PostgreSQL - Bruce Momjian](https://reader031.fdocuments.in/reader031/viewer/2022021007/6203978bda24ad121e4b3212/html5/thumbnails/88.jpg)
Conclusion
http://momjian.us/presentations
88 / 88