-- Copyright (c) 2017 Uber Technologies, Inc. -- -- Permission is hereby granted, free of charge, to any person obtaining a copy -- of this software and associated documentation files (the "Software"), to deal -- in the Software without restriction, including without limitation the rights -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -- copies of the Software, and to permit persons to whom the Software is -- furnished to do so, subject to the following conditions: -- -- The above copyright notice and this permission notice shall be included in -- all copies or substantial portions of the Software. -- -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -- THE SOFTWARE. {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE RecordWildCards #-} module Database.Sql.Hive.Type where import Database.Sql.Type hiding (insertValues, insertInfo) 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 import Database.Sql.Util.Scope import Database.Sql.Util.Schema import Database.Sql.Util.Tables import Control.Monad.Identity import Control.Monad.Writer (tell) import Data.Aeson import qualified Data.Map as M import qualified Data.Set as S import Data.Text.Lazy (Text) import qualified Data.Text.Lazy.Encoding as TL import Data.ByteString.Lazy (ByteString) import qualified Data.ByteString.Lazy as BL import Data.Proxy (Proxy (..)) import GHC.Generics (Generic) import Data.Data (Data) data Hive deriving instance Data Hive dialectProxy :: Proxy Hive dialectProxy = Proxy instance Dialect Hive where type DialectCreateTableExtra Hive r = HiveCreateTableExtra r shouldCTEsShadowTables _ = False -- Nothing to resolve in the table extra resolveCreateTableExtra _ HiveCreateTableExtra{..} = pure HiveCreateTableExtra{..} getSelectScope _ fromColumns selectionAliases = SelectScope { bindForWhere = bindFromColumns fromColumns , bindForGroup = bindFromColumns fromColumns , bindForHaving = bindBothColumns fromColumns selectionAliases , bindForOrder = bindAliasedColumns selectionAliases , bindForNamedWindow = bindFromColumns fromColumns } areLcolumnsVisibleInLateralViews _ = False data HiveStatement r a = HiveStandardSqlStatement (Statement Hive r a) | HiveUseStmt (Use a) | HiveAnalyzeStmt (Analyze r a) | HiveInsertDirectoryStmt (InsertDirectory r a) | HiveTruncatePartitionStmt (TruncatePartition r a) | HiveAlterTableSetLocationStmt (AlterTableSetLocation r a) | HiveAlterPartitionSetLocationStmt (AlterPartitionSetLocation r a) | HiveSetPropertyStmt (SetProperty a) | HiveUnhandledStatement a deriving instance (ConstrainSNames Data r a, Data r) => Data (HiveStatement r a) deriving instance Generic (HiveStatement r a) deriving instance ConstrainSNames Eq r a => Eq (HiveStatement r a) deriving instance ConstrainSNames Show r a => Show (HiveStatement r a) deriving instance ConstrainSASNames Functor r => Functor (HiveStatement r) deriving instance ConstrainSASNames Foldable r => Foldable (HiveStatement r) deriving instance ConstrainSASNames Traversable r => Traversable (HiveStatement r) data SetProperty a = SetProperty (SetPropertyDetails a) | PrintProperties a Text deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable) data SetPropertyDetails a = SetPropertyDetails { setPropertyDetailsInfo :: a , setPropertyDetailsName :: Text , setPropertyDetailsValue :: Text } deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable) data HiveCreateTableExtra r a = HiveCreateTableExtra { hiveCreateTableExtraInfo :: a , hiveCreateTableExtraTableProperties :: Maybe (HiveMetadataProperties a) } deriving instance (ConstrainSNames Data r a, Data r) => Data (HiveCreateTableExtra r a) deriving instance Generic (HiveCreateTableExtra r a) deriving instance ConstrainSNames Eq r a => Eq (HiveCreateTableExtra r a) deriving instance ConstrainSNames Show r a => Show (HiveCreateTableExtra r a) deriving instance ConstrainSASNames Functor r => Functor (HiveCreateTableExtra r) deriving instance ConstrainSASNames Foldable r => Foldable (HiveCreateTableExtra r) deriving instance ConstrainSASNames Traversable r => Traversable (HiveCreateTableExtra r) data HiveMetadataProperties a = HiveMetadataProperties { hiveMetadataPropertiesInfo :: a , hiveMetadataPropertiesProperties :: [HiveMetadataProperty a] } deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable) data HiveMetadataProperty a = HiveMetadataProperty { hiveMetadataPropertyInfo :: a , hiveMetadataPropertyKey :: ByteString , hiveMetadataPropertyValue :: ByteString } deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable) -- Important terminology note: -- Hive "databases" are schemas. -- https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL#LanguageManualDDL-Create/Drop/Alter/UseDatabase data Use a = UseDatabase (UQSchemaName a) | UseDefault a deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable) data Analyze r a = Analyze { analyzeInfo :: a , analyzeTable :: TableName r a } deriving instance (ConstrainSNames Data r a, Data r) => Data (Analyze r a) deriving instance Generic (Analyze r a) deriving instance ConstrainSNames Eq r a => Eq (Analyze r a) deriving instance ConstrainSNames Show r a => Show (Analyze r a) deriving instance ConstrainSASNames Functor r => Functor (Analyze r) deriving instance ConstrainSASNames Foldable r => Foldable (Analyze r) deriving instance ConstrainSASNames Traversable r => Traversable (Analyze r) data InsertDirectory r a = InsertDirectory { insertDirectoryInfo :: a , insertDirectoryLocale :: InsertDirectoryLocale a , insertDirectoryPath :: Location a , insertDirectoryQuery :: Query r a } deriving instance (ConstrainSNames Data r a, Data r) => Data (InsertDirectory r a) deriving instance Generic (InsertDirectory r a) deriving instance ConstrainSNames Eq r a => Eq (InsertDirectory r a) deriving instance ConstrainSNames Show r a => Show (InsertDirectory r a) deriving instance ConstrainSASNames Functor r => Functor (InsertDirectory r) deriving instance ConstrainSASNames Foldable r => Foldable (InsertDirectory r) deriving instance ConstrainSASNames Traversable r => Traversable (InsertDirectory r) data Location a = HDFSPath a ByteString deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable) data InsertDirectoryLocale a = InsertDirectoryLocal a | InsertDirectoryHDFS deriving (Generic, Data, Eq, Show, Functor, Foldable, Traversable) data StaticPartitionSpecItem r a = StaticPartitionSpecItem a (ColumnRef r a) (Constant a) deriving instance (ConstrainSNames Data r a, Data r) => Data (StaticPartitionSpecItem r a) deriving instance Generic (StaticPartitionSpecItem r a) deriving instance ConstrainSNames Eq r a => Eq (StaticPartitionSpecItem r a) deriving instance ConstrainSNames Show r a => Show (StaticPartitionSpecItem r a) deriving instance ConstrainSASNames Functor r => Functor (StaticPartitionSpecItem r) deriving instance ConstrainSASNames Foldable r => Foldable (StaticPartitionSpecItem r) deriving instance ConstrainSASNames Traversable r => Traversable (StaticPartitionSpecItem r) data DynamicPartitionSpecItem r a = DynamicPartitionSpecItem a (ColumnRef r a) deriving instance (ConstrainSNames Data r a, Data r) => Data (DynamicPartitionSpecItem r a) deriving instance Generic (DynamicPartitionSpecItem r a) deriving instance ConstrainSNames Eq r a => Eq (DynamicPartitionSpecItem r a) deriving instance ConstrainSNames Show r a => Show (DynamicPartitionSpecItem r a) deriving instance ConstrainSASNames Functor r => Functor (DynamicPartitionSpecItem r) deriving instance ConstrainSASNames Foldable r => Foldable (DynamicPartitionSpecItem r) deriving instance ConstrainSASNames Traversable r => Traversable (DynamicPartitionSpecItem r) -- Note: We don't track anything at the partition level (for now), so -- we discard the info on which particular partition is being truncated. data TruncatePartition r a = TruncatePartition { truncatePartitionInfo :: a , truncatePartitionTruncate :: Truncate r a } deriving instance (ConstrainSNames Data r a, Data r) => Data (TruncatePartition r a) deriving instance Generic (TruncatePartition r a) deriving instance ConstrainSNames Eq r a => Eq (TruncatePartition r a) deriving instance ConstrainSNames Show r a => Show (TruncatePartition r a) deriving instance ConstrainSASNames Functor r => Functor (TruncatePartition r) deriving instance ConstrainSASNames Foldable r => Foldable (TruncatePartition r) deriving instance ConstrainSASNames Traversable r => Traversable (TruncatePartition r) data AlterTableSetLocation r a = AlterTableSetLocation { alterTableSetLocationInfo :: a , alterTableSetLocationTable :: TableName r a , alterTableSetLocationLocation :: Location a } deriving instance (ConstrainSNames Data r a, Data r) => Data (AlterTableSetLocation r a) deriving instance ConstrainSNames Eq r a => Eq (AlterTableSetLocation r a) deriving instance ConstrainSNames Show r a => Show (AlterTableSetLocation r a) deriving instance ConstrainSASNames Functor r => Functor (AlterTableSetLocation r) deriving instance ConstrainSASNames Foldable r => Foldable (AlterTableSetLocation r) deriving instance ConstrainSASNames Traversable r => Traversable (AlterTableSetLocation r) data AlterPartitionSetLocation r a = AlterPartitionSetLocation { alterPartitionSetLocationInfo :: a , alterPartitionSetLocationTable :: TableName r a , alterPartitionSetLocationPartition :: [StaticPartitionSpecItem r a] , alterPartitionSetLocationLocation :: Location a } deriving instance (ConstrainSNames Data r a, Data r) => Data (AlterPartitionSetLocation r a) deriving instance ConstrainSNames Eq r a => Eq (AlterPartitionSetLocation r a) deriving instance ConstrainSNames Show r a => Show (AlterPartitionSetLocation r a) deriving instance ConstrainSASNames Functor r => Functor (AlterPartitionSetLocation r) deriving instance ConstrainSASNames Foldable r => Foldable (AlterPartitionSetLocation r) deriving instance ConstrainSASNames Traversable r => Traversable (AlterPartitionSetLocation r) instance HasJoins (HiveStatement ResolvedNames a) where getJoins (HiveStandardSqlStatement stmt) = getJoins stmt getJoins (HiveInsertDirectoryStmt stmt) = getJoins (QueryStmt $ insertDirectoryQuery stmt) getJoins (HiveUseStmt _) = S.empty getJoins (HiveAnalyzeStmt _) = S.empty getJoins (HiveTruncatePartitionStmt _) = S.empty getJoins (HiveAlterTableSetLocationStmt _) = S.empty getJoins (HiveAlterPartitionSetLocationStmt _) = S.empty getJoins (HiveSetPropertyStmt _) = S.empty getJoins (HiveUnhandledStatement _) = S.empty instance HasTableLineage (HiveStatement ResolvedNames a) where getTableLineage (HiveStandardSqlStatement stmt) = tableLineage stmt getTableLineage (HiveUseStmt _) = M.empty getTableLineage (HiveAnalyzeStmt _) = M.empty getTableLineage (HiveInsertDirectoryStmt _) = M.empty getTableLineage (HiveTruncatePartitionStmt (TruncatePartition _ (Truncate _ (RTableName t _)))) = let table = mkFQTN t in M.singleton table $ S.singleton table getTableLineage (HiveAlterTableSetLocationStmt _) = M.empty getTableLineage (HiveAlterPartitionSetLocationStmt _) = M.empty getTableLineage (HiveSetPropertyStmt _) = M.empty getTableLineage (HiveUnhandledStatement _) = M.empty instance HasColumnLineage (HiveStatement ResolvedNames Range) where getColumnLineage (HiveStandardSqlStatement stmt) = columnLineage stmt getColumnLineage (HiveUseStmt _) = returnNothing M.empty getColumnLineage (HiveAnalyzeStmt _) = returnNothing M.empty getColumnLineage (HiveInsertDirectoryStmt _) = returnNothing M.empty getColumnLineage (HiveTruncatePartitionStmt (TruncatePartition _ (Truncate _ (RTableName t SchemaMember{..})))) = returnNothing $ M.insert (Left $ fqtnToFQTN t) (singleTableSet (getInfo t) $ fqtnToFQTN t) $ M.fromList $ map ((\ fqcn -> (Right fqcn, singleColumnSet (getInfo t) fqcn)) . fqcnToFQCN . qualifyColumnName t) columnsList getColumnLineage (HiveAlterTableSetLocationStmt _) = returnNothing M.empty getColumnLineage (HiveAlterPartitionSetLocationStmt _) = returnNothing M.empty getColumnLineage (HiveSetPropertyStmt _) = returnNothing M.empty getColumnLineage (HiveUnhandledStatement _) = returnNothing M.empty resolveHiveStatement :: HiveStatement RawNames a -> Resolver (HiveStatement ResolvedNames) a resolveHiveStatement (HiveStandardSqlStatement stmt) = HiveStandardSqlStatement <$> resolveStatement stmt resolveHiveStatement (HiveUseStmt stmt) = pure $ HiveUseStmt stmt resolveHiveStatement (HiveAnalyzeStmt stmt) = HiveAnalyzeStmt <$> resolveAnalyze stmt resolveHiveStatement (HiveInsertDirectoryStmt stmt) = HiveInsertDirectoryStmt <$> resolveInsertDirectory stmt resolveHiveStatement (HiveTruncatePartitionStmt stmt) = HiveTruncatePartitionStmt <$> resolveTruncatePartition stmt resolveHiveStatement (HiveAlterTableSetLocationStmt stmt) = HiveAlterTableSetLocationStmt <$> resolveAlterTableSetLocation stmt resolveHiveStatement (HiveAlterPartitionSetLocationStmt stmt) = HiveAlterPartitionSetLocationStmt <$> resolveAlterPartitionSetLocation stmt resolveHiveStatement (HiveSetPropertyStmt stmt) = pure $ HiveSetPropertyStmt stmt resolveHiveStatement (HiveUnhandledStatement stmt) = pure $ HiveUnhandledStatement stmt resolveAnalyze :: Analyze RawNames a -> Resolver (Analyze ResolvedNames) a resolveAnalyze Analyze{..} = do analyzeTable' <- resolveTableName analyzeTable pure Analyze { analyzeTable = analyzeTable' , .. } resolveInsertDirectory :: InsertDirectory RawNames a -> Resolver (InsertDirectory ResolvedNames) a resolveInsertDirectory InsertDirectory{..} = do insertDirectoryQuery' <- resolveQuery insertDirectoryQuery pure InsertDirectory { insertDirectoryQuery = insertDirectoryQuery' , .. } resolveTruncatePartition :: TruncatePartition RawNames a -> Resolver (TruncatePartition ResolvedNames) a resolveTruncatePartition TruncatePartition{..} = do truncatePartitionTruncate' <- resolveTruncate truncatePartitionTruncate pure TruncatePartition { truncatePartitionTruncate = truncatePartitionTruncate' , .. } resolveAlterTableSetLocation :: AlterTableSetLocation RawNames a -> Resolver (AlterTableSetLocation ResolvedNames) a resolveAlterTableSetLocation AlterTableSetLocation{..} = do alterTableSetLocationTable' <- resolveTableName alterTableSetLocationTable pure AlterTableSetLocation { alterTableSetLocationTable = alterTableSetLocationTable' , .. } resolveAlterPartitionSetLocation :: AlterPartitionSetLocation RawNames a -> Resolver (AlterPartitionSetLocation ResolvedNames) a resolveAlterPartitionSetLocation AlterPartitionSetLocation{..} = do alterPartitionSetLocationTable'@(RTableName fqtn table@SchemaMember{..}) <- resolveTableName alterPartitionSetLocationTable let tableInfo = tableNameInfo fqtn columnSet = [ ( Just $ RTableRef fqtn table , map (RColumnRef . (const tableInfo <$>) . qualifyColumnName fqtn) columnsList ) ] alterPartitionSetLocationPartition' <- bindColumns columnSet $ forM alterPartitionSetLocationPartition $ \ (StaticPartitionSpecItem info column constant) -> do column' <- resolveColumnName column pure $ StaticPartitionSpecItem info column' constant pure AlterPartitionSetLocation { alterPartitionSetLocationTable = alterPartitionSetLocationTable' , alterPartitionSetLocationPartition = alterPartitionSetLocationPartition' , .. } instance HasSchemaChange (HiveStatement ResolvedNames a) where getSchemaChange (HiveStandardSqlStatement stmt) = getSchemaChange stmt getSchemaChange (HiveUseStmt (UseDefault _)) = [UsePath [QSchemaName () None "default" NormalSchema]] getSchemaChange (HiveUseStmt (UseDatabase schema)) = [UsePath [void schema]] getSchemaChange (HiveAnalyzeStmt _) = [] getSchemaChange (HiveInsertDirectoryStmt _) = [] getSchemaChange (HiveTruncatePartitionStmt _) = [] getSchemaChange (HiveAlterTableSetLocationStmt _) = [] -- In fact, it may very well have a schema change but -- we can't know without hitting the metastore. getSchemaChange (HiveAlterPartitionSetLocationStmt _) = [] getSchemaChange (HiveSetPropertyStmt _) = [] getSchemaChange (HiveUnhandledStatement _) = [] instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (HiveStatement r a) where toJSON (HiveStandardSqlStatement stmt) = toJSON stmt toJSON (HiveInsertDirectoryStmt stmt) = object [ "tag" .= String "InsertDirectoryStmt" , "target" .= stmt ] toJSON (HiveUseStmt stmt) = object [ "tag" .= String "UseStmt" , "target" .= stmt ] toJSON (HiveAnalyzeStmt stmt) = object [ "tag" .= String "AnalyzeStmt" , "target" .= stmt ] toJSON (HiveTruncatePartitionStmt truncatePartition) = object [ "tag" .= String "HiveTruncatePartitionStmt" , "statement" .= truncatePartition ] toJSON (HiveAlterTableSetLocationStmt alterTableSetLocation) = object [ "tag" .= String "HiveAlterTableSetLocationStmt" , "statement" .= alterTableSetLocation ] toJSON (HiveAlterPartitionSetLocationStmt alterPartitionSetLocation) = object [ "tag" .= String "HiveAlterPartitionSetLocationStmt" , "statement" .= alterPartitionSetLocation ] toJSON (HiveSetPropertyStmt stmt) = object [ "tag" .= String "HiveSetPropertyStmt" , "info" .= stmt ] toJSON (HiveUnhandledStatement info) = object [ "tag" .= String "HiveUnhandledStatement" , "info" .= info ] typeExample :: () typeExample = const () $ toJSON (undefined :: HiveStatement ResolvedNames Range) instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (HiveCreateTableExtra r a) where toJSON HiveCreateTableExtra{..} = object [ "tag" .= String "HiveCreateTableExtra" , "info" .= hiveCreateTableExtraInfo , "properties" .= hiveCreateTableExtraTableProperties ] instance ToJSON a => ToJSON (HiveMetadataProperties a) where toJSON HiveMetadataProperties{..} = object [ "tag" .= String "HiveMetadataProperties" , "info" .= hiveMetadataPropertiesInfo , "properties" .= hiveMetadataPropertiesProperties ] instance ToJSON a => ToJSON (HiveMetadataProperty a) where toJSON HiveMetadataProperty{..} = object [ "tag" .= String "MetadataProperty" , "info" .= hiveMetadataPropertyInfo , "key" .= bsToJSON hiveMetadataPropertyKey , "value" .= bsToJSON hiveMetadataPropertyValue ] bsToJSON :: ByteString -> Value bsToJSON bs = case TL.decodeUtf8' bs of Left _ -> toJSON $ BL.unpack bs Right str -> toJSON str instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (InsertDirectory r a) where toJSON stmt = object [ "tag" .= String "InsertDirectory" , "info" .= insertDirectoryInfo stmt , "directory" .= insertDirectoryPath stmt , "locale" .= insertDirectoryLocale stmt , "values" .= insertDirectoryQuery stmt ] instance ToJSON a => ToJSON (Location a) where toJSON (HDFSPath _ p) = bsToJSON p instance ToJSON a => ToJSON (InsertDirectoryLocale a) where toJSON (InsertDirectoryLocal _) = String "Local" toJSON InsertDirectoryHDFS = String "HDFS" instance ToJSON a => ToJSON (Use a) where toJSON (UseDatabase dbn) = toJSON dbn toJSON (UseDefault _) = String "Default" instance ToJSON a => ToJSON (SetProperty a) where toJSON (SetProperty details) = toJSON details toJSON (PrintProperties info t) = object [ "tag" .= String "Set" , "info" .= info , "property" .= t ] instance ToJSON a => ToJSON (SetPropertyDetails a) where toJSON d@SetPropertyDetails{} = object [ "tag" .= String "Set" , "info" .= setPropertyDetailsInfo d , "property" .= setPropertyDetailsName d , "value" .= setPropertyDetailsValue d ] instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (Analyze r a) where toJSON (Analyze info tbn) = object [ "tag" .= String "Analyze" , "info" .= info , "table" .= toJSON tbn ] instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (TruncatePartition r a) where toJSON (TruncatePartition info truncate') = object [ "tag" .= String "TruncatePartition" , "info" .= info , "truncate" .= truncate' ] instance HasInfo (TruncatePartition r a) where type Info (TruncatePartition r a) = a getInfo (TruncatePartition info _) = info instance HasInfo (Location a) where type Info (Location a) = a getInfo (HDFSPath info _) = info instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (AlterTableSetLocation r a) where toJSON (AlterTableSetLocation info table location) = object [ "tag" .= String "AlterTableSetLocation" , "info" .= info , "table" .= table , "location" .= location ] instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (AlterPartitionSetLocation r a) where toJSON (AlterPartitionSetLocation info table items location) = object [ "tag" .= String "AlterPartitionSetLocation" , "info" .= info , "table" .= table , "items" .= items , "location" .= location ] instance (ConstrainSNames ToJSON r a, ToJSON a) => ToJSON (StaticPartitionSpecItem r a) where toJSON (StaticPartitionSpecItem info column constant) = object [ "tag" .= String "StaticPartitionSpecItem" , "info" .= info , "column" .= column , "constant" .= constant ] instance HasTables (HiveStatement ResolvedNames a) where goTables (HiveStandardSqlStatement s) = goTables s goTables (HiveUseStmt _) = return () goTables (HiveAnalyzeStmt _) = return () goTables (HiveInsertDirectoryStmt s) = goTables s goTables (HiveTruncatePartitionStmt s) = goTables s goTables (HiveAlterTableSetLocationStmt s) = goTables s goTables (HiveAlterPartitionSetLocationStmt (AlterPartitionSetLocation _ (RTableName fqtn _) _ _)) = tell $ S.singleton $ TableUse WriteMeta $ fqtnToFQTN fqtn goTables (HiveSetPropertyStmt _) = return () goTables (HiveUnhandledStatement _) = return () instance HasTables (InsertDirectory ResolvedNames a) where goTables InsertDirectory{..} = goTables insertDirectoryQuery instance HasTables (TruncatePartition ResolvedNames a) where goTables (TruncatePartition _ s) = goTables s instance HasTables (AlterTableSetLocation ResolvedNames a) where goTables (AlterTableSetLocation _ table _) = do goTables table instance HasColumns (HiveStatement ResolvedNames a) where goColumns (HiveStandardSqlStatement s) = goColumns s goColumns (HiveUseStmt _) = return () goColumns (HiveAnalyzeStmt _) = return () goColumns (HiveInsertDirectoryStmt s) = goColumns s goColumns (HiveTruncatePartitionStmt _) = return () goColumns (HiveAlterTableSetLocationStmt _) = return () goColumns (HiveAlterPartitionSetLocationStmt (AlterPartitionSetLocation _ _ items _)) = forM_ items $ \ (StaticPartitionSpecItem _ column _) -> tell [clauseObservation (void column) "PARTITION"] goColumns (HiveSetPropertyStmt _) = return () goColumns (HiveUnhandledStatement _) = return () instance HasColumns (InsertDirectory ResolvedNames a) where goColumns InsertDirectory{..} = goColumns insertDirectoryQuery