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

Typeorm integration fails after 0.2.30

Open zebieksts opened this issue 3 years ago • 4 comments

typeorm introduced this change link to diff after which pg-mem fails to integrate. It seems related to this #58 issue.

    it('can process updated typeorm columns schema selection', () => {
        simpleDb();
	 const sql = `SELECT columns.*,
              pg_catalog.col_description(('"' || table_catalog || '"."' || table_schema || '"."' || table_name || '"')::regclass::oid, ordinal_position) AS description,
              ('"' || "udt_schema" || '"."' || "udt_name" || '"')::"regtype" AS "regtype",
              pg_catalog.format_type("col_attr"."atttypid", "col_attr"."atttypmod") AS "format_type"
              FROM "information_schema"."columns"
              LEFT JOIN "pg_catalog"."pg_attribute" AS "col_attr"
              ON "col_attr"."attname" = "columns"."column_name"
              AND "col_attr"."attrelid" = (
                SELECT
                  "cls"."oid" FROM "pg_catalog"."pg_class" AS "cls"
                  LEFT JOIN "pg_catalog"."pg_namespace" AS "ns"
                  ON "ns"."oid" = "cls"."relnamespace"
                WHERE "cls"."relname" = "columns"."table_name"
                AND "ns"."nspname" = "columns"."table_schema"
              )`;
        expect(many(sql).length)
            .to.equal(4);
        expect(many(sql))
            .to.deep.equal([{ regtype: 'text' }
                , { regtype: 'jsonb' }
                , { regtype: 'integer' }
                , { regtype: 'text' }]);
    });

Error: column "columns.table_name" does not exist

zebieksts avatar Mar 03 '21 22:03 zebieksts

Quite good analysis 😊

Actually, this issue is a duplicate of #61 ... and will be fixed when the underlying cause #38 is fixed.

It requires a non trivial refactoring of how references are resolved in pg-mem, which I did not had the time do carry to its end yet :(

This is not an issue with Typeorm 0.2.29 and lower, if downgrading is an option for you, though.

ps: I'm leaving this issue open for future readers

oguimbal avatar Mar 03 '21 23:03 oguimbal

Hi, is there a workaround we can do? Or perhaps I can help with refactoring given enough context/help. Downgrading typeorm is not an option for us unfortunately :(

bhavitsharma avatar Oct 04 '21 12:10 bhavitsharma

Hi, I currently dont have any tested workaround, but I never looked into one.

That said, this could work:

const db = newDb();

const incriminatedQuery = `SELECT columns.*,
              pg_catalog.col_description(('"' || table_catalog || '"."' || table_schema || '"."' || table_name || '"')::regclass::oid, ordinal_position) AS description,
              ('"' || "udt_schema" || '"."' || "udt_name" || '"')::"regtype" AS "regtype",
              pg_catalog.format_type("col_attr"."atttypid", "col_attr"."atttypmod") AS "format_type"
              FROM "information_schema"."columns"
              LEFT JOIN "pg_catalog"."pg_attribute" AS "col_attr"
              ON "col_attr"."attname" = "columns"."column_name"
              AND "col_attr"."attrelid" = (
                SELECT
                  "cls"."oid" FROM "pg_catalog"."pg_class" AS "cls"
                  LEFT JOIN "pg_catalog"."pg_namespace" AS "ns"
                  ON "ns"."oid" = "cls"."relnamespace"
                WHERE "cls"."relname" = "columns"."table_name"
                AND "ns"."nspname" = "columns"."table_schema"
              )`;

db.public.interceptQueries(text => {
 if (text === incriminatedQuery) {
    return [];
}
 return null;
})

This will intercept the introspection query, which we know for a fact that it will not return anything on a blank database => forcing it to return [] is thus OK.

I did not test it, and the incriminatedQuery is probably wrong (at least the whitespace padding introduced here will be wrong).

Could you test that, tweak the query that fails, and tell me if it works (and repost here the right query if that works for others !)

Thanks :)

oguimbal avatar Oct 04 '21 16:10 oguimbal

https://github.com/oguimbal/pg-mem/issues/81#issuecomment-933654078 The code above works for me except this detail:

if (text === incriminatedQuery) {
    return [];

In my query a dynamic (based on entities) WHERE-clause also generates. So I replaced this place with:

if (text.replace(/[\n ]/g, '').startsWith(incriminatedQuery.replace(/[\n ]/g, ''))) {
    return [];

And now it works. Still waiting for this issue to be resolved though.

jvvvch avatar Nov 02 '21 14:11 jvvvch