org.apache.flink.table.api.windows.scala Maven / Gradle / Ivy
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.flink.table.api
import org.apache.flink.table.expressions._
import org.apache.flink.table.plan.logical._
import org.apache.flink.table.typeutils.{RowIntervalTypeInfo, TimeIntervalTypeInfo}
import org.apache.flink.table.api.scala.{CURRENT_RANGE, CURRENT_ROW}
/**
* Over window is similar to the traditional OVER SQL.
*/
case class OverWindow(
private[flink] val alias: Expression,
private[flink] val partitionBy: Seq[Expression],
private[flink] val orderBy: Expression,
private[flink] val preceding: Expression,
private[flink] val following: Expression)
case class CurrentRow() extends Expression {
override private[flink] def resultType = RowIntervalTypeInfo.INTERVAL_ROWS
override private[flink] def children = Seq()
override def toString = "CURRENT ROW"
}
case class CurrentRange() extends Expression {
override private[flink] def resultType = TimeIntervalTypeInfo.INTERVAL_MILLIS
override private[flink] def children = Seq()
override def toString = "CURRENT RANGE"
}
case class UnboundedRow() extends Expression {
override private[flink] def resultType = RowIntervalTypeInfo.INTERVAL_ROWS
override private[flink] def children = Seq()
override def toString = "UNBOUNDED ROW"
}
case class UnboundedRange() extends Expression {
override private[flink] def resultType = TimeIntervalTypeInfo.INTERVAL_MILLIS
override private[flink] def children = Seq()
override def toString = "UNBOUNDED RANGE"
}
/**
* A partially defined over window.
*/
class OverWindowWithPreceding(
private val partitionBy: Seq[Expression],
private val orderBy: Expression,
private val preceding: Expression) {
private[flink] var following: Expression = _
/**
* Assigns an alias for this window that the following `select()` clause can refer to.
*
* @param alias alias for this over window
* @return over window
*/
def as(alias: String): OverWindow = as(ExpressionParser.parseExpression(alias))
/**
* Assigns an alias for this window that the following `select()` clause can refer to.
*
* @param alias alias for this over window
* @return over window
*/
def as(alias: Expression): OverWindow = {
// set following to CURRENT_ROW / CURRENT_RANGE if not defined
if (null == following) {
if (preceding.resultType.isInstanceOf[RowIntervalTypeInfo]) {
following = CURRENT_ROW
} else {
following = CURRENT_RANGE
}
}
OverWindow(alias, partitionBy, orderBy, preceding, following)
}
/**
* Set the following offset (based on time or row-count intervals) for over window.
*
* @param following following offset that relative to the current row.
* @return this over window
*/
def following(following: String): OverWindowWithPreceding = {
this.following(ExpressionParser.parseExpression(following))
}
/**
* Set the following offset (based on time or row-count intervals) for over window.
*
* @param following following offset that relative to the current row.
* @return this over window
*/
def following(following: Expression): OverWindowWithPreceding = {
this.following = following
this
}
}
/**
* A window specification.
*
* Window groups rows based on time or row-count intervals. It is a general way to group the
* elements, which is very helpful for both groupBy-aggregations and over-aggregations to
* compute aggregates on groups of elements.
*
* Infinite streaming tables can only be grouped into time or row intervals. Hence window grouping
* is required to apply aggregations on streaming tables.
*
* For finite batch tables, window provides shortcuts for time-based groupBy.
*
*/
abstract class Window(val alias: Expression, val timeField: Expression) {
/**
* Converts an API class to a logical window for planning.
*/
private[flink] def toLogicalWindow: LogicalWindow
}
// ------------------------------------------------------------------------------------------------
// Tumbling windows
// ------------------------------------------------------------------------------------------------
/**
* Tumbling window.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param size the size of the window either as time or row-count interval.
*/
class TumbleWithSize(size: Expression) {
/**
* Tumbling window.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param size the size of the window either as time or row-count interval.
*/
def this(size: String) = this(ExpressionParser.parseExpression(size))
/**
* Specifies the time attribute on which rows are grouped.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param timeField time attribute for streaming and batch tables
* @return a tumbling window on event-time
*/
def on(timeField: Expression): TumbleWithSizeOnTime =
new TumbleWithSizeOnTime(timeField, size)
/**
* Specifies the time attribute on which rows are grouped.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param timeField time attribute for streaming and batch tables
* @return a tumbling window on event-time
*/
def on(timeField: String): TumbleWithSizeOnTime =
on(ExpressionParser.parseExpression(timeField))
}
/**
* Tumbling window on time.
*/
class TumbleWithSizeOnTime(time: Expression, size: Expression) {
/**
* Assigns an alias for this window that the following `groupBy()` and `select()` clause can
* refer to. `select()` statement can access window properties such as window start or end time.
*
* @param alias alias for this window
* @return this window
*/
def as(alias: Expression): TumbleWithSizeOnTimeWithAlias = {
new TumbleWithSizeOnTimeWithAlias(alias, time, size)
}
/**
* Assigns an alias for this window that the following `groupBy()` and `select()` clause can
* refer to. `select()` statement can access window properties such as window start or end time.
*
* @param alias alias for this window
* @return this window
*/
def as(alias: String): TumbleWithSizeOnTimeWithAlias = {
as(ExpressionParser.parseExpression(alias))
}
}
/**
* Tumbling window on time with alias. Fully specifies a window.
*/
class TumbleWithSizeOnTimeWithAlias(
alias: Expression,
timeField: Expression,
size: Expression)
extends Window(
alias,
timeField) {
/**
* Converts an API class to a logical window for planning.
*/
override private[flink] def toLogicalWindow: LogicalWindow = {
TumblingGroupWindow(alias, timeField, size)
}
}
// ------------------------------------------------------------------------------------------------
// Sliding windows
// ------------------------------------------------------------------------------------------------
/**
* Partially specified sliding window.
*
* @param size the size of the window either as time or row-count interval.
*/
class SlideWithSize(size: Expression) {
/**
* Partially specified sliding window.
*
* @param size the size of the window either as time or row-count interval.
*/
def this(size: String) = this(ExpressionParser.parseExpression(size))
/**
* Specifies the window's slide as time or row-count interval.
*
* The slide determines the interval in which windows are started. Hence, sliding windows can
* overlap if the slide is smaller than the size of the window.
*
* For example, you could have windows of size 15 minutes that slide by 3 minutes. With this
* 15 minutes worth of elements are grouped every 3 minutes and each row contributes to 5
* windows.
*
* @param slide the slide of the window either as time or row-count interval.
* @return a sliding window
*/
def every(slide: Expression): SlideWithSizeAndSlide = new SlideWithSizeAndSlide(size, slide)
/**
* Specifies the window's slide as time or row-count interval.
*
* The slide determines the interval in which windows are started. Hence, sliding windows can
* overlap if the slide is smaller than the size of the window.
*
* For example, you could have windows of size 15 minutes that slide by 3 minutes. With this
* 15 minutes worth of elements are grouped every 3 minutes and each row contributes to 5
* windows.
*
* @param slide the slide of the window either as time or row-count interval.
* @return a sliding window
*/
def every(slide: String): SlideWithSizeAndSlide = every(ExpressionParser.parseExpression(slide))
}
/**
* Sliding window.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param size the size of the window either as time or row-count interval.
*/
class SlideWithSizeAndSlide(size: Expression, slide: Expression) {
/**
* Specifies the time attribute on which rows are grouped.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param timeField time attribute for streaming and batch tables
* @return a tumbling window on event-time
*/
def on(timeField: Expression): SlideWithSizeAndSlideOnTime =
new SlideWithSizeAndSlideOnTime(timeField, size, slide)
/**
* Specifies the time attribute on which rows are grouped.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param timeField time attribute for streaming and batch tables
* @return a tumbling window on event-time
*/
def on(timeField: String): SlideWithSizeAndSlideOnTime =
on(ExpressionParser.parseExpression(timeField))
}
/**
* Sliding window on time.
*/
class SlideWithSizeAndSlideOnTime(timeField: Expression, size: Expression, slide: Expression) {
/**
* Assigns an alias for this window that the following `groupBy()` and `select()` clause can
* refer to. `select()` statement can access window properties such as window start or end time.
*
* @param alias alias for this window
* @return this window
*/
def as(alias: Expression): SlideWithSizeAndSlideOnTimeWithAlias = {
new SlideWithSizeAndSlideOnTimeWithAlias(alias, timeField, size, slide)
}
/**
* Assigns an alias for this window that the following `groupBy()` and `select()` clause can
* refer to. `select()` statement can access window properties such as window start or end time.
*
* @param alias alias for this window
* @return this window
*/
def as(alias: String): SlideWithSizeAndSlideOnTimeWithAlias = {
as(ExpressionParser.parseExpression(alias))
}
}
/**
* Sliding window on time with alias. Fully specifies a window.
*/
class SlideWithSizeAndSlideOnTimeWithAlias(
alias: Expression,
timeField: Expression,
size: Expression,
slide: Expression)
extends Window(
alias,
timeField) {
/**
* Converts an API class to a logical window for planning.
*/
override private[flink] def toLogicalWindow: LogicalWindow = {
SlidingGroupWindow(alias, timeField, size, slide)
}
}
// ------------------------------------------------------------------------------------------------
// Session windows
// ------------------------------------------------------------------------------------------------
/**
* Session window.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param gap the time interval of inactivity before a window is closed.
*/
class SessionWithGap(gap: Expression) {
/**
* Session window.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param gap the time interval of inactivity before a window is closed.
*/
def this(gap: String) = this(ExpressionParser.parseExpression(gap))
/**
* Specifies the time attribute on which rows are grouped.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param timeField time attribute for streaming and batch tables
* @return a tumbling window on event-time
*/
def on(timeField: Expression): SessionWithGapOnTime =
new SessionWithGapOnTime(timeField, gap)
/**
* Specifies the time attribute on which rows are grouped.
*
* For streaming tables you can specify grouping by a event-time or processing-time attribute.
*
* For batch tables you can specify grouping on a timestamp or long attribute.
*
* @param timeField time attribute for streaming and batch tables
* @return a tumbling window on event-time
*/
def on(timeField: String): SessionWithGapOnTime =
on(ExpressionParser.parseExpression(timeField))
}
/**
* Session window on time.
*/
class SessionWithGapOnTime(timeField: Expression, gap: Expression) {
/**
* Assigns an alias for this window that the following `groupBy()` and `select()` clause can
* refer to. `select()` statement can access window properties such as window start or end time.
*
* @param alias alias for this window
* @return this window
*/
def as(alias: Expression): SessionWithGapOnTimeWithAlias = {
new SessionWithGapOnTimeWithAlias(alias, timeField, gap)
}
/**
* Assigns an alias for this window that the following `groupBy()` and `select()` clause can
* refer to. `select()` statement can access window properties such as window start or end time.
*
* @param alias alias for this window
* @return this window
*/
def as(alias: String): SessionWithGapOnTimeWithAlias = {
as(ExpressionParser.parseExpression(alias))
}
}
/**
* Session window on time with alias. Fully specifies a window.
*/
class SessionWithGapOnTimeWithAlias(
alias: Expression,
timeField: Expression,
gap: Expression)
extends Window(
alias,
timeField) {
/**
* Converts an API class to a logical window for planning.
*/
override private[flink] def toLogicalWindow: LogicalWindow = {
SessionGroupWindow(alias, timeField, gap)
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy