pg-mem icon indicating copy to clipboard operation
pg-mem copied to clipboard

Doesn't work with regex rules in check constraints

Open rswheeldon opened this issue 3 years ago • 1 comments

Describe the bug

I have a number of tables with regex-based check constraints to prevent garbage from being put into the DB. Unfortunately, pg-mem doesn't seem to like them.

To Reproduce

Simplified variations on the theme include:

drop table if exists foo;
create table foo (
    greeting varchar(20) not null check (greeting ~ '^Hello .+$')
);

which works in postgres 14.1 but fails in pg-mem with the error:

    operator does not exist: character varying ~ text
...
      at buildBinaryValue (node_modules/pg-mem/src/parser/expression-builder.ts:401:23)
      at buildBinary (node_modules/pg-mem/src/parser/expression-builder.ts:253:12)
      at _buildValueReal (node_modules/pg-mem/src/parser/expression-builder.ts:71:20)
      at _buildValue (node_modules/pg-mem/src/parser/expression-builder.ts:51:11)
      at buildValue (node_modules/pg-mem/src/parser/expression-builder.ts:20:17)
      at node_modules/pg-mem/src/table.ts:531:70
      at StackOf.usingValue (node_modules/pg-mem/src/parser/context.ts:11:20)
      at MemoryTable.addCheck (node_modules/pg-mem/src/table.ts:531:37)
      at ColRef.addConstraints (node_modules/pg-mem/src/column.ts:63:32)
      at MemoryTable.addColumn (node_modules/pg-mem/src/table.ts:199:22)

Thinking this might be a type mismatch prob, I tried:

drop table if exists foo;
create table foo (
    greeting text not null check (greeting ~ '^Hello .+$')
);

which failed with the similar looking error:

    operator does not exist: text ~ text

at the same place.

Trying the case insensitive version:

drop table if exists foo;
create table foo (
    greeting text not null check (greeting ~* '^Hello .+$')
);

produces a different error:

    💀 Syntax error at line 3 col 45:

          greeting text not null check (greeting ~*
                                                  ^
    Unexpected star token: "*". Instead, I was expecting to see one of the following:

        - A "lparen" token
        - A "word" token
<snip lots of ops>
...
      at parseSql (node_modules/pg-mem/src/parser/parse-cache.ts:55:15)
      at DbSchema.parse (node_modules/pg-mem/src/schema/schema.ts:93:28)
      at DbSchema.queries (node_modules/pg-mem/src/schema/schema.ts:103:31)
          at queries.next (<anonymous>)
      at DbSchema.query (node_modules/pg-mem/src/schema/schema.ts:79:20)
      at MemPg.query (node_modules/pg-mem/src/adapters/adapters.ts:100:76)
      at query (src/utils/TestUtils.js:10:14)
      at tryCatch (node_modules/@babel/runtime-corejs2/helpers/regeneratorRuntime.js:99:17)
      at Generator._invoke (node_modules/@babel/runtime-corejs2/helpers/regeneratorRuntime.js:79:24)
      at Generator.next (node_modules/@babel/runtime-corejs2/helpers/regeneratorRuntime.js:131:21)

pg-mem version

2.6.3

rswheeldon avatar Jul 21 '22 07:07 rswheeldon

Not sure if this is a useful comment (can delete if not) but I'm finding this still happening in pg-mem version 3.0.5

samihan-m avatar Jul 05 '25 23:07 samihan-m