Visitar URL original
tursopg: parse the text in a cast to uuid by gaurav0107 · Pull Request #11600 · tursodatabase/turso · GitHub
Skip to content

tursopg: parse the text in a cast to uuid - #11600

Open
gaurav0107 wants to merge 1 commit into
tursodatabase:mainfrom
gaurav0107:fix/11475-in-tursopg-a-cast-to-uuid-keeps-uppercas
Open

gaurav0107 wants to merge 1 commit into
tursodatabase:mainfrom
gaurav0107:fix/11475-in-tursopg-a-cast-to-uuid-keeps-uppercas

Conversation

@gaurav0107

Copy link
Copy Markdown
Contributor

Problem

In tursopg, a cast to uuid keeps the text as written. 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11'::uuid = 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid is false, CAST('{A0EE...}' AS uuid) prints the braces and the uppercase letters, and 'hello'::uuid gives hello. An IN (SELECT ...::uuid ...) on an indexed uuid column counts the same row once for each spelling.

The PostgreSQL translator turned a cast to uuid into CAST(x AS TEXT).

Fix

A cast to uuid now goes to the built-in uuid type, which is what a uuid column already uses. Its ENCODE (uuid_blob) reads every spelling PostgreSQL accepts (any case, braces, no hyphens) and rejects text that is not a UUID, and its DECODE writes the value in lowercase with hyphens. date, time and timestamp casts already work this way in the same match.

The same mapping is used for the column list of json_to_record and jsonb_to_record, so a uuid column there is now parsed too, as in PostgreSQL.

Not the same as PostgreSQL: text that is not a UUID fails with invalid UUID value and not with PostgreSQL's message and SQLSTATE 22P02.

Tests

Added cases to pg-sqltests/select.sqltest for casting the uppercase, braced and no-hyphen forms, for an IN subquery of casts on an indexed uuid column, and for text that is not a UUID. They fail on main and pass with this change.

Fixes #11475


🤖 Opened with Superhuman, an open-source contribution agent.

A cast to uuid was translated to CAST(x AS TEXT), so the text was kept as
written. 'A0EE...'::uuid did not equal 'a0ee...'::uuid, a braced UUID
printed with its braces, text that is not a UUID was accepted, and an
IN (SELECT ...::uuid) on an indexed uuid column found the same row once
per spelling.

The cast now goes to the built-in uuid type, as a uuid column already
does. Its ENCODE parses every spelling PostgreSQL accepts and its DECODE
writes the value in lowercase with hyphens. A uuid column in the column
list of json_to_record now gets the same parsing.

Fixes tursodatabase#11475
@gaurav0107
gaurav0107 marked this pull request as ready for review November 8, 2026 18:31
@gaurav0107
gaurav0107 requested a review from penberg as a code owner November 8, 2026 18:32
@turso-github-handyman turso-github-handyman Bot added the autofixer: auto-review Autofixer reviews this outside contributor's PR unasked. Add autofixer: no-review to stop it label Nov 8, 2026
@turso-github-handyman

turso-github-handyman Bot commented Nov 8, 2026 •

Copy link
Copy Markdown

Autofixer review

🔄 Autofixer updates this comment while the review runs.

Autofixer reviews pull requests from outside contributors on its own. The review of 904f27205321 is here.

✅ Verdict: looks good to merge.

Automated review by Autofixer; maintainers decide what to merge. Autofixer started this review on its own, as it does for pull requests from outside contributors. Push a fix to get a re-review (up to 3 reviews in all); a pull request whose blocking findings stay unaddressed for 7 days is closed. Maintainers: add autofixer: no-review to stop these reviews, or autofixer: review-requested to review it as requested.

@turso-github-handyman turso-github-handyman 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.

Autofixer review of 904f27205321

What this pull request does: SELECT 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11'::uuid returned the text unchanged on main, so differently written equal UUIDs compared unequal; now it returns a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 like PostgreSQL, and 'hello'::uuid is an error.

✅ Verdict: looks good to merge.
What to do: nothing to fix; a maintainer decides whether to merge.

What the review found: No blocking problems. The description says every PostgreSQL spelling is accepted, but '{a0eebc999c0b4ef8bb6d6bb9bd380a11}'::uuid is rejected. The uuid parser shared with uuid columns also accepts urn:uuid: text that PostgreSQL rejects.


Not blocking

1 minor finding
  • Minor Description says ENCODE reads every PostgreSQL spelling; '{a0eebc999c0b4ef8bb6d6bb9bd380a11}'::uuid fails with invalid UUID value, PostgreSQL accepts it
    Suggested fix: Say that braces without hyphens and hyphens after any 4-digit group are rejected, and urn:uuid: text is accepted, unlike PostgreSQL
Also wrong on main: 3 inputs this pull request doesn't fix

main gets these wrong too, so this change did not cause them.

1. Casting a valid UUID with a hyphen after any 4 digits, or braces with no hyphens, to uuid fails

Every text cast to uuid (and every insert into a uuid column) that PostgreSQL accepts but the uuid crate's Uuid::parse_str rejects fails with 'invalid UUID value': braces around 32 plain hex digits, and hyphens after any group of 4 hex digits other than the standard 8-4-4-4-12 places. The reverse case also fails: 'urn:uuid:<uuid>' is accepted, but PostgreSQL rejects it.

Input:

