From f4c39bbf3cd90c7540ffff4a0a62fff7cd218bb2 Mon Sep 17 00:00:00 2001 From: Jan Prochazka Date: Sat, 4 Sep 2021 21:54:12 +0200 Subject: [PATCH] cockroach fk analyse fix --- .../__tests__/table-analyse.spec.js | 22 +++++++++++++++++++ integration-tests/engines.js | 2 +- packages/tools/src/SqlDumper.ts | 1 - .../src/backend/Analyser.js | 4 +++- .../src/backend/sql/foreignKeys.js | 2 +- .../src/frontend/drivers.js | 7 ++++++ 6 files changed, 34 insertions(+), 4 deletions(-) diff --git a/integration-tests/__tests__/table-analyse.spec.js b/integration-tests/__tests__/table-analyse.spec.js index bdb4bf32..d954a8b5 100644 --- a/integration-tests/__tests__/table-analyse.spec.js +++ b/integration-tests/__tests__/table-analyse.spec.js @@ -4,6 +4,8 @@ const { testWrapper } = require('../tools'); const t1Sql = 'CREATE TABLE t1 (id int not null primary key, val1 varchar(50) null)'; const ix1Sql = 'CREATE index ix1 ON t1(val1, id)'; const t2Sql = 'CREATE TABLE t2 (id int not null primary key, val2 varchar(50) null unique)'; +const t3Sql = 'CREATE TABLE t3 (id int not null primary key, valfk int, foreign key (valfk) references t2(id))'; +// const fkSql = 'ALTER TABLE t3 ADD FOREIGN KEY (valfk) REFERENCES t2(id)' const txMatch = (tname, vcolname, nextcol) => expect.objectContaining({ @@ -139,4 +141,24 @@ describe('Table analyse', () => { expect(t2.uniques[0].columns[0]).toEqual(expect.objectContaining({ columnName: 'val2' })); }) ); + + test.each(engines.map(engine => [engine.label, engine]))( + 'Foreign key - full analysis - %s', + testWrapper(async (conn, driver, engine) => { + await driver.query(conn, t2Sql); + await driver.query(conn, t3Sql); + // await driver.query(conn, fkSql); + + const structure = await driver.analyseFull(conn); + + const t3 = structure.tables.find(x => x.pureName == 't3'); + console.log('T3', t3.foreignKeys[0].columns); + expect(t3.foreignKeys.length).toEqual(1); + expect(t3.foreignKeys[0].columns.length).toEqual(1); + expect(t3.foreignKeys[0]).toEqual(expect.objectContaining({ refTableName: 't2' })); + expect(t3.foreignKeys[0].columns[0]).toEqual( + expect.objectContaining({ columnName: 'valfk', refColumnName: 'id' }) + ); + }) + ); }); diff --git a/integration-tests/engines.js b/integration-tests/engines.js index 54b299cd..26962699 100644 --- a/integration-tests/engines.js +++ b/integration-tests/engines.js @@ -34,7 +34,7 @@ const engines = [ }, { label: 'PostgreSQL', - skipLocal: true, + // skipLocal: true, connection: { engine: 'postgres@dbgate-plugin-postgres', password: 'Pwd2020Db', diff --git a/packages/tools/src/SqlDumper.ts b/packages/tools/src/SqlDumper.ts index 6ecacf28..acb80a37 100644 --- a/packages/tools/src/SqlDumper.ts +++ b/packages/tools/src/SqlDumper.ts @@ -429,7 +429,6 @@ export class SqlDumper implements AlterProcessor { } createIndex(ix: IndexInfo) { this.put('^create'); - if (ix.indexType) this.put(' %k', ix.indexType); if (ix.isUnique) this.put(' ^unique'); this.put(' ^index %i &n^on %f (&>&n', ix.constraintName, ix); this.putCollection(',&n', ix.columns, col => { diff --git a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js index 3148bde8..54459527 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/Analyser.js +++ b/plugins/dbgate-plugin-postgres/src/backend/Analyser.js @@ -41,7 +41,9 @@ class Analyser extends DatabaseAnalyser { } createQuery(resFileName, typeFields) { - return super.createQuery(sql[resFileName], typeFields); + return super + .createQuery(sql[resFileName], typeFields) + .replace('#REFTABLECOND#', this.driver.__analyserInternals.refTableCond); } async _computeSingleObjectId() { diff --git a/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeys.js b/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeys.js index 1ecd024d..81b96636 100644 --- a/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeys.js +++ b/plugins/dbgate-plugin-postgres/src/backend/sql/foreignKeys.js @@ -12,7 +12,7 @@ select refcol.column_name as "ref_column_name" from information_schema.referential_constraints fk inner join information_schema.table_constraints base on fk.constraint_name = base.constraint_name and fk.constraint_schema = base.constraint_schema -inner join information_schema.table_constraints ref on fk.unique_constraint_name = ref.constraint_name and fk.unique_constraint_schema = ref.constraint_schema +inner join information_schema.table_constraints ref on fk.unique_constraint_name = ref.constraint_name and fk.unique_constraint_schema = ref.constraint_schema #REFTABLECOND# inner join information_schema.key_column_usage basecol on base.table_name = basecol.table_name and base.constraint_name = basecol.constraint_name inner join information_schema.key_column_usage refcol on ref.table_name = refcol.table_name and ref.constraint_name = refcol.constraint_name and basecol.ordinal_position = refcol.ordinal_position where diff --git a/plugins/dbgate-plugin-postgres/src/frontend/drivers.js b/plugins/dbgate-plugin-postgres/src/frontend/drivers.js index 7de58ece..f36a70ad 100644 --- a/plugins/dbgate-plugin-postgres/src/frontend/drivers.js +++ b/plugins/dbgate-plugin-postgres/src/frontend/drivers.js @@ -33,6 +33,10 @@ const postgresDriverBase = { showConnectionField: (field, values) => ['server', 'port', 'user', 'password', 'defaultDatabase', 'singleDatabase'].includes(field), getQuerySplitterOptions: () => postgreSplitterOptions, + + __analyserInternals: { + refTableCond: '', + } }; /** @type {import('dbgate-types').EngineDriver} */ @@ -59,6 +63,9 @@ const cockroachDriver = { dropColumnDependencies: ['primaryKey'], dropPrimaryKey: false, }, + __analyserInternals: { + refTableCond: 'and fk.referenced_table_name = ref.table_name', + } }; /** @type {import('dbgate-types').EngineDriver} */