From f282c8c35ebd152bfafe407b4255d60626f20852 Mon Sep 17 00:00:00 2001 From: rakeshkky Date: Wed, 1 Aug 2018 16:35:33 +0530 Subject: [PATCH 1/2] update metadata when constraints on a table are altered, fix #240 --- server/src-exec/Ops.hs | 4 +-- server/src-lib/Hasura/GraphQL/Schema.hs | 6 ++-- server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs | 36 +++++++++++-------- server/src-lib/Hasura/RQL/DDL/Schema/Table.hs | 7 +++- .../src-lib/Hasura/RQL/Types/SchemaCache.hs | 33 ++++++++++++----- 5 files changed, 57 insertions(+), 29 deletions(-) diff --git a/server/src-exec/Ops.hs b/server/src-exec/Ops.hs index 34b72d42db84c..54293926a0b6f 100644 --- a/server/src-exec/Ops.hs +++ b/server/src-exec/Ops.hs @@ -6,7 +6,7 @@ module Ops ) where import Data.Time.Clock (UTCTime) -import Language.Haskell.TH.Syntax (Q, TExp, unTypeQ) +import Language.Haskell.TH.Syntax (Q, TExp, unTypeQ) import Hasura.Prelude import Hasura.RQL.DDL.Schema.Table @@ -18,7 +18,7 @@ import Hasura.SQL.Types import qualified Data.Aeson as A import qualified Data.ByteString.Lazy as BL import qualified Data.Text as T -import qualified Data.Yaml.TH as Y +import qualified Data.Yaml.TH as Y import qualified Database.PG.Query as Q import qualified Database.PG.Query.Connection as Q diff --git a/server/src-lib/Hasura/GraphQL/Schema.hs b/server/src-lib/Hasura/GraphQL/Schema.hs index 05101a7ed78e3..d8eb251bb69f2 100644 --- a/server/src-lib/Hasura/GraphQL/Schema.hs +++ b/server/src-lib/Hasura/GraphQL/Schema.hs @@ -173,7 +173,7 @@ upsertable :: [TableConstraint] -> Bool -> Bool -> Bool upsertable constraints isUpsertAllowed view = not (null uniqueOrPrimaryCons) && isUpsertAllowed && not view where - uniqueOrPrimaryCons = filter isUniqueOrPrimary constraints + uniqueOrPrimaryCons = filter (isUniqueOrPrimary . tcType) constraints toValidFieldInfos :: FieldInfoMap -> [FieldInfo] toValidFieldInfos = filter isValidField . Map.elems @@ -1263,7 +1263,7 @@ mkOnConflictTypes tn c cols = , TIEnum $ mkUpdColumnTy tn cols , TIInpObj $ mkOnConflictInp tn ] - constraints = filter isUniqueOrPrimary c + constraints = filter (isUniqueOrPrimary . tcType) c isUpdAllowed = not $ null cols mkGCtxRole' @@ -1667,7 +1667,7 @@ checkSchemaConflicts gCtx remoteCtx = do (\k _ -> G.unNamedType k `notElem` builtinTy ++ rmRootNames) $ _gTypes remoteCtx - isTyInfoSame ty = any (\t -> tyinfoEq t ty) hTypes + isTyInfoSame ty = any (`tyinfoEq` ty) hTypes -- name is same and structure is not same isSame n ty = G.unNamedType n `elem` hTyNames && not (isTyInfoSame ty) diff --git a/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs b/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs index c38a263315125..8dd6135db5166 100644 --- a/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs +++ b/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs @@ -39,6 +39,7 @@ data ConstraintMeta = ConstraintMeta { cmConstraintName :: !ConstraintName , cmConstraintOid :: !Int + , cmConstraintType :: !ConstraintType } deriving (Show, Eq) $(deriveJSON (aesonDrop 2 snakeCase){omitNothingFields=True} ''ConstraintMeta) @@ -84,11 +85,13 @@ fetchTableMeta = do ON (t.table_schema = c.table_schema AND t.table_name = c.table_name) LEFT OUTER JOIN (SELECT - table_schema, - table_name, - json_agg((SELECT r FROM (SELECT constraint_name, constraint_oid) r)) as constraints + tc.table_schema, + tc.table_name, + json_agg((SELECT r FROM (SELECT tc.constraint_name, r.oid::integer AS constraint_oid, tc.constraint_type) r)) as constraints FROM - hdb_catalog.hdb_foreign_key_constraint + information_schema.table_constraints tc + JOIN pg_catalog.pg_constraint r + ON tc.constraint_name = r.conname GROUP BY table_schema, table_name) f ON (t.table_schema = f.table_schema AND t.table_name = f.table_name) @@ -112,22 +115,27 @@ getDifference getKey left right = where mkMap = M.fromList . map (\v -> (getKey v, v)) +fromConstraintMeta :: ConstraintMeta -> TableConstraint +fromConstraintMeta (ConstraintMeta n _ ty) = TableConstraint ty n + data TableDiff = TableDiff - { _tdNewName :: !(Maybe QualifiedTable) - , _tdDroppedCols :: ![PGCol] - , _tdAddedCols :: ![PGColInfo] - , _tdAlteredCols :: ![(PGColInfo, PGColInfo)] - , _tdDroppedCons :: ![ConstraintName] + { _tdNewName :: !(Maybe QualifiedTable) + , _tdDroppedCols :: ![PGCol] + , _tdAddedCols :: ![PGColInfo] + , _tdAlteredCols :: ![(PGColInfo, PGColInfo)] + , _tdDroppedFKeyCons :: ![ConstraintName] + , _tdAllCons :: ![TableConstraint] } deriving (Show, Eq) getTableDiff :: TableMeta -> TableMeta -> TableDiff getTableDiff oldtm newtm = - TableDiff mNewName droppedCols addedCols alteredCols droppedConstraints + TableDiff mNewName droppedCols addedCols alteredCols droppedFKeyConstraints allCons where mNewName = bool (Just $ tmTable newtm) Nothing $ tmTable oldtm == tmTable newtm oldCols = tmColumns oldtm newCols = tmColumns newtm + allCons = map fromConstraintMeta $ tmConstraints newtm droppedCols = map pcmColumnName $ getDifference pcmOrdinalPosition oldCols newCols @@ -144,8 +152,8 @@ getTableDiff oldtm newtm = flip map (filter (uncurry (/=)) existingCols) $ \(pcmo, pcmn) -> (pcmToPci pcmo, pcmToPci pcmn) - droppedConstraints = - map cmConstraintName $ getDifference cmConstraintOid + droppedFKeyConstraints = map cmConstraintName $ + filter (isForeignKey . cmConstraintType) $ getDifference cmConstraintOid (tmConstraints oldtm) (tmConstraints newtm) getTableChangeDeps @@ -158,13 +166,13 @@ getTableChangeDeps ti tableDiff = do let objId = SOTableObj tn $ TOCol droppedCol return $ getDependentObjs sc objId -- for all dropped constraints - droppedConsDeps <- fmap concat $ forM droppedConstraints $ \droppedCons -> do + droppedConsDeps <- fmap concat $ forM droppedFKeyConstraints $ \droppedCons -> do let objId = SOTableObj tn $ TOCons droppedCons return $ getDependentObjs sc objId return $ droppedConsDeps <> droppedColDeps where tn = tiName ti - TableDiff _ droppedCols _ _ droppedConstraints = tableDiff + TableDiff _ droppedCols _ _ droppedFKeyConstraints _ = tableDiff data SchemaDiff = SchemaDiff diff --git a/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs b/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs index 1697ae28449de..746bcaefa2442 100644 --- a/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs +++ b/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs @@ -201,6 +201,9 @@ processTableChanges ti tableDiff = do when (isJust mNewName) $ throw400 NotSupported $ "table renames are not yet supported : " <>> tn + -- replace constraints + replaceConstraints + -- for all the dropped columns forM_ droppedCols $ \droppedCol -> -- Drop the column from the cache @@ -234,8 +237,10 @@ processTableChanges ti tableDiff = do updateFldInCache cn ci = do delColFromCache cn tn addColToCache cn ci tn + replaceConstraints = flip modTableInCache tn $ \tInfo -> + return $ tInfo {tiConstraints = constraints} tn = tiName ti - TableDiff mNewName droppedCols addedCols alteredCols _ = tableDiff + TableDiff mNewName droppedCols addedCols alteredCols _ constraints = tableDiff delTableAndDirectDeps :: (QErrM m, CacheRWM m, MonadTx m) => QualifiedTable -> m () diff --git a/server/src-lib/Hasura/RQL/Types/SchemaCache.hs b/server/src-lib/Hasura/RQL/Types/SchemaCache.hs index cacff9c58c034..c6284c8c3541a 100644 --- a/server/src-lib/Hasura/RQL/Types/SchemaCache.hs +++ b/server/src-lib/Hasura/RQL/Types/SchemaCache.hs @@ -16,6 +16,7 @@ module Hasura.RQL.Types.SchemaCache , onlyJSONBCols , onlyComparableCols , isUniqueOrPrimary + , isForeignKey , mkTableInfo , addTableToCache , modTableInCache @@ -339,8 +340,6 @@ data ConstraintType | CTUNIQUE deriving Eq -$(deriveToJSON defaultOptions{constructorTagModifier = drop 2} ''ConstraintType) - constraintTyToTxt :: ConstraintType -> T.Text constraintTyToTxt ty = case ty of CTCHECK -> "CHECK" @@ -351,6 +350,18 @@ constraintTyToTxt ty = case ty of instance Show ConstraintType where show = T.unpack . constraintTyToTxt +instance FromJSON ConstraintType where + parseJSON (String "CHECK") = return CTCHECK + parseJSON (String "FOREIGN KEY") = return CTFOREIGNKEY + parseJSON (String "PRIMARY KEY") = return CTPRIMARYKEY + parseJSON (String "UNIQUE") = return CTUNIQUE + parseJSON (String _) = fail + "expecting 'CHECK', 'FOREIGN KEY', 'PRIMARY KEY' and 'UNIQUE' for constraint_type" + parseJSON _ = fail "expecting String for constraint_type" + +instance ToJSON ConstraintType where + toJSON = String . constraintTyToTxt + instance Q.FromCol ConstraintType where fromCol bs = flip Q.fromColHelper bs $ PD.enum $ \case "CHECK" -> Just CTCHECK @@ -359,6 +370,17 @@ instance Q.FromCol ConstraintType where "UNIQUE" -> Just CTUNIQUE _ -> Nothing +isUniqueOrPrimary :: ConstraintType -> Bool +isUniqueOrPrimary = \case + CTPRIMARYKEY -> True + CTUNIQUE -> True + _ -> False + +isForeignKey :: ConstraintType -> Bool +isForeignKey = \case + CTFOREIGNKEY -> True + _ -> False + data TableConstraint = TableConstraint { tcType :: !ConstraintType @@ -367,13 +389,6 @@ data TableConstraint $(deriveToJSON (aesonDrop 2 snakeCase) ''TableConstraint) -isUniqueOrPrimary :: TableConstraint -> Bool -isUniqueOrPrimary (TableConstraint ty _) = case ty of - CTCHECK -> False - CTFOREIGNKEY -> False - CTPRIMARYKEY -> True - CTUNIQUE -> True - data ViewInfo = ViewInfo { viIsUpdatable :: !Bool From dce080503f996a456ecaecc6ad7738df5ac1b7e7 Mon Sep 17 00:00:00 2001 From: Vamshi Surabhi Date: Wed, 2 Jan 2019 18:32:47 +0530 Subject: [PATCH 2/2] capture only unique or primary constraints in tableinfo --- server/src-lib/Hasura/GraphQL/Schema.hs | 33 ++++++++----------- server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs | 33 ++++++++++++------- server/src-lib/Hasura/RQL/DDL/Schema/Table.hs | 2 +- server/src-lib/Hasura/RQL/DML/Insert.hs | 2 +- .../src-lib/Hasura/RQL/Types/SchemaCache.hs | 22 ++++++------- server/src-rsr/table_info.sql | 12 +++---- 6 files changed, 52 insertions(+), 52 deletions(-) diff --git a/server/src-lib/Hasura/GraphQL/Schema.hs b/server/src-lib/Hasura/GraphQL/Schema.hs index 58c5da11a7ab0..da9dbedfa04bb 100644 --- a/server/src-lib/Hasura/GraphQL/Schema.hs +++ b/server/src-lib/Hasura/GraphQL/Schema.hs @@ -169,11 +169,9 @@ isValidField = \case isRelEligible rn rt = isValidName (G.Name $ getRelTxt rn) && isValidTableName rt -upsertable :: [TableConstraint] -> Bool -> Bool -> Bool -upsertable constraints isUpsertAllowed view = +upsertable :: [ConstraintName] -> Bool -> Bool -> Bool +upsertable uniqueOrPrimaryCons isUpsertAllowed view = not (null uniqueOrPrimaryCons) && isUpsertAllowed && not view - where - uniqueOrPrimaryCons = filter (isUniqueOrPrimary . tcType) constraints toValidFieldInfos :: FieldInfoMap -> [FieldInfo] toValidFieldInfos = filter isValidField . Map.elems @@ -187,11 +185,9 @@ getValidCols = fst . validPartitionFieldInfoMap getValidRels :: FieldInfoMap -> [RelInfo] getValidRels = snd . validPartitionFieldInfoMap -mkValidConstraints :: [TableConstraint] -> [TableConstraint] -mkValidConstraints = filter isValid - where - isValid (TableConstraint _ n) = - isValidName $ G.Name $ getConstraintTxt n +mkValidConstraints :: [ConstraintName] -> [ConstraintName] +mkValidConstraints = + filter (isValidName . G.Name . getConstraintTxt) isRelNullable :: FieldInfoMap -> RelInfo -> Bool isRelNullable fim ri = isNullable @@ -1056,11 +1052,11 @@ mkInsMutFld tn isUpsertable = onConflictArg = InpValInfo (Just onConflictDesc) "on_conflict" $ G.toGT $ mkOnConflictInpTy tn -mkConstriantTy :: QualifiedTable -> [TableConstraint] -> EnumTyInfo +mkConstriantTy :: QualifiedTable -> [ConstraintName] -> EnumTyInfo mkConstriantTy tn cons = enumTyInfo where enumTyInfo = mkHsraEnumTyInfo (Just desc) (mkConstraintInpTy tn) $ - mapFromL _eviVal $ map (mkConstraintEnumVal . tcName ) cons + mapFromL _eviVal $ map mkConstraintEnumVal cons desc = G.Description $ "unique or primary key constraints on table " <>> tn @@ -1258,16 +1254,15 @@ mkOrdByInpObj tn selFlds = (inpObjTy, ordByCtx) -- mappend = (<>) mkOnConflictTypes - :: QualifiedTable -> [TableConstraint] -> [PGCol] -> Bool -> [TypeInfo] -mkOnConflictTypes tn c cols = + :: QualifiedTable -> [ConstraintName] -> [PGCol] -> Bool -> [TypeInfo] +mkOnConflictTypes tn uniqueOrPrimaryCons cols = bool [] tyInfos where tyInfos = [ TIEnum $ mkConflictActionTy isUpdAllowed - , TIEnum $ mkConstriantTy tn constraints + , TIEnum $ mkConstriantTy tn uniqueOrPrimaryCons , TIEnum $ mkUpdColumnTy tn cols , TIInpObj $ mkOnConflictInp tn ] - constraints = filter (isUniqueOrPrimary . tcType) c isUpdAllowed = not $ null cols mkGCtxRole' @@ -1283,7 +1278,7 @@ mkGCtxRole' -- primary key columns -> [PGColInfo] -- constraints - -> [TableConstraint] + -> [ConstraintName] -> Maybe ViewInfo -> TyAgg mkGCtxRole' tn insPermM selPermM updColsM delPermM pkeyCols constraints viM = @@ -1433,7 +1428,7 @@ mkGCtxRole' tn insPermM selPermM updColsM delPermM pkeyCols constraints viM = getRootFldsRole' :: QualifiedTable -> [PGCol] - -> [TableConstraint] + -> [ConstraintName] -> FieldInfoMap -> Maybe ([T.Text], Bool) -- insert perm -> Maybe (AnnBoolExpSQL, Maybe Int, [T.Text], Bool) -- select filter @@ -1576,7 +1571,7 @@ mkGCtxRole -> QualifiedTable -> FieldInfoMap -> [PGCol] - -> [TableConstraint] + -> [ConstraintName] -> Maybe ViewInfo -> RoleName -> RolePermInfo @@ -1601,7 +1596,7 @@ mkGCtxRole tableCache tn fields pCols constraints viM role permInfo = do getRootFldsRole :: QualifiedTable -> [PGCol] - -> [TableConstraint] + -> [ConstraintName] -> FieldInfoMap -> Maybe ViewInfo -> RolePermInfo diff --git a/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs b/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs index a05966f34405f..7c692ec38e11d 100644 --- a/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs +++ b/server/src-lib/Hasura/RQL/DDL/Schema/Diff.hs @@ -37,9 +37,9 @@ $(deriveJSON (aesonDrop 3 snakeCase){omitNothingFields=True} ''PGColMeta) data ConstraintMeta = ConstraintMeta - { cmConstraintName :: !ConstraintName - , cmConstraintOid :: !Int - , cmConstraintType :: !ConstraintType + { cmName :: !ConstraintName + , cmOid :: !Int + , cmType :: !ConstraintType } deriving (Show, Eq) $(deriveJSON (aesonDrop 2 snakeCase){omitNothingFields=True} ''ConstraintMeta) @@ -87,7 +87,13 @@ fetchTableMeta = do (SELECT tc.table_schema, tc.table_name, - json_agg((SELECT r FROM (SELECT tc.constraint_name, r.oid::integer AS constraint_oid, tc.constraint_type) r)) as constraints + json_agg( + json_build_object( + 'name', tc.constraint_name, + 'oid', r.oid::integer, + 'type', tc.constraint_type + ) + ) as constraints FROM information_schema.table_constraints tc JOIN pg_catalog.pg_constraint r @@ -115,9 +121,6 @@ getDifference getKey left right = where mkMap = M.fromList . map (\v -> (getKey v, v)) -fromConstraintMeta :: ConstraintMeta -> TableConstraint -fromConstraintMeta (ConstraintMeta n _ ty) = TableConstraint ty n - data TableDiff = TableDiff { _tdNewName :: !(Maybe QualifiedTable) @@ -125,17 +128,23 @@ data TableDiff , _tdAddedCols :: ![PGColInfo] , _tdAlteredCols :: ![(PGColInfo, PGColInfo)] , _tdDroppedFKeyCons :: ![ConstraintName] - , _tdAllCons :: ![TableConstraint] + -- The final list of uniq/primary constraint names + -- used for generating types on_conflict clauses + -- TODO: this ideally should't be part of TableDiff + , _tdUniqOrPriCons :: ![ConstraintName] } deriving (Show, Eq) getTableDiff :: TableMeta -> TableMeta -> TableDiff getTableDiff oldtm newtm = - TableDiff mNewName droppedCols addedCols alteredCols droppedFKeyConstraints allCons + TableDiff mNewName droppedCols addedCols alteredCols + droppedFKeyConstraints uniqueOrPrimaryCons where mNewName = bool (Just $ tmTable newtm) Nothing $ tmTable oldtm == tmTable newtm oldCols = tmColumns oldtm newCols = tmColumns newtm - allCons = map fromConstraintMeta $ tmConstraints newtm + + uniqueOrPrimaryCons = + [cmName cm | cm <- tmConstraints newtm, isUniqueOrPrimary $ cmType cm] droppedCols = map pcmColumnName $ getDifference pcmOrdinalPosition oldCols newCols @@ -152,8 +161,8 @@ getTableDiff oldtm newtm = flip map (filter (uncurry (/=)) existingCols) $ \(pcmo, pcmn) -> (pcmToPci pcmo, pcmToPci pcmn) - droppedFKeyConstraints = map cmConstraintName $ - filter (isForeignKey . cmConstraintType) $ getDifference cmConstraintOid + droppedFKeyConstraints = map cmName $ + filter (isForeignKey . cmType) $ getDifference cmOid (tmConstraints oldtm) (tmConstraints newtm) getTableChangeDeps diff --git a/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs b/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs index 3bd1f6864d7ae..4c2d27fee8d65 100644 --- a/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs +++ b/server/src-lib/Hasura/RQL/DDL/Schema/Table.hs @@ -172,7 +172,7 @@ processTableChanges ti tableDiff = do delColFromCache cn tn addColToCache cn ci tn replaceConstraints = flip modTableInCache tn $ \tInfo -> - return $ tInfo {tiConstraints = constraints} + return $ tInfo {tiUniqOrPrimConstraints = constraints} tn = tiName ti TableDiff mNewName droppedCols addedCols alteredCols _ constraints = tableDiff diff --git a/server/src-lib/Hasura/RQL/DML/Insert.hs b/server/src-lib/Hasura/RQL/DML/Insert.hs index cffa2277bed5c..951103535ba2e 100644 --- a/server/src-lib/Hasura/RQL/DML/Insert.hs +++ b/server/src-lib/Hasura/RQL/DML/Insert.hs @@ -145,7 +145,7 @@ buildConflictClause tableInfo inpCols (OnConflict mTCol mTCons act) = \pgCol -> askPGType fieldInfoMap pgCol "" validateConstraint c = do - let tableConsNames = map tcName $ tiConstraints tableInfo + let tableConsNames = tiUniqOrPrimConstraints tableInfo withPathK "constraint" $ unless (c `elem` tableConsNames) $ throw400 Unexpected $ "constraint " <> getConstraintTxt c diff --git a/server/src-lib/Hasura/RQL/Types/SchemaCache.hs b/server/src-lib/Hasura/RQL/Types/SchemaCache.hs index b85a32acde78c..a5b4d08ad1acb 100644 --- a/server/src-lib/Hasura/RQL/Types/SchemaCache.hs +++ b/server/src-lib/Hasura/RQL/Types/SchemaCache.hs @@ -322,14 +322,14 @@ mutableView qt f mVI operation = data TableInfo = TableInfo - { tiName :: !QualifiedTable - , tiSystemDefined :: !Bool - , tiFieldInfoMap :: !FieldInfoMap - , tiRolePermInfoMap :: !RolePermInfoMap - , tiConstraints :: ![TableConstraint] - , tiPrimaryKeyCols :: ![PGCol] - , tiViewInfo :: !(Maybe ViewInfo) - , tiEventTriggerInfoMap :: !EventTriggerInfoMap + { tiName :: !QualifiedTable + , tiSystemDefined :: !Bool + , tiFieldInfoMap :: !FieldInfoMap + , tiRolePermInfoMap :: !RolePermInfoMap + , tiUniqOrPrimConstraints :: ![ConstraintName] + , tiPrimaryKeyCols :: ![PGCol] + , tiViewInfo :: !(Maybe ViewInfo) + , tiEventTriggerInfoMap :: !EventTriggerInfoMap } deriving (Show, Eq) $(deriveToJSON (aesonDrop 2 snakeCase) ''TableInfo) @@ -337,13 +337,13 @@ $(deriveToJSON (aesonDrop 2 snakeCase) ''TableInfo) mkTableInfo :: QualifiedTable -> Bool - -> [TableConstraint] + -> [ConstraintName] -> [PGColInfo] -> [PGCol] -> Maybe ViewInfo -> TableInfo -mkTableInfo tn isSystemDefined constraints cols pcols mVI = +mkTableInfo tn isSystemDefined uniqCons cols pcols mVI = TableInfo tn isSystemDefined colMap (M.fromList []) - constraints pcols mVI (M.fromList []) + uniqCons pcols mVI (M.fromList []) where colMap = M.fromList $ map f cols f colInfo = (fromPGCol $ pgiName colInfo, FIColumn colInfo) diff --git a/server/src-rsr/table_info.sql b/server/src-rsr/table_info.sql index 406fc0b9d25a0..cf53f85c57cdd 100644 --- a/server/src-rsr/table_info.sql +++ b/server/src-rsr/table_info.sql @@ -38,16 +38,12 @@ from select c.table_schema, c.table_name, - json_agg( - json_build_object( - 'name', - constraint_name, - 'type', - constraint_type - ) - ) as constraints + json_agg(constraint_name) as constraints from information_schema.table_constraints c + where + c.constraint_type = 'UNIQUE' + or c.constraint_type = 'PRIMARY KEY' group by c.table_schema, c.table_name