added Flux language spec to reference section

pull/22/head
Scott Anderson 2019-01-21 22:01:38 -07:00
parent 9c45700db1
commit 8e254a3b43
19 changed files with 1474 additions and 0 deletions

View File

@ -0,0 +1,12 @@
---
title: Flux query language
description: placeholder
menu:
v2_0_ref:
name: Flux query language
weight: 2
---
[Flux functions](/v2.0/reference/flux/functions/)
[Flux language specification](/v2.0/reference/flux/language/)

View File

@ -0,0 +1,47 @@
---
title: Flux language specification
description: >
Covers the current and future Flux functional data scripting language,
which is designed for querying, analyzing, and acting on data.
menu:
v2_0_ref:
name: Flux language specification
parent: Flux query language
weight: 5
---
The following document specifies the Flux language and query execution.
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
The Flux language is centered on querying and manipulating time series data.
### Notation
The syntax of the language is specified using [Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form):
```js
Production = production_name "=" [ Expression ] "." .
Expression = Alternative { "|" Alternative } .
Alternative = Term { Term } .
Term = production_name | token [ "…" token ] | Group | Option | Repetition .
Group = "(" Expression ")" .
Option = "[" Expression "]" .
Repetition = "{" Expression "}" .
```
Productions are expressions constructed from terms and the following operators, in increasing precedence:
```
| alternation
() grouping
[] option (0 or 1 times)
{} repetition (0 to n times)
```
Lower-case production names are used to identify lexical tokens.
Non-terminals are in Camel case.
Lexical tokens are enclosed in double quotes (`""`) or back quotes (``).

View File

