parser

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 26, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Overview

Package parser mirrors pg_query_go's parser subpackage: the Error type and the byte-level (protobuf-encoded) entry points.

Upstream these exist because cgo speaks bytes; here they are thin conveniences over the native Go implementations. The signatures are kept identical so code importing pg_query_go/v6/parser migrates with an import swap.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeparseFromProtobuf

func DeparseFromProtobuf(input []byte) (result string, err error)

DeparseFromProtobuf is pg_query_deparse_protobuf: decode the tree and render it back to SQL, statements joined with "; ".

func FingerprintToHexStr

func FingerprintToHexStr(input string) (result string, err error)

FingerprintToHexStr renders the fingerprint the way the C implementation prints XXH64_canonical_t: big-endian, zero-padded hex.

func FingerprintToUInt64

func FingerprintToUInt64(input string) (result uint64, err error)

FingerprintToUInt64 is pg_query_fingerprint: parse, then hash the raw tree (version-3 fingerprint).

func HashXXH3_64

func HashXXH3_64(input []byte, seed uint64) (result uint64)

HashXXH3_64 runs the XXH3 hash function (64-bit variant) on the given bytes, with the specified seed.

func IsUtilityStmt

func IsUtilityStmt(input string) (result []bool, err error)

IsUtilityStmt reports, per statement, whether it is a utility statement (pg_query_is_utility_stmt.c: everything except SELECT/INSERT/UPDATE/ DELETE/MERGE).

func Normalize

func Normalize(input string) (result string, err error)

Normalize is pg_query_normalize: constants become $n parameter references.

func NormalizeUtility

func NormalizeUtility(input string) (result string, err error)

NormalizeUtility is pg_query_normalize_utility: only utility statements are normalized.

func ParsePlPgSqlToJSON

func ParsePlPgSqlToJSON(input string) (result string, err error)

ParsePlPgSqlToJSON is pg_query_parse_plpgsql: compile every CREATE FUNCTION/PROCEDURE and DO statement with the PL/pgSQL parser and render the JSON array of function dumps.

func ParseToJSON

func ParseToJSON(input string) (result string, err error)

func ParseToProtobuf

func ParseToProtobuf(input string) ([]byte, error)

func ParseToTree added in v0.2.0

func ParseToTree(input string) (*ast.ParseResult, error)

ParseToTree parses the input and returns the tree the Go parser built, without the protobuf round trip Parse would otherwise make.

This is oliphant's one addition to pg_query_go's surface (see PLAN.md § 1). Upstream's Parse decodes bytes because the parse tree is built in C and crosses the cgo boundary as protobuf; here the tree is already a Go value, so marshalling it only to unmarshal it back costs about three quarters of Parse's time and doubles its allocations for no observable difference.

"No observable difference" holds with one exception, which is why the round trip survives as a fallback: proto3 string fields must be valid UTF-8, so a tree carrying a raw invalid byte fails to marshal and upstream reports that as an error from Parse. Such a byte can only have come from the input verbatim — the scanner rejects escape sequences that would synthesize one (E'\xff' raises "invalid byte sequence for encoding UTF8"), and identifier truncation is pg_mbcliplen-equivalent, so it never splits a character — which makes utf8.ValidString a sufficient guard.

One difference remains, and is not observable through pg_query_go's own API: the tree may share subtrees, where the round trip silently deep-copied them (a multi-column UPDATE ... SET (a, b, c) = (...) points every ResTarget at one MultiAssignRef source, exactly as the C tree does). Callers that only read the tree cannot tell; callers that mutate one now can. See TestParseToTreeSharesMultiAssignSource.

func ScanToProtobuf

func ScanToProtobuf(input string) (result []byte, err error)

ScanToProtobuf lexes the input with the core scanner exactly as pg_query_scan.c does: raw core_yylex tokens (comments included, no base_yylex filtering), start/end byte offsets, and the keyword kind.

func SplitWithParser

func SplitWithParser(input string, trimSpace bool) (result []string, err error)

SplitWithParser splits on the RawStmt boundaries of a real parse (pg_query_split.c: pg_query_split_with_parser); a zero stmt_len runs to the end of the input.

func SplitWithScanner

func SplitWithScanner(input string, trimSpace bool) (result []string, err error)

SplitWithScanner is pg_query_split.c's pg_query_split_with_scanner: a lexer-level statement splitter. A statement ends at a top-level ";" (or EOF) and is only emitted if it contained at least one keyword.

func SummaryToProtobuf

func SummaryToProtobuf(input string, truncateLimit int) ([]byte, error)

SummaryToProtobuf is pg_query_summary: parse, walk for tables/aliases/ CTEs/functions/filter columns/statement types, and — unless truncateLimit is -1 — produce the smart-truncated query text.

Types

type Error

type Error struct {
	Message   string // exception message
	Funcname  string // source function of exception (e.g. SearchSysCache)
	Filename  string // source of exception (e.g. parse.l)
	Lineno    int    // source of exception (e.g. 104)
	Cursorpos int    // char in query at which exception occurred
	Context   string // additional context (optional, can be NULL)
}

Error mirrors pg_query_go's parser.Error field-for-field.

func (*Error) Error

func (e *Error) Error() string

type ParseFileResult added in v0.2.0

type ParseFileResult struct {
	*ast.ParseResult

	// Comments holds the input's SQL_COMMENT and C_COMMENT tokens in source
	// order, positioned by the same byte offsets the tree's location fields
	// carry. Token.Start and Token.End bound each comment as written, marker
	// included and terminating newline excluded; the text is input[Start:End].
	Comments []*ast.ScanToken
}

ParseFileResult is a parse tree together with the comments the grammar never sees, both from one pass over the input.

func ParseFile added in v0.2.0

func ParseFile(input string) (*ParseFileResult, error)

ParseFile parses the input and returns its tree along with its comments.

This is a second oliphant addition to pg_query_go's surface (see PLAN.md § 1), for consumers that need the comments back — a formatter reprinting a query file has to put them where they were written. They are already scanned: libpg_query's patch 04 has the scanner emit them as tokens and base_yylex drop them on the way to the grammar, which is exactly what Scan exposes. Scan and Parse together would answer this, at the cost of lexing the input twice and marshalling the whole token stream to protobuf to recover a handful of comments; ParseFile keeps them from the pass the parse already makes.

A parse error returns no comments: the scan stops where the grammar does, so what had been collected covers only part of the input.

ParseFile accepts and rejects exactly what Parse does, the proto3 UTF-8 rejection included (see ParseToTree). That answer is not a property of the input: an invalid byte inside a comment never reaches a string field, so the tree marshals and Parse returns it — and a comment is the one place ParseFile must not reject one.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL