diff --git a/packages/core/database/lib/dialects/postgresql/schema-inspector.js b/packages/core/database/lib/dialects/postgresql/schema-inspector.js index 7e13a56e4d..33c1fe2b17 100644 --- a/packages/core/database/lib/dialects/postgresql/schema-inspector.js +++ b/packages/core/database/lib/dialects/postgresql/schema-inspector.js @@ -40,29 +40,41 @@ const SQL_QUERIES = { `, FOREIGN_KEY_LIST: /* sql */ ` SELECT - tco."constraint_name" as constraint_name, - kcu."column_name" as column_name, - rel_kcu."table_name" as foreign_table, - rel_kcu."column_name" as fk_column_name, - rco.update_rule as on_update, - rco.delete_rule as on_delete + tco."constraint_name" as constraint_name FROM information_schema.table_constraints tco - JOIN information_schema.key_column_usage kcu - ON tco.constraint_schema = kcu.constraint_schema - AND tco.constraint_name = kcu.constraint_name - JOIN information_schema.referential_constraints rco - ON tco.constraint_schema = rco.constraint_schema - AND tco.constraint_name = rco.constraint_name - JOIN information_schema.key_column_usage rel_kcu - ON rco.unique_constraint_schema = rel_kcu.constraint_schema - AND rco.unique_constraint_name = rel_kcu.constraint_name - AND kcu.ordinal_position = rel_kcu.ordinal_position WHERE tco.constraint_type = 'FOREIGN KEY' AND tco.constraint_schema = ? AND tco.table_name = ? - ORDER BY kcu.table_schema, kcu.table_name, kcu.ordinal_position, kcu.constraint_name; `, + FOREIGN_KEY_REFERENCES: /* sql */ ` + SELECT + kcu."constraint_name" as constraint_name, + kcu."column_name" as column_name + + FROM information_schema.key_column_usage kcu + WHERE kcu.constraint_name=ANY(?) + AND kcu.table_schema = ? + AND kcu.table_name = ?; + `, + + FOREIGN_KEY_REFERENCES_CONSTRAIN: /* sql */ ` + SELECT + rco.update_rule as on_update, + rco.delete_rule as on_delete, + rco."unique_constraint_name" as unique_constraint_name + FROM information_schema.referential_constraints rco + WHERE rco.constraint_name=ANY(?) + AND rco.constraint_schema = ? +`, + FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE: /* sql */ ` + SELECT + rel_kcu."table_name" as foreign_table, + rel_kcu."column_name" as fk_column_name + FROM information_schema.key_column_usage rel_kcu + WHERE rel_kcu.constraint_name=? + AND rel_kcu.table_schema = ? +`, }; const toStrapiType = column => { @@ -210,18 +222,52 @@ class PostgresqlSchemaInspector { const ret = {}; for (const fk of rows) { - if (!ret[fk.constraint_name]) { - ret[fk.constraint_name] = { - name: fk.constraint_name, - columns: [fk.column_name], - referencedColumns: [fk.fk_column_name], - referencedTable: fk.foreign_table, - onUpdate: fk.on_update.toUpperCase(), - onDelete: fk.on_delete.toUpperCase(), - }; - } else { - ret[fk.constraint_name].columns.push(fk.column_name); - ret[fk.constraint_name].referencedColumns.push(fk.fk_column_name); + ret[fk.constraint_name] = { + name: fk.constraint_name, + columns: [], + referencedColumns: [], + referencedTable: null, + onUpdate: null, + onDelete: null, + }; + } + const constraintNames = Object.keys(ret); + const dbSchema = this.getDatabaseSchema(); + if (constraintNames.length > 0) { + const { + rows: fkReferences, + } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES, [ + [constraintNames], + dbSchema, + tableName, + ]); + + for (const fkReference of fkReferences) { + ret[fkReference.constraint_name].columns.push(fkReference.column_name); + + const { + rows: fkReferencesConstraint, + } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN, [ + [fkReference.constraint_name], + dbSchema, + ]); + + for (const fkReferenceC of fkReferencesConstraint) { + const { + rows: fkReferencesConstraintReferece, + } = await this.db.connection.raw(SQL_QUERIES.FOREIGN_KEY_REFERENCES_CONSTRAIN_RFERENCE, [ + fkReferenceC.unique_constraint_name, + dbSchema, + ]); + for (const fkReferenceConst of fkReferencesConstraintReferece) { + ret[fkReference.constraint_name].referencedTable = fkReferenceConst.foreign_table; + ret[fkReference.constraint_name].referencedColumns.push( + fkReferenceConst.fk_column_name + ); + } + ret[fkReference.constraint_name].onUpdate = fkReferenceC.on_update.toUpperCase(); + ret[fkReference.constraint_name].onDelete = fkReferenceC.on_delete.toUpperCase(); + } } }