Skip to content

#4096 fix(cypher): undirected multi-hop patterns must not reuse the same edge - #4114

Merged
robfrank merged 3 commits into
mainfrom
fix/4096-undirected-rel-reuse-isomorphism
May 6, 2026
Merged

#4096 fix(cypher): undirected multi-hop patterns must not reuse the same edge#4114
robfrank merged 3 commits into
mainfrom
fix/4096-undirected-rel-reuse-isomorphism

Conversation

@robfrank

@robfrank robfrank commented May 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The optimizer's ExpandAll physical operator did not enforce Cypher's path isomorphism constraint, so (a)-[r1:KNOWS]-(b)-[r2:KNOWS]-(c) could bind the same edge to both r1 and r2, producing rows like Alice, Bob, Alice, sameRel=true.
  • Fix: skip a candidate edge whose RID already appears under another Edge-typed property in the row, using a new isEdgeAlreadyUsed() helper. The same check already lived in MatchRelationshipStep.isEdgeAlreadyUsed() for the non-optimizer path; the optimizer path bypassed it entirely.
  • Added 3 regression tests in Issue4096UndirectedRelReuseIsomorphismTest.

Closes #4096

Test plan

  • mvn test -pl engine -Dtest=Issue4096UndirectedRelReuseIsomorphismTest - 3/3 pass
  • mvn test -pl engine -Dtest="*Cypher*,*OpenCypher*,*opencypher*" - 5896 tests, 0 failures
  • Confirmed pre-fix the test failed with same edge reused as r1=r2

…ame edge

The optimizer's ExpandAll physical operator did not enforce Cypher's path
isomorphism constraint. For (a)-[r1:KNOWS]-(b)-[r2:KNOWS]-(c) it allowed
the same edge to satisfy both r1 and r2, producing rows like
"Alice, Bob, Alice, sameRel=true". Added isEdgeAlreadyUsed() check so a
candidate edge whose RID already appears under another Edge-typed
property in the row is skipped.
@codacy-production

codacy-production Bot commented May 6, 2026

Copy link
Copy Markdown

Not up to standards ⛔

🔴 Issues 1 medium

Alerts:
⚠ 1 issue (≤ 0 issues of at least minor severity)

Results:
1 new issue

Category Results
Complexity 1 medium

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

🟢 Coverage 62.79% diff coverage · -7.79% coverage variation

Metric Results
Coverage variation -7.79% coverage variation
Diff coverage 62.79% diff coverage

View coverage diff in Codacy

Coverage variation details
Coverable lines Covered lines Coverage
Common ancestor commit (34d8898) 123485 90693 73.44%
Head commit (cd6314f) 154905 (+31420) 101701 (+11008) 65.65% (-7.79%)

Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: <coverage of head commit> - <coverage of common ancestor commit>

