{-# LANGUAGE UndecidableInstances #-}

module Hasura.RQL.IR.Value
  ( UnpreparedValue (..),
    ValueWithOrigin (..),
    openValueOrigin,
    mkParameter,
  )
where

import Hasura.GraphQL.Parser.Variable
import Hasura.Prelude
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.Column
import Hasura.SQL.Backend
import Hasura.Session (SessionVariable)

data UnpreparedValue (b :: BackendType)
  = -- | A SQL value that can be parameterized over.
    UVParameter
      (Maybe VariableInfo)
      -- ^ The GraphQL variable this value came from, if any.
      (ColumnValue b)
  | -- | A literal SQL expression that /cannot/ be parameterized over.
    UVLiteral (SQLExpression b)
  | -- | The entire session variables JSON object.
    UVSession
  | -- | A single session variable.
    UVSessionVar (SessionVarType b) SessionVariable

deriving instance
  ( Backend b,
    Eq (ColumnValue b),
    Eq (ScalarValue b)
  ) =>
  Eq (UnpreparedValue b)

deriving instance
  ( Backend b,
    Show (ColumnValue b),
    Show (ScalarValue b)
  ) =>
  Show (UnpreparedValue b)

-- | This indicates whether a variable value came from a certain GraphQL variable
data ValueWithOrigin a
  = ValueWithOrigin VariableInfo a
  | ValueNoOrigin a
  deriving (a -> ValueWithOrigin b -> ValueWithOrigin a
(a -> b) -> ValueWithOrigin a -> ValueWithOrigin b
(forall a b. (a -> b) -> ValueWithOrigin a -> ValueWithOrigin b)
-> (forall a b. a -> ValueWithOrigin b -> ValueWithOrigin a)
-> Functor ValueWithOrigin
forall a b. a -> ValueWithOrigin b -> ValueWithOrigin a
forall a b. (a -> b) -> ValueWithOrigin a -> ValueWithOrigin b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: a -> ValueWithOrigin b -> ValueWithOrigin a
$c<$ :: forall a b. a -> ValueWithOrigin b -> ValueWithOrigin a
fmap :: (a -> b) -> ValueWithOrigin a -> ValueWithOrigin b
$cfmap :: forall a b. (a -> b) -> ValueWithOrigin a -> ValueWithOrigin b
Functor)

openValueOrigin :: ValueWithOrigin a -> a
openValueOrigin :: ValueWithOrigin a -> a
openValueOrigin (ValueWithOrigin VariableInfo
_ a
a) = a
a
openValueOrigin (ValueNoOrigin a
a) = a
a

mkParameter :: ValueWithOrigin (ColumnValue b) -> UnpreparedValue b
mkParameter :: ValueWithOrigin (ColumnValue b) -> UnpreparedValue b
mkParameter (ValueWithOrigin VariableInfo
valInfo ColumnValue b
columnValue) =
  Maybe VariableInfo -> ColumnValue b -> UnpreparedValue b
forall (b :: BackendType).
Maybe VariableInfo -> ColumnValue b -> UnpreparedValue b
UVParameter (VariableInfo -> Maybe VariableInfo
forall a. a -> Maybe a
Just VariableInfo
valInfo) ColumnValue b
columnValue
mkParameter (ValueNoOrigin ColumnValue b
columnValue) =
  Maybe VariableInfo -> ColumnValue b -> UnpreparedValue b
forall (b :: BackendType).
Maybe VariableInfo -> ColumnValue b -> UnpreparedValue b
UVParameter Maybe VariableInfo
forall a. Maybe a
Nothing ColumnValue b
columnValue