Skip to content

refactor(plugin-postgresql): tidy search-path and centralize identifier/literal escaping#1546

Merged
datlechin merged 2 commits into
mainfrom
worktree-pg-search-path-refactor
Jun 1, 2026
Merged

refactor(plugin-postgresql): tidy search-path and centralize identifier/literal escaping#1546
datlechin merged 2 commits into
mainfrom
worktree-pg-search-path-refactor

Conversation

@datlechin

@datlechin datlechin commented Jun 1, 2026

Copy link
Copy Markdown
Member

What

Two related cleanups in the PostgreSQL plugin's SQL generation.

  1. Redundant public entry. When the selected schema is public, the search-path builder emitted SET search_path TO "public", public. This collapses it to SET search_path TO "public". Every non-public schema still gets "schema", public, and the quote-doubling injection guard is unchanged.
  2. Centralized quoting/escaping. Identifier quoting ("name" with doubled inner quotes) was hand-rolled in ~10 spots across PostgreSQLPluginDriver, RedshiftPluginDriver, and CockroachPluginDriver. Those now call the shared quoteIdentifier(_:) from TableProPluginKit. Duplicated literal escaping (' -> ''), including a fileprivate escapeLiteralForColumns, now routes through the canonical escapeStringLiteral(_:).

Why

A user asked why, after switching to a non-public schema, the SQL editor can still query other schemas unqualified. Investigation confirmed this is correct PostgreSQL behavior, not a bug: search_path is a name-resolution order, not an access boundary, and the , public fallback is the principled choice (dropping it breaks unqualified extension functions/types in public and buys zero security). The only real defect was the redundant "public", public token, plus the scattered copy-paste of escaping logic that the framework already provides in one audited place.

Behavior

  • Identifier quoting is byte-identical to the hand-rolled code, so DDL and CREATE/DROP DATABASE output is unchanged.
  • escapeStringLiteral also strips null bytes (the old escapeLiteralForColumns did not). This is a defensive improvement with no practical effect: PostgreSQL identifiers cannot contain null bytes.
  • PostgreSQLSchemaQueries.setSearchPath keeps its own quoting on purpose. That enum is a standalone, separately unit-tested SQL builder, deliberately decoupled from any driver instance, so it does not depend on the instance quoteIdentifier.

Tests

Added publicSchema() to PostgreSQLSearchPathTests locking in the no-redundancy output. Existing mixed-case, embedded-quote, and injection tests still pass (they take the non-public branch). The quoting/escaping consolidation is behavior-preserving and covered by existing DDL generation paths.

No CHANGELOG or docs entry: no user-facing behavior change.

@datlechin datlechin changed the title refactor(plugin-postgresql): drop the redundant public entry when public is the selected schema refactor(plugin-postgresql): tidy search-path and centralize identifier/literal escaping Jun 1, 2026
@datlechin datlechin merged commit ab7e154 into main Jun 1, 2026
2 of 3 checks passed
@datlechin datlechin deleted the worktree-pg-search-path-refactor branch June 1, 2026 16:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant