CommitFest 7374 Review: psql tab-completion fix for GRANT/REVOKE CREATE

report · generated from canonical Markdown

Type
report
Source
postgresql-master
Slug
commitfest-7374-review
Tags
commitfestpg-review-harnesspg-review-report-v2
Updated
2026-10-02T00:37:13.208524+00:00
Verdict / Summaryready-for-committer (test follow-up required)
Front matter
schema: review-report-v2
target: CommitFest 7374 - psql: avoid CREATE command completion after GRANT/REVOKE CREATE
base: 1378aa13430e264a990a18597e9d8fdae740927e
head: 1378aa13430e264a990a18597e9d8fdae740927e
verdict: ready-for-committer (test follow-up required)
blocker_counts:
  verified: 0
  unverified: 0
diff_blob_sha: e743f35cc349805a6c5aa7560d4786b38be9e4fa
model: glm-5.2:cloud

CommitFest 7374 Review: psql tab-completion fix for GRANT/REVOKE CREATE

Summary

Patch: [PATCH] psql: avoid CREATE command completion after GRANT/REVOKE CREATE Author: Haruna Miwa (miwa@sraoss.co.jp) Date: 2026-10-01 Thread-ID: OSOP286MB78539E88C47403451BFFF140F18A2@OSOP286MB7853.JPNP286.PROD.OUTLOOK.COM