Diff coverage details
Coverable lines Covered lines Diff coverage
Pull request (#4114) 86 54 62.79%

Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: <covered lines added or modified>/<coverable lines added or modified> * 100%

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.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request implements Cypher path isomorphism in the ExpandAll operator, ensuring that relationship variables within a MATCH pattern are bound to distinct edges. It includes a new regression test suite for issue #4096. A review comment suggests optimizing the edge reuse check by pre-calculating a set of used edge RIDs per input row to avoid redundant property iterations in the expansion loop.

Comment on lines +213 to +222
private boolean isEdgeAlreadyUsed(final Result row, final RID edgeRid) {
for (final String prop : row.getPropertyNames()) {
if (prop.equals(edgeVariable))
continue;
final Object val = row.getProperty(prop);
if (val instanceof Edge && ((Edge) val).getIdentity().equals(edgeRid))
return true;
}
return false;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

This method is called for every edge of a source vertex, causing the properties of the result row to be iterated repeatedly. This could lead to performance issues when expanding from vertices with a high degree.

To optimize this, you could compute the set of used edge RIDs just once per input row, before iterating over the edges. This would involve:

  1. Adding a private Set<RID> usedEdgeRids field to the anonymous ResultSet implementation in execute().
  2. When a new currentInputResult is fetched in fetchMore(), populate this set by iterating over its properties once.
  3. In the edge expansion loop, replace the call to isEdgeAlreadyUsed with a more efficient usedEdgeRids.contains(edge.getIdentity()).

This refactoring would make the isEdgeAlreadyUsed method redundant and improve performance by avoiding redundant computations in a hot loop.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Implemented in f27207a. The check now precomputes a RidHashSet of used edge RIDs once per input row in ExpandAll and queries it per edge with O(1) contains(). The set is also scoped to same-MATCH-clause preceding rel vars only, so it is null/empty in the common single-hop case and the lookup is free.

@claude

claude Bot commented May 6, 2026

Copy link
Copy Markdown

Code Review

Overview

This PR fixes a correctness bug in the Cypher optimizer path: the ExpandAll physical operator was not enforcing Cypher's path isomorphism constraint, allowing the same edge to bind to two different named relationship variables in an undirected multi-hop pattern. The fix mirrors the check already present in MatchRelationshipStep.isEdgeAlreadyUsed() for the legacy path.

The core fix is correct and the approach is sound. A few things are worth calling out.


Issues

1. Missing previousStepVariables guard (correctness risk)

File: ExpandAll.java:213-222

The MatchRelationshipStep.isEdgeAlreadyUsed() counterpart skips variables that originate from previous MATCH clauses (tracked via previousStepVariables), because Cypher's relationship uniqueness constraint only applies within a single MATCH clause:

// MatchRelationshipStep - existing code
if (previousStepVariables != null && previousStepVariables.contains(prop))
    continue;

The new ExpandAll.isEdgeAlreadyUsed() omits this guard entirely. This means a query like:

MATCH (a)-[r1:KNOWS]-(b)
WITH a, b, r1
MATCH (b)-[r2:KNOWS]-(c)

...would incorrectly suppress rows where r1 and r2 happen to be the same edge, because when the second MATCH's ExpandAll runs, it sees r1 in the row and flags it as already used. Cross-clause edge reuse is valid Cypher and must not be blocked.

This should be addressed either by passing a previousStepVariables set into ExpandAll from the planner, or by documenting that the optimizer currently only emits ExpandAll for single-clause patterns (if that is actually guaranteed today).


2. ExpandInto is not covered

File: ExpandInto.java

ExpandInto also has an edgeVariable field and is used by the optimizer when both endpoints are already bound. If two hops in a pattern both resolve to ExpandInto (e.g., after index seeks bind all three nodes), the isomorphism check is also absent there. The scenario is narrower than ExpandAll but the same root cause applies.


3. Unnamed relationships are still unguarded

The fix is gated on edgeVariable != null. Cypher's relationship uniqueness constraint also applies to unnamed relationships: (a)--(b)--(c) must not traverse the same edge twice. For the optimizer path, unnamed relationships with ExpandAll remain unguarded. This is a pre-existing gap (the legacy MatchRelationshipStep always calls isEdgeAlreadyUsed unconditionally), but worth noting since this PR is touching exactly this area.


Observations

Test: undirectedMultiHopTotalCountMatchesExplicitFilter is redundant

File: Issue4096UndirectedRelReuseIsomorphismTest.java:101-119

This third test asserts that the unfiltered count equals the count with an explicit WHERE r1 <> r2. But undirectedMultiHopDistinctRelationshipCount already checks the count is 2, and undirectedMultiHopDoesNotReuseRelationship already confirms sameRel = false for both rows. The third test adds no independent signal. Consider replacing it with a test for a cross-clause pattern (the previousStepVariables scenario above) to both document the expected behavior and guard against the gap in item 1.

No coverage for the cross-clause case

There is no test verifying that an edge bound in a previous MATCH clause is still eligible for traversal in a subsequent MATCH clause using the optimizer path. Adding one would both document intent and catch a regression if the previousStepVariables guard is later added.


Positives

  • The fix correctly identifies the optimizer code path that bypassed the isomorphism check.
  • Passing a RID rather than an Edge to isEdgeAlreadyUsed() is a small but nice improvement over the MatchRelationshipStep signature.
  • Existing Cypher test suite (5896 tests) passes with the change.
  • The regression test class is well-structured and uses the project's standard assertion style (assertThat(...).isEqualTo(...)).
  • @BeforeEach/@AfterEach correctly drop the test database to avoid cross-test contamination.

Cypher relationship uniqueness only applies within a single MATCH clause;
the previous fix would block valid cross-clause edge reuse. Track each
LogicalRelationship's clause index and pass the same-clause preceding
relationship variable names to ExpandAll/ExpandInto so the check stays
scoped. Cache the used edge RIDs once per input row instead of scanning
the result properties on every edge. ExpandInto also gets the check.

Tests: replaced the redundant filter-equivalence test with a cross-clause
regression and added an ExpandInto-path test.
@robfrank

robfrank commented May 6, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up in f27207a addresses the review.

Issue 1 (cross-clause scoping): Confirmed real - ran a probe query (MATCH (a)-[r1]-(b) MATCH (b)-[r2]-(c) RETURN count(*)) which returned 2 instead of the expected 6 with the original fix, because the optimizer merges all MATCH clauses into a single LogicalPlan. Fixed by:

  1. Adding a clauseIndex field to LogicalRelationship (set in LogicalPlan.extractPatterns).
  2. CypherOptimizer.buildExpansionChain now tracks rel vars per clause index in a Map<Integer, Set<String>> and passes the same-clause preceding set to each operator via setSameClausePrecedingRelVars.
  3. ExpandAll/ExpandInto only check edges bound to variables in that scoped set.

Issue 2 (ExpandInto): Same scoping mechanism added. ExpandInto already resolves the connecting edge when an edgeVariable is set; when it isn't but the row has a same-clause edge bound, the check loads it via findEdgeForCheck (cheap getFirstEdgeConnectedToVertex).

Issue 3 (anonymous relationships): Out of scope for this PR. The legacy MatchRelationshipStep already synthesises internal anonymous variables via computeHopEdgeTrackingNeeds for multi-hop anonymous patterns with overlapping types; the optimizer has no equivalent. Worth a separate issue.

Observations: Replaced the redundant undirectedMultiHopTotalCountMatchesExplicitFilter test with crossClauseEdgeReuseIsAllowed (covers issue 1) and added expandIntoPathDoesNotReuseRelationship (covers issue 2).

Gemini's perf suggestion: Implemented. ExpandAll builds a RidHashSet of used edge RIDs once per input row instead of scanning result properties on every edge.

Full Cypher suite (5896 tests) still green.

@claude

claude Bot commented May 6, 2026

Copy link
Copy Markdown

Code Review - PR #4114: Fix Cypher Undirected Multi-Hop Relationship Isomorphism

Overview

This PR correctly identifies and fixes a real Cypher compliance bug: the optimizer's ExpandAll and ExpandInto physical operators did not enforce relationship uniqueness within a MATCH clause, allowing the same edge to be bound to two different relationship variables. The fix is targeted and the clause-scoping logic (same-clause vs. cross-clause) reflects the correct Cypher semantics.


Correctness Issues

1. collectUsedEdgeRids / isSameClauseEdgeReuse miss TraversalPath and List<Edge> bindings

The reference implementation in MatchRelationshipStep.isEdgeAlreadyUsed() (lines 920-948) handles three kinds of edge bindings in a row:

if (val instanceof Edge && ...)                return true;
if (val instanceof TraversalPath)   { ... }   // variable-length pattern edges
if (val instanceof List)            { ... }   // VLP relationship variable edge lists

The new ExpandAll.collectUsedEdgeRids and ExpandInto.isSameClauseEdgeReuse check only instanceof Edge. A variable-length hop earlier in the same MATCH clause (e.g. (a)-[r1*1..2]-(b)-[r2]-(c)) can put a TraversalPath or a List<Edge> into the row, and those edges will not be extracted. This means isomorphism enforcement silently falls through for mixed fixed/variable-length patterns in the same clause.

2. ExpandInto.findEdgeForCheck returns at most one edge, causing false positives on multi-edge graphs

GraphEngine.getFirstEdgeConnectedToVertex returns only the first matching edge. When there are multiple edges of the same type between two vertices, findEdgeForCheck may return an edge that happens to conflict with a same-clause variable, even though a different valid edge exists between the same pair. The row gets dropped even though a non-conflicting traversal was possible. This is a correctness hole for multigraph schemas.

3. Anonymous relationship patterns bypass the check

The optimizer only tracks named relationship variables:

if (rel.getVariable() != null && !rel.getVariable().isEmpty()) {
    relVarsPerClause.computeIfAbsent(...).add(rel.getVariable());
}

Cypher's relationship uniqueness constraint applies to all relationships in a pattern, named or not. For (a)-->(b)-->(c) the two traversed edges must also be distinct. Because anonymous edges are never stored under a row property, they cannot be checked post-hoc. This matches the same limitation as MatchRelationshipStep, so it is not a regression, but a comment noting the known gap would help future contributors.


Minor Issues

4. Inconsistent isEmpty() guard in ExpandInto

isSameClauseEdgeReuse guards with isEmpty() but hasUsedRels does not:

// hasUsedRels - missing isEmpty() check
if (sameClausePrecedingRelVars == null) return false;

// isSameClauseEdgeReuse - has the guard
if (sameClausePrecedingRelVars == null || sameClausePrecedingRelVars.isEmpty()) return false;

Iterating an empty set is harmless, but the inconsistency is noticeable.

5. ExpandInto performs two edge lookups when edgeVariable is null

When no edge binding is required (edgeVariable == null), the existing code already found connectivity. The new isomorphism check then calls findEdgeForCheck which does another full getFirstEdgeConnectedToVertex traversal. For the common single-hop case the sameClausePrecedingRelVars set is empty so hasUsedRels returns false quickly - but for longer chains this adds an extra edge scan per row. This is acceptable given the correctness requirement, just worth noting in a comment.

6. Default clauseIndex = 0 in legacy constructors

The 8- and 9-argument LogicalRelationship constructors (kept for backwards compatibility) default clauseIndex to 0. These constructors are used directly in ExpandIntoRuleTest. If any non-test caller creates relationships across multiple MATCH clauses using these constructors, the clause index will be wrong and isomorphism will be incorrectly scoped to clause 0. This is low risk today but could silently misfire if new callers are added.


Test Coverage

The four regression tests in Issue4096UndirectedRelReuseIsomorphismTest cover the stated scenarios well. A few gaps worth adding in follow-up:

  • A directed multi-hop pattern ((a)-[r1]->(b)-[r2]->(c)) - verify the fix does not regress directed paths
  • A mixed fixed+variable-length pattern in the same clause ((a)-[r1*1..2]-(b)-[r2]-(c)) to demonstrate the known gap (issue 1 above) or confirm it is handled
  • A multigraph case (two parallel edges between the same vertex pair) to document expected behavior under issue 2

The cross-clause count assertion (crossClauseEdgeReuseIsAllowed expecting 6) is correct and the comment explaining the breakdown is appreciated.


Code Quality

  • The RidHashSet usage and the null-short-circuit pattern (return null from collectUsedEdgeRids vs. an empty set) are good performance choices consistent with the project's GC-pressure guidelines.
  • The clause-scoping design (relVarsPerClause keyed by clauseIndex) is clean and the rationale is well-commented.
  • The Javadoc on setSameClausePrecedingRelVars explains the Cypher semantics correctly.
  • LogicalRelationship.getClauseIndex() Javadoc is accurate.

Summary

The core fix is correct and the approach is sound. Before merging I would suggest:

  1. (Required) Extend collectUsedEdgeRids and isSameClauseEdgeReuse to handle TraversalPath and List<Edge> bindings, mirroring MatchRelationshipStep.isEdgeAlreadyUsed.
  2. (Recommended) Add a comment on findEdgeForCheck noting the first-edge limitation and its implication for multigraph schemas.
  3. (Optional) Align hasUsedRels to also guard with isEmpty() for consistency.

@claude

claude Bot commented May 6, 2026

Copy link
Copy Markdown

Code Review - #4096 fix(cypher): undirected multi-hop patterns must not reuse the same edge

Overview

This PR enforces Cypher path isomorphism for the optimizer's physical operators (ExpandAll / ExpandInto), which previously bypassed the same check that already existed in MatchRelationshipStep.isEdgeAlreadyUsed(). The per-clause scoping approach (via clauseIndex on LogicalRelationship and relVarsPerClause in buildExpansionChain) is the correct way to implement Cypher's rule that relationship uniqueness applies only within a single MATCH clause.


Bug: GAVExpandAll bypasses the isomorphism check

In createExpandAllOperator, when a GraphTraversalProvider is registered for the edge type, the optimizer returns a GAVExpandAll early - before setSameClausePrecedingRelVars is ever called:

if (provider != null) {
    return new GAVExpandAll(input, provider, sourceVariable, targetVariable, direction, edgeTypes,
        gavCost, outputCardinality);   // <-- returned here, no isomorphism wiring
}

final ExpandAll expandAll = new ExpandAll(...);
expandAll.setSameClausePrecedingRelVars(sameClausePrecedingRelVars);  // never reached for GAV
return expandAll;

GAVExpandAll has no setSameClausePrecedingRelVars method and no corresponding check in its expansion loop, so queries that trigger the GAV fast path will still reuse the same edge across hops. A regression test should cover this path, or GAVExpandAll should gain the same guard.


Potential Issue: ExpandInto.findEdgeForCheck with parallel edges

findEdgeForCheck calls getFirstEdgeConnectedToVertex, which returns the first edge between two vertices. In a graph with multiple parallel edges of the same type between the same pair of vertices, the method might return an edge that is different from the one actually selected for the traversal. This could produce a false positive (incorrectly skipping a valid path where the first edge happens to match a bound variable, but another parallel edge would not) or a false negative (the traversal picks the first edge which does match a bound variable, but findEdgeForCheck is never called because connectedEdge was already set).

This is a pre-existing limitation of ExpandInto's existence-check semantics, but the new code amplifies it.


Design concern: setter instead of constructor parameter

sameClausePrecedingRelVars is a non-final field set via setSameClausePrecedingRelVars() in both ExpandAll and ExpandInto. The GAV bug above exists precisely because the object can be returned before the setter is called. Passing it through the constructor (or at minimum making the field final after a mandatory setter call) would make the dependency explicit. Given that ExpandAll already has many constructor parameters, a builder or an optional config wrapper might be cleaner long-term.


Minor: anonymous relationship variables are not covered

buildExpansionChain only tracks named relationship variables in relVarsPerClause:

if (rel.getVariable() != null && !rel.getVariable().isEmpty()) {
    relVarsPerClause.computeIfAbsent(rel.getClauseIndex(), k -> new HashSet<>())
        .add(rel.getVariable());
}

Cypher's path isomorphism rule applies to all relationships, named or not. A pattern like MATCH (a)--(b)--(c) should not reuse the same edge. Because anonymous edges are never stored in the result row in the optimizer path (the if (edgeVariable != null && !edgeVariable.isEmpty()) guard), the check has no information to work with for anonymous hops. This is a pre-existing limitation rather than a regression from this PR, but worth tracking.


Code quality notes

  • The whitespace alignment changes throughout CypherOptimizer.java (field declarations, constructor parameter lists, Javadoc @param tags) add substantial diff noise. They are not harmful, but make it harder to see the semantically meaningful changes.
  • ExpandAll uses RidHashSet for O(1) lookups while ExpandInto uses a linear scan over sameClausePrecedingRelVars with direct equals comparisons. Both are correct; the inconsistency is minor for typical query sizes (2-4 hops).
  • The hasUsedRels gate in ExpandInto before calling findEdgeForCheck is a good performance guard.

Test coverage

The three regression tests are well-chosen:

Test Purpose
undirectedMultiHopDoesNotReuseRelationship Named vars, verifies sameRel = false
undirectedMultiHopDistinctRelationshipCount Count-based sanity check
crossClauseEdgeReuseIsAllowed Cross-MATCH allowance (critical for scoping correctness)
expandIntoPathDoesNotReuseRelationship ExpandInto path

Missing: a test that uses a GAV-backed edge type to confirm the check also works there (currently it does not, per the bug above).

A note on assertion style: the CLAUDE.md convention prefers the assertThat(x).isEqualTo(y) form throughout - the tests use it correctly.


Summary

The core logic - per-clause variable tracking in the optimizer, delegating the check into ExpandAll/ExpandInto at the row level - is correct and matches the semantics of the existing MatchRelationshipStep path. The primary concern before merging is the GAVExpandAll gap, which leaves the original bug active for queries that go through that fast path.

@robfrank
robfrank merged commit c1814a7 into main May 6, 2026
20 of 24 checks passed
@codecov

codecov Bot commented May 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 54.65116% with 39 lines in your changes missing coverage. Please review.
✅ Project coverage is 64.45%. Comparing base (34d8898) to head (cd6314f).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...uery/opencypher/executor/operators/ExpandInto.java 10.25% 30 Missing and 5 partials ⚠️
...opencypher/optimizer/plan/LogicalRelationship.java 71.42% 2 Missing ⚠️
...query/opencypher/executor/operators/ExpandAll.java 94.11% 0 Missing and 1 partial ⚠️
...db/query/opencypher/optimizer/CypherOptimizer.java 94.73% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4114      +/-   ##
==========================================
- Coverage   64.46%   64.45%   -0.01%     
==========================================
  Files        1623     1623              
  Lines      123485   123556      +71     
  Branches    26288    26303      +15     
==========================================
+ Hits        79610    79644      +34     
- Misses      32823    32856      +33     
- Partials    11052    11056       +4     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request May 10, 2026
robfrank added a commit that referenced this pull request May 12, 2026
tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request Jun 28, 2026
… 2.66.0 to 2.67.0 [skip ci]

Bumps [com.google.api.grpc:proto-google-common-protos](https://github.com/googleapis/sdk-platform-java) from 2.66.0 to 2.67.0.
Release notes

*Sourced from [com.google.api.grpc:proto-google-common-protos's releases](https://github.com/googleapis/sdk-platform-java/releases).*

> v2.67.0
> -------
>
> [2.67.0](googleapis/sdk-platform-java@v2.66.1...v2.67.0) (2026-02-18)
> ------------------------------------------------------------------------------------------------
>
> ### Features
>
> * **observability:** introduce minimal tracing implementation ([ArcadeData#4105](https://redirect.github.com/googleapis/sdk-platform-java/issues/4105)) ([e4e5e89](googleapis/sdk-platform-java@e4e5e89))
>
> ### Dependencies
>
> * Upgrade Google-Auth-Library to v1.43.0 ([ArcadeData#4114](https://redirect.github.com/googleapis/sdk-platform-java/issues/4114)) ([825298b](googleapis/sdk-platform-java@825298b))
> * Upgrade grpc to 1.76.3 ([ArcadeData#4106](https://redirect.github.com/googleapis/sdk-platform-java/issues/4106)) ([c6555f5](googleapis/sdk-platform-java@c6555f5))
>
> v2.66.1
> -------
>
> [2.66.1](googleapis/sdk-platform-java@v2.66.0...v2.66.1) (2026-02-04)
> ------------------------------------------------------------------------------------------------
>
> ### Documentation
>
> * [common-protos] update reference documentation for `SelectionInput.DROPDOWN` to include dynamic data sources and autosuggestion ([9960262](googleapis/sdk-platform-java@9960262))


Changelog

*Sourced from [com.google.api.grpc:proto-google-common-protos's changelog](https://github.com/googleapis/sdk-platform-java/blob/main/CHANGELOG.md).*

> [2.67.0](googleapis/sdk-platform-java@v2.66.1...v2.67.0) (2026-02-18)
> ------------------------------------------------------------------------------------------------
>
> ### Features
>
> * **observability:** introduce minimal tracing implementation ([ArcadeData#4105](https://redirect.github.com/googleapis/sdk-platform-java/issues/4105)) ([e4e5e89](googleapis/sdk-platform-java@e4e5e89))
>
> ### Dependencies
>
> * Upgrade Google-Auth-Library to v1.43.0 ([ArcadeData#4114](https://redirect.github.com/googleapis/sdk-platform-java/issues/4114)) ([825298b](googleapis/sdk-platform-java@825298b))
> * Upgrade grpc to 1.76.3 ([ArcadeData#4106](https://redirect.github.com/googleapis/sdk-platform-java/issues/4106)) ([c6555f5](googleapis/sdk-platform-java@c6555f5))
>
> [2.66.1](googleapis/sdk-platform-java@v2.66.0...v2.66.1) (2026-02-04)
> ------------------------------------------------------------------------------------------------
>
> ### Documentation
>
> * [common-protos] update reference documentation for `SelectionInput.DROPDOWN` to include dynamic data sources and autosuggestion ([9960262](googleapis/sdk-platform-java@9960262))


Commits

* [`50d2af3`](googleapis/sdk-platform-java@50d2af3) chore(main): release 2.67.0 ([ArcadeData#4107](https://redirect.github.com/googleapis/sdk-platform-java/issues/4107))
* [`ffb6b02`](googleapis/sdk-platform-java@ffb6b02) chore(deps): update upper bound dependencies file ([ArcadeData#4112](https://redirect.github.com/googleapis/sdk-platform-java/issues/4112))
* [`825298b`](googleapis/sdk-platform-java@825298b) deps: Upgrade Google-Auth-Library to v1.43.0 ([ArcadeData#4114](https://redirect.github.com/googleapis/sdk-platform-java/issues/4114))
* [`3fa1ca3`](googleapis/sdk-platform-java@3fa1ca3) chore: update googleapis commit at Thu Feb 5 03:00:22 UTC 2026 ([ArcadeData#4104](https://redirect.github.com/googleapis/sdk-platform-java/issues/4104))
* [`e4e5e89`](googleapis/sdk-platform-java@e4e5e89) feat(observability): introduce minimal tracing implementation ([ArcadeData#4105](https://redirect.github.com/googleapis/sdk-platform-java/issues/4105))
* [`c6555f5`](googleapis/sdk-platform-java@c6555f5) deps: Upgrade grpc to 1.76.3 ([ArcadeData#4106](https://redirect.github.com/googleapis/sdk-platform-java/issues/4106))
* [`117c390`](googleapis/sdk-platform-java@117c390) chore(main): release 2.66.2-SNAPSHOT ([ArcadeData#4102](https://redirect.github.com/googleapis/sdk-platform-java/issues/4102))
* [`ff33367`](googleapis/sdk-platform-java@ff33367) tests: Upgrade logback to 1.5.25 in tests ([ArcadeData#4103](https://redirect.github.com/googleapis/sdk-platform-java/issues/4103))
* [`a4d8c44`](googleapis/sdk-platform-java@a4d8c44) tests: Remove 3.25.8 from protobuf compatibility testing ([ArcadeData#4101](https://redirect.github.com/googleapis/sdk-platform-java/issues/4101))
* [`3b280a3`](googleapis/sdk-platform-java@3b280a3) chore(main): release 2.66.1 ([ArcadeData#4100](https://redirect.github.com/googleapis/sdk-platform-java/issues/4100))
* Additional commits viewable in [compare view](googleapis/sdk-platform-java@v2.66.0...v2.67.0)
  
[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility\_score?dependency-name=com.google.api.grpc:proto-google-common-protos&package-manager=maven&previous-version=2.66.0&new-version=2.67.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
tae898 pushed a commit to humemai/arcadedb-embedded-python that referenced this pull request Jun 28, 2026
@lvca
lvca deleted the fix/4096-undirected-rel-reuse-isomorphism branch July 3, 2026 20:18
mergify Bot added a commit that referenced this pull request Jul 8, 2026
…skip ci]

Bumps [org.postgresql:postgresql](https://github.com/pgjdbc/pgjdbc) from 42.7.12 to 42.7.13.
Release notes

*Sourced from [org.postgresql:postgresql's releases](https://github.com/pgjdbc/pgjdbc/releases).*

> v42.7.13
> --------
>
> Changes
> -------
>
> * docs: add 42.7.13 release changelog [`@​davecramer`](https://github.com/davecramer) ([#4270](https://redirect.github.com/pgjdbc/pgjdbc/issues/4270))
> * Adjust EditorConfig für Makefile [`@​BaumiCoder`](https://github.com/BaumiCoder) ([#4279](https://redirect.github.com/pgjdbc/pgjdbc/issues/4279))
> * fix(scram): fail closed on channel-binding downgrade (no scram bump) [`@​vlsi`](https://github.com/vlsi) ([#4272](https://redirect.github.com/pgjdbc/pgjdbc/issues/4272))
> * Bump pgjdbc version from 42.7.12 to 42.7.13 [`@​davecramer`](https://github.com/davecramer) ([#4269](https://redirect.github.com/pgjdbc/pgjdbc/issues/4269))
> * chore: remove test-anorm-sbt module and its disabled CI wiring [`@​vlsi`](https://github.com/vlsi) ([#4261](https://redirect.github.com/pgjdbc/pgjdbc/issues/4261))
> * refactor(test-gss): convert to Java/JUnit 5 submodule of the main build [`@​vlsi`](https://github.com/vlsi) ([#4166](https://redirect.github.com/pgjdbc/pgjdbc/issues/4166))
> * ci: derive PG test versions from a Renovate-managed maxPgVersion [`@​vlsi`](https://github.com/vlsi) ([#4218](https://redirect.github.com/pgjdbc/pgjdbc/issues/4218))
> * feat(insert): cap reWriteBatchedInserts by the protocol limit, not 128 [`@​vlsi`](https://github.com/vlsi) ([#4207](https://redirect.github.com/pgjdbc/pgjdbc/issues/4207))
> * refactor(metadata): derive getPrimaryKeys from pg\_constraint.conkey [`@​vlsi`](https://github.com/vlsi) ([#4202](https://redirect.github.com/pgjdbc/pgjdbc/issues/4202))
> * fix(protocol): defer flushes until response processing [`@​vlsi`](https://github.com/vlsi) ([#4196](https://redirect.github.com/pgjdbc/pgjdbc/issues/4196))
> * fix(build): resolve the Temurin 8 test toolchain by vendor [`@​vlsi`](https://github.com/vlsi) ([#4257](https://redirect.github.com/pgjdbc/pgjdbc/issues/4257))
> * build: include multi-release source sets in the JaCoCo coverage report [`@​vlsi`](https://github.com/vlsi) ([#4256](https://redirect.github.com/pgjdbc/pgjdbc/issues/4256))
> * fix(ci): read java\_vendor before overwriting java\_distribution [`@​vlsi`](https://github.com/vlsi) ([#4255](https://redirect.github.com/pgjdbc/pgjdbc/issues/4255))
> * ci: generate the whole matrix in one batch, coverage job included [`@​vlsi`](https://github.com/vlsi) ([#4253](https://redirect.github.com/pgjdbc/pgjdbc/issues/4253))
> * ci: pass CODECOV\_TOKEN so protected-branch coverage uploads succeed [`@​vlsi`](https://github.com/vlsi) ([#4254](https://redirect.github.com/pgjdbc/pgjdbc/issues/4254))
> * ci: collect coverage on one pinned job [`@​vlsi`](https://github.com/vlsi) ([#4245](https://redirect.github.com/pgjdbc/pgjdbc/issues/4245))
> * ci: apply -DqueryTimeout from the matrix query\_timeout axis [`@​vlsi`](https://github.com/vlsi) ([#4246](https://redirect.github.com/pgjdbc/pgjdbc/issues/4246))
> * ci: make Codecov project and patch statuses informational [`@​vlsi`](https://github.com/vlsi) ([#4244](https://redirect.github.com/pgjdbc/pgjdbc/issues/4244))
> * fix(build): restore JaCoCo XML report so Codecov receives coverage [`@​vlsi`](https://github.com/vlsi) ([#4240](https://redirect.github.com/pgjdbc/pgjdbc/issues/4240))
> * test(replication): shrink big-transaction inserts to avoid CI timeouts [`@​vlsi`](https://github.com/vlsi) ([#4243](https://redirect.github.com/pgjdbc/pgjdbc/issues/4243))
> * update maintainers [`@​davecramer`](https://github.com/davecramer) ([#4222](https://redirect.github.com/pgjdbc/pgjdbc/issues/4222))
> * test: add hermetic test for localSocketAddress [`@​vlsi`](https://github.com/vlsi) ([#4224](https://redirect.github.com/pgjdbc/pgjdbc/issues/4224))
> * docs(translation): clean up leftover German header in ja.po [`@​vlsi`](https://github.com/vlsi) ([#4206](https://redirect.github.com/pgjdbc/pgjdbc/issues/4206))
> * Update ja.po [`@​davecramer`](https://github.com/davecramer) ([#2004](https://redirect.github.com/pgjdbc/pgjdbc/issues/2004))
> * test: add PostgreSQL 18 to the CI test matrix [`@​vlsi`](https://github.com/vlsi) ([#4198](https://redirect.github.com/pgjdbc/pgjdbc/issues/4198))
> * test: silence expected SSPI warning stack trace in SSPIClientWaffleTest [`@​vlsi`](https://github.com/vlsi) ([#4197](https://redirect.github.com/pgjdbc/pgjdbc/issues/4197))
> * fix(ssl): build PKIX trust anchors without a KeyStore so FIPS-mode JVMs can load sslrootcert [`@​vlsi`](https://github.com/vlsi) ([#4193](https://redirect.github.com/pgjdbc/pgjdbc/issues/4193))
> * test: fix flaky sentLocationEqualToLastReceiveLSN replication test [`@​vlsi`](https://github.com/vlsi) ([#4175](https://redirect.github.com/pgjdbc/pgjdbc/issues/4175))
> * build: promote MethodCanBeStatic to error level [`@​vlsi`](https://github.com/vlsi) ([#4172](https://redirect.github.com/pgjdbc/pgjdbc/issues/4172))
> * Fix PGInterval.setSeconds to reject out of range and NaN values [`@​sehrope`](https://github.com/sehrope) ([#4194](https://redirect.github.com/pgjdbc/pgjdbc/issues/4194))
> * Replace connectThreadFactory with connectExecutor [`@​sehrope`](https://github.com/sehrope) ([#4165](https://redirect.github.com/pgjdbc/pgjdbc/issues/4165))
> * Fix deleting temp file when spooling large stream to disk in StreamWrapper [`@​sehrope`](https://github.com/sehrope) ([#4190](https://redirect.github.com/pgjdbc/pgjdbc/issues/4190))
> * chore: Add top level /scratch to gitignore [`@​sehrope`](https://github.com/sehrope) ([#4164](https://redirect.github.com/pgjdbc/pgjdbc/issues/4164))
> * refactor: favour composition over inheritance for Driver.ConnectTask [`@​vlsi`](https://github.com/vlsi) ([#4160](https://redirect.github.com/pgjdbc/pgjdbc/issues/4160))
> * Fix NumberParser.getFastLong(...) handling of overlong values [`@​sehrope`](https://github.com/sehrope) ([#4163](https://redirect.github.com/pgjdbc/pgjdbc/issues/4163))
> * build: produce a multi-release jar from reduced-pom.xml on Java 11+ [`@​vlsi`](https://github.com/vlsi) ([#4157](https://redirect.github.com/pgjdbc/pgjdbc/issues/4157))
> * Add connectThreadFactory and refactor Driver to use FutureTask for loginTimeout connection attempts [`@​sehrope`](https://github.com/sehrope) ([#4120](https://redirect.github.com/pgjdbc/pgjdbc/issues/4120))
> * test: verify custom properties reach socket factory [`@​vlsi`](https://github.com/vlsi) ([#4125](https://redirect.github.com/pgjdbc/pgjdbc/issues/4125))
> * test: fix LazyCleanerTest timeouts for the lingering Java 8 cleanup thread [`@​vlsi`](https://github.com/vlsi) ([#4122](https://redirect.github.com/pgjdbc/pgjdbc/issues/4122))
> * test: stabilise StatementTest.fastCloses on Windows [`@​vlsi`](https://github.com/vlsi) ([#4121](https://redirect.github.com/pgjdbc/pgjdbc/issues/4121))
> * fix: append default non-proxy hosts when socksNonProxyHosts is set [`@​davecramer`](https://github.com/davecramer) ([#4045](https://redirect.github.com/pgjdbc/pgjdbc/issues/4045))
> * test: budget terminating Sync in BatchDeadlockTest small-RETURNING branch [`@​vlsi`](https://github.com/vlsi) ([#4116](https://redirect.github.com/pgjdbc/pgjdbc/issues/4116))
> * test: make message assertions locale-independent [`@​vlsi`](https://github.com/vlsi) ([#4113](https://redirect.github.com/pgjdbc/pgjdbc/issues/4113))
> * build: drop xgettext default keywords; regenerate translations [`@​vlsi`](https://github.com/vlsi) ([#4100](https://redirect.github.com/pgjdbc/pgjdbc/issues/4100))
> * ci: opt-in scheduled workflows via ENABLE\_SCHEDULED\_JOBS repo variable [`@​vlsi`](https://github.com/vlsi) ([#4085](https://redirect.github.com/pgjdbc/pgjdbc/issues/4085))
> * Avoid direct java.lang.management dependency in maxResultBuffer parser [`@​mblakley-casana`](https://github.com/mblakley-casana) ([#4069](https://redirect.github.com/pgjdbc/pgjdbc/issues/4069))
> * fix: restore pre-describe for generated-key batches [`@​bilalshehata`](https://github.com/bilalshehata) ([#4014](https://redirect.github.com/pgjdbc/pgjdbc/issues/4014))

... (truncated)


Changelog

*Sourced from [org.postgresql:postgresql's changelog](https://github.com/pgjdbc/pgjdbc/blob/master/CHANGELOG.md).*

> [42.7.13] (2026-07-06)
> ----------------------
>
> ### Added
>
> * feat: invalidate the prepared-statement cache when the server reports a `search_path` change via GUC\_REPORT (PostgreSQL 18+), so cached plans are no longer used against the wrong schema [PR [#4259](https://redirect.github.com/pgjdbc/pgjdbc/issues/4259)]([pgjdbc/pgjdbc#4259](https://redirect.github.com/pgjdbc/pgjdbc/pull/4259))
> * feat: `reWriteBatchedInserts` now merges up to 32768 rows into one multi-values `INSERT` (bounded by the 65535 bind-parameter limit on the extended protocol) instead of capping at 128, which speeds up batches of few-column rows. The new `reWriteBatchedInsertsSize` connection property lowers that cap when set; the default of `0` uses that maximum. [PR [#4207](https://redirect.github.com/pgjdbc/pgjdbc/issues/4207)]([pgjdbc/pgjdbc#4207](https://redirect.github.com/pgjdbc/pgjdbc/pull/4207))
> * feat: invalidate the prepared-statement cache after CREATE/DROP/ALTER so callers no longer trip on "cached plan must not change result type" without opting into `autosave=ALWAYS`. Controlled by the new `flushCacheOnDdl` connection property (default `true`); set to `false` for the prior behaviour. [PR [#4067](https://redirect.github.com/pgjdbc/pgjdbc/issues/4067)]([pgjdbc/pgjdbc#4067](https://redirect.github.com/pgjdbc/pgjdbc/pull/4067))
> * feat: add `connectExecutor` connection property to customize the `Executor` used to run the worker task that performs the connection attempt when `loginTimeout` is in effect. The value is the fully qualified name of a class implementing `java.util.concurrent.Executor`. With a null value, the default, the driver retains the prior behavior of running the connection attempt on a daemon thread named `"PostgreSQL JDBC driver connection thread"`. The executor must run the task on a thread other than the caller's. Running the attempt on a named thread lets applications that monitor driver-created threads identify it. [PR [#4165](https://redirect.github.com/pgjdbc/pgjdbc/issues/4165)]([pgjdbc/pgjdbc#4165](https://redirect.github.com/pgjdbc/pgjdbc/pull/4165))
> * feat: add `classLoaderStrategy` connection property to control which classloaders the driver searches when loading a class named by a connection property, for example `socketFactory`. The default `driver-first` now falls back to the thread context classloader when the driver's classloader cannot resolve the class, which fixes class loading in non-flat class paths such as Quarkus and OSGi. Set `driver` to keep the previous driver-classloader-only behaviour, or `context-first` to prefer the thread context classloader [Issue [#2112](https://redirect.github.com/pgjdbc/pgjdbc/issues/2112)]([pgjdbc/pgjdbc#2112](https://redirect.github.com/pgjdbc/pgjdbc/issues/2112)) [PR [#4167](https://redirect.github.com/pgjdbc/pgjdbc/issues/4167)]([pgjdbc/pgjdbc#4167](https://redirect.github.com/pgjdbc/pgjdbc/pull/4167))
> * feat: add OID constants for geometric arrays, `RECORD`, and `refcursor` [PR [#4220](https://redirect.github.com/pgjdbc/pgjdbc/issues/4220)]([pgjdbc/pgjdbc#4220](https://redirect.github.com/pgjdbc/pgjdbc/pull/4220))
> * feat: `LargeObject` `BlobInputStream` now skips by seeking instead of reading, and the driver exposes the server version so it can select the 64-bit large-object API where available [PR [#4204](https://redirect.github.com/pgjdbc/pgjdbc/issues/4204)]([pgjdbc/pgjdbc#4204](https://redirect.github.com/pgjdbc/pgjdbc/pull/4204))
>
> ### Changed
>
> * refactor: the worker that runs the connection attempt under `loginTimeout` is now a `FutureTask` (`ConnectTask`) instead of the hand-rolled `ConnectThread`. When the caller hits the timeout, the task is now cancelled with `cancel(true)`, which interrupts the worker thread rather than letting it run to completion. This makes the connection attempt interruptible, so `loginTimeout` can stop a slow connection attempt instead of leaking a thread. As before, a connection that the worker still manages to establish after the caller gives up is closed by the worker so that it does not leak. There are no public API changes and this should only lead to faster background resource cleanup for connections that time out. [PR [#4120](https://redirect.github.com/pgjdbc/pgjdbc/issues/4120)]([pgjdbc/pgjdbc#4120](https://redirect.github.com/pgjdbc/pgjdbc/pull/4120))
> * chore: `PGXAConnection.ConnectionHandler` now rejects `setAutoCommit(false)` and `setSavepoint(...)` during an active XA branch, in addition to the long-rejected `setAutoCommit(true)` / `commit()` / `rollback()`. The `setSavepoint` rejection was already meant to be in place but the guard misspelled the method name as `setSavePoint`, so savepoints silently went through. Both changes bring the proxy in line with JTA 1.2 §3.4. [PR [#4114](https://redirect.github.com/pgjdbc/pgjdbc/issues/4114)]([pgjdbc/pgjdbc#4114](https://redirect.github.com/pgjdbc/pgjdbc/pull/4114))
> * chore: `commitPrepared` / `rollback`-of-prepared now return `XAER_RMFAIL` instead of `XAER_RMERR` when the underlying connection is left in a non-idle `TransactionState`. Transaction managers (Geronimo, Narayana, Atomikos) treat `XAER_RMFAIL` as retryable on a fresh `XAResource`; the prepared transaction is no longer abandoned. [PR [#4114](https://redirect.github.com/pgjdbc/pgjdbc/issues/4114)]([pgjdbc/pgjdbc#4114](https://redirect.github.com/pgjdbc/pgjdbc/pull/4114))
> * refactor: derive `getPrimaryKeys` from `pg_constraint.conkey` [PR [#4202](https://redirect.github.com/pgjdbc/pgjdbc/issues/4202)]([pgjdbc/pgjdbc#4202](https://redirect.github.com/pgjdbc/pgjdbc/pull/4202))
>
> ### Fixed
>
> * fix: the published GitHub release now ships the released `postgresql-<version>.jar` and its detached PGP signature, taken from the same signed build that is uploaded to Maven Central, instead of a leftover SNAPSHOT jar [Issue [#3812](https://redirect.github.com/pgjdbc/pgjdbc/issues/3812)]([pgjdbc/pgjdbc#3812](https://redirect.github.com/pgjdbc/pgjdbc/issues/3812)) [PR [#3814](https://redirect.github.com/pgjdbc/pgjdbc/issues/3814)]([pgjdbc/pgjdbc#3814](https://redirect.github.com/pgjdbc/pgjdbc/pull/3814))
> * fix: simplify the `Statement#cancel` state machine by dropping the redundant `CANCELLED` state. `killTimerTask` now waits for the state to return to `IDLE` directly, which removes a spin-forever case when more than one thread observes the cancel completing [PR [#1827](https://redirect.github.com/pgjdbc/pgjdbc/issues/1827)]([pgjdbc/pgjdbc#1827](https://redirect.github.com/pgjdbc/pgjdbc/pull/1827)).
> * perf: defer simple-query flushes until the driver reads the response, allowing `BEGIN` and the following query to share a network flush [Issue [#3894](https://redirect.github.com/pgjdbc/pgjdbc/issues/3894)]([pgjdbc/pgjdbc#3894](https://redirect.github.com/pgjdbc/pgjdbc/issues/3894)) [PR [#4196](https://redirect.github.com/pgjdbc/pgjdbc/issues/4196)]([pgjdbc/pgjdbc#4196](https://redirect.github.com/pgjdbc/pgjdbc/pull/4196))
> * fix: `reWriteBatchedInserts` no longer throws `IllegalArgumentException` when batching a parameterless `INSERT` (for example `INSERT INTO t VALUES (1, 2)`) of 256 rows or more [PR [#4207](https://redirect.github.com/pgjdbc/pgjdbc/issues/4207)]([pgjdbc/pgjdbc#4207](https://redirect.github.com/pgjdbc/pgjdbc/pull/4207))
> * fix: a comment before `CALL` in a `CallableStatement` no longer hides the native call, so OUT parameter registration works for `/* comment */ call proc(?, ?)` and similar. `Parser.modifyJdbcCall` now skips leading whitespace and SQL comments (both `--` and `/* */`) before the call, tolerates a trailing comment after a `{ ... }` escape, and no longer adds a spurious comma when moving an OUT parameter into a call whose arguments are only a comment [Issue [#2538](https://redirect.github.com/pgjdbc/pgjdbc/issues/2538)]([pgjdbc/pgjdbc#2538](https://redirect.github.com/pgjdbc/pgjdbc/issues/2538)) [PR [#4209](https://redirect.github.com/pgjdbc/pgjdbc/issues/4209)]([pgjdbc/pgjdbc#4209](https://redirect.github.com/pgjdbc/pgjdbc/pull/4209))
> * fix: `PreparedStatement.toString()` no longer throws for a `bytea` value supplied as text via `PGobject`. Hex-format values (`\x...`) are validated and rendered as a `bytea` literal, and escape-format values are quoted and cast like any other literal [Issue [#3757](https://redirect.github.com/pgjdbc/pgjdbc/issues/3757)]([pgjdbc/pgjdbc#3757](https://redirect.github.com/pgjdbc/pgjdbc/issues/3757)) [PR [#4201](https://redirect.github.com/pgjdbc/pgjdbc/issues/4201)]([pgjdbc/pgjdbc#4201](https://redirect.github.com/pgjdbc/pgjdbc/pull/4201))
> * fix: the driver no longer nulls the `contextClassLoader` of shared `ForkJoinPool.commonPool()` worker threads, which previously left unrelated tasks on those threads running with a `null` classloader [Issue [#4155](https://redirect.github.com/pgjdbc/pgjdbc/issues/4155)]([pgjdbc/pgjdbc#4155](https://redirect.github.com/pgjdbc/pgjdbc/issues/4155)) [PR [#4156](https://redirect.github.com/pgjdbc/pgjdbc/issues/4156)]([pgjdbc/pgjdbc#4156](https://redirect.github.com/pgjdbc/pgjdbc/pull/4156))
> * fix: `PgResultSet#getCharacterStream` wraps `String` in a `StringReader` [PR [#4063](https://redirect.github.com/pgjdbc/pgjdbc/issues/4063)]([pgjdbc/pgjdbc#4063](https://redirect.github.com/pgjdbc/pgjdbc/pull/4063))
> * fix: `PGXAConnection` no longer saves and restores the underlying connection's JDBC `autoCommit` flag. All XA-protocol SQL (`BEGIN`, `PREPARE TRANSACTION`, `COMMIT`, `ROLLBACK`, `COMMIT PREPARED`, `ROLLBACK PREPARED`, the `recover()` SELECT) is sent through `QUERY_SUPPRESS_BEGIN`, so the caller's `autoCommit` value is invariant across every `XAResource` call. Fixes the "2nd phase commit must be issued using an idle connection" failure during recovery on managed datasources that pool connections with `autoCommit=false` (TomEE, WildFly, WebSphere Liberty) [PR [#4114](https://redirect.github.com/pgjdbc/pgjdbc/issues/4114)]([pgjdbc/pgjdbc#4114](https://redirect.github.com/pgjdbc/pgjdbc/pull/4114))
> * fix: `PGXAConnection.prepare()` now mutates XA state only after `PREPARE TRANSACTION` succeeds. A failed `PREPARE` previously left the driver thinking the branch was already prepared, so the follow-up `rollback(xid)` tried `ROLLBACK PREPARED` against a non-existent gid and returned `XAER_RMERR`. Transaction managers (Narayana) escalated this to `HeuristicMixedException`. With the fix, `rollback(xid)` takes the active-branch path and issues a plain `ROLLBACK`, which the server accepts cleanly. Fixes [Issue [#3153](https://redirect.github.com/pgjdbc/pgjdbc/issues/3153)]([pgjdbc/pgjdbc#3153](https://redirect.github.com/pgjdbc/pgjdbc/issues/3153)), [Issue [#3123](https://redirect.github.com/pgjdbc/pgjdbc/issues/3123)]([pgjdbc/pgjdbc#3123](https://redirect.github.com/pgjdbc/pgjdbc/issues/3123)). [PR [#4114](https://redirect.github.com/pgjdbc/pgjdbc/issues/4114)]([pgjdbc/pgjdbc#4114](https://redirect.github.com/pgjdbc/pgjdbc/pull/4114))
> * fix: an updatable result set over an unqualified table name is now classified using only the table visible through `search_path`. When two schemas held a table with the same name and the same primary or unique index name but a different set of key columns, the driver took the union of both schemas' columns, so the result set could be wrongly rejected as not updatable [PR [#4214](https://redirect.github.com/pgjdbc/pgjdbc/issues/4214)]([pgjdbc/pgjdbc#4214](https://redirect.github.com/pgjdbc/pgjdbc/pull/4214)). Supersedes [PR [#3400](https://redirect.github.com/pgjdbc/pgjdbc/issues/3400)]([pgjdbc/pgjdbc#3400](https://redirect.github.com/pgjdbc/pgjdbc/pull/3400)).
> * fix: `LargeObject.close()` now flushes a buffered output stream before marking the object closed, so closing a large object without an explicit `flush()` no longer drops buffered writes. The flush runs while the object is still open (it calls back into `LargeObject.write()`), and `lo_close` always runs afterward; a failure from `lo_close` no longer masks an earlier flush error, and the transaction is not committed when the flush failed [Issue [#4247](https://redirect.github.com/pgjdbc/pgjdbc/issues/4247)]([pgjdbc/pgjdbc#4247](https://redirect.github.com/pgjdbc/pgjdbc/issues/4247)) [PR [#4248](https://redirect.github.com/pgjdbc/pgjdbc/issues/4248)]([pgjdbc/pgjdbc#4248](https://redirect.github.com/pgjdbc/pgjdbc/pull/4248)).
> * fix: reject empty `timestamp`, `timestamptz`, and `date` text with a clear `SQLException` (SQLState `22007`) instead of an `ArrayIndexOutOfBoundsException` [PR [#4278](https://redirect.github.com/pgjdbc/pgjdbc/issues/4278)]([pgjdbc/pgjdbc#4278](https://redirect.github.com/pgjdbc/pgjdbc/pull/4278))
> * fix: return null `CHAR_OCTET_LENGTH` for non-character columns [PR [#4231](https://redirect.github.com/pgjdbc/pgjdbc/issues/4231)]([pgjdbc/pgjdbc#4231](https://redirect.github.com/pgjdbc/pgjdbc/pull/4231))
> * fix: honor scale in `ResultSet.getBigDecimal(int, int)` [PR [#4211](https://redirect.github.com/pgjdbc/pgjdbc/issues/4211)]([pgjdbc/pgjdbc#4211](https://redirect.github.com/pgjdbc/pgjdbc/pull/4211))
> * fix: support `java.time` values in an updatable `ResultSet` `updateRow()` / `insertRow()` [PR [#3848](https://redirect.github.com/pgjdbc/pgjdbc/issues/3848)]([pgjdbc/pgjdbc#3848](https://redirect.github.com/pgjdbc/pgjdbc/pull/3848))
> * fix: improve batching when the `RETURNING` clause contains `varchar` or `numeric` types [PR [#4014](https://redirect.github.com/pgjdbc/pgjdbc/issues/4014)]([pgjdbc/pgjdbc#4014](https://redirect.github.com/pgjdbc/pgjdbc/pull/4014))
> * fix: correct `estimatedReceiveBufferBytes` accounting after a forced `Sync` [PR [#4014](https://redirect.github.com/pgjdbc/pgjdbc/issues/4014)]([pgjdbc/pgjdbc#4014](https://redirect.github.com/pgjdbc/pgjdbc/pull/4014))
> * fix: avoid creating a transient `ResultSet` for describe-statement purposes, and restore the pre-describe path for generated-key batches [PR [#4014](https://redirect.github.com/pgjdbc/pgjdbc/issues/4014)]([pgjdbc/pgjdbc#4014](https://redirect.github.com/pgjdbc/pgjdbc/pull/4014))
> * fix: add an explicit failure message when a multi-statement command executes in a batch [PR [#4014](https://redirect.github.com/pgjdbc/pgjdbc/issues/4014)]([pgjdbc/pgjdbc#4014](https://redirect.github.com/pgjdbc/pgjdbc/pull/4014))
> * fix: detect `search_path` changes case-insensitively [PR [#4216](https://redirect.github.com/pgjdbc/pgjdbc/issues/4216)]([pgjdbc/pgjdbc#4216](https://redirect.github.com/pgjdbc/pgjdbc/pull/4216))
> * fix: auto-detect the SSL key format instead of relying on the `.key` extension [PR [#3946](https://redirect.github.com/pgjdbc/pgjdbc/issues/3946)]([pgjdbc/pgjdbc#3946](https://redirect.github.com/pgjdbc/pgjdbc/pull/3946))
> * fix: build PKIX trust anchors without a `KeyStore` so FIPS JVMs work [PR [#4193](https://redirect.github.com/pgjdbc/pgjdbc/issues/4193)]([pgjdbc/pgjdbc#4193](https://redirect.github.com/pgjdbc/pgjdbc/pull/4193))
> * fix: use `gssResponseTimeout` rather than `sslResponseTimeout` for GSS connections [PR [#4076](https://redirect.github.com/pgjdbc/pgjdbc/issues/4076)]([pgjdbc/pgjdbc#4076](https://redirect.github.com/pgjdbc/pgjdbc/pull/4076))
> * fix: skip the autosave savepoint for `SET LOCAL` / `SET SESSION TRANSACTION` [PR [#4203](https://redirect.github.com/pgjdbc/pgjdbc/issues/4203)]([pgjdbc/pgjdbc#4203](https://redirect.github.com/pgjdbc/pgjdbc/pull/4203))
> * fix: do not throw `AssertionError` from `BatchResultHandler` on a closed connection [PR [#4187](https://redirect.github.com/pgjdbc/pgjdbc/issues/4187)]([pgjdbc/pgjdbc#4187](https://redirect.github.com/pgjdbc/pgjdbc/pull/4187))
> * fix: reject `SQL_TSI_FRAC_SECOND` with an explicit, explained error [PR [#4229](https://redirect.github.com/pgjdbc/pgjdbc/issues/4229)]([pgjdbc/pgjdbc#4229](https://redirect.github.com/pgjdbc/pgjdbc/pull/4229))
> * fix: reject a null URL in `Driver.acceptsURL` with a clear `NullPointerException` [PR [#4205](https://redirect.github.com/pgjdbc/pgjdbc/issues/4205)]([pgjdbc/pgjdbc#4205](https://redirect.github.com/pgjdbc/pgjdbc/pull/4205))
> * fix: reject overlong inputs in `NumberParser.getFastLong` instead of silently wrapping [PR [#4163](https://redirect.github.com/pgjdbc/pgjdbc/issues/4163)]([pgjdbc/pgjdbc#4163](https://redirect.github.com/pgjdbc/pgjdbc/pull/4163))
> * fix: reject out-of-range and NaN values in `PGInterval.setSeconds` [PR [#4194](https://redirect.github.com/pgjdbc/pgjdbc/issues/4194)]([pgjdbc/pgjdbc#4194](https://redirect.github.com/pgjdbc/pgjdbc/pull/4194))
> * fix: close the socket when `PgConnection` setup fails after connect [PR [#4161](https://redirect.github.com/pgjdbc/pgjdbc/issues/4161)]([pgjdbc/pgjdbc#4161](https://redirect.github.com/pgjdbc/pgjdbc/pull/4161))
> * fix: keep the `LazyCleanerImpl` cleanup task alive across a transient empty queue [PR [#4038](https://redirect.github.com/pgjdbc/pgjdbc/issues/4038)]([pgjdbc/pgjdbc#4038](https://redirect.github.com/pgjdbc/pgjdbc/pull/4038))

... (truncated)


Commits

* [`3297557`](pgjdbc/pgjdbc@3297557) docs: add 42.7.13 release changelog ([#4270](https://redirect.github.com/pgjdbc/pgjdbc/issues/4270))
* [`d93d370`](pgjdbc/pgjdbc@d93d370) style: apply Autostyle to docs/ and .github/
* [`2e05ff9`](pgjdbc/pgjdbc@2e05ff9) build: check docs/ and .github/ formatting with Autostyle
* [`b4a6087`](pgjdbc/pgjdbc@b4a6087) Adjust EditorConfig für Makefiles
* [`725cebb`](pgjdbc/pgjdbc@725cebb) fix(jdbc): reject empty timestamp/timestamptz text with a clear error
* [`23a1b0d`](pgjdbc/pgjdbc@23a1b0d) fix(scram): fail closed on channel-binding downgrade (no scram bump)
* [`0b4077a`](pgjdbc/pgjdbc@0b4077a) Bump pgjdbc version from 42.7.12 to 42.7.13 ([#4269](https://redirect.github.com/pgjdbc/pgjdbc/issues/4269))
* [`394800a`](pgjdbc/pgjdbc@394800a) fix: flush LargeObject output stream before marking closed ([#4248](https://redirect.github.com/pgjdbc/pgjdbc/issues/4248))
* [`83780f1`](pgjdbc/pgjdbc@83780f1) Maintain consistency with the use of the word maintainer vs comitter ([#4234](https://redirect.github.com/pgjdbc/pgjdbc/issues/4234))
* [`d42cad5`](pgjdbc/pgjdbc@d42cad5) fix(jdbc): classify updatable result set by search\_path visibility
* Additional commits viewable in [compare view](pgjdbc/pgjdbc@REL42.7.12...REL42.7.13)
  
[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility\_score?dependency-name=org.postgresql:postgresql&package-manager=maven&previous-version=42.7.12&new-version=42.7.13)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
Dependabot commands and options
  
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot show  ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
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.

Consecutive undirected relationship patterns may reuse the same relationship

1 participant