SELECT '{a0eebc999c0b4ef8bb6d6bb9bd380a11}'::uuid;
SELECT 'a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11'::uuid;
SELECT 'urn:uuid:a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid;

This PR:

ERROR: invalid UUID value / ERROR: invalid UUID value / a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11

main:

{a0eebc999c0b4ef8bb6d6bb9bd380a11} / a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11 / urn:uuid:a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 (text returned unchanged)

PostgreSQL:

a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 / a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11 / ERROR: invalid input syntax for type uuid: "urn:uuid:a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11"

2. An invalid text cast to uuid fails with SQLSTATE P0001 instead of 22P02

This PR main PostgreSQL
ERROR: P0001: invalid UUID value bogus (no error) ERROR: 22P02: invalid input syntax for type uuid: "bogus"

Every text cast to uuid that does not parse fails with SQLSTATE P0001 (raise_exception) and the message 'invalid UUID value'. PostgreSQL gives 22P02 and 'invalid input syntax for type uuid: "..."'. Inserting bad text into a uuid column gives the same wrong SQLSTATE.

Input:

\set VERBOSITY verbose
SELECT 'bogus'::uuid;

3. Casting bytea, integer, numeric or boolean to uuid is accepted or gives the wrong error

This PR main PostgreSQL
30313233-3435-3637-3839-616263646566 / ERROR: invalid UUID value 0123456789abcdef / 123 ERROR: cannot cast type bytea to uuid / ERROR: cannot cast type integer to uuid

Every cast to uuid from a type other than text or uuid (bytea, integer, numeric, boolean) should fail with 'cannot cast type X to uuid' (SQLSTATE 42846). Instead, bytea of exactly 16 bytes becomes a uuid, and the other types fail with 'invalid UUID value'.

Input:

SELECT '0123456789abcdef'::bytea::uuid;
SELECT 123::uuid;
3 other problems found outside this change
  • tursopg uuid input rejects some spellings PostgreSQL accepts and accepts urn:uuid: text: CREATE TABLE t(u uuid); INSERT INTO t VALUES ('{a0eebc999c0b4ef8bb6d6bb9bd380a11}'); INSERT INTO t VALUES ('a0ee-bc99-9c0b4ef8-bb6d-6bb9bd380a11'); INSERT INTO t VALUES ('urn:uuid:a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'); SELECT u FROM t;
  • tursopg: comparing a uuid or date column with a differently written string literal finds no rows: CREATE TABLE d(x date, u uuid); INSERT INTO d VALUES ('2024-01-05', 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'); SELECT count(*) FROM d WHERE x = '2024-1-5'; SELECT count(*) FROM d WHERE u = 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11';
  • Casting a uuid to bytea or integer is accepted instead of failing: SELECT 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid::int; SELECT 'A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11'::uuid::bytea;
Other checks: 4 refuted, 2 are findings
  1. Refuted: postgres/parser/translator.rs:6527: Column path may differ: inserting uppercase or braced text into a uuid column may not normalize it
    → INSERT of uppercase and braced text into a uuid column reads back lowercase with hyphens on main and on this pull request, as in PostgreSQL timeout 60 $b -q :memory: < /tmp/q2.sql
  2. Refuted: postgres/parser/translator.rs:6527: The bare name "uuid" must match the core built-in type name
    → Same literal is used by the column mapping (translator.rs:6096) and for date/time in the same match; core registers CREATE TYPE uuid; new sqltests fail if the name is wrong timeout 1500 make -C postgres/conformance run-one FILE=pg-sqltests/select.sqltest
  3. Refuted: postgres/conformance/pg-sqltests/select.sqltest:333: New tests may not pass on real PostgreSQL
    → All three uuid tests pass against PostgreSQL 18; the one failure in the file is an unrelated LIKE test timeout 900 cargo run -q --manifest-path ../../testing/sqltest/Cargo.toml --bin sqltest -- run pg-sqltests/select.sqltest --backend postgres --postgres-dsn "$PG_DSN"
  4. Refuted: postgres/parser/translator.rs:6527: json_to_record also uses this mapping; behavior change there
    → json_to_record(...) AS x(a uuid) now returns lowercase like PostgreSQL; main returned the uppercase text timeout 60 $b -q :memory: < /tmp/q2.sql

Automated review by Autofixer; maintainers decide what to merge. Autofixer started this review on its own, as it does for pull requests from outside contributors. Push a fix to get a re-review (up to 3 reviews in all); a pull request whose blocking findings stay unaddressed for 7 days is closed. Maintainers: add autofixer: no-review to stop these reviews, or autofixer: review-requested to review it as requested.

@turso-github-handyman turso-github-handyman Bot added autofixer: follow-ups-recommended Autofixer found other bugs while reviewing this PR. It files them as issues when this PR merges autofixer: merge-recommended Autofixer reviewed this PR and recommends merging it as is and removed autofixer: merge-recommended Autofixer reviewed this PR and recommends merging it as is labels Nov 8, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofixer: auto-review Autofixer reviews this outside contributor's PR unasked. Add autofixer: no-review to stop it autofixer: follow-ups-recommended Autofixer found other bugs while reviewing this PR. It files them as issues when this PR merges autofixer: merge-recommended Autofixer reviewed this PR and recommends merging it as is

Projects

None yet

Development

Successfully merging this pull request may close these issues.

In tursopg, a cast to uuid keeps uppercase or braced text

1 participant