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

Getting an issue for enums with sequelize

Open rehanmunir opened this issue 8 months ago • 1 comments

Bug

Executing the following SQL statement in pg-mem results in an error:

ALTER TABLE public.users REPLICA IDENTITY FULL;
Error: Cannot find token from: "REPLICA"

This works perfectly on an actual PostgreSQL database.
It seems pg-mem does not currently support the REPLICA IDENTITY clause in ALTER TABLE.

(pg-mem tries to throw nice error messages when possible... so paste it here if you have one !)

To Reproduce

CREATE TABLE public.users (
  id SERIAL PRIMARY KEY,
  name TEXT NOT NULL
);

ALTER TABLE public.users REPLICA IDENTITY FULL;
"If possible, paste here (including create table statements) a query that fails on https://oguimbal.github.io/pg-mem-playground/, but suceeds when ran on an actual PG database"

pg-mem version

"version": "3.0.5",
  "description": "A memory version of postgres",
    "release-deno": "git add -A && git commit -m \"Build deno [autogenerated commit]\" && PACKAGE_VERSION=$(cat package.json | grep \\\"version\\\" | head -1 | awk -F: '{ print $2 }' | sed 's/[\",]//g' | tr -d '[[:space:]]') && git tag $PACKAGE_VERSION && git push --tags",

For more details

console.error
    Unable to connect to the database: Error: 
        at Query.run (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query.js:76:25)
        at /home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/sequelize.js:650:28
        at async Promise.all (index 0)
        at PostgresQueryInterface.ensureEnums (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query-interface.js:47:21)
        at PostgresQueryInterface.createTable (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/abstract/query-interface.js:210:5)
        at Function.sync (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/model.js:1353:7)
        at Sequelize.sync (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/sequelize.js:825:9)
        at Object.<anonymous> (/home/bilal/Projects/rentsolution-backend/tests/_shared/testSetup.js:35:3) {
      name: 'SequelizeDatabaseError',
      parent: TypeError: Cannot read properties of null (reading 'Symbol()')
      
      💥 This is a nasty error, which was unexpected by pg-mem. Also known "a bug" 😁 Please file an issue !
      
      *️⃣ Failed SQL statement: SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = 'public' AND t.typname='enum_users_userType' GROUP BY 1;
      
      👉 You can file an issue at https://github.com/oguimbal/pg-mem along with a way to reproduce this error (if you can), and  the stacktrace:
      
      
          at Evaluator.val (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/aggregation.ts:114:25)
          at new Evaluator (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/evaluator.ts:93:33)
          at new Aggregation (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/aggregation.ts:108:46)
          at Object.buildGroupBy (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/aggregation.ts:40:17)
          at AndFilter.groupBy (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/transform-base.ts:96:26)
          at buildRawSelect (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:186:19)
          at buildSelect (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:54:20)
          at buildWithable (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:34:20)
          at new SelectExec (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:269:67)
          at StatementExec._getExecutor (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:83:24)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:185:52
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:184:40
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:183:36
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:182:29
          at StatementExec.niceErrors (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:226:20)
          at StatementExec.compile (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:158:21)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/prepared.ts:176:64
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at new PreparedQuery (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/prepared.ts:176:44)
          at prepareQuery (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/prepared.ts:95:11)
          at DbSchema.prepare (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/schema.ts:90:37)
          at DbSchema.query (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/schema.ts:63:21)
          at MemPg.query (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/adapters/adapters.ts:89:76)
          at query (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query.js:71:53)
          at new Promise (<anonymous>)
          at Query.run (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query.js:71:9)
          at /home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/sequelize.js:650:28
          at async Promise.all (index 0)
          at PostgresQueryInterface.ensureEnums (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query-interface.js:47:21)
          at PostgresQueryInterface.createTable (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/abstract/query-interface.js:210:5)
          at Function.sync (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/model.js:1353:7)
          at Sequelize.sync (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/sequelize.js:825:9)
          at Object.<anonymous> (/home/bilal/Projects/rentsolution-backend/tests/_shared/testSetup.js:35:3) {
        location: { start: 0, end: 0 },
        sql: "SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = 'public' AND t.typname='enum_users_userType' GROUP BY 1",
        parameters: undefined,
        [Symbol(errorDetailsIncluded)]: true
      },
      original: TypeError: Cannot read properties of null (reading 'Symbol()')
      
      💥 This is a nasty error, which was unexpected by pg-mem. Also known "a bug" 😁 Please file an issue !
      
      *️⃣ Failed SQL statement: SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = 'public' AND t.typname='enum_users_userType' GROUP BY 1;
      
      👉 You can file an issue at https://github.com/oguimbal/pg-mem along with a way to reproduce this error (if you can), and  the stacktrace:
      
      
          at Evaluator.val (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/aggregation.ts:114:25)
          at new Evaluator (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/evaluator.ts:93:33)
          at new Aggregation (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/aggregation.ts:108:46)
          at Object.buildGroupBy (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/aggregation.ts:40:17)
          at AndFilter.groupBy (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/transforms/transform-base.ts:96:26)
          at buildRawSelect (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:186:19)
          at buildSelect (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:54:20)
          at buildWithable (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:34:20)
          at new SelectExec (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/select.ts:269:67)
          at StatementExec._getExecutor (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:83:24)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:185:52
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:184:40
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:183:36
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:182:29
          at StatementExec.niceErrors (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:226:20)
          at StatementExec.compile (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/execution/statement-exec.ts:158:21)
          at /home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/prepared.ts:176:64
          at StackOf.usingValue (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/parser/context.ts:11:20)
          at new PreparedQuery (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/prepared.ts:176:44)
          at prepareQuery (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/prepared.ts:95:11)
          at DbSchema.prepare (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/schema.ts:90:37)
          at DbSchema.query (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/schema/schema.ts:63:21)
          at MemPg.query (/home/bilal/Projects/rentsolution-backend/node_modules/pg-mem/src/adapters/adapters.ts:89:76)
          at query (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query.js:71:53)
          at new Promise (<anonymous>)
          at Query.run (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query.js:71:9)
          at /home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/sequelize.js:650:28
          at async Promise.all (index 0)
          at PostgresQueryInterface.ensureEnums (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/postgres/query-interface.js:47:21)
          at PostgresQueryInterface.createTable (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/dialects/abstract/query-interface.js:210:5)
          at Function.sync (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/model.js:1353:7)
          at Sequelize.sync (/home/bilal/Projects/rentsolution-backend/node_modules/sequelize/src/sequelize.js:825:9)
          at Object.<anonymous> (/home/bilal/Projects/rentsolution-backend/tests/_shared/testSetup.js:35:3) {
        location: { start: 0, end: 0 },
        sql: "SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = 'public' AND t.typname='enum_users_userType' GROUP BY 1",
        parameters: undefined,
        [Symbol(errorDetailsIncluded)]: true
      },
      sql: "SELECT t.typname enum_name, array_agg(e.enumlabel ORDER BY enumsortorder) enum_value FROM pg_type t JOIN pg_enum e ON t.oid = e.enumtypid JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace WHERE n.nspname = 'public' AND t.typname='enum_users_userType' GROUP BY 1",
      parameters: {}
    }

rehanmunir avatar Apr 22 '25 22:04 rehanmunir

For those having the same issue, try adding this to your jest.setup.js file in the function beforeAll()...

WARNING: UGLY PATCH

beforeAll(function() {
    // Patch pg-mem to handle enum introspection queries that cause failures
    const originalQuery = sequelize.query.bind(sequelize);
    sequelize.query = function (sql, options) {
      // Check for any enum-related query that pg-mem can't handle
      if (
        typeof sql === "string" &&
        (sql.includes("pg_enum") ||
          sql.includes("enum_") ||
          sql.includes("SELECT t.typname enum_name"))
      ) {
        // Return empty result for enum introspection queries that pg-mem can't handle
        return Promise.resolve([[], { fields: [] }]);
      }
      // For all other queries, use the original query method
      return originalQuery(sql, options);
    };

    // Also patch the QueryInterface.ensureEnums method to bypass enum handling entirely
    const QueryInterface = sequelize.getQueryInterface();
    const _originalEnsureEnums = QueryInterface.ensureEnums;
    QueryInterface.ensureEnums = function () {
      // Return immediately without doing enum processing
      return Promise.resolve();
    };
}

ps: This "patch" was generated by Claude 4 using Claude Code.

roychri avatar Jul 24 '25 13:07 roychri