postgres analyser fixed - broken loading FKs in incremental analysis

This commit is contained in:
Jan Prochazka
2025-11-28 10:24:53 +01:00
parent 0913011120
commit 65d13189b3
5 changed files with 104 additions and 44 deletions

View File

@@ -99,55 +99,60 @@ class Analyser extends DatabaseAnalyser {
this.feedback({ analysingMessage: 'DBGM-00244 Loading foreign key constraints' });
// const fk_tableConstraints = await this.analyserQuery('fk_tableConstraints', ['tables']);
this.feedback({ analysingMessage: 'DBGM-00245 Loading foreign key refs' });
const foreignKeys = await this.analyserQuery('foreignKeys', ['tables']);
if (this.objectIdConditionApplied(['tables'])) {
this.feedback({ analysingMessage: 'DBGM-00000 Loading foreign key refs' });
fkColumns = await this.analyserQuery('foreignKeyColumns', ['tables']);
} else {
this.feedback({ analysingMessage: 'DBGM-00245 Loading foreign key refs' });
const foreignKeys = await this.analyserQuery('foreignKeys', ['tables']);
this.feedback({ analysingMessage: 'DBGM-00246 Loading foreign key columns' });
const fk_keyColumnUsage = await this.analyserQuery('fk_keyColumnUsage', ['tables']);
this.feedback({ analysingMessage: 'DBGM-00246 Loading foreign key columns' });
const fk_keyColumnUsage = await this.analyserQuery('fk_keyColumnUsage', ['tables']);
// const cntKey = x => `${x.constraint_name}|${x.constraint_schema}`;
const fkRows = [];
// const fkConstraintDct = _.keyBy(fk_tableConstraints.rows, cntKey);
for (const fkRef of foreignKeys.rows) {
// const cntBase = fkConstraintDct[cntKey(fkRef)];
// const cntRef = fkConstraintDct[`${fkRef.unique_constraint_name}|${fkRef.unique_constraint_schema}`];
// if (!cntBase || !cntRef) continue;
const baseCols = _.sortBy(
fk_keyColumnUsage.rows.filter(
x =>
x.table_name == fkRef.table_name &&
x.constraint_name == fkRef.constraint_name &&
x.table_schema == fkRef.table_schema
),
'ordinal_position'
);
const refCols = _.sortBy(
fk_keyColumnUsage.rows.filter(
x =>
x.table_name == fkRef.ref_table_name &&
x.constraint_name == fkRef.unique_constraint_name &&
x.table_schema == fkRef.ref_table_schema
),
'ordinal_position'
);
if (baseCols.length != refCols.length) continue;
// const cntKey = x => `${x.constraint_name}|${x.constraint_schema}`;
const fkRows = [];
// const fkConstraintDct = _.keyBy(fk_tableConstraints.rows, cntKey);
for (const fkRef of foreignKeys.rows) {
// const cntBase = fkConstraintDct[cntKey(fkRef)];
// const cntRef = fkConstraintDct[`${fkRef.unique_constraint_name}|${fkRef.unique_constraint_schema}`];
// if (!cntBase || !cntRef) continue;
const baseCols = _.sortBy(
fk_keyColumnUsage.rows.filter(
x =>
x.table_name == fkRef.table_name &&
x.constraint_name == fkRef.constraint_name &&
x.table_schema == fkRef.table_schema
),
'ordinal_position'
);
const refCols = _.sortBy(
fk_keyColumnUsage.rows.filter(
x =>
x.table_name == fkRef.ref_table_name &&
x.constraint_name == fkRef.unique_constraint_name &&
x.table_schema == fkRef.ref_table_schema
),
'ordinal_position'
);
if (baseCols.length != refCols.length) continue;
for (let i = 0; i < baseCols.length; i++) {
const baseCol = baseCols[i];
const refCol = refCols[i];
for (let i = 0; i < baseCols.length; i++) {
const baseCol = baseCols[i];
const refCol = refCols[i];
fkRows.push({
...fkRef,
pure_name: fkRef.table_name,
schema_name: fkRef.table_schema,
ref_table_name: fkRef.ref_table_name,
ref_schema_name: fkRef.ref_table_schema,
column_name: baseCol.column_name,
ref_column_name: refCol.column_name,
});
fkRows.push({
...fkRef,
pure_name: fkRef.table_name,
schema_name: fkRef.table_schema,
ref_table_name: fkRef.ref_table_name,
ref_schema_name: fkRef.ref_table_schema,
column_name: baseCol.column_name,
ref_column_name: refCol.column_name,
});
}
}
fkColumns = { rows: fkRows };
}
fkColumns = { rows: fkRows };
this.feedback({ analysingMessage: 'DBGM-00247 Loading views' });
const views = await this.analyserQuery('views', ['views']);

View File

@@ -0,0 +1,36 @@
module.exports = `
SELECT
tc.table_schema as schema_name,
tc.table_name as pure_name,
tc.constraint_name,
tc_pk.table_schema AS ref_schema_name,
tc_pk.table_name AS ref_table_name,
rc.unique_constraint_name,
kcu.column_name,
kcu.ordinal_position,
ccu.column_name AS ref_column_name
FROM information_schema.table_constraints AS tc
JOIN information_schema.key_column_usage AS kcu
ON tc.constraint_name = kcu.constraint_name
AND tc.table_schema = kcu.table_schema
JOIN information_schema.referential_constraints AS rc
ON rc.constraint_name = tc.constraint_name
AND rc.constraint_schema = tc.table_schema
JOIN information_schema.table_constraints AS tc_pk
ON tc_pk.constraint_name = rc.unique_constraint_name
AND tc_pk.constraint_schema = rc.unique_constraint_schema
JOIN information_schema.key_column_usage AS ccu
ON ccu.constraint_name = rc.unique_constraint_name
AND ccu.constraint_schema = rc.unique_constraint_schema
AND ccu.ordinal_position = kcu.position_in_unique_constraint
WHERE tc.constraint_type = 'FOREIGN KEY'
AND (('tables:' || tc.table_schema || '.' || tc.table_name) =OBJECT_ID_CONDITION AND tc.table_schema =SCHEMA_NAME_CONDITION)
OR
(('tables:' || tc_pk.table_schema || '.' || tc_pk.table_name) =OBJECT_ID_CONDITION AND tc.table_schema =SCHEMA_NAME_CONDITION)
ORDER BY
tc.table_schema,
tc.table_name,
tc.constraint_name,
kcu.ordinal_position
;
`;

View File

@@ -16,6 +16,7 @@ const geometryColumns = require('./geometryColumns');
const geographyColumns = require('./geographyColumns');
const proceduresParameters = require('./proceduresParameters');
const foreignKeys = require('./foreignKeys');
const foreignKeyColumns = require('./foreignKeyColumns');
const triggers = require('./triggers');
const listDatabases = require('./listDatabases');
const listVariables = require('./listVariables');
@@ -30,6 +31,7 @@ module.exports = {
viewModifications,
primaryKeys,
fk_keyColumnUsage,
foreignKeyColumns,
foreignKeys,
views,
routines,