Skip to content

A CHECK constraint that calls regexp_like with a cast argument refuses every row #3333

Description

@mattchristenson

On DoltgreSQL 1.3.1, a table accepts a CHECK constraint such as regexp_like(z::text, '^[0-9]+$'), and
then refuses every row, whether or not the row satisfies the check:

ERROR:  at or near "as": syntax error

PostgreSQL 18.6 stores a row that satisfies the check and refuses one that does not.

Reproduction

repro.sql:

-- A check that calls regexp_like with a cast argument.
CREATE TABLE t (
    z text CHECK (regexp_like(z::text, '^[0-9]+$'))
);

-- A value that satisfies the check.
INSERT INTO t VALUES ('12345');

SELECT z FROM t;

Expected behavior

The row satisfies the check, so it is stored. This is what PostgreSQL 18.6 prints:

-- A check that calls regexp_like with a cast argument.
CREATE TABLE t (
    z text CHECK (regexp_like(z::text, '^[0-9]+$'))
);
CREATE TABLE
-- A value that satisfies the check.
INSERT INTO t VALUES ('12345');
INSERT 0 1
SELECT z FROM t;
   z   
-------
 12345
(1 row)

Actual behavior

The CREATE TABLE succeeds, but the INSERT fails, and the table stays empty. This is what DoltgreSQL
1.3.1 prints:

-- A check that calls regexp_like with a cast argument.
CREATE TABLE t (
    z text CHECK (regexp_like(z::text, '^[0-9]+$'))
);
CREATE TABLE
-- A value that satisfies the check.
INSERT INTO t VALUES ('12345');
psql:/tmp/repro.sql:7: ERROR:  at or near "as": syntax error
SELECT z FROM t;
 z 
---
(0 rows)

Run it

A runnable reproduction is at https://github.com/Reliable-Collaboration/repro-doltgresql-bug-regexp-like-check. Its script runs the test on PostgreSQL and DoltgreSQL in throwaway containers and prints the two outputs side by side:

git clone https://github.com/Reliable-Collaboration/repro-doltgresql-bug-regexp-like-check.git
cd repro-doltgresql-bug-regexp-like-check
./repro.sh

Other observations

Each was run on DoltgreSQL 1.3.1 and on PostgreSQL 18.6. PostgreSQL ran every statement below without an
error, except the rows that break a check, which it refused with a check violation.

  • A row that breaks the check, INSERT INTO t VALUES ('abcde'), gets the same syntax error, not a check
    violation.
  • Added to a table that already holds a row, ALTER TABLE ... ADD CONSTRAINT u_z_check CHECK (regexp_like(z::text, '^[0-9]+$'))
    succeeds, and then INSERT, UPDATE and COPY ... FROM stdin fail with the same error.
  • information_schema.check_constraints shows the test's check stored as
    regexp_like("z"::TEXT as z,'^[0-9]+$'); PostgreSQL shows regexp_like(z, '^[0-9]+$'::text).
  • Other arguments trigger it too: CAST(z AS text), a cast on the pattern only
    (regexp_like(z, '^[0-9]+$'::text)), regexp_like((z)::text, '^[0-9]+$'::text) on a character(5)
    column, and arguments without a cast, lower(z) and z || ''.
  • Other regular expression functions with a cast argument trigger it: regexp_replace(z::text, '[0-9]', '', 'g') = '',
    regexp_substr(z::text, '[0-9]+') = z and regexp_instr(z::text, '[a-z]') = 0.
  • Not triggered: regexp_like(z, '^[0-9]+$'), which accepts '12345' and refuses 'abcde';
    regexp_like(z, '^[0-9]+' || '$'); length(z::text) = 5; upper(z::text) = z; z::text ~ '^[0-9]+$'.
  • Outside a check, the same call works: SELECT z, regexp_like(z::text, '^[0-9]+$') FROM s answers t, and
    a column GENERATED ALWAYS AS (regexp_like(z::text, '^[0-9]+$')) STORED accepts the row.
  • pg_dump 18.6 writes a check declared without any cast, CHECK (regexp_like(z, '^[0-9]+$')), as
    CHECK (regexp_like(z, '^[0-9]+$'::text)), the pattern-cast form above that triggers the error.
  • Possibly related: dolthub/doltgresql#3323, where a
    saved generated-column expression also carries an as alias and fails with the same syntax error.

Possibly related

#3323 (open) shows the same stray as alias in a saved expression, for a generated column.

Environment

  • DoltgreSQL 1.3.1, the newest release when this was written: image dolthub/doltgresql:1.3.1, digest
    sha256:6c85cb1f35beabf47f094336a420255130b841b1645f36d79ef046276af36851. Its bundled psql is 17.11.
  • PostgreSQL 18.6: image postgres:18.6-bookworm, digest
    sha256:1c59e2c3c818eaa0f0628f695b36e7c9e362d6b219b36a54a32df645cbd7e1af. Its psql is 18.6.
  • Reproduced on 2026-09-11 (UTC) with Docker 29.7.2 on Linux x86_64 (Ubuntu 26.04.1 LTS under WSL 2).

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions