SQL/PGQ Cheat Sheet for PostgreSQL 19 [2026 Guide]
Bottom Line
As of April 30, 2026, SQL/PGQ is in PostgreSQL 19devel, giving Postgres native property graph DDL and GRAPH_TABLE queries in core SQL. If you already store graph-shaped data in relational tables, this is the fastest path to graph querying without adding a separate graph engine.
Key Takeaways
- ›SQL/PGQ landed in PostgreSQL 19devel on March 16, 2026.
- ›Core surface area: GRAPH_TABLE, CREATE/ALTER/DROP PROPERTY GRAPH, and psql \dG.
- ›PostgreSQL 18 is still current GA; this cheat sheet targets the PostgreSQL 19 development line.
- ›Pattern syntax supports labels, per-element WHERE clauses, graph-level WHERE, and quantified paths.
- ›No extension install is required; property graphs are a core PostgreSQL feature in 19devel.
As of April 30, 2026, SQL/PGQ is part of PostgreSQL 19devel, while PostgreSQL 18 remains the current generally available release. That matters: this cheat sheet is for engineers testing the upcoming graph-query surface in core Postgres, not an extension. The payoff is straightforward: you can define a property graph over existing tables and query paths directly with GRAPH_TABLE, using SQL syntax your team can version, review, and ship.
SQL/PGQ At A Glance
Bottom Line
If your graph already lives in relational tables, PostgreSQL 19devel lets you model and query it in core SQL with GRAPH_TABLE and PROPERTY GRAPH DDL. The main trap is versioning: this is 19devel functionality as of April 30, 2026, not something available in PostgreSQL 18.
What Landed
- GRAPH_TABLE for graph pattern matching in the
FROMclause. - CREATE PROPERTY GRAPH, ALTER PROPERTY GRAPH, and DROP PROPERTY GRAPH.
- psql \dG support for listing property graphs.
- New graph-related catalog and information schema coverage in core Postgres.
- Access checks that behave similarly to a security-invoker view over the underlying tables.
Smallest Useful Shape
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (u IS users)-[f IS follows]->(v IS users)
COLUMNS (
u.name AS from_user,
v.name AS to_user
)
);
SELECT version(); before debugging the parser.Setup And Introspection
What You Need
- PostgreSQL 19devel or a later build that includes the SQL/PGQ merge from March 16, 2026.
- No extension install. This feature is in core.
- psql from the same development line if you want \dG and updated describe output.
Sanity Checks
SELECT version();
\dG
\d social_graph
\d+ social_graph
Operational Notes
- Use regular SQL migrations for graph DDL; it is first-class schema, not sidecar metadata.
- Keep sample data clean. If you are publishing demos with user or customer edges, scrub them first with the Data Masking Tool.
- For snippet-heavy docs and internal runbooks, the Code Formatter helps keep larger SQL examples readable.
Query Patterns Cheat Sheet
Live Filter
Keyboard Shortcuts
| Key | Action | Notes |
|---|---|---|
/ | Focus filter | Jump straight to the live search box. |
Esc | Clear filter | Also blurs the input if it is focused. |
j | Next section | Moves to the next <h2>. |
k | Previous section | Moves to the previous <h2>. |
t | Top of page | Smooth-scrolls back to the intro. |
Commands Grouped By Purpose
Start with a single vertex scan
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (u IS users)
COLUMNS (
u.id AS user_id,
u.name AS user_name
)
);
Filter inside a vertex pattern
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (u IS users WHERE u.active)
COLUMNS (
u.id AS user_id,
u.name AS user_name
)
);
Follow a directed edge
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (u IS users)-[f IS follows]->(v IS users)
COLUMNS (
u.name AS from_user,
v.name AS to_user,
f.created_at AS followed_at
)
);
Add an edge predicate
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (u IS users)-[f IS follows WHERE f.weight > 10]->(v IS users)
COLUMNS (
u.name AS from_user,
v.name AS to_user,
f.weight AS follow_weight
)
);
Use one graph-level WHERE clause
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (a IS users)-[]->(x IS users)<-[]-(b IS users)
WHERE a.name <> b.name
COLUMNS (
a.name AS left_user,
x.name AS common_user,
b.name AS right_user
)
);
Match any-direction edges
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (u IS users)-[f IS follows]-(v IS users)
COLUMNS (
u.name AS user_a,
v.name AS user_b
)
);
Repeat a path segment with a quantifier
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH ((u IS users)-[f IS follows]->(v IS users)){1,3}
COLUMNS (
u.name AS start_user,
v.name AS end_user
)
);
Combine multiple path patterns in one MATCH
SELECT *
FROM GRAPH_TABLE (
social_graph
MATCH (a IS users)-[]->(x IS users), (b IS users)-[]->(x IS users)
WHERE a.name <> b.name
COLUMNS (
a.name AS left_user,
b.name AS right_user,
x.name AS shared_target
)
);
Property Graph DDL
Create a Graph Over Existing Tables
CREATE PROPERTY GRAPH social_graph
VERTEX TABLES (
users KEY (id)
LABEL users PROPERTIES (id, name, active),
teams KEY (id)
LABEL teams PROPERTIES (id, name)
)
EDGE TABLES (
follows
SOURCE KEY (follower_id) REFERENCES users (id)
DESTINATION KEY (followee_id) REFERENCES users (id)
LABEL follows PROPERTIES (follower_id, followee_id, created_at, weight),
memberships
SOURCE KEY (user_id) REFERENCES users (id)
DESTINATION KEY (team_id) REFERENCES teams (id)
LABEL memberships PROPERTIES (user_id, team_id, role)
);
Use Aliases and Synonyms
- NODE is accepted as a synonym for VERTEX.
- RELATIONSHIP is accepted as a synonym for EDGE.
- You can alias element tables with
ASin graph DDL.
CREATE PROPERTY GRAPH org_graph
NODE TABLES (
employees AS people KEY (id)
LABEL employees PROPERTIES (id, name, manager_id)
)
RELATIONSHIP TABLES (
reporting_lines AS reports_to
SOURCE KEY (employee_id) REFERENCES people (id)
DESTINATION KEY (manager_id) REFERENCES people (id)
LABEL reports_to PROPERTIES (employee_id, manager_id)
);
Common ALTER Forms
ALTER PROPERTY GRAPH social_graph
ADD VERTEX TABLES (
projects KEY (id)
LABEL projects PROPERTIES (id, name)
);
ALTER PROPERTY GRAPH social_graph
ADD EDGE TABLES (
assignments
SOURCE KEY (user_id) REFERENCES users (id)
DESTINATION KEY (project_id) REFERENCES projects (id)
LABEL assignments PROPERTIES (user_id, project_id, hours_per_week)
);
ALTER PROPERTY GRAPH social_graph
ALTER VERTEX TABLE users ADD LABEL staff;
ALTER PROPERTY GRAPH social_graph
ALTER EDGE TABLE follows ALTER LABEL follows DROP PROPERTIES (weight);
Temporary Graphs and Drop
CREATE TEMP PROPERTY GRAPH session_graph
VERTEX TABLES (
scratch_nodes KEY (id)
);
DROP PROPERTY GRAPH session_graph;
- TEMP graphs are supported.
- UNLOGGED property graphs are rejected because property graphs do not have their own storage.
- If you omit explicit property lists, the default behavior is effectively all columns for that element definition.
Configuration And Advanced Usage
Configuration Reality Check
- There is no separate extension, server parameter, or sidecar service to enable basic SQL/PGQ usage in 19devel.
- Your real configuration surface is schema design: keys, edge direction, labels, and which columns become graph properties.
- Property graphs sit over ordinary tables, so your existing indexing and table design still drive performance.
Advanced Usage Patterns
- Keep COLUMNS narrow. Returning only the properties you need is the fastest way to cut network and application overhead.
- Use explicit KEY clauses in graph DDL when the natural identity is not obvious from table structure.
- Split labels intentionally. Shared labels across multiple tables are flexible, but they only stay sane when property names stay consistent.
- Prefer graph-level WHERE only for cross-variable predicates like
a.name <> b.name. - Model demo graphs from relational truth first. SQL/PGQ works best when the base tables already encode clean source and destination relationships.
When This Is a Good Fit
- You already run PostgreSQL and want graph traversal syntax without introducing a second database engine.
- Your graph is derived from well-structured application tables.
- You want graph queries in migrations, code review, CI, and ordinary SQL tooling.
When It Is Not
- You are pinned to PostgreSQL 18 or earlier.
- You need mature production guidance for a feature that is still in the development branch.
- Your team has not yet settled stable relational keys for nodes and edges.
Frequently Asked Questions
Does SQL/PGQ ship in PostgreSQL 18? +
GRAPH_TABLE or CREATE PROPERTY GRAPH, check your server version first.Do I need an extension to use GRAPH_TABLE in PostgreSQL 19? +
What is the fastest way to inspect property graphs in psql? +
\dG to list property graphs, then use regular describe commands like \d or \d+ on the graph object. Those updated psql describe paths are part of the same development-line feature set.Can SQL/PGQ query existing relational tables, or do I need to move data? +
Get Engineering Deep-Dives in Your Inbox
Weekly breakdowns of architecture, security, and developer tooling — no fluff.