From 2bdc47d453726918e959cd50cf80a9b772eb246b Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 25 Dec 2024 11:08:41 +0700 Subject: [PATCH 1/4] Improve loading schemas of views --- src/Schema.php | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/src/Schema.php b/src/Schema.php index d9847071..f4061627 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -301,15 +301,12 @@ protected function loadTableIndexes(string $tableName): array FROM "pg_class" AS "tc" INNER JOIN "pg_namespace" AS "tcns" ON "tcns"."oid" = "tc"."relnamespace" - LEFT JOIN pg_rewrite AS rw - ON tc.relkind = 'v' AND rw.ev_class = tc.oid AND rw.rulename = '_RETURN' + LEFT JOIN "pg_rewrite" AS "rw" + ON "tc"."relkind" = 'v' AND "rw"."ev_class" = "tc"."oid" AND "rw"."rulename" = '_RETURN' INNER JOIN "pg_index" AS "i" ON "i"."indrelid" = "tc"."oid" - OR rw.ev_action IS NOT NULL - AND (SELECT regexp_matches( - rw.ev_action, - '{TARGETENTRY .*? :resorigtbl ' || "i"."indrelid" || ' :resorigcol ' || "i"."indkey"[0] || ' ' - )) IS NOT NULL + OR "rw"."ev_action" IS NOT NULL + AND strpos("rw"."ev_action", ':resorigtbl ' || "i"."indrelid" || ' :resorigcol ' || "i"."indkey"[0] || ' ') > 0 INNER JOIN "pg_class" AS "ic" ON "ic"."oid" = "i"."indexrelid" INNER JOIN "pg_attribute" AS "ia" @@ -665,15 +662,22 @@ protected function findColumns(TableSchemaInterface $table): bool LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum LEFT JOIN pg_type t ON a.atttypid = t.oid LEFT JOIN pg_type tb ON (a.attndims > 0 OR t.typcategory='A') AND t.typelem > 0 AND t.typelem = tb.oid - OR t.typbasetype > 0 AND t.typbasetype = tb.oid + OR t.typbasetype > 0 AND t.typbasetype = tb.oid LEFT JOIN pg_type td ON t.typndims > 0 AND t.typbasetype > 0 AND tb.typelem = td.oid LEFT JOIN pg_namespace d ON d.oid = c.relnamespace LEFT JOIN pg_rewrite rw ON c.relkind = 'v' AND rw.ev_class = c.oid AND rw.rulename = '_RETURN' LEFT JOIN pg_constraint ct ON (ct.contype = 'p' OR ct.contype = 'u' AND cardinality(ct.conkey) = 1) - AND (ct.conrelid = c.oid AND a.attnum = ANY (ct.conkey) - OR rw.ev_action IS NOT NULL AND (ARRAY( - SELECT regexp_matches(rw.ev_action, '{TARGETENTRY .*? :resorigtbl (\d+) :resorigcol (\d+) ', 'g') - ))[a.attnum:a.attnum] <@ (ct.conrelid::text || ct.conkey::text[])) + AND ( + ct.conrelid = c.oid AND a.attnum = ANY (ct.conkey) + OR rw.ev_action IS NOT NULL + AND strpos(rw.ev_action, ':resorigtbl ' || ct.conrelid || ' ') > 0 + AND regexp_like( + rw.ev_action, + ' :resno ' || a.attnum || ' :resname \S+ :ressortgroupref \d+ :resorigtbl ' + || ct.conrelid || ' :resorigcol (?:' + || replace(substr(ct.conkey::text, 2, length(ct.conkey::text) - 2), ',', '|') || ') ' + ) + ) WHERE a.attnum > 0 AND t.typname != '' AND NOT a.attisdropped AND c.relname = :tableName @@ -831,9 +835,13 @@ private function loadTableConstraints(string $tableName, string $returnType): ar INNER JOIN "pg_constraint" AS "c" ON "c"."conrelid" = "tc"."oid" AND "a"."attnum" = ANY ("c"."conkey") OR "rw"."ev_action" IS NOT NULL AND "c"."conrelid" != 0 - AND (ARRAY( - SELECT regexp_matches("rw"."ev_action", '{TARGETENTRY .*? :resorigtbl (\d+) :resorigcol (\d+) ', 'g') - ))["a"."attnum":"a"."attnum"] <@ ("c"."conrelid"::text || "c"."conkey"::text[]) + AND strpos("rw"."ev_action", ':resorigtbl ' || "c"."conrelid" || ' ') > 0 + AND regexp_like( + "rw"."ev_action", + ' :resno ' || "a"."attnum" || ' :resname \S+ :ressortgroupref \d+ :resorigtbl ' + || "c"."conrelid" || ' :resorigcol (?:' + || replace(substr("c"."conkey"::text, 2, length("c"."conkey"::text) - 2), ',', '|') || ') ' + ) LEFT JOIN "pg_class" AS "ftc" ON "ftc"."oid" = "c"."confrelid" LEFT JOIN "pg_namespace" AS "ftcns" From 5a00ec2604365075e5f2a8aac04cd658ad58dea5 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 25 Dec 2024 14:12:27 +0700 Subject: [PATCH 2/4] Fix for version below 15 --- src/Schema.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/Schema.php b/src/Schema.php index f4061627..b8bf6681 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -671,12 +671,9 @@ protected function findColumns(TableSchemaInterface $table): bool ct.conrelid = c.oid AND a.attnum = ANY (ct.conkey) OR rw.ev_action IS NOT NULL AND strpos(rw.ev_action, ':resorigtbl ' || ct.conrelid || ' ') > 0 - AND regexp_like( - rw.ev_action, - ' :resno ' || a.attnum || ' :resname \S+ :ressortgroupref \d+ :resorigtbl ' + AND rw.ev_action ~ ('.* :resno ' || a.attnum || ' :resname \S+ :ressortgroupref \d+ :resorigtbl ' || ct.conrelid || ' :resorigcol (?:' - || replace(substr(ct.conkey::text, 2, length(ct.conkey::text) - 2), ',', '|') || ') ' - ) + || replace(substr(ct.conkey::text, 2, length(ct.conkey::text) - 2), ',', '|') || ') .*') ) WHERE a.attnum > 0 AND t.typname != '' AND NOT a.attisdropped @@ -836,12 +833,9 @@ private function loadTableConstraints(string $tableName, string $returnType): ar ON "c"."conrelid" = "tc"."oid" AND "a"."attnum" = ANY ("c"."conkey") OR "rw"."ev_action" IS NOT NULL AND "c"."conrelid" != 0 AND strpos("rw"."ev_action", ':resorigtbl ' || "c"."conrelid" || ' ') > 0 - AND regexp_like( - "rw"."ev_action", - ' :resno ' || "a"."attnum" || ' :resname \S+ :ressortgroupref \d+ :resorigtbl ' + AND "rw"."ev_action" ~ ('.* :resno ' || "a"."attnum" || ' :resname \S+ :ressortgroupref \d+ :resorigtbl ' || "c"."conrelid" || ' :resorigcol (?:' - || replace(substr("c"."conkey"::text, 2, length("c"."conkey"::text) - 2), ',', '|') || ') ' - ) + || replace(substr("c"."conkey"::text, 2, length("c"."conkey"::text) - 2), ',', '|') || ') .*') LEFT JOIN "pg_class" AS "ftc" ON "ftc"."oid" = "c"."confrelid" LEFT JOIN "pg_namespace" AS "ftcns" From 44ab87fcabf1ef290dc878a52746ebff3d1d4731 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 25 Dec 2024 22:20:22 +0700 Subject: [PATCH 3/4] Improve query --- src/Schema.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Schema.php b/src/Schema.php index b8bf6681..20372835 100644 --- a/src/Schema.php +++ b/src/Schema.php @@ -669,7 +669,7 @@ protected function findColumns(TableSchemaInterface $table): bool LEFT JOIN pg_constraint ct ON (ct.contype = 'p' OR ct.contype = 'u' AND cardinality(ct.conkey) = 1) AND ( ct.conrelid = c.oid AND a.attnum = ANY (ct.conkey) - OR rw.ev_action IS NOT NULL + OR rw.ev_action IS NOT NULL AND ct.conrelid != 0 AND strpos(rw.ev_action, ':resorigtbl ' || ct.conrelid || ' ') > 0 AND rw.ev_action ~ ('.* :resno ' || a.attnum || ' :resname \S+ :ressortgroupref \d+ :resorigtbl ' || ct.conrelid || ' :resorigcol (?:' From 12d528291c650b5474f19cf4bc6b5ea14435710c Mon Sep 17 00:00:00 2001 From: Tigrov Date: Wed, 25 Dec 2024 22:43:03 +0700 Subject: [PATCH 4/4] Add line to CHANGELOG.md [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 27eb497a..5cea179f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,7 @@ - New #373: Override `QueryBuilder::prepareBinary()` method (@Tigrov) - Chg #375: Update `QueryBuilder` constructor (@Tigrov) - Enh #374: Use `ColumnDefinitionBuilder` to generate table column SQL representation (@Tigrov) +- Enh #378: Improve loading schemas of views (@Tigrov) ## 1.3.0 March 21, 2024