risingwave_expr/window_function/
kind.rs

1// Copyright 2025 RisingWave Labs
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use anyhow::Context;
16use enum_as_inner::EnumAsInner;
17use parse_display::{Display, FromStr};
18use risingwave_common::bail;
19
20use crate::Result;
21use crate::aggregate::AggType;
22
23/// Kind of window functions.
24#[expect(clippy::large_enum_variant)]
25#[derive(Debug, Display, FromStr /* for builtin */, Clone, PartialEq, Eq, Hash, EnumAsInner)]
26#[display(style = "snake_case")]
27pub enum WindowFuncKind {
28    // General-purpose window functions.
29    RowNumber,
30    Rank,
31    DenseRank,
32    Lag,
33    Lead,
34
35    // Aggregate functions that are used with `OVER`.
36    #[display("{0}")]
37    Aggregate(AggType),
38}
39
40impl WindowFuncKind {
41    pub fn from_protobuf(
42        window_function_type: &risingwave_pb::expr::window_function::PbType,
43    ) -> Result<Self> {
44        use risingwave_pb::expr::agg_call::PbKind as PbAggKind;
45        use risingwave_pb::expr::window_function::{PbGeneralType, PbType};
46
47        let kind = match window_function_type {
48            PbType::General(typ) => match PbGeneralType::try_from(*typ) {
49                Ok(PbGeneralType::Unspecified) => bail!("Unspecified window function type"),
50                Ok(PbGeneralType::RowNumber) => Self::RowNumber,
51                Ok(PbGeneralType::Rank) => Self::Rank,
52                Ok(PbGeneralType::DenseRank) => Self::DenseRank,
53                Ok(PbGeneralType::Lag) => Self::Lag,
54                Ok(PbGeneralType::Lead) => Self::Lead,
55                Err(_) => bail!("no such window function type"),
56            },
57            PbType::Aggregate(kind) => Self::Aggregate(AggType::from_protobuf_flatten(
58                PbAggKind::try_from(*kind).context("no such aggregate function type")?,
59                None,
60                None,
61            )?),
62            PbType::Aggregate2(agg_type) => Self::Aggregate(AggType::from_protobuf(agg_type)?),
63        };
64        Ok(kind)
65    }
66}
67
68impl WindowFuncKind {
69    pub fn is_numbering(&self) -> bool {
70        matches!(self, Self::RowNumber | Self::Rank | Self::DenseRank)
71    }
72}