hydra-0.15.0: src/main/haskell/Hydra/Sources/Kusto/Kql.hs
module Hydra.Sources.Kusto.Kql where
-- Standard imports for type-level sources outside of the kernel
import Hydra.Kernel
import Hydra.Dsl.Annotations
import Hydra.Dsl.Bootstrap
import Hydra.Dsl.Types ((>:))
import qualified Hydra.Dsl.Types as T
import qualified Hydra.Sources.Kernel.Types.Core as Core
import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S
import qualified Data.Maybe as Y
ns :: Namespace
ns = Namespace "hydra.kusto.kql"
define :: String -> Type -> Binding
define = defineType ns
kql :: String -> Type
kql = typeref ns
module_ :: Module
module_ = Module {
moduleNamespace = ns,
moduleDefinitions = (map toTypeDef definitions),
moduleTermDependencies = [Core.ns],
moduleTypeDependencies = [Core.ns],
moduleDescription = Just ("A partial KQL (Kusto Query Language) model, based on examples from the documentation. Not normative.")}
where
definitions = [
betweenExpression,
binaryExpression,
binaryOperator,
builtInFunction,
columnAlias,
columnAssignment,
columnName,
columns,
command,
datetime,
duration,
durationUnit,
expression,
function_,
functionExpression,
functionName,
indexExpression,
joinCommand,
joinKind,
keyValuePair,
letBinding,
letExpression,
literal_,
order,
parameter,
parseCommand,
pipelineExpression,
printCommand,
projection,
propertyExpression,
query,
searchCommand,
summarizeCommand,
tableName,
topCommand,
sortBy,
tabularExpression,
unaryExpression,
unaryOperator,
unionCommand,
unionKind]
betweenExpression :: Binding
betweenExpression = define "BetweenExpression" $
T.record [
"not">: T.boolean,
"expression">: kql "Expression",
"lowerBound">: kql "Expression",
"upperBound">: kql "Expression"]
binaryExpression :: Binding
binaryExpression = define "BinaryExpression" $
T.record [
"left">: kql "Expression",
"operator">: kql "BinaryOperator",
"right">: kql "Expression"]
binaryOperator :: Binding
binaryOperator = define "BinaryOperator" $
T.enum [
"caseInsensitiveEqual",
"contains",
"divide",
"endsWith",
"equal",
"greater",
"greaterOrEqual",
"has",
"hasPrefix",
"hasSuffix",
"less",
"lessOrEqual",
"matchesRegex",
"minus",
"notEqual",
"plus",
"startsWith",
"times"]
builtInFunction :: Binding
builtInFunction = define "BuiltInFunction" $
T.enum [
"ago",
"bin",
"count",
"dcount",
"endofday",
"extract",
"format_datetime",
"materialize",
"now",
"range",
"startofday",
"strcat",
"todynamic"]
columnAlias :: Binding
columnAlias = define "ColumnAlias" $
T.record [
"column">: kql "ColumnName",
"alias">: kql "ColumnName"]
columnAssignment :: Binding
columnAssignment = define "ColumnAssignment" $
T.record [
"column">: kql "ColumnName",
"expression">: kql "Expression"]
columnName :: Binding
columnName = define "ColumnName" $ T.wrap T.string
columns :: Binding
columns = define "Columns" $
T.union [
"all">: T.unit,
"single">: kql "ColumnName"]
command :: Binding
command = define "Command" $
T.union [
"count">: T.unit,
"distinct">:
doc "See https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/distinct-operator" $
nonemptyList $ kql "ColumnName",
"extend">: nonemptyList $ kql "ColumnAssignment",
"join">: kql "JoinCommand",
"limit">: T.int32,
"mvexpand">: kql "ColumnName",
"orderBy">: nonemptyList $ kql "SortBy",
"parse">: kql "ParseCommand",
"print">: kql "PrintCommand",
"project">: nonemptyList $ kql "Projection",
"projectAway">: nonemptyList $ kql "ColumnName",
"projectRename">: nonemptyList $ kql "ColumnAlias",
"render">: T.string,
"search">: kql "SearchCommand",
"sortBy">: nonemptyList $ kql "SortBy",
"summarize">: kql "SummarizeCommand",
"take">:
doc "Limit a search to a specified number of results"
T.int32,
"top">: kql "TopCommand",
"union">: kql "UnionCommand",
"where">: kql "Expression"]
datetime :: Binding
datetime = define "Datetime" $ T.wrap T.string
duration :: Binding
duration = define "Duration" $
T.record [
"value">: T.int32,
"unit">: kql "DurationUnit"]
durationUnit :: Binding
durationUnit = define "DurationUnit" $
T.enum ["second", "minute", "hour"]
expression :: Binding
expression = define "Expression" $
T.union [
"and">: nonemptyList $ kql "Expression",
"any">: T.unit,
"between">: kql "BetweenExpression",
"binary">: kql "BinaryExpression",
"braces">: kql "Expression", -- TODO: what do braces represent? E.g. "let timeRange = {TimeRange}"
"column">: kql "ColumnName",
"dataset">: kql "TableName",
"index">: kql "IndexExpression",
"list">: T.list $ kql "Expression",
"literal">: kql "Literal",
"or">: nonemptyList $ kql "Expression",
"parentheses">: kql "Expression",
"property">: kql "PropertyExpression",
"unary">: kql "UnaryExpression"]
function_ :: Binding
function_ = define "Function" $
T.union [
"builtIn">: kql "BuiltInFunction",
"custom">: kql "FunctionName"]
functionExpression :: Binding
functionExpression = define "FunctionExpression" $
T.record [
"function">: kql "Function",
"arguments">: T.list $ kql "Expression"]
functionName :: Binding
functionName = define "FunctionName" $ T.wrap T.string
indexExpression :: Binding
indexExpression = define "IndexExpression" $
T.record [
"expression">: kql "Expression",
"index">: T.string]
joinCommand :: Binding
joinCommand = define "JoinCommand" $
T.record [
"kind">: kql "JoinKind",
"expression">: kql "TableName",
"on">: kql "Expression"]
joinKind :: Binding
joinKind = define "JoinKind" $
T.enum ["leftouter", "leftsemi", "leftanti", "fullouter", "inner", "innerunique", "rightouter", "rightsemi", "rightanti"]
keyValuePair :: Binding
keyValuePair = define "KeyValuePair" $
T.record [
"key">: T.string,
"value">: kql "Expression"]
letBinding :: Binding
letBinding = define "LetBinding" $
T.record [
"name">: kql "ColumnName",
"expression">: kql "Expression"]
letExpression :: Binding
letExpression = define "LetExpression" $
T.record [
"bindings">: nonemptyList $ kql "LetBinding",
"expression">: kql "TabularExpression"]
literal_ :: Binding
literal_ = define "Literal" $
T.union [
"duration">: kql "Duration",
"datetime">: kql "Datetime",
"string">: T.string,
-- TODO: unverified
"int">: T.int32,
"long">: T.int64,
"double">: T.float64,
"boolean">: T.boolean]
order :: Binding
order = define "Order" $
T.enum ["ascending", "descending"]
parameter :: Binding
parameter = define "Parameter" $
T.record [
"key">: T.string,
"value">: kql "Literal"]
parseCommand :: Binding
parseCommand = define "ParseCommand" $
T.record [
"column">: kql "ColumnName",
"pairs">: nonemptyList $ kql "KeyValuePair"]
-- TODO: what are these expressions actually called in KQL?
pipelineExpression :: Binding
pipelineExpression = define "PipelineExpression" $
T.wrap $ nonemptyList $ kql "TabularExpression"
printCommand :: Binding
printCommand = define "PrintCommand" $
T.record [
"column">: T.maybe $ kql "ColumnName",
"expression">: kql "Expression"]
projection :: Binding
projection = define "Projection" $
T.record [
"expression">: kql "Expression",
"alias">: T.maybe $ kql "ColumnName"]
propertyExpression :: Binding
propertyExpression = define "PropertyExpression" $
T.record [
"expression">: kql "Expression",
"property">: T.string]
query :: Binding
query = define "Query" $ T.wrap $ kql "TabularExpression"
searchCommand :: Binding
searchCommand = define "SearchCommand" $
doc "Search across all datasets and columns or, if provided, specific datasets and/or columns" $
T.record [
"datasets">: T.list $ kql "TableName",
"pattern">: kql "Expression"]
summarizeCommand :: Binding
summarizeCommand = define "SummarizeCommand" $
T.record [
"columns">: nonemptyList $ kql "ColumnAssignment",
"by">: T.list $ kql "ColumnName"]
tableName :: Binding
tableName = define "TableName" $ T.wrap T.string
topCommand :: Binding
topCommand = define "TopCommand" $
T.record [
"count">: T.int32,
"sort">: T.list $ kql "SortBy"]
sortBy :: Binding
sortBy = define "SortBy" $
T.record [
"column">: kql "ColumnName",
"order">: T.maybe $ kql "Order"]
tabularExpression :: Binding
tabularExpression = define "TabularExpression" $
T.union [
"command">: kql "Command",
"pipeline">: kql "PipelineExpression",
"let">: kql "LetExpression",
"table">: kql "TableName"]
unaryExpression :: Binding
unaryExpression = define "UnaryExpression" $
T.record [
"operator">: kql "UnaryOperator",
"expression">: kql "Expression"]
unaryOperator :: Binding
unaryOperator = define "UnaryOperator" $
T.enum ["not"]
unionCommand :: Binding
unionCommand = define "UnionCommand" $
T.record [
"parameters">: T.list $ kql "Parameter",
"kind">: T.maybe $ kql "UnionKind",
"withSource">: T.maybe $ kql "ColumnName",
"isFuzzy">: T.maybe T.boolean,
"tables">: nonemptyList $ kql "TableName"]
unionKind :: Binding
unionKind = define "UnionKind" $
T.enum ["inner", "outer"]