Back to Postgres Language Server

ARCHITECTURE

ARCHITECTURE.md

0.25.75.5 KB
Original Source

Architecture

This document describes the high-level architecture of postgres_lsp. If you want to familiarize yourself with the code base, you are just in the right place!

Since the project still evolves rapidly, this document may not be up-to-date. If you find any inconsistency, please let us know by creating an issue.

Bird's Eye View

On the highest level, the postgres language server is a thing which accepts input source code, cuts it into individual sql statements and parses and analyses each. In addition, it connects to a postgres database and stores an im-memory schema cache with all required type information such as tables, columns and functions. The result of the parsing is used alongside the schema cache to answer queries about a statement.

The client can submit a delta of input data (typically, a change to a single file), and the server will update the affected statements and their analysis accordingly. The underlying engine makes sure that we only re-parse and re-analyse what is necessary.

Entry Points

There are two main entry points, both thin frontends over the shared pgls_workspace API:

  • crates/pgls_lsp — the language server. It spawns the server and listens for incoming LSP messages.
  • crates/pgls_cli — the command-line interface, exposing commands like check. The published binary is postgres-language-server (legacy name postgrestools).

Code Map

This section talks briefly about various important crates and data structures. All crates are prefixed with pgls_.

Core infrastructure

crates/pgls_workspace

The main API for consumers of the IDE (both the LSP and the CLI). It stores the internal state of the workspace — the schema cache, the parsed documents and their per-feature analysis — and orchestrates the feature crates. Its _macros companion (pgls_workspace_macros) generates repetitive glue code.

crates/pgls_fs

Virtual file system abstraction used to read and watch source files.

crates/pgls_configuration

Configuration model and loading. pgls_configuration_macros generates the merge/partial boilerplate.

crates/pgls_env

Environment variables and runtime configuration constants.

Parser and language processing

crates/pgls_query

Wraps libpg_query to parse an SQL statement into a Postgres AST (NodeEnum). Also provides deparsing, normalization, fingerprinting, statement splitting hints, plpgsql parsing, and mutable/immutable node iterators. Much of the repetitive node code is generated by pgls_query_macros from the protobuf definitions shipped with libpg_query.

crates/pgls_query_ext

Thin extension layer over pgls_query holding helpers and diagnostics not yet contributed upstream.

crates/pgls_lexer / crates/pgls_tokenizer

Tokenize the input source code. pgls_tokenizer is the low-level scanner; pgls_lexer enriches it with whitespace tokens. pgls_lexer_codegen generates the token definitions.

crates/pgls_statement_splitter

Cuts the input source code into individual SQL statements.

crates/pgls_treesitter

Tree-sitter integration used by features (e.g. completions and hover) that need positional/CST context. pgls_treesitter_grammar holds the grammar.

crates/pgls_schema_cache

In-memory representation of the database schema (tables, columns, functions, types). Built from introspection SQL queries and used to resolve types efficiently.

crates/pgls_type_resolver

Utility crate used by the feature crates to resolve source types to the actual types in the schema cache.

Formatting

crates/pgls_pretty_print

SQL pretty-printer / formatter: normalizes the AST and renders it back to formatted SQL with a safety re-parse check. pgls_pretty_print_codegen generates the per-node emitters.

Analysis and linting

crates/pgls_analyse / crates/pgls_analyser

The linting framework. pgls_analyse provides the rule registry, categories, filters, and metadata; pgls_analyser hosts the concrete lint rules and the linter runtime.

crates/pgls_pglinter

Integration with the pglinter Postgres extension for database-level linting.

crates/pgls_splinter

Runs Splinter rules against a live database connection to surface schema/security advisories.

crates/pgls_plpgsql_check

Integration with plpgsql_check to validate PL/pgSQL function bodies.

crates/pgls_typecheck

Type-checks statements against the database (via EXPLAIN).

crates/pgls_suppressions

Handles -- pgls-ignore style rule suppression comments.

Feature crates

crates/pgls_completions, crates/pgls_hover

Autocompletion and hover providers. They operate on the schema cache plus a single statement and its parse results, and are intentionally free of any language-server flavour so they can be reused from the CLI.

Diagnostics and utilities

  • crates/pgls_diagnostics (+ _categories, _macros) — error and warning reporting model.
  • crates/pgls_console / pgls_markup — terminal output and markup.
  • crates/pgls_text_edit, pgls_text_size — text manipulation and byte/char range types.
  • crates/pgls_matcher — Unix shell style pattern matching (glob).
  • crates/pgls_test_utils, pgls_test_macros — shared test helpers.
  • crates/pgls_wasm — WASM bindings for browser/editor integrations.

TypeScript packages

Editor integrations and distribution live under packages/: a JSON-RPC backend bridge, the npm CLI wrapper, and the WASM package. See AGENTS.md for the full list.