From 8783615ebcf06b6066230abfa8a2ad428e168d79 Mon Sep 17 00:00:00 2001 From: Ruslan Talpa Date: Thu, 24 Sep 2015 23:30:47 +0300 Subject: [PATCH] detect primary keys for views (fix #217) --- src/PostgREST/PgStructure.hs | 35 ++++++++++---- test/Feature/StructureSpec.hs | 88 +++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+), 10 deletions(-) diff --git a/src/PostgREST/PgStructure.hs b/src/PostgREST/PgStructure.hs index 9e5647b8a..2a79b7610 100644 --- a/src/PostgREST/PgStructure.hs +++ b/src/PostgREST/PgStructure.hs @@ -110,16 +110,31 @@ columns table = do primaryKeyColumns :: QualifiedIdentifier -> H.Tx P.Postgres s [Text] primaryKeyColumns table = do r <- H.listEx $ [H.stmt| - select kc.column_name - from - information_schema.table_constraints tc, - information_schema.key_column_usage kc - where - tc.constraint_type = 'PRIMARY KEY' - and kc.table_name = tc.table_name and kc.table_schema = tc.table_schema - and kc.constraint_name = tc.constraint_name - and kc.table_schema = ? - and kc.table_name = ? |] (qiSchema table) (qiName table) + WITH table_pk AS + ( SELECT kc.table_schema, + kc.table_name, + kc.column_name + FROM information_schema.table_constraints tc, + information_schema.key_column_usage kc + WHERE tc.constraint_type = 'PRIMARY KEY' + AND kc.table_name = tc.table_name + AND kc.table_schema = tc.table_schema + AND kc.constraint_name = tc.constraint_name + AND kc.table_schema = ?) + SELECT column_name + FROM table_pk + WHERE table_pk.table_name = ? + UNION + ( + SELECT vcu.column_name + FROM information_schema.view_column_usage AS vcu + JOIN table_pk ON table_pk.table_schema = vcu.view_schema + AND table_pk.TABLE_NAME = vcu.TABLE_NAME + AND table_pk.column_name = vcu.column_name + WHERE vcu.view_schema = ? + AND vcu.view_name = ? + ) + |] (qiSchema table) (qiName table) (qiSchema table) (qiName table) return $ map runIdentity r doesProcExist :: Text -> Text -> H.Tx P.Postgres s Bool diff --git a/test/Feature/StructureSpec.hs b/test/Feature/StructureSpec.hs index f63628e8a..d2f6bdb45 100644 --- a/test/Feature/StructureSpec.hs +++ b/test/Feature/StructureSpec.hs @@ -145,6 +145,94 @@ spec = around withApp $ do } |] + it "it includes primary key for views" $ + request methodOptions "/insertable_view_with_join" [] "" `shouldRespondWith` + [json| + { + "pkey":["id"], + "columns":[ + { + "references":null, + "default":null, + "precision":64, + "updatable":false, + "schema":"1", + "name":"id", + "type":"bigint", + "maxLen":null, + "enum":[], + "nullable":true, + "position":1 + }, + { + "references":null, + "default":null, + "precision":32, + "updatable":false, + "schema":"1", + "name":"auto_inc_fk", + "type":"integer", + "maxLen":null, + "enum":[], + "nullable":true, + "position":2 + }, + { + "references":null, + "default":null, + "precision":null, + "updatable":false, + "schema":"1", + "name":"simple_fk", + "type":"character varying", + "maxLen":255, + "enum":[], + "nullable":true, + "position":3 + }, + { + "references":null, + "default":null, + "precision":null, + "updatable":false, + "schema":"1", + "name":"nullable_string", + "type":"character varying", + "maxLen":null, + "enum":[], + "nullable":true, + "position":4 + }, + { + "references":null, + "default":null, + "precision":null, + "updatable":false, + "schema":"1", + "name":"non_nullable_string", + "type":"character varying", + "maxLen":null, + "enum":[], + "nullable":true, + "position":5 + }, + { + "references":null, + "default":null, + "precision":null, + "updatable":false, + "schema":"1", + "name":"inserted_at", + "type":"timestamp with time zone", + "maxLen":null, + "enum":[], + "nullable":true, + "position":6 + } + ] + } + |] + it "includes foreign key data" $ do pendingWith "have to resolve issue #107"