Skip to content

Feature: add TRY_CONVERT extension - #1872

Open
Alena0704 wants to merge 1 commit into
apache:mainfrom
Alena0704:try_convert-main
Open

Feature: add TRY_CONVERT extension#1872
Alena0704 wants to merge 1 commit into
apache:mainfrom
Alena0704:try_convert-main

Conversation

@Alena0704

@Alena0704 Alena0704 commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Feature: add TRY_CONVERT extension

TRY_CONVERT(source_value, default_value) casts source_value to the type of default_value and returns default_value whenever the cast fails, which is the behaviour of TRY_CAST in SQL Server. Without it a single malformed value makes the whole query fail, and the plpgsql workarounds that catch the error per row are several times slower.

TRY_CONVERT('42'::text, NULL::int2)   -- returns 42::int2
TRY_CONVERT('42d'::text, NULL::int2)  -- returns NULL::int2
TRY_CONVERT('42d'::text, 1234::int2)  -- returns 1234::int2

The conversion to use is resolved the same way the parser resolves an explicit cast in coerce_type(): a pg_cast entry, an I/O conversion or a binary-compatible relabel, followed by the length coercion of the target type. Casts between array types and casts to domain types are not supported and are reported as query errors, the same as a cast that does not exist at all; only a failure caused by the converted data is turned into the default value.

The cast itself runs inside a PG_TRY() block, since the datatype input functions of Cloudberry cannot yet report a conversion failure without throwing.

The extension is marked trusted, so the owner of a database can install it without being a superuser.

Co-authored-by: Vladimir Rachkin vova@kpnn.ru
See: PR#901 #901

Fixes #ISSUE_Number

What does this PR do?

Type of Change

  • Bug fix (non-breaking change)
  • New feature (non-breaking change)
  • Breaking change (fix or feature with breaking changes)
  • Documentation update

Breaking Changes

Test Plan

  • Unit tests added/updated
  • Integration tests added/updated
  • Passed make installcheck
  • Passed make -C src/test installcheck-cbdb-parallel

Impact

Performance:

User-facing changes:

Dependencies:

Checklist

Additional Context

CI Skip Instructions


@Alena0704 Alena0704 mentioned this pull request Jul 30, 2026
12 tasks
@Alena0704

Copy link
Copy Markdown
Contributor Author

The initial PR for this feature was #901 but I didn't have push access to the original fork, and the head branch of an existing PR couldn't be changed, so instead of updating this one I opened a separate PR #1872 with the rebased version.

All credit for the extension goes to @robozmey - the commit lists him as a co-author.

On top of the rebase I addressed the open review comments, pulled in the follow-up fixes the extension got in open-gpdb since this PR was opened, added the module to the ic-contrib CI matrix (nothing was running its tests before), and marked the extension trusted so that a non-superuser with CREATE privilege on the database can install it.

@leborchuk leborchuk 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.

LGTM, we want to add it to Cloudberry

@my-ship-it my-ship-it 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.

LGTM. Thanks for the contribution.

TRY_CONVERT(source_value, default_value) casts source_value to the type
of default_value and returns default_value whenever the cast fails,
which is the behaviour of TRY_CAST in SQL Server.  Without it a single
malformed value makes the whole query fail, and the plpgsql workarounds
that catch the error per row are several times slower.

    TRY_CONVERT('42'::text, NULL::int2)   -- returns 42::int2
    TRY_CONVERT('42d'::text, NULL::int2)  -- returns NULL::int2
    TRY_CONVERT('42d'::text, 1234::int2)  -- returns 1234::int2

The conversion to use is resolved the same way the parser resolves an
explicit cast in coerce_type(): a pg_cast entry, an I/O conversion or a
binary-compatible relabel, followed by the length coercion of the
target type.  Casts between array types and casts to domain types are
not supported and are reported as query errors, the same as a cast that
does not exist at all; only a failure caused by the converted data is
turned into the default value.

The cast itself runs inside a PG_TRY() block, since the datatype input
functions of Cloudberry cannot yet report a conversion failure without
throwing.

The extension is marked trusted, so the owner of a database can install
it without being a superuser.

Co-authored-by: Vladimir Rachkin <vova@kpnn.ru>
See: PR#901 <apache#901>
@tuhaihe
tuhaihe force-pushed the try_convert-main branch from ac07b4e to 9e88271 Compare July 31, 2026 03:51
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.

3 participants