A CHECK constraint that calls regexp_like with a cast argument refuses every row
- Dominant language
- Go
- Stars
- 2.1k
- Forks
- 73
- Avg merge
- 1d 10h
- Merged PRs (30d)
- 129
Description
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`](https://github.com/Reliable-Collaboration/repro-doltgresql-bug-regexp-like-check/blob/main/repro.sql):
```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:
```sh
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](https://github.com/dolthub/doltgresql/issues/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).
Contributor guide
Assessment
This issue has not been assessed yet.