The patch adds an exclusion condition to the generic CREATE tab-completion rule in src/bin/psql/tab-complete.in.c so that GRANT CREATE and REVOKE CREATE (no longer trigger the create_command_generator, which offers irrelevant object types like ACCESS METHOD, AGGREGATE, DATABASE, etc. Instead, the privilege completion path fires and correctly offers ON.

Verdict: ready-for-committer (test follow-up required)

The implementation is correct, minimal, and well-scoped. No correctness, security, performance, or maintainability issues were found. One test-gap finding (COV-1, MAJOR, class=tests) requires a follow-up test patch to guard the new exclusion branch. The proposed test patch has been validated with a two-run gate (passes on patched code, fails on unpatched code).

Patch Diff

diff
diff --git a/src/bin/psql/tab-complete.in.c b/src/bin/psql/tab-complete.in.c
--- a/src/bin/psql/tab-complete.in.c
+++ b/src/bin/psql/tab-complete.in.c
@@ -2186,7 +2186,9 @@ match_previous_words(int pattern_id,
 
 /* CREATE */
 	/* complete with something you can create */
-	else if (TailMatches("CREATE"))
+	else if (TailMatches("CREATE") &&
+		/* exclude cases of GRANT/REVOKE CREATE */
+			 !TailMatches("GRANT|REVOKE", "CREATE"))
 	{
 		/* only some object types can be created as part of CREATE SCHEMA */
 		if (HeadMatches("CREATE", "SCHEMA"))

Review Findings

COV-1

No test coverage for new GRANT/REVOKE CREATE exclusion (MAJOR, tests)

Location: src/bin/psql/tab-complete.in.c:2189 Severity: MAJOR Class: tests Verification status: verified (by coverage)

Mechanism: The patch adds !TailMatches("GRANT|REVOKE", "CREATE") as a new AND condition to the CREATE completion rule at line 2189. Fresh-epoch gcov branch coverage (measured at HEAD with only the implementation patch applied) shows:

  • Line 2189-2191: executed 1 time (by the existing CREATE TY\t test)
  • Branch 1 (fallthrough, condition true → enters create body): taken 100%
  • Branch 2 (condition false → exclusion triggers): taken 0%

The GRANT/REVOKE CREATE exclusion path is never exercised by any existing test. The TAP test 010_tab_completion.pl does not test GRANT or REVOKE completions at all.

Failure risk: Without a test, a future refactor could remove the exclusion and reintroduce irrelevant create_command_generator suggestions after GRANT CREATE / REVOKE CREATE with no test failure.

Repair: Add two check_completion calls to src/bin/psql/t/010_tab_completion.pl verifying that GRANT CREATE\t and REVOKE CREATE\t produce qr/ON / (the privilege completion path) instead of the create_command_generator object list.

Suggested code (exact postimage)

perl
check_completion(
	"GRANT CREATE \t",
	qr/ON /,
	"GRANT CREATE offers ON, not create_command_generator");

clear_query();

check_completion(
	"REVOKE CREATE \t",
	qr/ON /,
	"REVOKE CREATE offers ON, not create_command_generator");

clear_query();

Repair patch (HEAD-bound unified diff, sha256: b8bf19b15003051f94128c51e33dfd43d17f6c6322e9b88d8c016dd3a032bf89)

diff
diff --git a/src/bin/psql/t/010_tab_completion.pl b/src/bin/psql/t/010_tab_completion.pl
--- a/src/bin/psql/t/010_tab_completion.pl
+++ b/src/bin/psql/t/010_tab_completion.pl
@@ -409,6 +409,24 @@ check_completion(
 
 clear_query();
 
+# check that generic CREATE completion is not offered after GRANT/REVOKE
+# CREATE.  On the unpatched code, GRANT CREATE<tab> offers object types
+# from create_command_generator (ACCESS METHOD, AGGREGATE, ...).  After
+# the fix, only the privilege completion path fires and offers ON.
+check_completion(
+	"GRANT CREATE \t",
+	qr/ON /,
+	"GRANT CREATE offers ON, not create_command_generator");
+
+clear_query();
+
+check_completion(
+	"REVOKE CREATE \t",
+	qr/ON /,
+	"REVOKE CREATE offers ON, not create_command_generator");
+
+clear_query();
+
 # check no-completions code path
 check_completion("blarg \t\t", qr//, "check completion failure path");

Repair Validation Summary

MethodResultEvidence
apply-checkpassedgit apply succeeds on HEAD 1378aa13430
diff-checkpassedUnified diff is well-formed with correct ---/+++ markers
targeted-testpassedPatched: 93/93 tests pass (2 new tests ok 86, ok 88)
two-runpassedUnpatched: test times out (query_until qr/ON / never matches because unpatched offers ACCESS METHOD, AGGREGATE, ...); Patched: all pass

Verification Summary

Static verification

gen_tabcomplete.pl (line 236-251). The first clause TailMatches("CREATE") becomes a switch case label; the remainder !TailMatches("GRANT|REVOKE", "CREATE") is emitted as the if guard. Verified by building tab-complete.c and inspecting the output: case 1: followed by

| as the OR separator, which is handled by word_matches() (line 1577). The pattern matches when the last 2 words are [GRANT or REVOKE, CREATE].

consistent with existing multi-line conditions at line 3584.

No server-side changes, no privilege escalation, no injection risk.

create_command_generator from firing after GRANT CREATE / REVOKE CREATE, allowing the privilege completion path at line 4610 (TailMatches("GRANT|REVOKE", MatchAny)) to offer ON.

Runtime verification

passes all 89 tests with the implementation patch applied (no regression).

Changed-Code Coverage

Coverage requirement: required (changed instrumentable implementation in src/bin/psql/tab-complete.in.c)

Counter epoch: fresh (gcda files deleted before test run, disposable build)

Execution lane: host-disposable

LaneStatusEvidence
nested-sandboxblockedCoverage LDFLAGS cause libpq-refs-stamp failure (gcov exit@GLIBC)
host-disposablepassedFull build with -fprofile-arcs -ftest-coverage, 89 tests pass, gcov data collected

Test commands

make -C src/bin/psql check PROVE_TESTS=t/010_tab_completion.pl

Raw metrics (without test patch)

MetricValue
Changed executable lines2
Covered changed lines2
Compiler-uncovered changed lines0
Uncovered changed lines0
Structural uncovered changed lines0
Changed branches1
Covered changed branches0

Uncovered branches

Branch at src/bin/psql/tab-complete.in.c:2189 (branch_id=2, count=0)

c
else if (TailMatches("CREATE") &&
    /* exclude cases of GRANT/REVOKE CREATE */
         !TailMatches("GRANT|REVOKE", "CREATE"))

create_command_generator body) is never exercised. No existing test sends GRANT CREATE or REVOKE CREATE to psql tab-completion. Trivially coverable by a TAP test typing GRANT CREATE<TAB> and verifying ON is offered.

Touched functions

FunctionFileLinesEnteredWhole-function linesWhole-function branches
match_previous_wordssrc/bin/psql/tab-complete.in.c2171-5745yes665/2452427/1595

Coverage with proposed test patch

When the proposed test patch is applied, branch 2 at line 2189 is taken 67% (2 out of 3 times), confirming the test covers the exclusion. All 93 tests pass.

Non-instrumented changes

None. The only changed file is src/bin/psql/tab-complete.in.c (C implementation).

pgsql-hackers Thread Ledger

Status: no-thread-found

Reconstruction methods: pgsql-hackers mail search (BM25)

Summary: Searched the pgsql-hackers inbox for the patch subject. Found exactly one message: OSOP286MB78539E88C47403451BFFF140F18A2@OSOP286MB7853.JPNP286.PROD.OUTLOOK.COM (2026-10-01, Haruna Miwa, [PATCH] psql: avoid CREATE command completion after GRANT/REVOKE CREATE). This is the initial patch submission with no replies or review responses. No prior thread discussion of this specific issue was found.

Finding links:

FindingDispositionRationale
COV-1newTest gap newly identified by this review; no prior reviewer raised it

Aggregated Test Plan

  1. Existing: t/010_tab_completion.pl — 89 tests covering basic completions,

GUCs, psql variables, CREATE/DROP/PUBLICATION completions.

  1. Proposed (COV-1 repair): Add GRANT CREATE\t → ON and

REVOKE CREATE\t → ON tests to t/010_tab_completion.pl.

Residual Risk

Low. The patch is a 2-line change to psql client-side tab-completion logic with no server-side impact. The only residual risk is the untested exclusion branch, which is addressed by the proposed test patch (COV-1).

Provenance

pg-test-author (test proposal), pg-finding-verifier (repair validation), pg-change-coverage-reviewer (coverage analysis)