@ -0,0 +1,83 @@
---
title: Assignment and scope
description: An assignment binds an identifier to a variable, option, or function. Every identifier in a program must be assigned.
menu:
v2_0_ref:
parent: Flux language specification
name: Assignment and scope
weight: 20
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
An assignment binds an identifier to a variable, option, or function.
Every identifier in a program must be assigned.
Flux is lexically scoped using blocks:
1. The scope of a preassigned identifier is in the universe block.
2. The scope of an identifier denoting a variable, option, or function at the top level (outside any function) is the package block.
3. The scope of the name of an imported package is the file block of the file containing the import declaration.
4. The scope of an identifier denoting a function argument is the function body.
5. The scope of an identifier assigned inside a function is the innermost containing block.
An identifier assigned in a block may be reassigned in an inner block with the exception of option identifiers.
While the identifier of the inner assignment is in scope, it denotes the entity assigned by the inner assignment.
Note that the package clause is not an assignment.
The package name does not appear in any scope.
Its purpose is to identify the files belonging to the same package and to specify the default package name for import declarations.
{{% note %}}
To be implemented: [IMPL#247](https://github.com/influxdata/platform/issues/247) Add package/namespace support.
{{% /note %}}
## Variable assignment
A variable assignment creates a variable bound to an identifier and gives it a type and value.
A variable keeps the same type and value for the remainder of its lifetime.
An identifier assigned to a variable in a block cannot be reassigned in the same block.
An identifier can be reassigned or shadowed in an inner block.
```js
VariableAssignment = identifier "=" Expression
```
##### Examples of variable assignment
```js
n = 1
m = 2
x = 5.4
f = () => {
n = "a"
m = "b"
return a + b
}
```
## Option assignment
```js
OptionAssignment = "option" [ identifier "." ] identifier "=" Expression
```
An option assignment creates an option bound to an identifier and gives it a type and a value.
Options may only be assigned in a package block.
An identifier assigned to an option may be reassigned a new value but not a new type.
An option keeps the same type for the remainder of its lifetime.
###### Examples
```js
// alert package
option severity = ["low", "moderate", "high"]
// foo package
import "alert"
option alert.severity = ["low", "critical"] // qualified option
option n = 1
option n = 2
f = (a, b) => a + b + n
x = f(a:1, b:1) // x = 4
```

View File

@ -0,0 +1,25 @@
---
title: Blocks
description: A block is a possibly empty sequence of statements within matching braces ({}).
menu:
v2_0_ref:
parent: Flux language specification
name: Blocks
weight: 30
---
A _block_ is a possibly empty sequence of statements within matching braces (`{}`).
```
Block = "{" StatementList "} .
StatementList = { Statement } .
```
In addition to _explicit blocks_ in the source code, there are _implicit blocks_:
1. The _universe block_ encompasses all Flux source text.
2. Each package has a _package block_ containing all Flux source text for that package.
3. Each file has a _file block_ containing all Flux source text in that file.
4. Each function literal has its own _function block_ even if not explicitly declared.
Blocks nest and influence scoping.

View File

@ -0,0 +1,20 @@
---
title: Built-ins
description: >
Flux contains many preassigned values.
These preassigned values are defined in the source files for the various built-in packages.
menu:
v2_0_ref:
name: Built-ins
parent: Flux language specification
weight: 80
---
Flux contains many preassigned values.
These preassigned values are defined in the source files for the various built-in packages.
## [System built-ins](/flux/v0.x/language/built-ins/system-built-ins)
When a built-in value is not expressible in Flux, its value may be defined by the hosting environment.
## [Time constants](/flux/v0.x/language/built-ins/time-constants)
When a built-in value is not expressible in Flux, its value may be defined by the hosting environment.

View File

@ -0,0 +1,24 @@
---
title: System built-ins
description: >
When a built-in value is not expressible in Flux, its value may be defined by the hosting environment.
All such values must have a corresponding builtin statement to declare the existence and type of the built-in value.
menu:
v2_0_ref:
name: System built-ins
parent: Built-ins
weight: 80
---
When a built-in value is not expressible in Flux, its value may be defined by the hosting environment.
All such values must have a corresponding builtin statement to declare the existence and type of the built-in value.
```js
BuiltinStatement = "builtin" identifer ":" TypeExpression
```
##### Example
```js
builtin from : (bucket: string, bucketID: string) -> stream
```

View File

@ -0,0 +1,56 @@
---
title: Time constants
description: >
Flux provides built-in time constants for days of the week and months of the year.
menu:
v2_0_ref:
name: Time constants
parent: Built-ins
weight: 80
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
## Days of the week
Days of the week are represented as integers in the range `[0-6]`.
The following builtin values are defined:
```js
Sunday = 0
Monday = 1
Tuesday = 2
Wednesday = 3
Thursday = 4
Friday = 5
Saturday = 6
```
{{% note %}}
To be implemented: [IMPL#153](https://github.com/influxdata/flux/issues/153) Add Days of the Week constants
{{% /note %}}
## Months of the year
Months are represented as integers in the range `[1-12]`.
The following builtin values are defined:
```js
January = 1
February = 2
March = 3
April = 4
May = 5
June = 6
July = 7
August = 8
September = 9
October = 10
November = 11
December = 12
```
{{% note %}}
To be implemented: [IMPL#154](https://github.com/influxdata/flux/issues/154) Add Months of the Year constants
{{% /note %}}

View File

@ -0,0 +1,60 @@
---
title: Flux data model
description: Flux employs a basic data model built from basic data types. The data model consists of tables, records, columns and streams.
menu:
v2_0_ref:
name: Data model
parent: Flux language specification
weight: 1
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
Flux employs a basic data model built from basic data types.
The data model consists of tables, records, columns and streams.
## Record
A **record** is a tuple of named values and is represented using an object type.
## Column
A **column** has a label and a data type.
The available data types for a column are:
| Data type | Description |
| --------- |:----------- |
| bool | A boolean value, true or false. |
| uint | An unsigned 64-bit integer. |
| int | A signed 64-bit integer. |
| float | An IEEE-754 64-bit floating-point number. |
| string | A sequence of unicode characters. |
| bytes | A sequence of byte values. |
| time | A nanosecond precision instant in time. |
| duration | A nanosecond precision duration of time. |
## Table
A **table** is set of records with a common set of columns and a group key.
The group key is a list of columns.
A table's group key denotes which subset of the entire dataset is assigned to the table.
All records within a table will have the same values for each column that is part of the group key.
These common values are referred to as the "group key value" and can be represented as a set of key value pairs.
A tables schema consists of its group key and its columns' labels and types.
## Stream of tables
A **stream** represents a potentially unbounded set of tables.
A stream is grouped into individual tables using their respective group keys.
Tables within a stream each have a unique group key value.
## Missing values
A record may be missing a value for a specific column.
Missing values are represented with a special `null` value.
The `null` value can be of any data type.
{{% note %}}
To be implemented: [IMPL#300](https://github.com/influxdata/platform/issues/300) Design how nulls behave
{{% /note %}}

View File

@ -0,0 +1,189 @@
---
title: Expressions
description: An expression specifies the computation of a value by applying the operators and functions to operands.
menu:
v2_0_ref:
parent: Flux language specification
name: Expressions
weight: 40
---
An _expression_ specifies the computation of a value by applying the operators and functions to operands.
## Operands and primary expressions
Operands denote the elementary values in an expression.
Primary expressions are the operands for unary and binary expressions.
A primary expressions may be a literal, an identifier denoting a variable, or a parenthesized expression.
```js
PrimaryExpression = identifier | Literal | "(" Expression ")" .
```
## Literals
Literals construct a value.
```js
Literal = int_lit
| float_lit
| string_lit
| regex_lit
| duration_lit
| pipe_receive_lit
| ObjectLiteral
| ArrayLiteral
| FunctionLiteral .
```
### Object literals
Object literals construct a value with the object type.
```js
ObjectLiteral = "{" PropertyList "}" .
PropertyList = [ Property { "," Property } ] .
Property = identifier [ ":" Expression ]
| string_lit ":" Expression .
```
### Array literals
Array literals construct a value with the array type.
```js
ArrayLiteral = "[" ExpressionList "]" .
ExpressionList = [ Expression { "," Expression } ] .
```
### Function literals
A _function literal_ defines a new function with a body and parameters.
The function body may be a block or a single expression.
The function body must have a return statement if it is an explicit block, otherwise the expression is the return value.
```js
FunctionLiteral = FunctionParameters "=>" FunctionBody .
FunctionParameters = "(" [ ParameterList [ "," ] ] ")" .
ParameterList = Parameter { "," Parameter } .
Parameter = identifier [ "=" Expression ] .
FunctionBody = Expression | Block .
```
##### Examples of function literals
```js
() => 1 // function returns the value 1
(a, b) => a + b // function returns the sum of a and b
(x=1, y=1) => x * y // function with default values
(a, b, c) => { // function with a block body
d = a + b
return d / c
}
```
All function literals are anonymous.
A function may be given a name using a variable assignment.
```
add = (a,b) => a + b
mul = (a,b) => a * b
```
Function literals are _closures_ and may refer to variables defined in a surrounding block.
Those variables are shared between the function literal and the surrounding block.
## Call expressions
A _call expression_ invokes a function with the provided arguments.
Arguments must be specified using the argument name.
Positional arguments are not supported.
Argument order does not matter.
When an argument has a default value, it is not required to be specified.
```js
CallExpression = "(" PropertyList ")" .
```
##### Examples of call expressions
```js
f(a:1, b:9.6)
float(v:1)
```
## Pipe expressions
A _pipe expression_ is a call expression with an implicit piped argument.
Pipe expressions simplify creating long nested call chains.
Pipe expressions pass the result of the left hand expression as the _pipe argument_ to the right hand call expression.
Function literals specify which if any argument is the pipe argument using the _pipe literal_ as the argument's default value.
It is an error to use a pipe expression if the function does not declare a pipe argument.
```js
pipe_receive_lit = "<-" .
```
##### Examples of pipe expressions
```js
foo = () => // function body elided
bar = (x=<-) => // function body elided
baz = (y=<-) => // function body elided
foo() |> bar() |> baz() // equivalent to baz(x:bar(y:foo()))
```
## Index expressions
Index expressions access a value from an array based on a numeric index.
```js
IndexExpression = "[" Expression "]" .
```
## Member expressions
Member expressions access a property of an object.
The property being accessed must be either an identifier or a string literal.
In either case the literal value is the name of the property being accessed, the identifier is not evaluated.
It is not possible to access an object's property using an arbitrary expression.
```js
MemberExpression = DotExpression | MemberBracketExpression
DotExpression = "." identifer
MemberBracketExpression = "[" string_lit "]" .
```
### Operators
Operators combine operands into expressions.
Operator precedence is encoded directly into the grammar.
```js
Expression = LogicalExpression .
LogicalExpression = UnaryLogicalExpression
| LogicalExpression LogicalOperator UnaryLogicalExpression .
LogicalOperator = "and" | "or" .
UnaryLogicalExpression = ComparisonExpression
| UnaryLogicalOperator UnaryLogicalExpression .
UnaryLogicalOperator = "not" .
ComparisonExpression = MultiplicativeExpression
| ComparisonExpression ComparisonOperator MultiplicativeExpression .
ComparisonOperator = "==" | "!=" | "<" | "<=" | ">" | ">=" | "=~" | "!~" .
MultiplicativeExpression = AdditiveExpression
| MultiplicativeExpression MultiplicativeOperator AdditiveExpression .
MultiplicativeOperator = "*" | "/" .
AdditiveExpression = PipeExpression
| AdditiveExpression AdditiveOperator PipeExpression .
AdditiveOperator = "+" | "-" .
PipeExpression = PostfixExpression
| PipeExpression PipeOperator UnaryExpression .
PipeOperator = "|>" .
UnaryExpression = PostfixExpression
| PrefixOperator UnaryExpression .
PrefixOperator = "+" | "-" .
PostfixExpression = PrimaryExpression
| PostfixExpression PostfixOperator .
PostfixOperator = MemberExpression
| CallExpression
| IndexExpression .
```
_Also see [Flux Operators](/v2.0/reference/flux/language/operators)._

View File

@ -0,0 +1,359 @@
---
title: Lexical elements
description: Descriptions of Flux comments, tokens, identifiers, keywords, and other lexical elements.
menu:
v2_0_ref:
parent: Flux language specification
name: Lexical elements
weight: 50
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
## Comments
Comment serve as documentation.
Comments begin with the character sequence `//` and stop at the end of the line.
Comments cannot start inside string or regexp literals.
Comments act like newlines.
## Tokens
Flux is built up from tokens.
There are four classes of tokens:
* _identifiers_
* _keywords_
* _operators_
* _literals_
_White space_ formed from spaces, horizontal tabs, carriage returns, and newlines is ignored except as it separates tokens that would otherwise combine into a single token.
While breaking the input into tokens, the next token is the longest sequence of characters that form a valid token.
## Identifiers
Identifiers name entities within a program.
An _identifier_ is a sequence of one or more letters and digits.
An identifier must start with a letter.
```js
identifier = letter { letter | unicode_digit } .
```
##### Examples of identifiers
```
a
_x
longIdentifierName
αβ
```
## Keywords
The following keywords are reserved and may not be used as identifiers:
```
and import not return option
empty in or package builtin
```
{{% note %}}
To be implemented: [IMPL#256](https://github.com/influxdata/platform/issues/256) Add in and empty operator support.
To be implemented: [IMPL#334](https://github.com/influxdata/platform/issues/334) Add "import" support
{{% /note %}}
## Operators
The following character sequences represent operators:
```
+ == != ( )
- < !~ [ ]
* > =~ { }
/ <= = , :
% >= <- . |>
```
## Numeric literals
Numeric literals may be integers or floating point values.
Literals have arbitrary precision and are coerced to a specific type when used.
The following coercion rules apply to numeric literals:
* An integer literal can be coerced to an "int", "uint", or "float" type,
* A float literal can be coerced to a "float" type.
* An error will occur if the coerced type cannot represent the literal value.
{{% note %}}
To be implemented: [IMPL#255](https://github.com/influxdata/platform/issues/255) Allow numeric literal coercion.
{{% /note %}}
### Integer literals
An integer literal is a sequence of digits representing an integer value.
Only decimal integers are supported.
```js
int_lit = "0" | decimal_lit .
decimal_lit = ( "1" … "9" ) { decimal_digit } .
```
##### Examples of integer literals
```
0
42
317316873
```
## Floating-point literals
A _floating-point literal_ is a decimal representation of a floating-point value.
It has an integer part, a decimal point, and a fractional part.
The integer and fractional part comprise decimal digits.
One of the integer part or the fractional part may be elided.
```js
float_lit = decimals "." [ decimals ]
| "." decimals .
decimals = decimal_digit { decimal_digit } .
```
##### Examples of floating-point literals
```js
0.
72.40
072.40 // == 72.40
2.71828
.26
```
{{% note %}}
To be implemented: [IMPL#254](https://github.com/influxdata/platform/issues/254) Parse float literals.
{{% /note %}}
### Duration literals
A _duration literal_ is a representation of a length of time.
It has an integer part and a duration unit part.
Multiple durations may be specified together and the resulting duration is the sum of each smaller part.
When several durations are specified together, larger units must appear before smaller ones, and there can be no repeated units.
```js
duration_lit = { int_lit duration_unit } .
duration_unit = "y" | "mo" | "w" | "d" | "h" | "m" | "s" | "ms" | "us" | "µs" | "ns" .
```
| Units | Meaning |
| ----- | ------- |
| y | year (12 months) |
| mo | month |
| w | week (7 days) |
| d | day |
| h | hour (60 minutes) |
| m | minute (60 seconds) |
| s | second |
| ms | milliseconds (1 thousandth of a second) |
| us or µs | microseconds (1 millionth of a second) |
| ns | nanoseconds (1 billionth of a second) |
Durations represent a length of time.
Lengths of time are dependent on specific instants in time they occur and as such, durations do not represent a fixed amount of time.
No amount of seconds is equal to a day, as days vary in their number of seconds.
No amount of days is equal to a month, as months vary in their number of days.
A duration consists of three basic time units: seconds, days and months.
Durations can be combined via addition and subtraction.
Durations can be multiplied by an integer value.
These operations are performed on each time unit independently.
##### Examples of duration literals
```js
1s
10d
1h15m // 1 hour and 15 minutes
5w
1mo5d // 1 month and 5 days
```
Durations can be added to date times to produce a new date time.
Addition and subtraction of durations to date times do not commute and are left associative.
Addition and subtraction of durations to date times applies months, days and seconds in that order.
When months are added to a date times and the resulting date is past the end of the month, the day is rolled back to the last day of the month.
##### Examples of duration literals
```js
2018-01-01T00:00:00Z + 1d // 2018-01-02T00:00:00Z
2018-01-01T00:00:00Z + 1mo // 2018-02-01T00:00:00Z
2018-01-01T00:00:00Z + 2mo // 2018-03-01T00:00:00Z
2018-01-31T00:00:00Z + 2mo // 2018-03-31T00:00:00Z
2018-02-28T00:00:00Z + 2mo // 2018-04-28T00:00:00Z
2018-01-31T00:00:00Z + 1mo // 2018-02-28T00:00:00Z, February 31th is rolled back to the last day of the month, February 28th in 2018.
// Addition and subtraction of durations to date times does not commute
2018-02-28T00:00:00Z + 1mo + 1d // 2018-03-29T00:00:00Z
2018-02-28T00:00:00Z + 1d + 1mo // 2018-04-01T00:00:00Z
2018-01-01T00:00:00Z + 2mo - 1d // 2018-02-28T00:00:00Z
2018-01-01T00:00:00Z - 1d + 3mo // 2018-03-31T00:00:00Z
// Addition and subtraction of durations to date times applies months, days and seconds in that order.
2018-01-28T00:00:00Z + 1mo + 2d // 2018-03-02T00:00:00Z
2018-01-28T00:00:00Z + 1mo2d // 2018-03-02T00:00:00Z
2018-01-28T00:00:00Z + 2d + 1mo // 2018-02-28T00:00:00Z, explicit left associative add of 2d first changes the result
2018-02-01T00:00:00Z + 2mo2d // 2018-04-03T00:00:00Z
2018-01-01T00:00:00Z + 1mo30d // 2018-03-02T00:00:00Z, Months are applied first to get February 1st, then days are added resulting in March 2 in 2018.
2018-01-31T00:00:00Z + 1mo1d // 2018-03-01T00:00:00Z, Months are applied first to get February 28th, then days are added resulting in March 1 in 2018.
```
{{% note %}}
To be implemented: [IMPL#657](https://github.com/influxdata/platform/issues/657) Implement Duration vectors.
{{% /note %}}
## Date and time literals
A _date and time literal_ represents a specific moment in time.
It has a date part, a time part and a time offset part.
The format follows the [RFC 3339](https://tools.ietf.org/html/rfc3339) specification.
The time is optional.
When it is omitted, the time is assumed to be midnight for the default location.
The `time_offset` is optional.
When it is omitted, the location option is used to determine the offset.
```js
date_time_lit = date [ "T" time ] .
date = year_lit "-" month "-" day .
year = decimal_digit decimal_digit decimal_digit decimal_digit .
month = decimal_digit decimal_digit .
day = decimal_digit decimal_digit .
time = hour ":" minute ":" second [ fractional_second ] [ time_offset ] .
hour = decimal_digit decimal_digit .
minute = decimal_digit decimal_digit .
second = decimal_digit decimal_digit .
fractional_second = "." { decimal_digit } .
time_offset = "Z" | ("+" | "-" ) hour ":" minute .
```
##### Examples of date and time literals
```js
1952-01-25T12:35:51Z
2018-08-15T13:36:23-07:00
2009-10-15T09:00:00 // October 15th 2009 at 9 AM in the default location
2018-01-01 // midnight on January 1st 2018 in the default location
```
{{% note %}}
To be implemented: [IMPL#152](https://github.com/influxdata/flux/issues/152) Implement shorthand time literals.
{{% /note %}}
### String literals
A _string literal_ represents a sequence of characters enclosed in double quotes.
Within the quotes any character may appear except an unescaped double quote.
String literals support several escape sequences.
```
\n U+000A line feed or newline
\r U+000D carriage return
\t U+0009 horizontal tab
\" U+0022 double quote
\\ U+005C backslash
\{ U+007B open curly bracket
\} U+007D close curly bracket
```
Additionally, any byte value may be specified via a hex encoding using `\x` as the prefix.
```
string_lit = `"` { unicode_value | byte_value | StringExpression | newline } `"` .
byte_value = `\` "x" hex_digit hex_digit .
hex_digit = "0" … "9" | "A" … "F" | "a" … "f" .
unicode_value = unicode_char | escaped_char .
escaped_char = `\` ( "n" | "r" | "t" | `\` | `"` ) .
StringExpression = "{" Expression "}" .
```
{{% note %}}
To be added: TODO: With string interpolation `string_lit` is not longer a lexical token as part of a literal, but an entire expression in and of itself.
To be implemented: [IMPL#252](https://github.com/influxdata/platform/issues/252) Parse string literals.
{{% /note %}}
##### Examples of string literals
```js
"abc"
"string with double \" quote"
"string with backslash \\"
"日本語"
"\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" // the explicit UTF-8 encoding of the previous line
```
String literals are also interpolated for embedded expressions to be evaluated as strings.
Embedded expressions are enclosed in curly brackets (`{}`).
The expressions are evaluated in the scope containing the string literal.
The result of an expression is formatted as a string and replaces the string content between the brackets.
All types are formatted as strings according to their literal representation.
A function `printf` exists to allow more precise control over formatting of various types.
To include the literal curly brackets within a string they must be escaped.
{{% note %}}
To be implemented: [IMPL#248](https://github.com/influxdata/platform/issues/248) Add printf function.
{{% /note %}}
##### Example: Interpolation
```js
n = 42
"the answer is {n}" // the answer is 42
"the answer is not {n+1}" // the answer is not 43
"openinng curly bracket \{" // openinng curly bracket {
"closing curly bracket \}" // closing curly bracket }
```
{{% note %}}
To be implemented: [IMPL#251](https://github.com/influxdata/platform/issues/251) Add string interpolation support
{{% /note %}}
### Regular expression literals
A _regular expression literal_ represents a regular expression pattern, enclosed in forward slashes.
Within the forward slashes, any unicode character may appear except for an unescaped forward slash.
The `\x` hex byte value representation from string literals may also be present.
Regular expression literals support only the following escape sequences:
```
\/ U+002f forward slash
\\ U+005c backslash
```
```
regexp_lit = "/" { unicode_char | byte_value | regexp_escape_char } "/" .
regexp_escape_char = `\` (`/` | `\`)
```
##### Examples of regular expression literals
```js
/.*/
/http:\/\/localhost:9999/
/^\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e(ZZ)?$/
/^日本語(ZZ)?$/ // the above two lines are equivalent
/\\xZZ/ // this becomes the literal pattern "\xZZ"
```
The regular expression syntax is defined by [RE2](https://github.com/google/re2/wiki/Syntax).

View File

@ -0,0 +1,34 @@
---
title: Notation
description: Notation principles for the Flux functional data scripting language.
menu:
v2_0_ref:
parent: Flux language specification
name: Notation
weight: 60
---
The syntax of the language is specified using [Extended Backus-Naur Form (EBNF)](https://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_form):
```
Production = production_name "=" [ Expression ] "." .
Expression = Alternative { "|" Alternative } .
Alternative = Term { Term } .
Term = production_name | token [ "…" token ] | Group | Option | Repetition .
Group = "(" Expression ")" .
Option = "[" Expression "]" .
Repetition = "{" Expression "}" .
```
A _production_ is an expression constructed from terms and the following operators, in increasing precedence:
```
| alternation
() grouping
[] option (0 or 1 times)
{} repetition (0 to n times)
```
Lowercase production names are used to identify lexical tokens.
Non-terminals are in [camel case](https://en.wikipedia.org/wiki/Camel_case).
Lexical tokens are enclosed in double quotes (`""`) or back quotes (``).

View File

@ -0,0 +1,105 @@
---
title: Operators in the Flux language
description: Flux supports many types of operators including arithmetic operators, comparison operators, function operators, and others.
menu:
v2_0_ref:
name: Operators
parent: Flux language specification
weight: 130
---
Flux includes the following types of operators:
- [Arithmetic operators](#arithmetic-operators)
- [Comparison operators](#comparison-operators)
- [Assignment operators](#assignment-operators)
- [Function operators](#function-operators)
- [String Operators](#string-operators)
- [Literal constructors](#literal-constructors)
- [Miscellaneous operators](#miscellaneous-operators)
## Arithmetic operators
Arithmetic operators take two numerical values (either literals or variables) and
perform a calculation that returns a single numerical value.
| Operator | Description | Example | Result |
|:--------:| ----------- | ------- | ------ |
| `+` | Addition | `1 + 1` | `2` |
| `-` | Subtraction | `3 - 2` | `1` |
| `*` | Multiplication | `2 * 3` | `6` |
| `/` | Division | `9 / 3` | `3` |
| `%` | Modulus | `10 % 5` | `0` |
{{% note %}}
In the current version of Flux, values used in arithmetic operations must
be of the same numeric type (integer or float).
Operations with values of different numeric types will result in a type error.
{{% /note %}}
## Comparison operators
Comparison operators compare expressions and return true or false based on the comparison.
| Operator | Description | Example | Result |
|:--------:| ----------- | ------- | ------ |
| `==` | Equal to | `"abc" == "abc"` | `true` |
| `!=` | Not equal to | `"abc" != "def"` | `true` |
| `<` | Less than | `1 < 2` | `true` |
| `>` | Greater than | `1 > 2` | `false` |
| `<=` | Less than or equal | `1 <= 2` | `true` |
| `>=` | Greater than or equal | `1 >= 2` | `false` |
| `=~` | Equal to regular expression | `"abc" =~ /[a-z]*/` | `true` |
| `!~` | Not equal to regular expression | `"abc" !~ /[0-9]*/` | `true` |
{{% note %}}
The `>` and `<` operators also [compare the lexicographic order of strings](#string-operators).
{{% /note %}}
## Assignment operators
An assignment operator assigns a value to its left operand based on the value of its right operand.
| Operator | Description | Example | Meaning |
|:--------:| ----------- | ------- | ------- |
| `=` | Assign value of left expression to right expression | `x = y` | x = y |
## Function operators
Function operators facilitate the creation of functions and control the flow of data through operations.
| Operator | Description | Examples | Meaning |
|:--------: | ----------- | -------- | ------- |
| <code>&#124;></code> | Pipe&#8209;forward | <code>data &#124;> function()</code> | Tables contained in the "data" variable are piped into the function. |
| `<-` | Pipe&#8209;receive | `tables=<-` | The "tables" variable or parameter is assigned to data piped into the operation. _This operator is used for any data type passed into a function; not just table data._ |
| `=>` | Arrow | `(r) => r.tag1 == "tagvalue"` | The arrow passes an object or parameters into function operations. |
| `()` | Function call | `top(n:10)` | Call the `top` function setting the `n` parameter to `10` and perform the associated operations. |
---
_See [Custom functions](#) for examples of function operators is use._
---
## String Operators
String operators concatenate or compare string values.
| Operator | Description | Examples | Result |
|:--------:| ----------- | -------- | ------ |
| `+` | Concatenation | `"ab" + "c"` | `"abc"` |
| `<` | Less than in lexicographic order | `"ant" < "bee"` | `true` |
| `>` | Greater than in lexicographic order | `"ant" > "bee"` | `false` |
## Literal constructors
Literal constructors define fixed values.
| Operator | Description |
|:--------:| ----------- |
| `[ ]` | List / array |
| `{ }` | Object |
| `""` | String |
## Miscellaneous operators
| Operator | Description | Example |
|:--------:| ----------- | ------- |
| `( )` | Logical grouping | `r._value / (r._value * 2)` |
| `,` | Sequence delimiter | `item1, item2, item3` |
| `:` | Key-value separator | `{name: "Bob"}` |
| `.` | Dot reference | `r._measurement` |

View File

@ -0,0 +1,60 @@
---
title: Options
description: placeholder
menu:
v2_0_ref:
parent: Flux language specification
name: Options
weight: 110
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
An option represents a storage location for any value of a specified type.
Options are mutable.
An option can hold different values during its lifetime.
Below is a list of built-in options currently implemented in the Flux language:
- now
- task
- location
##### now
The `now` option is a function that returns a time value used as a proxy for the current system time.
```js
// Query should execute as if the below time is the current system time
option now = () => 2006-01-02T15:04:05-07:00
```
##### task
The `task` option schedules the execution of a Flux query.
```js
option task = {
name: "foo", // Name is required.
every: 1h, // Task should be run at this interval.
delay: 10m, // Delay scheduling this task by this duration.
cron: "0 2 * * *", // Cron is a more sophisticated way to schedule. 'every' and 'cron' are mutually exclusive.
retry: 5, // Number of times to retry a failed query.
}
```
##### location
The `location` option sets the default time zone of all times in the script.
The location maps the UTC offset in use at that location for a given time.
The default value is set using the time zone of the running process.
```js
option location = fixedZone(offset:-5h) // Set timezone to be 5 hours west of UTC.
option location = loadLocation(name:"America/Denver") // Set location to be America/Denver.
```
{{% note %}}
To be implemented: [IMPL#660](https://github.com/influxdata/platform/issues/660) Implement Location option
{{% /note %}}

View File

@ -0,0 +1,71 @@
---
title: Packages
description: >
Flux source is organized into packages.
A package consists of one or more source files.
Each source file is parsed individually and composed into a single package.
aliases:
- /flux/v0.x/language/programs
menu:
v2_0_ref:
parent: Flux language specification
name: Packages
weight: 70
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
Flux source is organized into packages.
A package consists of one or more source files.
Each source file is parsed individually and composed into a single package.
```js
File = [ PackageClause ] [ ImportList ] StatementList .
ImportList = { ImportDeclaration } .
```
## Package clause
```js
PackageClause = "package" identifier .
```
A _package clause_ defines the name for the current package.
Package names must be valid Flux identifiers.
The package clause must be at the beginning of any Flux source file.
All files in the same package must declare the same package name.
When a file does not declare a package clause, all identifiers in that
file will belong to the special `main` package.
{{% note %}}
To be implemented: [IMPL#247](https://github.com/influxdata/platform/issues/247) Add package/namespace support.
{{% /note %}}
### Package main
The `main` package is special for a few reasons:
1. It defines the entry point of a Flux program.
2. It cannot be imported.
3. All statements are marked as producing side effects.
## Package initialization
Packages are initialized in the following order:
1. All imported packages are initialized and assigned to their package identifier.
2. All option declarations are evaluated and assigned regardless of order. An option cannot have dependencies on any other options assigned in the same package block.
3. All variable declarations are evaluated and assigned regardless of order. A variable cannot have a direct or indirect dependency on itself.
4. Any package side effects are evaluated.
A package will only be initialized once across all file blocks and across all packages blocks regardless of how many times it is imported.
Initializing imported packages must be deterministic.
Specifically after all imported packages are initialized, each option must be assigned the same value.
Packages imported in the same file block are initialized in declaration order.
Packages imported across different file blocks have no known order.
When a set of imports modify the same option, they must be ordered by placing them in the same file block.

View File

@ -0,0 +1,37 @@
---
title: Representation
description: Source code is encoded in UTF-8. The text need not be canonicalized.
menu:
v2_0_ref:
parent: Flux language specification
name: Representation
weight: 80
---
Source code is encoded in UTF-8.
The text need not be canonicalized.
## Characters
This document will use the term _character_ to refer to a Unicode code point.
The following terms are used to denote specific Unicode character classes:
```
newline = /* the Unicode code point U+000A */ .
unicode_char = /* an arbitrary Unicode code point except newline */ .
unicode_letter = /* a Unicode code point classified as "Letter" */ .
unicode_digit = /* a Unicode code point classified as "Number, decimal digit" */ .
```
In The Unicode Standard 8.0, Section 4.5, "General Category" defines a set of character categories.
Flux treats all characters in any of the Letter categories (Lu, Ll, Lt, Lm, or Lo) as Unicode letters, and those in the Number category (Nd) as Unicode digits.
### Letters and digits
The underscore character `_` (`U+005F`) is considered a letter.
```
letter = unicode_letter | "_" .
decimal_digit = "0" … "9" .
```

View File

@ -0,0 +1,16 @@
---
title: Side effects
description: A summary of side effects in the Flux functional data scripting language.
menu:
v2_0_ref:
parent: Flux language specification
name: Side effects
weight: 90
---
Side effects can occur in one of two ways.
1. By reassigning built-in options
2. By calling a function that produces side effects
A function produces side effects when it is explicitly declared to have side effects or when it calls a function that itself produces side effects.

View File

@ -0,0 +1,161 @@
---
title: Statements
description: Statements control execution in the Flux functional data scripting language.
menu:
v2_0_ref:
parent: Flux language specification
name: Statements
weight: 100
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
A _statement_ controls execution.
```js
Statement = OptionAssignment
| BuiltinStatement
| VariableAssignment
| ReturnStatement
| ExpressionStatement .
```
## Import declaration
```js
ImportDeclaration = "import" [identifier] string_lit
```
A package name and an import path is associated with every package.
The import statement takes a package's import path and brings all of the identifiers
defined in that package into the current scope under a namespace.
The import statement defines the namespace through which to access the imported identifiers.
By default the identifier of this namespace is the package name unless otherwise specified.
For example, given a variable `x` declared in package `foo`, importing `foo` and referencing `x` would look like this:
```js
import "import/path/to/package/foo"
foo.x
```
Or this:
```js
import bar "import/path/to/package/foo"
bar.x
```
A package's import path is always absolute.
A package may reassign a new value to an option identifier declared in one of its imported packages.
A package cannot access nor modify the identifiers belonging to the imported packages of its imported packages.
Every statement contained in an imported package is evaluated.
## Return statements
A terminating statement prevents execution of all statements that appear after it in the same block.
A return statement is a terminating statement.
```
ReturnStatement = "return" Expression .
```
## Expression statements
An _expression statement_ is an expression where the computed value is discarded.
```
ExpressionStatement = Expression .
```
##### Examples of expression statements
```js
1 + 1
f()
a
```
## Named types
A named type can be created using a type assignment statement.
A named type is equivalent to the type it describes and may be used interchangeably.
```js
TypeAssignement = "type" identifier "=" TypeExpression
TypeExpression = identifier
| TypeParameter
| ObjectType
| ArrayType
| GeneratorType
| FunctionType .
TypeParameter = "'" identifier .
ObjectType = "{" PropertyTypeList [";" ObjectUpperBound ] "}" .
ObjectUpperBound = "any" | PropertyTypeList .
PropertyTypeList = PropertyType [ "," PropertyType ] .
PropertyType = identifier ":" TypeExpression
| string_lit ":" TypeExpression .
ArrayType = "[]" TypeExpression .
GeneratorType = "[...]" TypeExpression .
FunctionType = ParameterTypeList "->" TypeExpression
ParameterTypeList = "(" [ ParameterType { "," ParameterType } ] ")" .
ParameterType = identifier ":" [ pipe_receive_lit ] TypeExpression .
```
Named types are a separate namespace from values.
It is possible for a value and a type to have the same identifier.
The following named types are built-in.
```js
bool // boolean
int // integer
uint // unsigned integer
float // floating point number
duration // duration of time
time // time
string // utf-8 encoded string
regexp // regular expression
type // a type that itself describes a type
```
When an object's upper bound is not specified, it is assumed to be equal to its lower bound.
Parameters to function types define whether the parameter is a pipe forward
parameter and whether the parameter has a default value.
The `<-` indicates the parameter is the pipe forward parameter.
###### Examples
```js
// alias the bool type
type boolean = bool
// define a person as an object type
type person = {
name: string,
age: int,
}
// Define addition on ints
type intAdd = (a: int, b: int) -> int
// Define polymorphic addition
type add = (a: 'a, b: 'a) -> 'a
// Define funcion with pipe parameter
type bar = (foo: <-string) -> string
// Define object type with an empty lower bound and an explicit upper bound
type address = {
;
street: string,
city: string,
state: string,
country: string,
province: string,
zip: int,
}
```

View File

@ -0,0 +1,102 @@
---
title: Types
description: A type defines the set of values and operations on those values. Types are never explicitly declared as part of the syntax. Types are always inferred from the usage of the value.
menu:
v2_0_ref:
parent: Flux language specification
name: Types
weight: 110
---
{{% note %}}
This document is a living document and may not represent the current implementation of Flux.
Any section that is not currently implemented is commented with a **[IMPL#XXX]** where
**XXX** is an issue number tracking discussion and progress towards implementation.
{{% /note %}}
A _type_ defines the set of values and operations on those values.
Types are never explicitly declared as part of the syntax.
Types are always inferred from the usage of the value.
{{% note %}}
To be implemented: [IMPL#249](https://github.com/influxdata/platform/issues/249) Specify type inference rules.
{{% /note %}}
## Boolean types
A _boolean type_ represents a truth value, corresponding to the preassigned variables `true` and `false`.
The boolean type name is `bool`.
## Numeric types
A _numeric type_ represents sets of integer or floating-point values.
The following numeric types exist:
```
uint the set of all unsigned 64-bit integers
int the set of all signed 64-bit integers
float the set of all IEEE-754 64-bit floating-point numbers
```
## Time types
A _time type_ represents a single point in time with nanosecond precision.
The time type name is `time`.
## Duration types
A _duration type_ represents a length of time with nanosecond precision.
The duration type name is `duration`.
Durations can be added to times to produce a new time.
##### Examples of duration types
```js
2018-07-01T00:00:00Z + 1mo // 2018-08-01T00:00:00Z
2018-07-01T00:00:00Z + 2y // 2020-07-01T00:00:00Z
2018-07-01T00:00:00Z + 5h // 2018-07-01T05:00:00Z
```
## String types
A _string type_ represents a possibly empty sequence of characters.
Strings are immutable and cannot be modified once created.
The string type name is `string`.
The length of a string is its size in bytes, not the number of characters, since a single character may be multiple bytes.
## Regular expression types
A _regular expression type_ represents the set of all patterns for regular expressions.
The regular expression type name is `regexp`.
## Array types
An _array type_ represents a sequence of values of any other type.
All values in the array must be of the same type.
The length of an array is the number of elements in the array.
## Object types
An _object type_ represents a set of unordered key and value pairs.
The key must always be a string.
The value may be any other type, and need not be the same as other values within the object.
## Function types
A _function type_ represents a set of all functions with the same argument and result types.
{{% note %}}
To be implemented: [IMPL#249](https://github.com/influxdata/platform/issues/249) Specify type inference rules.
{{% /note %}}
## Generator types
A _generator type_ represents a value that produces an unknown number of other values.
The generated values may be of any other type, but must all be the same type.
{{% note %}}
To be implemented: [IMPL#658](https://github.com/influxdata/platform/query/issues/658) Implement Generators types.
{{% /note %}}

View File

@ -0,0 +1,13 @@
---
title: Variables
description: Flux variables hold values. A variable can only hold values defined by its type.
menu:
v2_0_ref:
parent: Flux language specification
name: Variables
weight: 120
---
A **variable** represents a storage location for a single value.
Variables are immutable.
Once a variable is given a value, it holds that value for the remainder of its lifetime.