module Database.Sql.Vertica.Type where
import Database.Sql.Type
import Database.Sql.Position
import Database.Sql.Info
import Database.Sql.Util.Columns
import Database.Sql.Util.Joins
import Database.Sql.Util.Lineage.Table
import Database.Sql.Util.Lineage.ColumnPlus as ColumnPlus
import Database.Sql.Util.Scope
import Database.Sql.Util.Tables
import Database.Sql.Util.Schema as Schema
import Control.Arrow
import Control.Monad.Reader (asks, local)
import Control.Monad.Writer (listen)
import Control.Monad.Identity
import Data.Either (partitionEithers)
import Data.List (foldl')
import Data.List.NonEmpty (NonEmpty((:|)), toList, fromList)
import Data.Maybe (catMaybes)
import Data.Semigroup
import Data.Text.Lazy (Text)
import Data.Traversable (traverse)
import Data.Aeson (ToJSON (..), (.=))
import qualified Data.Aeson as JSON
import qualified Data.Foldable as F
import Data.Proxy (Proxy (..))
import Data.Set (Set)
import qualified Data.Set as S
import Data.Map (Map)
import qualified Data.Map as M
import Data.Data (Data)
import GHC.Generics (Generic)
data Vertica
deriving instance Data Vertica
dialectProxy :: Proxy Vertica
dialectProxy = Proxy
instance Dialect Vertica where
type DialectCreateTableExtra Vertica r = TableInfo r
shouldCTEsShadowTables _ = True
resolveCreateTableExtra _ = resolveTableInfo
getSelectScope _ fromColumns selectionAliases = SelectScope
{ bindForWhere = bindFromColumns fromColumns
, bindForGroup = bindBothColumns fromColumns selectionAliases
, bindForHaving = bindFromColumns fromColumns
, bindForOrder = bindBothColumns fromColumns selectionAliases
, bindForNamedWindow = bindFromColumns fromColumns
}
areLcolumnsVisibleInLateralViews _ = False
data TableInfo r a = TableInfo
{ tableInfoInfo :: a
, tableInfoOrdering :: Maybe [Order r a]
, tableInfoEncoding :: Maybe (TableEncoding r a)
, tableInfoSegmentation :: Maybe (Segmentation r a)
, tableInfoKSafety :: Maybe (KSafety a)
, tableInfoPartitioning :: Maybe (Partitioning r a)
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (TableInfo r a)
deriving instance Generic (TableInfo r a)
deriving instance ConstrainSNames Eq r a => Eq (TableInfo r a)
deriving instance ConstrainSNames Show r a => Show (TableInfo r a)
deriving instance ConstrainSASNames Functor r => Functor (TableInfo r)
deriving instance ConstrainSASNames Foldable r => Foldable (TableInfo r)
deriving instance ConstrainSASNames Traversable r => Traversable (TableInfo r)
resolveTableInfo :: TableInfo RawNames a -> Resolver (TableInfo ResolvedNames) a
resolveTableInfo TableInfo{..} = do
tableInfoOrdering' <- traverse (mapM $ resolveOrder []) tableInfoOrdering
tableInfoEncoding' <- traverse resolveTableEncoding tableInfoEncoding
tableInfoSegmentation' <- traverse resolveSegmentation tableInfoSegmentation
tableInfoPartitioning' <- traverse resolvePartitioning tableInfoPartitioning
pure TableInfo
{ tableInfoOrdering = tableInfoOrdering'
, tableInfoEncoding = tableInfoEncoding'
, tableInfoSegmentation = tableInfoSegmentation'
, tableInfoPartitioning = tableInfoPartitioning'
, ..
}
data VerticaStatement r a = VerticaStandardSqlStatement (Statement Vertica r a)
| VerticaCreateProjectionStatement (CreateProjection r a)
| VerticaMultipleRenameStatement (MultipleRename r a)
| VerticaSetSchemaStatement (SetSchema r a)
| VerticaMergeStatement (Merge r a)
| VerticaUnhandledStatement a
deriving instance (ConstrainSNames Data r a, Data r) => Data (VerticaStatement r a)
deriving instance Generic (VerticaStatement r a)
deriving instance ConstrainSNames Eq r a => Eq (VerticaStatement r a)
deriving instance ConstrainSNames Show r a => Show (VerticaStatement r a)
deriving instance ConstrainSASNames Functor r => Functor (VerticaStatement r)
deriving instance ConstrainSASNames Foldable r => Foldable (VerticaStatement r)
deriving instance ConstrainSASNames Traversable r => Traversable (VerticaStatement r)
data TableEncoding r a = TableEncoding a [(ColumnRef r a, Encoding a)]
deriving instance (ConstrainSNames Data r a, Data r) => Data (TableEncoding r a)
deriving instance Generic (TableEncoding r a)
deriving instance ConstrainSNames Eq r a => Eq (TableEncoding r a)
deriving instance ConstrainSNames Show r a => Show (TableEncoding r a)
deriving instance ConstrainSASNames Functor r => Functor (TableEncoding r)
deriving instance ConstrainSASNames Foldable r => Foldable (TableEncoding r)
deriving instance ConstrainSASNames Traversable r => Traversable (TableEncoding r)
resolveTableEncoding :: TableEncoding RawNames a -> Resolver (TableEncoding ResolvedNames) a
resolveTableEncoding (TableEncoding info encodings) = do
encodings' <- forM encodings $ \ (column, encoding) -> do
column' <- resolveColumnName column
pure (column', encoding)
pure $ TableEncoding info encodings'
data Segmentation r a = UnsegmentedAllNodes a
| UnsegmentedOneNode a (Node a)
| SegmentedBy a (Expr r a) (NodeList a)
deriving instance (ConstrainSNames Data r a, Data r) => Data (Segmentation r a)
deriving instance Generic (Segmentation r a)
deriving instance ConstrainSNames Eq r a => Eq (Segmentation r a)
deriving instance ConstrainSNames Show r a => Show (Segmentation r a)
deriving instance ConstrainSASNames Functor r => Functor (Segmentation r)
deriving instance ConstrainSASNames Foldable r => Foldable (Segmentation r)
deriving instance ConstrainSASNames Traversable r => Traversable (Segmentation r)
resolveSegmentation :: Segmentation RawNames a -> Resolver (Segmentation ResolvedNames) a
resolveSegmentation (UnsegmentedAllNodes info) = pure $ UnsegmentedAllNodes info
resolveSegmentation (UnsegmentedOneNode info node) = pure $ UnsegmentedOneNode info node
resolveSegmentation (SegmentedBy info expr nodelist) = do
expr' <- resolveExpr expr
pure $ SegmentedBy info expr' nodelist
data Node a = Node a Text
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data NodeListOffset a = NodeListOffset a Int
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data NodeList a = AllNodes a (Maybe (NodeListOffset a))
| Nodes a (NonEmpty (Node a))
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data KSafety a = KSafety a (Maybe Int)
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data Partitioning r a = Partitioning a (Expr r a)
deriving instance (ConstrainSNames Data r a, Data r) => Data (Partitioning r a)
deriving instance Generic (Partitioning r a)
deriving instance ConstrainSNames Eq r a => Eq (Partitioning r a)
deriving instance ConstrainSNames Show r a => Show (Partitioning r a)
deriving instance ConstrainSASNames Functor r => Functor (Partitioning r)
deriving instance ConstrainSASNames Foldable r => Foldable (Partitioning r)
deriving instance ConstrainSASNames Traversable r => Traversable (Partitioning r)
resolvePartitioning :: Partitioning RawNames a -> Resolver (Partitioning ResolvedNames) a
resolvePartitioning (Partitioning info expr) = Partitioning info <$> resolveExpr expr
data Encoding a = EncodingAuto a
| EncodingBlockDict a
| EncodingBlockDictComp a
| EncodingBZipComp a
| EncodingCommonDeltaComp a
| EncodingDeltaRangeComp a
| EncodingDeltaVal a
| EncodingGCDDelta a
| EncodingGZipComp a
| EncodingRLE a
| EncodingNone a
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data CreateProjection r a = CreateProjection
{ createProjectionInfo :: a
, createProjectionIfNotExists :: Maybe a
, createProjectionName :: ProjectionName a
, createProjectionColumns :: Maybe (NonEmpty (ProjectionColumn a))
, createProjectionQuery :: Query r a
, createProjectionSegmentation :: Maybe (Segmentation r a)
, createProjectionKSafety :: Maybe (KSafety a)
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (CreateProjection r a)
deriving instance Generic (CreateProjection r a)
deriving instance ConstrainSNames Eq r a => Eq (CreateProjection r a)
deriving instance ConstrainSNames Show r a => Show (CreateProjection r a)
deriving instance ConstrainSASNames Functor r => Functor (CreateProjection r)
deriving instance ConstrainSASNames Foldable r => Foldable (CreateProjection r)
deriving instance ConstrainSASNames Traversable r => Traversable (CreateProjection r)
data ProjectionName a = ProjectionName a (Maybe (QSchemaName Maybe a)) Text
deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data ProjectionColumn a = ProjectionColumn
{ projectionColumnInfo :: a
, projectionColumnName :: Text
, projectionColumnAccessRank :: Maybe (AccessRank a)
, projectionColumnEncoding :: Maybe (Encoding a)
} deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable)
data AccessRank a = AccessRank a Int
deriving (Generic, Data, Read, Show, Eq, Ord, Functor, Foldable, Traversable)
data MultipleRename r a = MultipleRename a [AlterTable r a]
deriving instance (ConstrainSNames Data r a, Data r) => Data (MultipleRename r a)
deriving instance Generic (MultipleRename r a)
deriving instance ConstrainSNames Eq r a => Eq (MultipleRename r a)
deriving instance ConstrainSNames Show r a => Show (MultipleRename r a)
deriving instance ConstrainSASNames Functor r => Functor (MultipleRename r)
deriving instance ConstrainSASNames Foldable r => Foldable (MultipleRename r)
deriving instance ConstrainSASNames Traversable r => Traversable (MultipleRename r)
data SetSchema r a = SetSchema
{ setSchemaInfo :: a
, setSchemaTable :: TableName r a
, setSchemaName :: SchemaName r a
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (SetSchema r a)
deriving instance Generic (SetSchema r a)
deriving instance ConstrainSNames Eq r a => Eq (SetSchema r a)
deriving instance ConstrainSNames Show r a => Show (SetSchema r a)
deriving instance ConstrainSASNames Functor r => Functor (SetSchema r)
deriving instance ConstrainSASNames Foldable r => Foldable (SetSchema r)
deriving instance ConstrainSASNames Traversable r => Traversable (SetSchema r)
data Merge r a = Merge
{ mergeInfo :: a
, mergeTargetTable :: TableName r a
, mergeTargetAlias :: Maybe (TableAlias a)
, mergeSourceTable :: TableName r a
, mergeSourceAlias :: Maybe (TableAlias a)
, mergeCondition :: Expr r a
, mergeUpdateDirective :: Maybe (NonEmpty (ColumnRef r a, DefaultExpr r a))
, mergeInsertDirectiveColumns :: Maybe (NonEmpty (ColumnRef r a))
, mergeInsertDirectiveValues :: Maybe (NonEmpty (DefaultExpr r a))
}
deriving instance (ConstrainSNames Data r a, Data r) => Data (Merge r a)
deriving instance Generic (Merge r a)
deriving instance ConstrainSNames Eq r a => Eq (Merge r a)
deriving instance ConstrainSNames Show r a => Show (Merge r a)
deriving instance ConstrainSASNames Functor r => Functor (Merge r)
deriving instance ConstrainSASNames Foldable r => Foldable (Merge r)
deriving instance ConstrainSASNames Traversable r => Traversable (Merge r)
decomposeMerge :: forall d a . Merge ResolvedNames a -> NonEmpty (Statement d ResolvedNames a)
decomposeMerge Merge{..} = fromList $ catMaybes [ fmap mkInsert mergeInsertDirectiveValues
, fmap mkUpdate mergeUpdateDirective
]
where
r :: a
r = mergeInfo
toAliases :: Maybe (TableAlias a) -> TablishAliases a
toAliases mAlias = case mAlias of
Just alias -> TablishAliasesT alias
Nothing -> TablishAliasesNone
makeExprAlias :: Expr ResolvedNames a -> [ColumnAlias a]
makeExprAlias = const []
lhs :: Tablish ResolvedNames a
lhs = let RTableName lhsFqtn lhsSchemaMember = mergeTargetTable
in TablishTable r (toAliases mergeTargetAlias) (RTableRef lhsFqtn lhsSchemaMember)
rhs :: Tablish ResolvedNames a
rhs = let RTableName rhsFqtn rhsSchemaMember = mergeSourceTable
in TablishTable r (toAliases mergeSourceAlias) (RTableRef rhsFqtn rhsSchemaMember)
mkInsert :: NonEmpty (DefaultExpr ResolvedNames a) -> Statement d ResolvedNames a
mkInsert insertVals =
let selectInfo = r
toSelectExpr (DefaultValue _) = error "don't know how to make SelectExpr from DefaultValue"
toSelectExpr (ExprValue expr) = SelectExpr r (makeExprAlias expr) expr
selectCols = SelectColumns r $ map toSelectExpr $ toList insertVals
selectFrom =
let join' = TablishJoin r (JoinInner r) (JoinOn $ UnOpExpr r "NOT" mergeCondition) lhs rhs
in Just $ SelectFrom r [join']
selectWhere = Nothing
selectTimeseries = Nothing
selectGroup = Nothing
selectHaving = Nothing
selectNamedWindow = Nothing
selectDistinct = Distinct False
insertInfo = r
insertBehavior = InsertAppend r
insertTable = mergeTargetTable
insertColumns = mergeInsertDirectiveColumns
insertValues = InsertSelectValues $ QuerySelect r Select{..}
in InsertStmt Insert{..}
mkUpdate :: NonEmpty (RColumnRef a, DefaultExpr ResolvedNames a) -> Statement d ResolvedNames a
mkUpdate setExprs =
let updateInfo = r
updateTable = mergeTargetTable
updateAlias = mergeTargetAlias
updateSetExprs = setExprs
updateFrom = Just $ TablishJoin r (JoinInner r) (JoinOn mergeCondition) lhs rhs
updateWhere = Nothing
in UpdateStmt Update{..}
instance HasJoins (VerticaStatement ResolvedNames a) where
getJoins (VerticaStandardSqlStatement stmt) = getJoins stmt
getJoins (VerticaCreateProjectionStatement CreateProjection{..}) = getJoins (QueryStmt createProjectionQuery)
getJoins (VerticaMultipleRenameStatement _) = S.empty
getJoins (VerticaSetSchemaStatement _) = S.empty
getJoins (VerticaMergeStatement merge) = foldMap getJoins $ toList $ decomposeMerge merge
getJoins (VerticaUnhandledStatement _) = S.empty
instance HasTableLineage (VerticaStatement ResolvedNames a) where
getTableLineage (VerticaStandardSqlStatement stmt) = tableLineage stmt
getTableLineage (VerticaCreateProjectionStatement _) = M.empty
getTableLineage (VerticaMultipleRenameStatement (MultipleRename _ renames)) =
foldl' (\ ls -> squashTableLineage ls . tableLineage . AlterTableStmt) M.empty renames
getTableLineage (VerticaSetSchemaStatement (SetSchema _ (RTableName fqtn _) (QSchemaName _ (Identity (DatabaseName _ db)) schema schemaType))) = case schemaType of
NormalSchema ->
let from@(FullyQualifiedTableName _ _ table) = mkFQTN fqtn
to = FullyQualifiedTableName db schema table
in M.fromList [(to, S.singleton from), (from, S.empty)]
SessionSchema -> error $ "can't set a table's schema to SessionSchema"
getTableLineage (VerticaMergeStatement merge) = M.unionsWith S.union $ map tableLineage $ toList $ decomposeMerge merge
getTableLineage (VerticaUnhandledStatement _) = M.empty
instance HasColumnLineage (VerticaStatement ResolvedNames Range) where
getColumnLineage (VerticaStandardSqlStatement stmt) = columnLineage stmt
getColumnLineage (VerticaCreateProjectionStatement _) = returnNothing M.empty
getColumnLineage (VerticaMultipleRenameStatement (MultipleRename _ renames)) =
returnNothing $ foldl' (\ ls -> squashColumns ls . snd . columnLineage . AlterTableStmt) M.empty renames
where
squashColumns :: ColumnLineagePlus -> ColumnLineagePlus -> ColumnLineagePlus
squashColumns old new =
let new' = M.map (toColumnPlusSet . M.foldMapWithKey go . fromColumnPlusSet) new
fromColumnPlusSet :: ColumnPlusSet -> Map (Either FQTN FQCN) (Set Range)
fromColumnPlusSet ColumnPlusSet{..} =
M.fromList $ map (Right *** (S.unions . M.elems)) (M.toList columnPlusColumns)
++ map (first Left) (M.toList columnPlusTables)
retuple :: (Either a b, c) -> Either (a, c) (b, c)
retuple (Left x, z) = Left (x, z)
retuple (Right y, z) = Right (y, z)
toColumnPlusSet :: Map (Either FQTN FQCN) (Set Range) -> ColumnPlusSet
toColumnPlusSet ds =
let (ts, cs) = partitionEithers $ map retuple $ M.toList ds
in ColumnPlusSet (M.singleton (FieldChain M.empty) <$> M.fromList cs) (M.fromList ts)
go k v = maybe (M.singleton k v) fromColumnPlusSet $ M.lookup k old
in M.union new' old
getColumnLineage (VerticaSetSchemaStatement (SetSchema _ (RTableName fqtn SchemaMember{..}) schemaName)) =
let from = map (qualifyColumnName fqtn) columnsList
to = map (qualifyColumnName fqtn{tableNameSchema = pure schemaName}) columnsList
in returnNothing
$ M.insert (Left $ fqtnToFQTN fqtn) emptyColumnPlusSet
$ M.insert (Left $ fqtnToFQTN fqtn{tableNameSchema = pure schemaName}) (singleTableSet (getInfo fqtn) $ fqtnToFQTN fqtn)
$ M.union (ColumnPlus.emptyLineage from) $ M.fromList $ zip (map (Right . fqcnToFQCN) to) $ map (singleColumnSet (getInfo fqtn) . fqcnToFQCN) from
getColumnLineage (VerticaMergeStatement merge) = returnNothing $
let x:xs = map (snd . columnLineage) (toList $ decomposeMerge merge)
in foldr (<>) x xs
getColumnLineage (VerticaUnhandledStatement _) = returnNothing M.empty
resolveVerticaStatement :: VerticaStatement RawNames a -> Resolver (VerticaStatement ResolvedNames) a
resolveVerticaStatement (VerticaStandardSqlStatement stmt) = VerticaStandardSqlStatement <$> resolveStatement stmt
resolveVerticaStatement (VerticaCreateProjectionStatement CreateProjection{..}) = do
WithColumns createProjectionQuery' columns <- resolveQueryWithColumns createProjectionQuery
bindColumns columns $ do
createProjectionSegmentation' <- traverse resolveSegmentation createProjectionSegmentation
pure $ VerticaCreateProjectionStatement CreateProjection
{ createProjectionQuery = createProjectionQuery'
, createProjectionSegmentation = createProjectionSegmentation'
, ..
}
resolveVerticaStatement (VerticaMultipleRenameStatement stmt) = VerticaMultipleRenameStatement <$> resolveMultipleRename stmt
resolveVerticaStatement (VerticaSetSchemaStatement stmt) = VerticaSetSchemaStatement <$> resolveSetSchema stmt
resolveVerticaStatement (VerticaMergeStatement Merge{..}) = do
mergeTargetTable'@(RTableName tFqtn tSchemaMember) <- resolveTableName mergeTargetTable
mergeSourceTable'@(RTableName sFqtn sSchemaMember) <- resolveTableName mergeSourceTable
let mkColRefs :: [UQColumnName ()] -> FQTableName a -> [RColumnRef a]
mkColRefs uqcns fqtn = map (\uqcn -> RColumnRef $ uqcn { columnNameInfo = tableNameInfo fqtn
, columnNameTable = Identity fqtn
}) uqcns
tgtColRefs = mkColRefs (columnsList tSchemaMember) tFqtn
tgtColSet = case mergeTargetAlias of
Just alias -> (Just $ RTableAlias alias, tgtColRefs)
Nothing -> (Just $ RTableRef tFqtn tSchemaMember, tgtColRefs)
srcColRefs = mkColRefs (columnsList sSchemaMember) sFqtn
srcColSet = case mergeSourceAlias of
Just alias -> (Just $ RTableAlias alias, srcColRefs)
Nothing -> (Just $ RTableRef sFqtn sSchemaMember, srcColRefs)
mergeCondition' <- bindColumns [srcColSet, tgtColSet] $ resolveExpr mergeCondition
let resolveColRef oqcn = RColumnRef $ oqcn { columnNameTable = Identity tFqtn }
resolveSetExpr (oqcn, expr) = do
expr' <- resolveDefaultExpr expr
return (resolveColRef oqcn, expr')
mergeUpdateDirective' <- bindColumns [srcColSet] $ mapM (mapM resolveSetExpr) mergeUpdateDirective
let mergeInsertDirectiveColumns' = fmap (fmap resolveColRef) mergeInsertDirectiveColumns
mergeInsertDirectiveValues' <- bindColumns [srcColSet] $ mapM (mapM resolveDefaultExpr) mergeInsertDirectiveValues
pure $ VerticaMergeStatement Merge
{ mergeTargetTable = mergeTargetTable'
, mergeSourceTable = mergeSourceTable'
, mergeCondition = mergeCondition'
, mergeUpdateDirective = mergeUpdateDirective'
, mergeInsertDirectiveColumns = mergeInsertDirectiveColumns'
, mergeInsertDirectiveValues = mergeInsertDirectiveValues'
, ..
}
resolveVerticaStatement (VerticaUnhandledStatement info) = pure $ VerticaUnhandledStatement info
resolveMultipleRename :: MultipleRename RawNames a -> Resolver (MultipleRename ResolvedNames) a
resolveMultipleRename (MultipleRename info []) = pure $ MultipleRename info []
resolveMultipleRename (MultipleRename info (a:as)) = do
(a', _) <- listen $ resolveAlterTable a
catalog <- asks catalog
let merge cat ch = fst $ applySchemaChange ch cat
catalog' = foldl' merge catalog $ getSchemaChange a'
MultipleRename info' as' <- local (\ ri -> ri { catalog = catalog' }) $ resolveMultipleRename $ MultipleRename info as
pure $ MultipleRename info' (a':as')
resolveSetSchema :: SetSchema RawNames a -> Resolver (SetSchema ResolvedNames) a
resolveSetSchema SetSchema{..} = do
setSchemaTable' <- resolveTableName setSchemaTable
setSchemaName' <- resolveSchemaName setSchemaName
pure SetSchema
{ setSchemaTable = setSchemaTable'
, setSchemaName = setSchemaName'
, ..
}
instance HasSchemaChange (VerticaStatement ResolvedNames a) where
getSchemaChange (VerticaStandardSqlStatement stmt) = getSchemaChange stmt
getSchemaChange (VerticaCreateProjectionStatement _) = []
getSchemaChange (VerticaMultipleRenameStatement stmt) = getSchemaChange stmt
getSchemaChange (VerticaSetSchemaStatement stmt) = getSchemaChange stmt
getSchemaChange (VerticaMergeStatement _) = []
getSchemaChange (VerticaUnhandledStatement _) = []
instance HasSchemaChange (MultipleRename ResolvedNames a) where
getSchemaChange (MultipleRename _ renames) = renames >>= getSchemaChange
instance HasSchemaChange (SetSchema ResolvedNames a) where
getSchemaChange (SetSchema _ (RTableName fqtn table) schemaName) =
[ Schema.DropTable $ void fqtn
, Schema.CreateTable (void fqtn { tableNameSchema = pure schemaName }) table
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (VerticaStatement r a) where
toJSON (VerticaStandardSqlStatement stmt) = toJSON stmt
toJSON (VerticaCreateProjectionStatement stmt) = toJSON stmt
toJSON (VerticaMultipleRenameStatement stmt) = toJSON stmt
toJSON (VerticaSetSchemaStatement stmt) = toJSON stmt
toJSON (VerticaMergeStatement stmt) = toJSON stmt
toJSON (VerticaUnhandledStatement info) = JSON.object
[ "tag" .= JSON.String "VerticaUnhandledStatement"
, "info" .= info
]
typeExample :: ()
typeExample = const () $ toJSON (undefined :: VerticaStatement ResolvedNames Range)
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (CreateProjection r a) where
toJSON CreateProjection{..} = JSON.object
[ "tag" .= JSON.String "CreateProjection"
, "info" .= createProjectionInfo
, "ifnotexists" .= createProjectionIfNotExists
, "name" .= createProjectionName
, "columns" .= fmap F.toList createProjectionColumns
, "query" .= createProjectionQuery
, "segmentation" .= createProjectionSegmentation
, "ksafety" .= createProjectionKSafety
]
instance ToJSON a => ToJSON (ProjectionColumn a) where
toJSON ProjectionColumn{..} = JSON.object
[ "tag" .= JSON.String "ProjectionColumn"
, "info" .= projectionColumnInfo
, "name" .= projectionColumnName
, "accessrank" .= projectionColumnAccessRank
, "encoding" .= projectionColumnEncoding
]
instance ToJSON a => ToJSON (ProjectionName a) where
toJSON (ProjectionName info schema projection) = JSON.object
[ "tag" .= JSON.String "ProjectionName"
, "info" .= info
, "schema" .= schema
, "projection" .= projection
]
instance ToJSON a => ToJSON (AccessRank a) where
toJSON (AccessRank info rank) = JSON.object
[ "tag" .= JSON.String "AccessRank"
, "info" .= info
, "rank" .= rank
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (TableInfo r a) where
toJSON TableInfo{..} = JSON.object
[ "tag" .= JSON.String "TableInfo"
, "dialect" .= JSON.String "Vertica"
, "ordering" .= tableInfoOrdering
, "encoding" .= tableInfoEncoding
, "segmentation" .= tableInfoSegmentation
, "ksafety" .= tableInfoKSafety
, "partitioning" .= tableInfoPartitioning
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (TableEncoding r a) where
toJSON (TableEncoding info encodings) = JSON.object
[ "tag" .= JSON.String "TableEncoding"
, "info" .= info
, "encodings" .= encodings
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (Segmentation r a) where
toJSON (UnsegmentedAllNodes info) = JSON.object
[ "tag" .= JSON.String "UnsegmentedAllNodes"
, "info" .= info
]
toJSON (UnsegmentedOneNode info node) = JSON.object
[ "tag" .= JSON.String "UnsegmentedAllNodes"
, "info" .= info
, "node" .= node
]
toJSON (SegmentedBy info expr nodes) = JSON.object
[ "tag" .= JSON.String "UnsegmentedAllNodes"
, "info" .= info
, "expr" .= expr
, "nodes" .= nodes
]
instance ToJSON a => ToJSON (KSafety a) where
toJSON (KSafety info factor) = JSON.object
[ "tag" .= JSON.String "KSafety"
, "info" .= info
, "factor" .= factor
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (Partitioning r a) where
toJSON (Partitioning info expr) = JSON.object
[ "tag" .= JSON.String "Partitioning"
, "info" .= info
, "expr" .= expr
]
instance ToJSON a => ToJSON (Encoding a) where
toJSON (EncodingAuto info) = JSON.object
[ "tag" .= JSON.String "EncodingAuto"
, "info" .= info
]
toJSON (EncodingBlockDict info) = JSON.object
[ "tag" .= JSON.String "EncodingBlockDict"
, "info" .= info
]
toJSON (EncodingBlockDictComp info) = JSON.object
[ "tag" .= JSON.String "EncodingBlockDictComp"
, "info" .= info
]
toJSON (EncodingBZipComp info) = JSON.object
[ "tag" .= JSON.String "EncodingBZipComp"
, "info" .= info
]
toJSON (EncodingCommonDeltaComp info) = JSON.object
[ "tag" .= JSON.String "EncodingCommonDeltaComp"
, "info" .= info
]
toJSON (EncodingDeltaRangeComp info) = JSON.object
[ "tag" .= JSON.String "EncodingDeltaRangeComp"
, "info" .= info
]
toJSON (EncodingDeltaVal info) = JSON.object
[ "tag" .= JSON.String "EncodingDeltaVal"
, "info" .= info
]
toJSON (EncodingGCDDelta info) = JSON.object
[ "tag" .= JSON.String "EncodingGCDDelta"
, "info" .= info
]
toJSON (EncodingGZipComp info) = JSON.object
[ "tag" .= JSON.String "EncodingGZipComp"
, "info" .= info
]
toJSON (EncodingRLE info) = JSON.object
[ "tag" .= JSON.String "EncodingRLE"
, "info" .= info
]
toJSON (EncodingNone info) = JSON.object
[ "tag" .= JSON.String "EncodingNone"
, "info" .= info
]
instance ToJSON a => ToJSON (Node a) where
toJSON (Node info name) = JSON.object
[ "tag" .= JSON.String "Node"
, "info" .= info
, "name" .= name
]
instance ToJSON a => ToJSON (NodeList a) where
toJSON (AllNodes info offset) = JSON.object
[ "tag" .= JSON.String "AllNodes"
, "info" .= info
, "offset" .= offset
]
toJSON (Nodes info (n:|ns)) = JSON.object
[ "tag" .= JSON.String "Nodes"
, "info" .= info
, "nodes" .= (n:ns)
]
instance ToJSON a => ToJSON (NodeListOffset a) where
toJSON (NodeListOffset info offset) = JSON.object
[ "tag" .= JSON.String "NodeListOffset"
, "info" .= info
, "offset" .= offset
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (MultipleRename r a) where
toJSON (MultipleRename info renames) = JSON.object
[ "tag" .= JSON.String "MultipleRename"
, "info" .= info
, "renames" .= renames
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (SetSchema r a) where
toJSON (SetSchema info table schema) = JSON.object
[ "tag" .= JSON.String "SetSchema"
, "info" .= info
, "table" .= table
, "schema" .= schema
]
instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (Merge r a) where
toJSON Merge{..} = JSON.object
[ "tag" .= JSON.String "Merge"
, "info" .= mergeInfo
, "mergeTargetTable" .= mergeTargetTable
, "mergeTargetAlias" .= mergeTargetAlias
, "mergeSourceTable" .= mergeSourceTable
, "mergeSourceAlias" .= mergeSourceAlias
, "mergeCondition" .= mergeCondition
, "mergeUpdateDirective" .= fmap toList mergeUpdateDirective
, "mergeInsertDirectiveColumns" .= fmap toList mergeInsertDirectiveColumns
, "mergeInsertDirectiveValues" .= fmap toList mergeInsertDirectiveValues
]
instance HasInfo (TableInfo r a) where
type Info (TableInfo r a) = a
getInfo TableInfo{..} = tableInfoInfo
instance HasInfo (TableEncoding r a) where
type Info (TableEncoding r a) = a
getInfo (TableEncoding info _) = info
instance HasInfo (Segmentation r a) where
type Info (Segmentation r a) = a
getInfo (UnsegmentedAllNodes info) = info
getInfo (UnsegmentedOneNode info _) = info
getInfo (SegmentedBy info _ _) = info
instance HasInfo (Partitioning r a) where
type Info (Partitioning r a) = a
getInfo (Partitioning info _) = info
instance HasInfo (KSafety a) where
type Info (KSafety a) = a
getInfo (KSafety info _) = info
instance HasInfo (NodeList a) where
type Info (NodeList a) = a
getInfo (AllNodes info _) = info
getInfo (Nodes info _) = info
instance HasInfo (NodeListOffset a) where
type Info (NodeListOffset a) = a
getInfo (NodeListOffset info _) = info
instance HasInfo (Node a) where
type Info (Node a) = a
getInfo (Node info _) = info
instance HasInfo (AccessRank a) where
type Info (AccessRank a) = a
getInfo (AccessRank info _) = info
instance HasInfo (Encoding a) where
type Info (Encoding a) = a
getInfo (EncodingAuto info) = info
getInfo (EncodingBlockDict info) = info
getInfo (EncodingBlockDictComp info) = info
getInfo (EncodingBZipComp info) = info
getInfo (EncodingCommonDeltaComp info) = info
getInfo (EncodingDeltaRangeComp info) = info
getInfo (EncodingDeltaVal info) = info
getInfo (EncodingGCDDelta info) = info
getInfo (EncodingGZipComp info) = info
getInfo (EncodingRLE info) = info
getInfo (EncodingNone info) = info
instance HasInfo (ProjectionName a) where
type Info (ProjectionName a) = a
getInfo (ProjectionName info _ _) = info
instance HasInfo (MultipleRename r a) where
type Info (MultipleRename r a) = a
getInfo (MultipleRename info _) = info
instance HasInfo (SetSchema r a) where
type Info (SetSchema r a) = a
getInfo (SetSchema info _ _) = info
instance HasInfo (Merge r a) where
type Info (Merge r a) = a
getInfo Merge{..} = mergeInfo
instance HasTables (VerticaStatement ResolvedNames a) where
goTables (VerticaStandardSqlStatement s) = goTables s
goTables (VerticaCreateProjectionStatement _) = return ()
goTables (VerticaMultipleRenameStatement mr) = goTables mr
goTables (VerticaSetSchemaStatement _) = return ()
goTables (VerticaMergeStatement merge) = goTables merge
goTables (VerticaUnhandledStatement _) = return ()
instance HasTables (MultipleRename ResolvedNames a) where
goTables (MultipleRename _ alters) = mapM_ goTables alters
instance HasTables (Merge ResolvedNames a) where
goTables merge = mapM_ goTables $ toList $ decomposeMerge merge
instance HasColumns (VerticaStatement ResolvedNames a) where
goColumns (VerticaStandardSqlStatement s) = goColumns s
goColumns (VerticaCreateProjectionStatement s) = goColumns s
goColumns (VerticaMultipleRenameStatement _) = return ()
goColumns (VerticaSetSchemaStatement _) = return ()
goColumns (VerticaMergeStatement m) = goColumns m
goColumns (VerticaUnhandledStatement _) = return ()
instance HasColumns (CreateProjection ResolvedNames a) where
goColumns CreateProjection{..} = bindClause "CREATE" $ do
goColumns createProjectionQuery
goColumns createProjectionSegmentation
instance HasColumns (Segmentation ResolvedNames a) where
goColumns (UnsegmentedAllNodes _) = return ()
goColumns (UnsegmentedOneNode _ _) = return ()
goColumns (SegmentedBy _ expr _) = goColumns expr
instance HasColumns (Merge ResolvedNames a) where
goColumns merge = bindClause "MERGE" $ mapM_ goColumns $ toList $ decomposeMerge merge