function foreign_keys($table) {
$return = array();
- foreach (get_rows("SELECT tc.constraint_name, kcu.column_name, rc.update_rule AS on_update, rc.delete_rule AS on_delete, unique_constraint_schema AS ns, ccu.table_name AS table, ccu.column_name AS ref
-FROM information_schema.table_constraints tc
-LEFT JOIN information_schema.key_column_usage kcu USING (constraint_catalog, constraint_schema, constraint_name)
-LEFT JOIN information_schema.referential_constraints rc USING (constraint_catalog, constraint_schema, constraint_name)
-LEFT JOIN information_schema.constraint_column_usage ccu ON rc.unique_constraint_catalog = ccu.constraint_catalog AND rc.unique_constraint_schema = ccu.constraint_schema AND rc.unique_constraint_name = ccu.constraint_name
-WHERE tc.constraint_type = 'FOREIGN KEY' AND tc.constraint_schema = current_schema() AND tc.table_name = " . q($table) //! there can be more unique_constraint_name
- ) as $row) {
- $foreign_key = &$return[$row["constraint_name"]];
- if (!$foreign_key) {
- $foreign_key = $row;
+ foreach (get_rows("SELECT conname, (SELECT nspname FROM pg_namespace WHERE oid = connamespace) AS ns, pg_get_constraintdef(oid) AS definition
+FROM pg_constraint
+WHERE conrelid = (SELECT oid FROM pg_class WHERE relname = " . q($table) . ")
+AND contype = 'f'::char
+ORDER BY conkey, conname") as $row) {
+ if (preg_match('~FOREIGN KEY\s*\((.+)\)\s*REFERENCES (.+)\((.+)\)(.*)$~iA', $row['definition'], $match)) {
+ $row['source'] = array_map('trim', explode(',', $match[1]));
+ $row['table'] = $match[2];
+ $row['target'] = array_map('trim', explode(',', $match[3]));
+ $row['on_delete'] = (preg_match('~ON DELETE (CASCADE|SET NULL|RESTRICT|NO ACTION)~', $match[4], $match2) ? $match2[1] : 'NO ACTION');
+ $row['on_update'] = (preg_match('~ON UPDATE (CASCADE|SET NULL|RESTRICT|NO ACTION)~', $match[4], $match2) ? $match2[1] : 'NO ACTION');
+ $return[$row['conname']] = $row;
}
- $foreign_key["source"][] = $row["column_name"];
- $foreign_key["target"][] = $row["ref"];
}
return $return;
}