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).
On DoltgreSQL 1.3.1, a table accepts a CHECK constraint such as
regexp_like(z::text, '^[0-9]+$'), andthen refuses every row, whether or not the row satisfies the check:
PostgreSQL 18.6 stores a row that satisfies the check and refuses one that does not.
Reproduction
repro.sql:Expected behavior
The row satisfies the check, so it is stored. This is what PostgreSQL 18.6 prints:
Actual behavior
The
CREATE TABLEsucceeds, but theINSERTfails, and the table stays empty. This is what DoltgreSQL1.3.1 prints:
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.shOther 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.
INSERT INTO t VALUES ('abcde'), gets the same syntax error, not a checkviolation.
ALTER TABLE ... ADD CONSTRAINT u_z_check CHECK (regexp_like(z::text, '^[0-9]+$'))succeeds, and then
INSERT,UPDATEandCOPY ... FROM stdinfail with the same error.information_schema.check_constraintsshows the test's check stored asregexp_like("z"::TEXT as z,'^[0-9]+$'); PostgreSQL showsregexp_like(z, '^[0-9]+$'::text).CAST(z AS text), a cast on the pattern only(
regexp_like(z, '^[0-9]+$'::text)),regexp_like((z)::text, '^[0-9]+$'::text)on acharacter(5)column, and arguments without a cast,
lower(z)andz || ''.regexp_replace(z::text, '[0-9]', '', 'g') = '',regexp_substr(z::text, '[0-9]+') = zandregexp_instr(z::text, '[a-z]') = 0.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]+$'.SELECT z, regexp_like(z::text, '^[0-9]+$') FROM sanswerst, anda column
GENERATED ALWAYS AS (regexp_like(z::text, '^[0-9]+$')) STOREDaccepts the row.CHECK (regexp_like(z, '^[0-9]+$')), asCHECK (regexp_like(z, '^[0-9]+$'::text)), the pattern-cast form above that triggers the error.saved generated-column expression also carries an
asalias and fails with the same syntax error.Possibly related
#3323 (open) shows the same stray
asalias in a saved expression, for a generated column.Environment
dolthub/doltgresql:1.3.1, digestsha256:6c85cb1f35beabf47f094336a420255130b841b1645f36d79ef046276af36851. Its bundledpsqlis 17.11.postgres:18.6-bookworm, digestsha256:1c59e2c3c818eaa0f0628f695b36e7c9e362d6b219b36a54a32df645cbd7e1af. Itspsqlis 18.6.