2022-04-22 16:38:35 +03:00
|
|
|
-- | This module defines the type class 'PostgresAnnotatedFieldJSON'.
|
|
|
|
module Hasura.Backends.Postgres.Translate.Select.AnnotatedFieldJSON
|
|
|
|
( PostgresAnnotatedFieldJSON (..),
|
|
|
|
)
|
|
|
|
where
|
|
|
|
|
|
|
|
import Data.Text qualified as T
|
|
|
|
import Hasura.Backends.Postgres.SQL.DML qualified as S
|
2022-04-22 20:18:20 +03:00
|
|
|
import Hasura.Backends.Postgres.Translate.Select.Internal.Helpers (withJsonBuildObj)
|
2022-04-22 16:38:35 +03:00
|
|
|
import Hasura.Prelude
|
|
|
|
import Hasura.RQL.Types.Common (FieldName (getFieldNameTxt))
|
|
|
|
import Hasura.SQL.Backend (PostgresKind (..))
|
|
|
|
|
|
|
|
class PostgresAnnotatedFieldJSON (pgKind :: PostgresKind) where
|
|
|
|
annRowToJson :: FieldName -> [(FieldName, S.SQLExp)] -> (S.Alias, S.SQLExp)
|
|
|
|
|
|
|
|
instance PostgresAnnotatedFieldJSON 'Vanilla where
|
|
|
|
annRowToJson fieldAlias fieldExps =
|
|
|
|
-- postgres ignores anything beyond 63 chars for an iden
|
|
|
|
-- in this case, we'll need to use json_build_object function
|
|
|
|
-- json_build_object is slower than row_to_json hence it is only
|
|
|
|
-- used when needed
|
|
|
|
if any ((> 63) . T.length . getFieldNameTxt . fst) fieldExps
|
|
|
|
then withJsonBuildObj fieldAlias $ concatMap toJsonBuildObjectExps fieldExps
|
|
|
|
else withRowToJSON fieldAlias $ map toRowToJsonExtr fieldExps
|
|
|
|
where
|
|
|
|
toJsonBuildObjectExps (fieldName, fieldExp) =
|
|
|
|
[S.SELit $ getFieldNameTxt fieldName, fieldExp]
|
|
|
|
|
|
|
|
toRowToJsonExtr (fieldName, fieldExp) =
|
|
|
|
S.Extractor fieldExp $ Just $ S.toAlias fieldName
|
|
|
|
|
|
|
|
-- uses row_to_json to build a json object
|
|
|
|
withRowToJSON ::
|
|
|
|
FieldName -> [S.Extractor] -> (S.Alias, S.SQLExp)
|
|
|
|
withRowToJSON parAls extrs =
|
|
|
|
(S.toAlias parAls, jsonRow)
|
|
|
|
where
|
|
|
|
jsonRow = S.applyRowToJson extrs
|
|
|
|
|
|
|
|
instance PostgresAnnotatedFieldJSON 'Citus where
|
|
|
|
annRowToJson fieldAlias fieldExps =
|
|
|
|
-- Due to the restrictions Citus imposes on joins between tables of various
|
|
|
|
-- distribution types we cannot use row_to_json and have to only rely on
|
|
|
|
-- json_build_object.
|
|
|
|
withJsonBuildObj fieldAlias $ concatMap toJsonBuildObjectExps fieldExps
|
|
|
|
where
|
|
|
|
toJsonBuildObjectExps (fieldName, fieldExp) =
|
|
|
|
[S.SELit $ getFieldNameTxt fieldName, fieldExp]
|