Introduction To Hacking Postgresql: With Lots of Code Review!
Introduction To Hacking Postgresql: With Lots of Code Review!
Development Environment PostgreSQL Architecture Conventions, and all that Submitting a pat
Gavin Sherry
gavin@alcove.com.au
Alcove Systems Engineering
Outline
2 Development Environment
3 PostgreSQL Architecture
5 Submitting a patch
Outline
2 Development Environment
3 PostgreSQL Architecture
5 Submitting a patch
Development Environment
The basics
Most of the Postgres developers
use Unix
You’ll need to know C
C is easy
Code reading is hard, but worth
getting good at
Development Tools
The Basics
gcc, Bison, Flex, CVS, autotools,
gdb
Configure flags:
--enable-depend
--enable-debug
--enable-cassert
CFLAGS=-O0
Text Editor
Coding
Use a proper text editor
Follow the style of the surrounding
code (Basically, Allman BSD)
If you don’t follow the style, it will
just slow down the review
process
Outline
2 Development Environment
3 PostgreSQL Architecture
5 Submitting a patch
PostgreSQL Architecture
PostgreSQL Architecture
PostgreSQL Architecture
PostgreSQL Architecture
PostgreSQL Architecture
Architecture Diagram
Postgres backend
PostgresMain()
PARSE:
Parse query string
pg_parse_query()
ANALYZE:
Semantic analysis of query, transform to Query node
parse_analyze()
PLAN:
Produce a query plan
pg_plan_queries()
EXECUTOR:
Execute DML
PortalRun() -> ExecutePlan()
The Parser
Semantic Analysis
Rewriter, Planner
Outline
2 Development Environment
3 PostgreSQL Architecture
5 Submitting a patch
Postgres uses a very simple object system with support for single
inheritance. The root of the class hierarchy is Node:
typedef struct typedef struct typedef struct
{ { {
NodeTag type; NodeTag type; Parent parent;
} Node; int a_field; int b_field;
} Parent; } Child;
Nodes, Cont.
Nodes, Cont.
Nodes, Cont.
Nodes, Cont.
Nodes, Cont.
Nodes, Cont.
Nodes: Hints
Memory Management
Error Handling
Outline
2 Development Environment
3 PostgreSQL Architecture
5 Submitting a patch
Sending A Proposal
Implementation
Thoroughness
Step 5: Testing
Make sure the existing regression tests don’t fail
No compiler warnings
Add new regression tests for the new feature
Thoroughness
Step 5: Testing
Make sure the existing regression tests don’t fail
No compiler warnings
Add new regression tests for the new feature
Outline
2 Development Environment
3 PostgreSQL Architecture
5 Submitting a patch
WHEN Clause
Syntax
Behavioral questions:
Should we allow WHEN clause for statement-level triggers? (SQL
spec doesn’t specify)
What subset of SQL should we allow? Aggregate functions,
subqueries, . . . ?
No backward-compat concerns
Obviously needs to be in the backend
Useful for at least SQL-spec compliance
Implementation Outline
1 Add support for the new syntax to the parser
2 Update the CREATE TRIGGER parsenode
3 Add support for WHEN clause to analysis phase
4 Add new field to pg trigger system catalog, containing the
WHEN clause
5 Modify implementation of CREATE TRIGGER to add the WHEN
clause to the new pg trigger row
6 Add support for the WHEN clause when firing triggers in the
executor (most of the difficulty is here)
7 Update pg dump/psql to support the WHEN clause
Implementation Outline
1 Add support for the new syntax to the parser
2 Update the CREATE TRIGGER parsenode
3 Add support for WHEN clause to analysis phase
4 Add new field to pg trigger system catalog, containing the
WHEN clause
5 Modify implementation of CREATE TRIGGER to add the WHEN
clause to the new pg trigger row
6 Add support for the WHEN clause when firing triggers in the
executor (most of the difficulty is here)
7 Update pg dump/psql to support the WHEN clause
Implementation Outline
1 Add support for the new syntax to the parser
2 Update the CREATE TRIGGER parsenode
3 Add support for WHEN clause to analysis phase
4 Add new field to pg trigger system catalog, containing the
WHEN clause
5 Modify implementation of CREATE TRIGGER to add the WHEN
clause to the new pg trigger row
6 Add support for the WHEN clause when firing triggers in the
executor (most of the difficulty is here)
7 Update pg dump/psql to support the WHEN clause
Implementation Outline
1 Add support for the new syntax to the parser
2 Update the CREATE TRIGGER parsenode
3 Add support for WHEN clause to analysis phase
4 Add new field to pg trigger system catalog, containing the
WHEN clause
5 Modify implementation of CREATE TRIGGER to add the WHEN
clause to the new pg trigger row
6 Add support for the WHEN clause when firing triggers in the
executor (most of the difficulty is here)
7 Update pg dump/psql to support the WHEN clause
Implementation Outline
1 Add support for the new syntax to the parser
2 Update the CREATE TRIGGER parsenode
3 Add support for WHEN clause to analysis phase
4 Add new field to pg trigger system catalog, containing the
WHEN clause
5 Modify implementation of CREATE TRIGGER to add the WHEN
clause to the new pg trigger row
6 Add support for the WHEN clause when firing triggers in the
executor (most of the difficulty is here)
7 Update pg dump/psql to support the WHEN clause
Implementation Outline
1 Add support for the new syntax to the parser
2 Update the CREATE TRIGGER parsenode
3 Add support for WHEN clause to analysis phase
4 Add new field to pg trigger system catalog, containing the
WHEN clause
5 Modify implementation of CREATE TRIGGER to add the WHEN
clause to the new pg trigger row
6 Add support for the WHEN clause when firing triggers in the
executor (most of the difficulty is here)
7 Update pg dump/psql to support the WHEN clause
Implementation Outline
1 Add support for the new syntax to the parser
2 Update the CREATE TRIGGER parsenode
3 Add support for WHEN clause to analysis phase
4 Add new field to pg trigger system catalog, containing the
WHEN clause
5 Modify implementation of CREATE TRIGGER to add the WHEN
clause to the new pg trigger row
6 Add support for the WHEN clause when firing triggers in the
executor (most of the difficulty is here)
7 Update pg dump/psql to support the WHEN clause
Parser Changes
Grammar code
1 CreateTrigStmt :
2 CREATE TRIGGER name T r i g g e r A c t i o n T i m e T r i g g e r E v e n t s ON
3 q u a l i f i e d n a m e TriggerForSpec TriggerWhen EXECUTE PROCEDURE
4 func name ’ ( ’ TriggerFuncArgs ’ ) ’
5 {
6 C r e a t e T r i g S t m t ∗ n = makeNode ( C r e a t e T r i g S t m t ) ;
7 /∗ ... ∗/
8 n−>when = $10 ;
9 $$ = ( Node ∗ ) n ;
10 }
11
12 TriggerWhen :
13 WHEN ’ ( ’ a e x p r ’) ’ { $$ = $3 ; }
14 | / ∗EMPTY∗ / { $$ = NULL ; }
Parsenode Changes
Expressions In Postgres
Variable Expressions
Analysis Phase
System Catalogs
TriggerDesc Updates
Executor Changes
Evaluating Variables
Note that the varno is ignored, except for the special INNER and
OUTER varnos
The code assumes that the caller will insert the current tuple into
the ExprContext’s “scan tuple” slot before calling ExecEvalExpr
This won’t work for us: the WHEN expression could reference two
different tuples (OLD and NEW)
How can we solve this?
Solution
psql Support
pg dump Support
Regression Tests
Documentation
TODO Items