Comment Extraction Guide
February 20, 2026 ยท View on GitHub
This guide covers:
COMMENT ON ...statement extraction (always enabled)- inline
--field comment extraction inCREATE TABLE(option-controlled)
COMMENT ON (Always Enabled)
COMMENT ON statements are parsed as DDL actions with:
Type = "COMMENT"ObjectType(for exampleTABLE,COLUMN,INDEX)ObjectNameSchema(when available)Target(generic path form, for examplepublic.users.email)Comment
Example: table comment
COMMENT ON TABLE public.users IS 'Stores user account information';
Example: column comment
COMMENT ON COLUMN public.users.email IS 'User email address, must be unique';
For column comments:
ObjectNameis the table name (users)Columnscontains the target column (["email"])
Identifier Notes (Target, dots, quoting)
Targetpreserves the SQL path text (for examplepublic.users.email).- Structured fields (
Schema,ObjectName,Columns) are extracted with quote-aware splitting. - Identifiers that contain
.must be quoted in PostgreSQL SQL text (for examplepublic."my.table"."my.col"). - Unquoted dots are always treated as separators. For example,
public.my.table.my.colis interpreted as a qualified path, not as identifier names containing dots.
Current behavior examples:
COMMENT ON COLUMN public."my.table"."my.col" IS 'x';maps toSchema=public,ObjectName="my.table",Columns=["my.col"],Target=public."my.table"."my.col".COMMENT ON COLUMN public.my.table.my.col IS 'x';maps toSchema=public.my.table,ObjectName=my,Columns=["col"],Target=public.my.table.my.col.
Example: index comment
COMMENT ON INDEX public.idx_bookings_dates IS 'Composite index for efficient date range queries on bookings';
Supported Object Types
The following object types are fully classified (the ObjectType field is set to the exact type name):
TABLECOLUMNINDEXSCHEMATYPEDOMAINFOREIGN TABLEVIEWMATERIALIZED VIEWSEQUENCE
The following object types produce ObjectType: "UNKNOWN":
FUNCTIONAGGREGATEOPERATORCONSTRAINTPROCEDUREROUTINETRANSFORMOPERATOR CLASSOPERATOR FAMILYLARGE OBJECTCAST
UNKNOWN types still parse the comment text correctly -- only the object type classification is degraded. The Comment field will contain the decoded comment string as expected. For example:
COMMENT ON FUNCTION public.my_func(integer) IS 'Does something';
produces ObjectType: "UNKNOWN" and Comment: "Does something".
CREATE TABLE Inline -- Field Comments (Option-Controlled)
Inline field comments are disabled by default and enabled with:
ParseSQLWithOptionsParseSQLAllWithOptionsParseSQLStrictWithOptions
using:
postgresparser.ParseOptions{
IncludeCreateTableFieldComments: true,
}
Example SQL
CREATE TABLE public.users (
-- [Attribute("Just an example")]
-- required, min 5, max 55
name text,
-- single-column FK, inline
org_id integer REFERENCES public.organizations(id)
);
Behavior
- consecutive
--lines immediately above a column are captured - comments are trimmed and stored as
[]string - comments above table constraints are not attached to columns
Performance Note
IncludeCreateTableFieldComments is opt-in because it performs extra hidden-token processing for CREATE TABLE column definitions.
In local benchmarks (benchmark/bench_test.go, -benchmem):
- non-DDL queries (
SELECT) showed no meaningful allocation overhead CREATE TABLEparsing showed measurable overhead (roughly ~10-13% slower, with higher allocations)
Use this option only when you need inline -- field comment metadata.
Parser API Example
opts := postgresparser.ParseOptions{
IncludeCreateTableFieldComments: true,
}
res, err := postgresparser.ParseSQLWithOptions(sql, opts)
if err != nil {
log.Fatal(err)
}
for _, action := range res.DDLActions {
if action.Type == postgresparser.DDLComment {
fmt.Println(action.ObjectType, action.Target, action.Comment)
}
}
Analysis API Example
The analysis layer reuses the same options type:
opts := postgresparser.ParseOptions{
IncludeCreateTableFieldComments: true,
}
res, err := analysis.AnalyzeSQLWithOptions(sql, opts)
if err != nil {
log.Fatal(err)
}