Skip to content

Fixed Issue #3325 - #3349

Open
Hydrocharged wants to merge 1 commit into
daylon/more-fixes-2from
daylon/more-fixes-3
Open

Hydrocharged wants to merge 1 commit into
daylon/more-fixes-2from
daylon/more-fixes-3

Conversation

@Hydrocharged

@Hydrocharged Hydrocharged commented Sep 11, 2026

Copy link
Copy Markdown
Collaborator

Fixes #3325.

Stacked on #3348.

@Hydrocharged
Hydrocharged added this pull request to stack #3358 September 11, 2026 23:07
@Hydrocharged
Hydrocharged requested a review from zachmu September 11, 2026 23:09
@itoqa

itoqa Bot commented Sep 11, 2026

Copy link
Copy Markdown

Ito QA test results
Commit: 6ad7bee: 13 test cases ran, 13 passed ✅.

Summary

Coverage spans fixed-width character handling across comparisons, ordering, casting, formatting, joins, grouping, indexing, uniqueness, concurrency, and null safety, along with contrasting variable-length text behavior. It exercises normal flows, boundary cases involving padding and meaningful spaces, and adversarial cases such as concurrent inserts and null inputs, with healthy results throughout.

Safe to merge — the run found no regressions, new failures, or previously flagged failures attributable to this PR, and the broad behavior coverage passed. No merge-blocking risk was identified.

Tests run by Ito

View full run

Result Severity Type Description
General Empty, single-space, and repeated-space endings compare as equal, while values with different non-space content remain distinct and ordered correctly.
General Rows that differ only by trailing spaces are treated as one key in equality checks, DISTINCT, grouping, window partitions, and indexed lookups, while the different B key stays separate.
General Rows filtered through the CHAR column and rows grouped through cast-derived text keys stayed aligned. Leading spaces and the meaningful X suffix were preserved.
General Two sessions tried to insert keys that differ only by trailing spaces. One insert committed, the other was rejected, and later lookups found one matching row in both completion orders.
Cast Casting a fixed-width CHAR value to text, varchar, and name returned L with no trailing space. Each result had length 1.
Cast Casting a value with a leading space kept that space in TEXT, VARCHAR, and NAME results while removing only the trailing padding spaces.
Compare CHAR values with the same letters compare equal even when one has trailing spaces, while different letters remain unequal.
Compare The value L sorts before R, and the comparison function returns a negative result as expected.
Output A CHAR value keeps its fixed-width display, reports its logical length, and becomes an unpadded text value when converted.
Output CHAR(2) returns AB at its full width, pads the shorter value A to two characters, and leaves unbounded CHAR output as A.
Rev Casting a NULL CHAR value to text, varchar, and name returned NULL. Comparing it with another CHAR value and calling the comparison function also returned NULL without an error.
Rev CHAR values that differ only by trailing spaces joined as the same key. The equality filter kept only A, excluded C, and the ordered results returned A before B.
String Text and varchar values that differ only by a trailing space remain different, and the unpadded value sorts first.

Tip

Reply with @itoqa to send us feedback on this test run.

@github-actions

Copy link
Copy Markdown
Contributor
Main PR
Total 42090 42090
Successful 19854 19856
Failures 22236 22234
Partial Successes1 5440 5440
Main PR
Successful 47.1703% 47.1751%
Failures 52.8297% 52.8249%

${\color{lightgreen}Progressions (2)}$

constraints

QUERY: SELECT * FROM DEFAULTEXPR_TBL;

subselect

QUERY: select count(*) from tenk1 t
where (exists(select 1 from tenk1 k where k.unique1 = t.unique2) or ten < 0);

Footnotes

  1. These are tests that we're marking as Successful, however they do not match the expected output in some way. This is due to small differences, such as different wording on the error messages, or the column names being incorrect while the data itself is correct.

@coffeegoddd

Copy link
Copy Markdown
Contributor

@Hydrocharged DOLT

read_tests from_latency to_latency percent_change
covering_index_scan_postgres 2.43 2.43 0.0
groupby_scan_postgres 80.03 78.6 -1.79
index_join_postgres 2.22 2.22 0.0
index_join_scan_postgres 1.61 1.61 0.0
index_scan_postgres 467.3 467.3 0.0
oltp_point_select 0.37 0.37 0.0
oltp_read_only 6.32 6.43 1.74
select_random_points 0.72 0.72 0.0
select_random_ranges 1.03 1.04 0.97
table_scan_postgres 467.3 475.79 1.82
types_table_scan_postgres 1170.65 1170.65 0.0
write_tests from_latency to_latency percent_change
oltp_delete_insert_postgres 6.67 6.67 0.0
oltp_insert 3.36 3.36 0.0
oltp_read_write 13.46 13.46 0.0
oltp_update_index 3.55 3.55 0.0
oltp_update_non_index 3.25 3.25 0.0
oltp_write_only 7.04 7.04 0.0
types_delete_insert_postgres 7.17 7.17 0.0

@zachmu zachmu left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Mostly looks good, but confirm how postgres handles other non-space whitespace characters for these cases and add tests for them.

Comment thread server/cast/char.go
if err != nil {
return nil, err
}
return strings.TrimRight(str, " "), nil

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this the right character set to trim? What about other whitespace chars like tabs and newlines?

Comment thread testing/go/issues_test.go
Name: "Issue #3325: trailing spaces of a bpchar value are ignored",
SetUpScript: []string{
"CREATE TABLE t3325 (id INT PRIMARY KEY, c CHAR(2) CHECK (c::text IN ('L', 'R')));",
"INSERT INTO t3325 VALUES (1, 'L'), (2, 'R ');",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This should be an assertion, not part of the setup

Comment thread testing/go/issues_test.go
},
Assertions: []ScriptTestAssertion{
{
Query: "SELECT '[' || 'L'::CHAR(2) || ']', length('L'::CHAR(2)), 'L'::CHAR(2) = 'L', 'L '::CHAR(2) = 'L'::CHAR(2), 'L'::CHAR(2)::TEXT = 'L', 'L'::CHAR(2)::VARCHAR = 'L', bpcharcmp('L'::CHAR(2), 'L ');",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is a good test, but we should also have a test case which is an exact match of the queries in the original issue. This is close but misses some, e.g. it doesn't directly select 'L '::character(2), it only tests it for equality.

Comment thread server/types/type.go
case string:
bb := v2.(string)
if t.ID == BpChar.ID {
ab = strings.TrimRight(ab, " ")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same comment about other whitespace chars. What does postgres do?

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.

Casting a character(n) value to text keeps its trailing spaces, so comparisons and CHECK constraints fail

3 participants