Skip to content

Ship a valid SET search_path with replicated DDL for an empty path#502

Merged
mason-sharp merged 1 commit into
mainfrom
spoc-570
Jun 26, 2026
Merged

Ship a valid SET search_path with replicated DDL for an empty path#502
mason-sharp merged 1 commit into
mainfrom
spoc-570

Conversation

@danolivo

Copy link
Copy Markdown
Contributor

Summary

The auto-DDL path in spock_auto_replicate_ddl() interpolated the publisher's search_path GUC straight into the queued command with a bare %s, guarded only by strlen(search_path) > 0. That is unsafe: GetConfigOptionByName("search_path", ...) does not always return something that is valid SQL on its own. In particular set_config('search_path', ' ', false) — exactly what core's namespace regression test does — leaves a bare space in the GUC, which interpolated directly emits the invalid SET search_path TO ;. That statement fails to parse on the subscriber, so the DDL (and any rows depending on it) never lands.

spock_replicate_ddl_command() already parsed and re-quoted the path correctly, so the two code paths disagreed. This PR factors the correct logic into a single helper and routes both call sites through it.

Changes

  • Add append_set_search_path(), which parses the search_path value with SplitIdentifierString() and re-emits each schema name through quote_identifier(). A value that resolves to no schemas (empty or whitespace-only) is shipped as SET search_path TO '';, so the command is always valid SQL and the subscriber ends up with the same effective (empty) path as the publisher.
  • Replace the unsafe %s interpolation in spock_auto_replicate_ddl() with a call to the helper.
  • Replace the duplicated open-coded loop in spock_replicate_ddl_command() with the same helper.
  • Upgrade the spock_relation_open() cache-miss elog to an ereport with errdetail/errhint that point at the likely cause — a relation message arriving after a data change that references it, usually a schema mismatch — so the subscriber-side failure is diagnosable rather than a bare "cache lookup failed".

@danolivo danolivo requested a review from mason-sharp June 15, 2026 12:02
@danolivo danolivo self-assigned this Jun 15, 2026
@danolivo danolivo added the bug Something isn't working label Jun 15, 2026
@coderabbitai

coderabbitai Bot commented Jun 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9d1f1cbe-f17e-4665-ad89-a712108facce

📥 Commits

Reviewing files that changed from the base of the PR and between 7254192 and 1eede9c.

⛔ Files ignored due to path filters (2)
  • tests/regress/expected/autoddl.out is excluded by !**/*.out
  • tests/regress/expected/exception_row_capture.out is excluded by !**/*.out
📒 Files selected for processing (3)
  • src/spock_functions.c
  • src/spock_relcache.c
  • tests/regress/sql/autoddl.sql
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/spock_relcache.c
  • tests/regress/sql/autoddl.sql
  • src/spock_functions.c

📝 Walkthrough

Walkthrough

Refactors search_path SQL generation into a shared helper, updates both DDL replication paths to use it, adds regression coverage for an effectively empty search_path, and replaces a relcache lookup elog with structured ereport output.

Changes

search_path Serialization Refactor

Layer / File(s) Summary
Helper and replication call sites
src/spock_functions.c
Adds append_set_search_path to serialize search_path into SET search_path TO ...;, including the empty-path form, and routes both DDL replication call sites through it.
Empty search_path regression case
tests/regress/sql/autoddl.sql
Adds a provider/subscriber regression block that sets search_path with set_config, creates and populates a schema/table, syncs replication, and checks the subscriber state.

Relcache Lookup Structured Error

Layer / File(s) Summary
Structured error for missing remote relation
src/spock_relcache.c
Replaces the remote relation cache miss elog with an ereport carrying internal error code, detail, and hint text.

Poem

🐇 A path once hazy now reads clean and neat,
With quoted schemas marching in a line so sweet.
And when a relcache rabbit misses its den,
It speaks with hints and codes again and again.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Clearly summarizes the main fix: generating a valid SET search_path for replicated DDL when the path is empty or whitespace-only.
Description check ✅ Passed It directly describes the search_path replication fix and the relcache error reporting change.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch spoc-570

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/spock_functions.c (1)

2240-2240: 💤 Low value

Use appendStringInfoString for literal strings.

appendStringInfo(buf, ", ") works but appendStringInfoString is more appropriate when there are no format specifiers—it avoids parsing the format string.

Suggested fix
		if (lc != list_head(path_list))
-			appendStringInfo(buf, ", ");
+			appendStringInfoString(buf, ", ");
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/spock_functions.c` at line 2240, Replace the `appendStringInfo(buf, ",
")` call with `appendStringInfoString(buf, ", ")` to avoid unnecessary format
string parsing when appending a literal string with no format specifiers. The
`appendStringInfoString` function is the appropriate choice for appending
literal strings and is more efficient than `appendStringInfo` in this case.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/spock_functions.c`:
- Line 2240: Replace the `appendStringInfo(buf, ", ")` call with
`appendStringInfoString(buf, ", ")` to avoid unnecessary format string parsing
when appending a literal string with no format specifiers. The
`appendStringInfoString` function is the appropriate choice for appending
literal strings and is more efficient than `appendStringInfo` in this case.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 96af3da6-96ee-4c8c-9603-ea16b1db026e

📥 Commits

Reviewing files that changed from the base of the PR and between 922ea93 and 7254192.

⛔ Files ignored due to path filters (2)
  • tests/regress/expected/autoddl.out is excluded by !**/*.out
  • tests/regress/expected/exception_row_capture.out is excluded by !**/*.out
📒 Files selected for processing (3)
  • src/spock_functions.c
  • src/spock_relcache.c
  • tests/regress/sql/autoddl.sql

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 duplication

Metric Results
Duplication 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@mason-sharp mason-sharp requested a review from rasifr June 15, 2026 19:15
The auto-DDL path in spock_auto_replicate_ddl() interpolated the
search_path GUC value into the queued command with a bare "%s", guarded
only by strlen() > 0.  That is unsafe because GetConfigOptionByName()
does not always return something that is valid SQL on its own.

Fix this issue. Change error message on missed entry in spock cache:
highlight the fact that the root of the issue might be schema mismatch.
@mason-sharp mason-sharp merged commit 543150e into main Jun 26, 2026
14 checks passed
@mason-sharp mason-sharp deleted the spoc-570 branch June 26, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants