Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Postgres Rules
Heresy
CREATE RULE
Esoteric
Y u no use trigger?
View
ViewCREATE TABLE users (    id     integer,    name    varchar(40),    PRIMARY KEY(did));CREATE VIEW myview AS SELECT * FR...
ViewCREATE TABLE users (    id     integer,    name    varchar(40),    PRIMARY KEY(did));CREATE VIEW myview AS SELECT * FR...
Speed
Warning
Warning
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
CREATE TABLE counts (    id    INT4 PRIMARY KEY,    count INT4 NOT NULL);
CREATE TABLE counts (    id    INT4 PRIMARY KEY,    count INT4 NOT NULL);CREATE RULE upsert_counts AS ON INSERT TO counts ...
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesq...
CREATE TABLE test (    id!      ! INT4 PRIMARY KEY,    val! INT4 NOT NULL);
CREATE TABLE test (    id!      ! INT4 PRIMARY KEY,    val! INT4 NOT NULL);CREATE TABLE test_log (   id       !! ! INT4 PR...
CREATE TABLE test (    id!      ! INT4 PRIMARY KEY,    val! INT4 NOT NULL);CREATE TABLE test_log (   id       !! ! INT4 PR...
CREATE TABLE test (    id!      ! INT4 PRIMARY KEY,    val! INT4 NOT NULL);CREATE TABLE test_log (   id       !! ! INT4 PR...
CREATE TABLE test (    id!      ! INT4 PRIMARY KEY,    val! INT4 NOT NULL);CREATE TABLE test_log (   id       !! ! INT4 PR...
CREATE TABLE test (    id!      ! INT4 PRIMARY KEY,    val! INT4 NOT NULL);CREATE TABLE test_log (   id       !! ! INT4 PR...
Use Case
reconciliations_datafinancial_operations                       idid                       bank_numamount                  ...
reconciliations_datafinancial_operations                       idid                       bank_numamount                  ...
CREATE OR REPLACE VIEW reconciliations AS  SELECT  ! rec.*,  ! fin1.id AS start_id,  ! fin1.upload_date AS start_date,  ! ...
reconciliations_datafinancial_operations                       idid                       bank_numamount                  ...
reconciliations_data financial_operations                                                   id id                         ...
reconciliations_datafinancial_operations                       idid                       bank_numamount                  ...
reconciliations_data         financial_operations                                                           id         id ...
FIN      guyren@relevantlogic.com
Postgres rules
Postgres rules
Postgres rules
Postgres rules
Upcoming SlideShare
Loading in …5
×

Postgres rules

2,940 views

Published on

A brief introduction to Postgres Rules

Published in: Technology, Business
  • Be the first to comment

Postgres rules

  1. 1. Postgres Rules
  2. 2. Heresy
  3. 3. CREATE RULE
  4. 4. Esoteric
  5. 5. Y u no use trigger?
  6. 6. View
  7. 7. ViewCREATE TABLE users ( id integer, name varchar(40), PRIMARY KEY(did));CREATE VIEW myview AS SELECT * FROM users;
  8. 8. ViewCREATE TABLE users ( id integer, name varchar(40), PRIMARY KEY(did));CREATE VIEW myview AS SELECT * FROM users; ==CREATE RULE "_RETURN" AS ON SELECT TO myview DO INSTEAD SELECT * FROM mytab;
  9. 9. Speed
  10. 10. Warning
  11. 11. Warning
  12. 12. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification added
  13. 13. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification added
  14. 14. CREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL);
  15. 15. CREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL);CREATE RULE upsert_counts AS ON INSERT TO counts WHERE exists ( SELECT * FROM counts WHERE id = NEW.id ) DO INSTEAD UPDATE counts SET count = count + 1 WHERE id = NEW.id;
  16. 16. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification added CREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL ); CREATE RULE upsert_counts AS ON INSERT TO counts WHERE exists ( SELECT * FROM counts WHERE id = NEW.id ) DO INSTEAD UPDATE counts SET count = count + 1 WHERE id = NEW.id;
  17. 17. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification addedCREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL);CREATE RULE upsert_counts AS ON INSERT TO counts WHERE exists ( SELECT * FROM counts WHERE id = NEW.id ) DO INSTEAD UPDATE counts SET count = count + 1 WHERE id = NEW.id;
  18. 18. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification addedCREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL);CREATE RULE upsert_counts AS ON INSERT TO counts WHERE exists ( SELECT * FROM counts WHERE id = NEW.id ) DO INSTEAD UPDATE counts SET count = count + 1 WHERE id = NEW.id;INSERT INTO counts (id, count) VALUES (1, 1);
  19. 19. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification addedCREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL);CREATE RULE upsert_counts AS ON INSERT TO counts WHERE exists ( SELECT * FROM counts WHERE id = NEW.id ) DO INSTEAD UPDATE counts SET count = count + 1 WHERE id = NEW.id;INSERT INTO counts (id, count) VALUES (1, 1); # SELECT * FROM counts; id | count ----+---------- 1 | 2 (1 row)
  20. 20. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification addedCREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL);CREATE RULE upsert_counts AS ON INSERT TO counts WHERE exists ( SELECT * FROM counts WHERE id = NEW.id ) DO INSTEAD UPDATE counts SET count = count + 1 WHERE id = NEW.id;INSERT INTO counts (id, count) VALUES (1, 1); # SELECT * FROM counts; id | count ----+---------- 1 | 2 (1 row)
  21. 21. Qualification given and INSTEADthe query tree from the rule action with the rule qualification and the original query treesqualification; and the original query tree with the negated rule qualification addedCREATE TABLE counts ( id INT4 PRIMARY KEY, count INT4 NOT NULL);CREATE RULE upsert_counts AS ON INSERT TO counts WHERE exists ( SELECT * FROM counts WHERE id = NEW.id ) DO INSTEAD UPDATE counts SET count = count + 1 WHERE id = NEW.id;INSERT INTO counts (id, count) VALUES (1, 1); # SELECT * FROM counts; id | countBECOMES: ----+----------INSERT INTO test (id, some_val) 1 | 2 SELECT 1, 1 WHERE NOT ( (1 row) EXISTS ( SELECT * FROM test WHERE id = 1) );UPDATE testSET some_val = some_val + 1WHERE id = 1 AND ( EXISTS ( SELECT * FROM test WHERE id = 1 ) );
  22. 22. CREATE TABLE test ( id! ! INT4 PRIMARY KEY, val! INT4 NOT NULL);
  23. 23. CREATE TABLE test ( id! ! INT4 PRIMARY KEY, val! INT4 NOT NULL);CREATE TABLE test_log ( id !! ! INT4 PRIMARY KEY, creation_date! TIMESTAMP NOT NULL, val ! ! ! ! INT4 NOT NULL,! CONSTRAINT test_log_pk PRIMARY KEY(id, creation_date));
  24. 24. CREATE TABLE test ( id! ! INT4 PRIMARY KEY, val! INT4 NOT NULL);CREATE TABLE test_log ( id !! ! INT4 PRIMARY KEY, creation_date! TIMESTAMP NOT NULL, val ! ! ! ! INT4 NOT NULL,! CONSTRAINT test_log_pk PRIMARY KEY(id, creation_date));CREATE RULE test_logging AS ON INSERT TO test! DO ALSO INSERT INTO test_log(id, creation_date, val) VALUES(NEW.id, NOW(), NEW.val);
  25. 25. CREATE TABLE test ( id! ! INT4 PRIMARY KEY, val! INT4 NOT NULL);CREATE TABLE test_log ( id !! ! INT4 PRIMARY KEY, creation_date! TIMESTAMP NOT NULL, val ! ! ! ! INT4 NOT NULL,! CONSTRAINT test_log_pk PRIMARY KEY(id, creation_date));CREATE RULE test_logging AS ON INSERT TO test! DO ALSO INSERT INTO test_log(id, creation_date, val) VALUES(NEW.id, NOW(), NEW.val);INSERT INTO test(id, count) VALUES (1, RANDOM());
  26. 26. CREATE TABLE test ( id! ! INT4 PRIMARY KEY, val! INT4 NOT NULL);CREATE TABLE test_log ( id !! ! INT4 PRIMARY KEY, creation_date! TIMESTAMP NOT NULL, val ! ! ! ! INT4 NOT NULL,! CONSTRAINT test_log_pk PRIMARY KEY(id, creation_date));CREATE RULE test_logging AS ON INSERT TO test! DO ALSO INSERT INTO test_log(id, creation_date, val) VALUES(NEW.id, NOW(), NEW.val);INSERT INTO test(id, count) VALUES (1, RANDOM());# SELECT * FROM test; id | val----+------ 1 | 46228(1 row)
  27. 27. CREATE TABLE test ( id! ! INT4 PRIMARY KEY, val! INT4 NOT NULL);CREATE TABLE test_log ( id !! ! INT4 PRIMARY KEY, creation_date! TIMESTAMP NOT NULL, val ! ! ! ! INT4 NOT NULL,! CONSTRAINT test_log_pk PRIMARY KEY(id, creation_date));CREATE RULE test_logging AS ON INSERT TO test! DO ALSO INSERT INTO test_log(id, creation_date, val) VALUES(NEW.id, NOW(), NEW.val);INSERT INTO test(id, count) VALUES (1, RANDOM());# SELECT * FROM test; # SELECT * FROM test_log; id | val id | creation_date! ! | val----+------ ----+--------------------------+----- 1 | 46228 1 | 2012-05-03 07:02:16.43841 15375(1 row) (1 row)
  28. 28. Use Case
  29. 29. reconciliations_datafinancial_operations idid bank_numamount start_countcard_number end_countcashier_id deposit_slip_numberreconciliation_id cashier_id
  30. 30. reconciliations_datafinancial_operations idid bank_numamount start_countcard_number end_countcashier_id deposit_slip_numberreconciliation_id cashier_id
  31. 31. CREATE OR REPLACE VIEW reconciliations AS SELECT ! rec.*, ! fin1.id AS start_id, ! fin1.upload_date AS start_date, ! fin2.id AS end_id, ! fin2.upload_date AS end_date FROM ! reconciliations_data rec LEFT OUTER JOIN ! (SELECT DISTINCT first_value(id) OVER (partition BY reconciliation_id ORDER BY upload_date ASC) AS id, first_value(upload_date) OVER (partition BY reconciliation_id ORDER BY upload_date ASC) AS upload_date, reconciliation_id FROM financial_operations) AS fin1 ON (fin1.reconciliation_id = rec.id) LEFT OUTER JOIN ! (SELECT DISTINCT first_value(id) OVER (partition BY reconciliation_id ORDER BY upload_date DESC) AS id, first_value(upload_date) OVER (partition BY reconciliation_id ORDER BY upload_date DESC) AS upload_date, reconciliation_id FROM financial_operations) AS fin2 ON (fin2.reconciliation_id = rec.id)
  32. 32. reconciliations_datafinancial_operations idid bank_numamount start_countcard_number end_countcashier_id deposit_slip_numberreconciliation_id cashier_id
  33. 33. reconciliations_data financial_operations id id bank_num amount start_count card_number end_count cashier_id deposit_slip_number reconciliation_id cashier_idCREATE OR REPLACE RULE fin_ops_from_recons AS ON INSERT TO reconciliations DO INSTEAD ( INSERT INTO reconciliations_data (cashier_id, lot_id, lane_id, start_count, end_count, cash_deposited, bank_amount,bank_returned, deposit_slip_number, created_at, updated_at) VALUES (new.cashier_id, new.lot_id, new.lane_id, new.start_count, new.end_count, new.cash_deposited, new.bank_amount,new.bank_returned, new.deposit_slip_number, new.created_at, new.updated_at) RETURNING! ! ! currval(reconciliations_id_seq)::integer,! ! ! cashier_id,! ! ! lot_id,! ! ! lane_id,! ! ! start_count,! ! ! end_count,! ! ! cash_deposited,! ! ! bank_amount,! ! ! bank_returned,! ! ! deposit_slip_number,! ! ! created_at,! ! ! updated_at,! ! ! null::varchar,! ! ! null::varchar,! ! ! null::timestamp,! ! ! null::varchar,! ! ! null::timestamp; ;
  34. 34. reconciliations_datafinancial_operations idid bank_numamount start_countcard_number end_countcashier_id deposit_slip_numberreconciliation_id cashier_id
  35. 35. reconciliations_data financial_operations id id bank_num amount start_count card_number end_count cashier_id deposit_slip_number reconciliation_id cashier_id UPDATE financial_operations SET reconciliation_id = lastval() WHERE financial_operations.remote_creation_date >= (( SELECT financial_operations.remote_creation_date FROM financial_operations WHERE financial_operations.id::text = new.start_id::text)) AND financial_operations.remote_creation_date <=(( SELECT financial_operations.remote_creation_date FROM financial_operations WHERE financial_operations.id::text = new.end_id::text)) AND financial_operations.order_transaction_id IS NOT NULLAND CASE WHEN new.lot_id IS NULL THEN new.cashier_id::text = (SELECT order_transactions.user_id FROM order_transactions WHERE order_transactions.id::text = financial_operations.order_transaction_id::text)::text ELSE ((new.cashier_id::text, new.lot_id) = ( SELECT order_transactions.user_id, order_transactions.lot_id FROM order_transactions WHERE order_transactions.id::text = financial_operations.order_transaction_id::text)) END; );
  36. 36. FIN guyren@relevantlogic.com

×