From bbaaa51393220fa56cbf644898cadd2cce164896 Mon Sep 17 00:00:00 2001 From: Yahor Yuzefovich Date: Sun, 4 Aug 2019 18:23:48 -0700 Subject: [PATCH] sql: add support for optional frame exclusion Adds support for optional frame exclusion clause in the specification of window frames. Release note (sql change): CockroachDB now supports optinal frame exclusion clause in the specification of window frames. Release note: None --- docs/generated/sql/bnf/stmt_block.bnf | 16 +- pkg/sql/distsqlpb/processors.go | 37 +- pkg/sql/distsqlpb/processors_sql.pb.go | 420 ++++++++++-------- pkg/sql/distsqlpb/processors_sql.proto | 10 + pkg/sql/distsqlrun/windower.go | 12 +- pkg/sql/logictest/testdata/logic_test/window | 105 +++++ pkg/sql/opt/exec/execbuilder/relational.go | 1 + pkg/sql/opt/memo/expr.go | 1 + pkg/sql/opt/memo/expr_format.go | 18 +- pkg/sql/opt/memo/interner.go | 4 +- pkg/sql/opt/memo/interner_test.go | 2 + pkg/sql/opt/optbuilder/window.go | 1 + pkg/sql/parser/parse_test.go | 5 + pkg/sql/parser/sql.y | 51 ++- pkg/sql/sem/builtins/window_builtins.go | 109 +++-- pkg/sql/sem/builtins/window_frame_builtins.go | 115 +++-- .../builtins/window_frame_builtins_test.go | 2 + pkg/sql/sem/tree/pretty.go | 3 + pkg/sql/sem/tree/select.go | 41 +- .../pretty/window.align-deindent.golden | 353 +++++++++++++++ .../pretty/window.align-deindent.golden.short | 26 ++ .../testdata/pretty/window.align-only.golden | 353 +++++++++++++++ .../pretty/window.align-only.golden.short | 26 ++ .../tree/testdata/pretty/window.ref.golden | 280 ++++++++++++ .../testdata/pretty/window.ref.golden.short | 38 ++ pkg/sql/sem/tree/testdata/pretty/window.sql | 1 + pkg/sql/sem/tree/window_funcs.go | 77 +++- 27 files changed, 1817 insertions(+), 290 deletions(-) create mode 100644 pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden create mode 100644 pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden.short create mode 100644 pkg/sql/sem/tree/testdata/pretty/window.align-only.golden create mode 100644 pkg/sql/sem/tree/testdata/pretty/window.align-only.golden.short create mode 100644 pkg/sql/sem/tree/testdata/pretty/window.ref.golden create mode 100644 pkg/sql/sem/tree/testdata/pretty/window.ref.golden.short create mode 100644 pkg/sql/sem/tree/testdata/pretty/window.sql diff --git a/docs/generated/sql/bnf/stmt_block.bnf b/docs/generated/sql/bnf/stmt_block.bnf index d2a359b134ed..7a2c516e9f16 100644 --- a/docs/generated/sql/bnf/stmt_block.bnf +++ b/docs/generated/sql/bnf/stmt_block.bnf @@ -620,6 +620,7 @@ unreserved_keyword ::= | 'ENCODING' | 'ENUM' | 'ESCAPE' + | 'EXCLUDE' | 'EXECUTE' | 'EXPERIMENTAL' | 'EXPERIMENTAL_AUDIT' @@ -703,6 +704,7 @@ unreserved_keyword ::= | 'OPTION' | 'OPTIONS' | 'ORDINALITY' + | 'OTHERS' | 'OVER' | 'OWNED' | 'PARENT' @@ -789,6 +791,7 @@ unreserved_keyword ::= | 'TEMPORARY' | 'TESTING_RELOCATE' | 'TEXT' + | 'TIES' | 'TRACE' | 'TRANSACTION' | 'TRIGGER' @@ -2287,9 +2290,9 @@ opt_partition_clause ::= | opt_frame_clause ::= - 'RANGE' frame_extent - | 'ROWS' frame_extent - | 'GROUPS' frame_extent + 'RANGE' frame_extent opt_frame_exclusion + | 'ROWS' frame_extent opt_frame_exclusion + | 'GROUPS' frame_extent opt_frame_exclusion | extract_list ::= @@ -2331,6 +2334,13 @@ frame_extent ::= frame_bound | 'BETWEEN' frame_bound 'AND' frame_bound +opt_frame_exclusion ::= + 'EXCLUDE' 'CURRENT' 'ROW' + | 'EXCLUDE' 'GROUP' + | 'EXCLUDE' 'TIES' + | 'EXCLUDE' 'NO' 'OTHERS' + | + extract_arg ::= 'identifier' | 'YEAR' diff --git a/pkg/sql/distsqlpb/processors.go b/pkg/sql/distsqlpb/processors.go index 7332b6eedb9c..f1e9b7912e57 100644 --- a/pkg/sql/distsqlpb/processors.go +++ b/pkg/sql/distsqlpb/processors.go @@ -75,6 +75,21 @@ func (spec *WindowerSpec_Frame_BoundType) initFromAST(bt tree.WindowFrameBoundTy } } +func (spec *WindowerSpec_Frame_Exclusion) initFromAST(e tree.WindowFrameExclusion) { + switch e { + case tree.NoExclusion: + *spec = WindowerSpec_Frame_NO_EXCLUSION + case tree.ExcludeCurrentRow: + *spec = WindowerSpec_Frame_EXCLUDE_CURRENT_ROW + case tree.ExcludeGroup: + *spec = WindowerSpec_Frame_EXCLUDE_GROUP + case tree.ExcludeTies: + *spec = WindowerSpec_Frame_EXCLUDE_TIES + default: + panic("unexpected WindowerFrameExclusion") + } +} + // If offset exprs are present, we evaluate them and save the encoded results // in the spec. func (spec *WindowerSpec_Frame_Bounds) initFromAST( @@ -190,6 +205,7 @@ func isNegative(evalCtx *tree.EvalContext, offset tree.Datum) bool { // offset expressions if present in the frame. func (spec *WindowerSpec_Frame) InitFromAST(f *tree.WindowFrame, evalCtx *tree.EvalContext) error { spec.Mode.initFromAST(f.Mode) + spec.Exclusion.initFromAST(f.Exclusion) return spec.Bounds.initFromAST(f.Bounds, f.Mode, evalCtx) } @@ -223,6 +239,21 @@ func (spec WindowerSpec_Frame_BoundType) convertToAST() tree.WindowFrameBoundTyp } } +func (spec WindowerSpec_Frame_Exclusion) convertToAST() tree.WindowFrameExclusion { + switch spec { + case WindowerSpec_Frame_NO_EXCLUSION: + return tree.NoExclusion + case WindowerSpec_Frame_EXCLUDE_CURRENT_ROW: + return tree.ExcludeCurrentRow + case WindowerSpec_Frame_EXCLUDE_GROUP: + return tree.ExcludeGroup + case WindowerSpec_Frame_EXCLUDE_TIES: + return tree.ExcludeTies + default: + panic("unexpected WindowerSpec_Frame_Exclusion") + } +} + // convertToAST produces tree.WindowFrameBounds based on // WindowerSpec_Frame_Bounds. Note that it might not be fully equivalent to // original - if offsetExprs were present in original tree.WindowFrameBounds, @@ -239,5 +270,9 @@ func (spec WindowerSpec_Frame_Bounds) convertToAST() tree.WindowFrameBounds { // ConvertToAST produces a tree.WindowFrame given a WindoweSpec_Frame. func (spec *WindowerSpec_Frame) ConvertToAST() *tree.WindowFrame { - return &tree.WindowFrame{Mode: spec.Mode.convertToAST(), Bounds: spec.Bounds.convertToAST()} + return &tree.WindowFrame{ + Mode: spec.Mode.convertToAST(), + Bounds: spec.Bounds.convertToAST(), + Exclusion: spec.Exclusion.convertToAST(), + } } diff --git a/pkg/sql/distsqlpb/processors_sql.pb.go b/pkg/sql/distsqlpb/processors_sql.pb.go index ac082c9f8c81..c5ecd4198bb9 100644 --- a/pkg/sql/distsqlpb/processors_sql.pb.go +++ b/pkg/sql/distsqlpb/processors_sql.pb.go @@ -64,7 +64,7 @@ func (x *ScanVisibility) UnmarshalJSON(data []byte) error { return nil } func (ScanVisibility) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{0} } // These mirror the aggregate functions supported by sql/parser. See @@ -160,7 +160,7 @@ func (x *AggregatorSpec_Func) UnmarshalJSON(data []byte) error { return nil } func (AggregatorSpec_Func) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{10, 0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{10, 0} } type AggregatorSpec_Type int32 @@ -206,7 +206,7 @@ func (x *AggregatorSpec_Type) UnmarshalJSON(data []byte) error { return nil } func (AggregatorSpec_Type) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{10, 1} + return fileDescriptor_processors_sql_05381d0399cda248, []int{10, 1} } type WindowerSpec_WindowFunc int32 @@ -270,7 +270,7 @@ func (x *WindowerSpec_WindowFunc) UnmarshalJSON(data []byte) error { return nil } func (WindowerSpec_WindowFunc) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 0} } // Mode indicates which mode of framing is used. @@ -314,7 +314,7 @@ func (x *WindowerSpec_Frame_Mode) UnmarshalJSON(data []byte) error { return nil } func (WindowerSpec_Frame_Mode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 1, 0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 1, 0} } // BoundType indicates which type of boundary is used. @@ -361,7 +361,50 @@ func (x *WindowerSpec_Frame_BoundType) UnmarshalJSON(data []byte) error { return nil } func (WindowerSpec_Frame_BoundType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 1, 1} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 1, 1} +} + +// Exclusion specifies the type of frame exclusion. +type WindowerSpec_Frame_Exclusion int32 + +const ( + WindowerSpec_Frame_NO_EXCLUSION WindowerSpec_Frame_Exclusion = 0 + WindowerSpec_Frame_EXCLUDE_CURRENT_ROW WindowerSpec_Frame_Exclusion = 1 + WindowerSpec_Frame_EXCLUDE_GROUP WindowerSpec_Frame_Exclusion = 2 + WindowerSpec_Frame_EXCLUDE_TIES WindowerSpec_Frame_Exclusion = 3 +) + +var WindowerSpec_Frame_Exclusion_name = map[int32]string{ + 0: "NO_EXCLUSION", + 1: "EXCLUDE_CURRENT_ROW", + 2: "EXCLUDE_GROUP", + 3: "EXCLUDE_TIES", +} +var WindowerSpec_Frame_Exclusion_value = map[string]int32{ + "NO_EXCLUSION": 0, + "EXCLUDE_CURRENT_ROW": 1, + "EXCLUDE_GROUP": 2, + "EXCLUDE_TIES": 3, +} + +func (x WindowerSpec_Frame_Exclusion) Enum() *WindowerSpec_Frame_Exclusion { + p := new(WindowerSpec_Frame_Exclusion) + *p = x + return p +} +func (x WindowerSpec_Frame_Exclusion) String() string { + return proto.EnumName(WindowerSpec_Frame_Exclusion_name, int32(x)) +} +func (x *WindowerSpec_Frame_Exclusion) UnmarshalJSON(data []byte) error { + value, err := proto.UnmarshalJSONEnum(WindowerSpec_Frame_Exclusion_value, data, "WindowerSpec_Frame_Exclusion") + if err != nil { + return err + } + *x = WindowerSpec_Frame_Exclusion(value) + return nil +} +func (WindowerSpec_Frame_Exclusion) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 1, 2} } // ValuesCoreSpec is the core of a processor that has no inputs and generates @@ -381,7 +424,7 @@ func (m *ValuesCoreSpec) Reset() { *m = ValuesCoreSpec{} } func (m *ValuesCoreSpec) String() string { return proto.CompactTextString(m) } func (*ValuesCoreSpec) ProtoMessage() {} func (*ValuesCoreSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{0} } func (m *ValuesCoreSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -476,7 +519,7 @@ func (m *TableReaderSpec) Reset() { *m = TableReaderSpec{} } func (m *TableReaderSpec) String() string { return proto.CompactTextString(m) } func (*TableReaderSpec) ProtoMessage() {} func (*TableReaderSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{1} + return fileDescriptor_processors_sql_05381d0399cda248, []int{1} } func (m *TableReaderSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -524,7 +567,7 @@ func (m *IndexSkipTableReaderSpec) Reset() { *m = IndexSkipTableReaderSp func (m *IndexSkipTableReaderSpec) String() string { return proto.CompactTextString(m) } func (*IndexSkipTableReaderSpec) ProtoMessage() {} func (*IndexSkipTableReaderSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{2} + return fileDescriptor_processors_sql_05381d0399cda248, []int{2} } func (m *IndexSkipTableReaderSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -612,7 +655,7 @@ func (m *JoinReaderSpec) Reset() { *m = JoinReaderSpec{} } func (m *JoinReaderSpec) String() string { return proto.CompactTextString(m) } func (*JoinReaderSpec) ProtoMessage() {} func (*JoinReaderSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{3} + return fileDescriptor_processors_sql_05381d0399cda248, []int{3} } func (m *JoinReaderSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -656,7 +699,7 @@ func (m *SorterSpec) Reset() { *m = SorterSpec{} } func (m *SorterSpec) String() string { return proto.CompactTextString(m) } func (*SorterSpec) ProtoMessage() {} func (*SorterSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{4} + return fileDescriptor_processors_sql_05381d0399cda248, []int{4} } func (m *SorterSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -700,7 +743,7 @@ func (m *DistinctSpec) Reset() { *m = DistinctSpec{} } func (m *DistinctSpec) String() string { return proto.CompactTextString(m) } func (*DistinctSpec) ProtoMessage() {} func (*DistinctSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{5} + return fileDescriptor_processors_sql_05381d0399cda248, []int{5} } func (m *DistinctSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -735,7 +778,7 @@ func (m *OrdinalitySpec) Reset() { *m = OrdinalitySpec{} } func (m *OrdinalitySpec) String() string { return proto.CompactTextString(m) } func (*OrdinalitySpec) ProtoMessage() {} func (*OrdinalitySpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{6} + return fileDescriptor_processors_sql_05381d0399cda248, []int{6} } func (m *OrdinalitySpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -791,7 +834,7 @@ func (m *ZigzagJoinerSpec) Reset() { *m = ZigzagJoinerSpec{} } func (m *ZigzagJoinerSpec) String() string { return proto.CompactTextString(m) } func (*ZigzagJoinerSpec) ProtoMessage() {} func (*ZigzagJoinerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{7} + return fileDescriptor_processors_sql_05381d0399cda248, []int{7} } func (m *ZigzagJoinerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -859,7 +902,7 @@ func (m *MergeJoinerSpec) Reset() { *m = MergeJoinerSpec{} } func (m *MergeJoinerSpec) String() string { return proto.CompactTextString(m) } func (*MergeJoinerSpec) ProtoMessage() {} func (*MergeJoinerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{8} + return fileDescriptor_processors_sql_05381d0399cda248, []int{8} } func (m *MergeJoinerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -946,7 +989,7 @@ func (m *HashJoinerSpec) Reset() { *m = HashJoinerSpec{} } func (m *HashJoinerSpec) String() string { return proto.CompactTextString(m) } func (*HashJoinerSpec) ProtoMessage() {} func (*HashJoinerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{9} + return fileDescriptor_processors_sql_05381d0399cda248, []int{9} } func (m *HashJoinerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -992,7 +1035,7 @@ func (m *AggregatorSpec) Reset() { *m = AggregatorSpec{} } func (m *AggregatorSpec) String() string { return proto.CompactTextString(m) } func (*AggregatorSpec) ProtoMessage() {} func (*AggregatorSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{10} + return fileDescriptor_processors_sql_05381d0399cda248, []int{10} } func (m *AggregatorSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1043,7 +1086,7 @@ func (m *AggregatorSpec_Aggregation) Reset() { *m = AggregatorSpec_Aggre func (m *AggregatorSpec_Aggregation) String() string { return proto.CompactTextString(m) } func (*AggregatorSpec_Aggregation) ProtoMessage() {} func (*AggregatorSpec_Aggregation) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{10, 0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{10, 0} } func (m *AggregatorSpec_Aggregation) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1107,7 +1150,7 @@ func (m *InterleavedReaderJoinerSpec) Reset() { *m = InterleavedReaderJo func (m *InterleavedReaderJoinerSpec) String() string { return proto.CompactTextString(m) } func (*InterleavedReaderJoinerSpec) ProtoMessage() {} func (*InterleavedReaderJoinerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{11} + return fileDescriptor_processors_sql_05381d0399cda248, []int{11} } func (m *InterleavedReaderJoinerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1163,7 +1206,7 @@ func (m *InterleavedReaderJoinerSpec_Table) Reset() { *m = InterleavedRe func (m *InterleavedReaderJoinerSpec_Table) String() string { return proto.CompactTextString(m) } func (*InterleavedReaderJoinerSpec_Table) ProtoMessage() {} func (*InterleavedReaderJoinerSpec_Table) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{11, 0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{11, 0} } func (m *InterleavedReaderJoinerSpec_Table) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1203,7 +1246,7 @@ func (m *ProjectSetSpec) Reset() { *m = ProjectSetSpec{} } func (m *ProjectSetSpec) String() string { return proto.CompactTextString(m) } func (*ProjectSetSpec) ProtoMessage() {} func (*ProjectSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{12} + return fileDescriptor_processors_sql_05381d0399cda248, []int{12} } func (m *ProjectSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1245,7 +1288,7 @@ func (m *WindowerSpec) Reset() { *m = WindowerSpec{} } func (m *WindowerSpec) String() string { return proto.CompactTextString(m) } func (*WindowerSpec) ProtoMessage() {} func (*WindowerSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13} } func (m *WindowerSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1281,7 +1324,7 @@ func (m *WindowerSpec_Func) Reset() { *m = WindowerSpec_Func{} } func (m *WindowerSpec_Func) String() string { return proto.CompactTextString(m) } func (*WindowerSpec_Func) ProtoMessage() {} func (*WindowerSpec_Func) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 0} } func (m *WindowerSpec_Func) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1308,15 +1351,16 @@ var xxx_messageInfo_WindowerSpec_Func proto.InternalMessageInfo // Frame is the specification of a single window frame for a window function. type WindowerSpec_Frame struct { - Mode WindowerSpec_Frame_Mode `protobuf:"varint,1,opt,name=mode,enum=cockroach.sql.distsqlrun.WindowerSpec_Frame_Mode" json:"mode"` - Bounds WindowerSpec_Frame_Bounds `protobuf:"bytes,2,opt,name=bounds" json:"bounds"` + Mode WindowerSpec_Frame_Mode `protobuf:"varint,1,opt,name=mode,enum=cockroach.sql.distsqlrun.WindowerSpec_Frame_Mode" json:"mode"` + Bounds WindowerSpec_Frame_Bounds `protobuf:"bytes,2,opt,name=bounds" json:"bounds"` + Exclusion WindowerSpec_Frame_Exclusion `protobuf:"varint,3,opt,name=exclusion,enum=cockroach.sql.distsqlrun.WindowerSpec_Frame_Exclusion" json:"exclusion"` } func (m *WindowerSpec_Frame) Reset() { *m = WindowerSpec_Frame{} } func (m *WindowerSpec_Frame) String() string { return proto.CompactTextString(m) } func (*WindowerSpec_Frame) ProtoMessage() {} func (*WindowerSpec_Frame) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 1} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 1} } func (m *WindowerSpec_Frame) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1357,7 +1401,7 @@ func (m *WindowerSpec_Frame_Bound) Reset() { *m = WindowerSpec_Frame_Bou func (m *WindowerSpec_Frame_Bound) String() string { return proto.CompactTextString(m) } func (*WindowerSpec_Frame_Bound) ProtoMessage() {} func (*WindowerSpec_Frame_Bound) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 1, 0} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 1, 0} } func (m *WindowerSpec_Frame_Bound) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1393,7 +1437,7 @@ func (m *WindowerSpec_Frame_Bounds) Reset() { *m = WindowerSpec_Frame_Bo func (m *WindowerSpec_Frame_Bounds) String() string { return proto.CompactTextString(m) } func (*WindowerSpec_Frame_Bounds) ProtoMessage() {} func (*WindowerSpec_Frame_Bounds) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 1, 1} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 1, 1} } func (m *WindowerSpec_Frame_Bounds) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1443,7 +1487,7 @@ func (m *WindowerSpec_WindowFn) Reset() { *m = WindowerSpec_WindowFn{} } func (m *WindowerSpec_WindowFn) String() string { return proto.CompactTextString(m) } func (*WindowerSpec_WindowFn) ProtoMessage() {} func (*WindowerSpec_WindowFn) Descriptor() ([]byte, []int) { - return fileDescriptor_processors_sql_6161e823454227e0, []int{13, 2} + return fileDescriptor_processors_sql_05381d0399cda248, []int{13, 2} } func (m *WindowerSpec_WindowFn) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1496,6 +1540,7 @@ func init() { proto.RegisterEnum("cockroach.sql.distsqlrun.WindowerSpec_WindowFunc", WindowerSpec_WindowFunc_name, WindowerSpec_WindowFunc_value) proto.RegisterEnum("cockroach.sql.distsqlrun.WindowerSpec_Frame_Mode", WindowerSpec_Frame_Mode_name, WindowerSpec_Frame_Mode_value) proto.RegisterEnum("cockroach.sql.distsqlrun.WindowerSpec_Frame_BoundType", WindowerSpec_Frame_BoundType_name, WindowerSpec_Frame_BoundType_value) + proto.RegisterEnum("cockroach.sql.distsqlrun.WindowerSpec_Frame_Exclusion", WindowerSpec_Frame_Exclusion_name, WindowerSpec_Frame_Exclusion_value) } func (m *ValuesCoreSpec) Marshal() (dAtA []byte, err error) { size := m.Size() @@ -2397,6 +2442,9 @@ func (m *WindowerSpec_Frame) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n27 + dAtA[i] = 0x18 + i++ + i = encodeVarintProcessorsSql(dAtA, i, uint64(m.Exclusion)) return i, nil } @@ -2920,6 +2968,7 @@ func (m *WindowerSpec_Frame) Size() (n int) { n += 1 + sovProcessorsSql(uint64(m.Mode)) l = m.Bounds.Size() n += 1 + l + sovProcessorsSql(uint64(l)) + n += 1 + sovProcessorsSql(uint64(m.Exclusion)) return n } @@ -6237,6 +6286,25 @@ func (m *WindowerSpec_Frame) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Exclusion", wireType) + } + m.Exclusion = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowProcessorsSql + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Exclusion |= (WindowerSpec_Frame_Exclusion(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipProcessorsSql(dAtA[iNdEx:]) @@ -6880,149 +6948,153 @@ var ( ) func init() { - proto.RegisterFile("sql/distsqlpb/processors_sql.proto", fileDescriptor_processors_sql_6161e823454227e0) -} - -var fileDescriptor_processors_sql_6161e823454227e0 = []byte{ - // 2236 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xbf, 0x73, 0xdb, 0xc8, - 0xf5, 0x17, 0x48, 0x40, 0x22, 0x1f, 0x7f, 0x08, 0xb7, 0xf6, 0x7d, 0xcd, 0xaf, 0x9c, 0x91, 0x64, - 0xfa, 0x12, 0xcb, 0x67, 0x47, 0xba, 0x28, 0x99, 0x24, 0x77, 0x97, 0xe2, 0x40, 0x12, 0xa4, 0x29, - 0x53, 0x80, 0x0c, 0x92, 0xf2, 0xd9, 0x45, 0x30, 0x10, 0xb1, 0xa2, 0x70, 0x22, 0x01, 0x0a, 0x0b, - 0x58, 0xd2, 0xfd, 0x03, 0xe9, 0x32, 0xc9, 0xa4, 0xcf, 0xa4, 0xc9, 0x4c, 0xfa, 0xa4, 0x48, 0x95, - 0xda, 0xe5, 0x75, 0xb9, 0x64, 0x32, 0x37, 0x89, 0x5d, 0xa4, 0x4b, 0x9b, 0x2e, 0x93, 0xd9, 0xc5, - 0x02, 0x02, 0x35, 0xa6, 0xc7, 0xb4, 0x3d, 0x71, 0xc7, 0x7d, 0x3f, 0x3e, 0xfb, 0xf6, 0xbd, 0xb7, - 0xef, 0xbd, 0x05, 0xa1, 0x4a, 0x4e, 0x46, 0x5b, 0xb6, 0x43, 0x02, 0x72, 0x32, 0x9a, 0x1c, 0x6c, - 0x4d, 0x7c, 0x6f, 0x80, 0x09, 0xf1, 0x7c, 0x62, 0x92, 0x93, 0xd1, 0xe6, 0xc4, 0xf7, 0x02, 0x0f, - 0x55, 0x06, 0xde, 0xe0, 0xd8, 0xf7, 0xac, 0xc1, 0xd1, 0x26, 0x25, 0x72, 0x69, 0x3f, 0x74, 0x57, - 0xbe, 0x45, 0xb5, 0xc9, 0xc9, 0xe8, 0xc0, 0x22, 0x78, 0x8b, 0x04, 0x7e, 0x38, 0x08, 0x42, 0x1f, - 0xdb, 0x91, 0xde, 0xca, 0xf5, 0x34, 0xf7, 0x0b, 0xcf, 0x71, 0xcd, 0xe0, 0x7c, 0x82, 0x39, 0xb3, - 0x32, 0xbd, 0xb1, 0x6d, 0x05, 0x16, 0xe7, 0xdc, 0x9c, 0x69, 0x12, 0x05, 0xe2, 0x42, 0x57, 0x87, - 0xde, 0xd0, 0x63, 0x3f, 0xb7, 0xe8, 0xaf, 0x88, 0x5a, 0xfd, 0x95, 0x00, 0xe5, 0x7d, 0x6b, 0x14, - 0x62, 0x52, 0xf7, 0x7c, 0xdc, 0x9d, 0xe0, 0x01, 0xaa, 0xc3, 0xd2, 0xc0, 0x1b, 0x85, 0x63, 0x97, - 0x54, 0x84, 0xf5, 0xec, 0x46, 0x61, 0xfb, 0xe6, 0xe6, 0xac, 0xe3, 0x6c, 0x36, 0xac, 0x20, 0x1c, - 0xb7, 0xdd, 0x43, 0xaf, 0x26, 0x3e, 0xfd, 0x66, 0x6d, 0xc1, 0x88, 0x35, 0xd1, 0x75, 0xc8, 0xfb, - 0xd6, 0xa9, 0x79, 0x70, 0x1e, 0x60, 0x52, 0xc9, 0xac, 0x67, 0x37, 0x8a, 0x46, 0xce, 0xb7, 0x4e, - 0x6b, 0x74, 0x8d, 0xd6, 0x20, 0xe7, 0x86, 0x63, 0xd3, 0xf7, 0x4e, 0x49, 0x25, 0xbb, 0x2e, 0x6c, - 0x88, 0xb1, 0xb6, 0x1b, 0x8e, 0x0d, 0xef, 0x94, 0x54, 0xff, 0x92, 0x85, 0xe5, 0x9e, 0x75, 0x30, - 0xc2, 0x06, 0xb6, 0x6c, 0xec, 0x33, 0xb3, 0x6a, 0x20, 0x05, 0x94, 0x54, 0x11, 0xd6, 0x85, 0x8d, - 0xc2, 0xf6, 0x77, 0x2e, 0x19, 0xc5, 0xbd, 0xb6, 0xc9, 0xd4, 0x1a, 0x98, 0x0c, 0x7c, 0x67, 0x12, - 0x78, 0x3e, 0x47, 0x8e, 0x54, 0xd1, 0x0d, 0xc8, 0x3b, 0xae, 0x8d, 0xcf, 0x4c, 0xc7, 0x3e, 0xab, - 0x64, 0xd6, 0x85, 0x8d, 0x12, 0xe7, 0xe7, 0x18, 0xb9, 0x6d, 0x9f, 0xa1, 0x55, 0x58, 0xf2, 0xf1, - 0x13, 0xec, 0x13, 0xcc, 0x4c, 0xcb, 0xc5, 0xa6, 0x71, 0x22, 0x52, 0x41, 0x22, 0x13, 0xcb, 0x25, - 0x15, 0x91, 0xf9, 0xe6, 0xf6, 0x6c, 0xdf, 0x4c, 0x1d, 0xc0, 0x72, 0x63, 0x4b, 0x98, 0x36, 0xba, - 0x09, 0x30, 0x72, 0xc6, 0x4e, 0x60, 0x1e, 0x39, 0x6e, 0x50, 0x91, 0xd6, 0x85, 0x8d, 0x2c, 0x17, - 0xc8, 0x33, 0xfa, 0x3d, 0xc7, 0x0d, 0xa8, 0x9f, 0x1c, 0x62, 0x0e, 0x8e, 0xf0, 0xe0, 0xb8, 0xb2, - 0x98, 0x36, 0xc6, 0x21, 0x75, 0x4a, 0x44, 0x1a, 0xc0, 0x13, 0x87, 0x38, 0x07, 0xce, 0xc8, 0x09, - 0xce, 0x2b, 0x4b, 0xeb, 0xc2, 0x46, 0x79, 0x7b, 0x63, 0xb6, 0x45, 0xdd, 0x81, 0xe5, 0xee, 0x27, - 0xf2, 0x1c, 0x2c, 0x85, 0x80, 0xbe, 0x0d, 0x85, 0xb1, 0x75, 0x66, 0xfa, 0x98, 0x84, 0xa3, 0x80, - 0x54, 0x72, 0xa9, 0xd8, 0xc0, 0xd8, 0x3a, 0x33, 0x22, 0x3a, 0xfa, 0x14, 0xae, 0x51, 0xb1, 0xc0, - 0x19, 0x63, 0x12, 0x58, 0xe3, 0x89, 0x69, 0x0d, 0xb1, 0xe9, 0x5a, 0xae, 0x47, 0x2a, 0xf9, 0x94, - 0xca, 0xd5, 0xb1, 0x75, 0xd6, 0x8b, 0x65, 0x94, 0x21, 0xd6, 0xa8, 0x44, 0xf5, 0x8f, 0x19, 0xa8, - 0xb4, 0xa9, 0xb7, 0xbb, 0xc7, 0xce, 0xe4, 0x1d, 0x05, 0x39, 0x09, 0x62, 0xf6, 0x8d, 0x82, 0x38, - 0xed, 0x7e, 0xf1, 0x8d, 0xdd, 0x9f, 0xca, 0x3d, 0xe9, 0x05, 0xb9, 0x57, 0xfd, 0x7d, 0x16, 0xca, - 0x3b, 0x9e, 0xe3, 0xfe, 0xef, 0x1d, 0x76, 0x1b, 0xca, 0x23, 0xcf, 0x3b, 0x0e, 0x27, 0x66, 0x5c, - 0x1a, 0xa8, 0xe7, 0x4a, 0xb5, 0x8c, 0x2c, 0x18, 0xa5, 0x88, 0x53, 0xe7, 0x37, 0xbf, 0x0e, 0x4b, - 0x9e, 0x6b, 0xe2, 0xb3, 0x89, 0xcf, 0x3c, 0x52, 0xd8, 0xfe, 0x60, 0xb6, 0x47, 0xd4, 0xb3, 0x89, - 0x8f, 0x09, 0x71, 0xbc, 0xd8, 0xb1, 0x8b, 0x9e, 0x4b, 0x69, 0xe8, 0x63, 0x10, 0x69, 0xe5, 0x63, - 0x59, 0x5f, 0xde, 0x5e, 0x9b, 0x71, 0x2a, 0xea, 0x8b, 0xde, 0xf9, 0x04, 0x73, 0x65, 0xa6, 0xf2, - 0xd6, 0xef, 0xc4, 0xc7, 0xf0, 0x7f, 0xd3, 0x47, 0x37, 0x2d, 0x1f, 0x9b, 0xc7, 0xf8, 0x9c, 0x5d, - 0x8f, 0x38, 0x46, 0x57, 0xa6, 0x9c, 0xa0, 0xf8, 0xf8, 0x3e, 0x3e, 0xdf, 0x11, 0x73, 0x92, 0xbc, - 0x48, 0x4b, 0x2c, 0x74, 0x3d, 0x3f, 0xe0, 0x11, 0x7b, 0x00, 0xcb, 0x5e, 0x18, 0x4c, 0xc2, 0xc0, - 0xf4, 0x7c, 0x1b, 0xfb, 0x8e, 0x3b, 0xe4, 0xb1, 0xab, 0xce, 0x36, 0x52, 0xe7, 0x92, 0x7c, 0xb3, - 0x72, 0x04, 0x10, 0x53, 0xd1, 0x36, 0xa0, 0x18, 0xcb, 0x1c, 0x5b, 0xc1, 0xe0, 0xc8, 0x1c, 0x61, - 0x77, 0x2a, 0x92, 0x72, 0xcc, 0xdf, 0xa5, 0xec, 0x0e, 0x76, 0xab, 0x07, 0x50, 0x6c, 0x38, 0x24, - 0x70, 0xdc, 0x41, 0xc0, 0xcc, 0xba, 0x05, 0xcb, 0x4c, 0x06, 0xdb, 0x66, 0xba, 0xfa, 0x97, 0x8c, - 0x32, 0x27, 0xc7, 0xf1, 0xbd, 0x0d, 0xb2, 0xcd, 0x15, 0x13, 0xc9, 0x0c, 0x93, 0x5c, 0x8e, 0xe9, - 0x5c, 0xb4, 0x2a, 0x43, 0x59, 0xf7, 0x6d, 0xc7, 0xb5, 0xa8, 0x23, 0xe9, 0x2e, 0xd5, 0x9f, 0x67, - 0x41, 0x7e, 0xec, 0x0c, 0xbf, 0xb4, 0x86, 0x34, 0x76, 0xdc, 0x23, 0x0d, 0x58, 0x64, 0x89, 0x18, - 0xf7, 0x9b, 0xf9, 0x92, 0x98, 0xeb, 0xa2, 0x26, 0x00, 0x3e, 0x99, 0xb2, 0xa8, 0xb0, 0x7d, 0x63, - 0xb6, 0x4b, 0xb9, 0x8d, 0x71, 0xd1, 0xc5, 0x27, 0xf1, 0xf9, 0xd6, 0x2e, 0x6e, 0x43, 0x3a, 0xcb, - 0xe3, 0xbb, 0xf0, 0x96, 0x12, 0xfc, 0x3e, 0x14, 0x0f, 0x9d, 0x33, 0x6c, 0x9b, 0x4f, 0x58, 0xf3, - 0xad, 0x48, 0xcc, 0xde, 0x97, 0xe4, 0xe9, 0x74, 0x93, 0x36, 0x0a, 0x4c, 0x3b, 0x22, 0xbe, 0xc1, - 0x6d, 0xa9, 0xfe, 0x2d, 0x03, 0xcb, 0xbb, 0xd8, 0x1f, 0xe2, 0x54, 0x3c, 0x76, 0xa1, 0x34, 0xc2, - 0x87, 0x6f, 0x90, 0x9f, 0x45, 0xaa, 0x9e, 0x64, 0xa7, 0x0e, 0x65, 0xdf, 0x19, 0x1e, 0xa5, 0xf0, - 0x32, 0x73, 0xe2, 0x95, 0x98, 0x7e, 0x02, 0x98, 0x0a, 0x80, 0xf4, 0x2e, 0x2a, 0xcc, 0x6d, 0x28, - 0xb9, 0xe1, 0x68, 0x64, 0xe2, 0x93, 0xd0, 0x4a, 0x8a, 0x4c, 0x5c, 0x08, 0x8a, 0x94, 0xa5, 0x72, - 0x4e, 0xf5, 0x97, 0x59, 0x28, 0xdf, 0xb3, 0xc8, 0x51, 0xca, 0xbb, 0x1f, 0xc2, 0x32, 0xf3, 0x6e, - 0x2a, 0x59, 0x85, 0x54, 0x2d, 0xc5, 0x87, 0x81, 0x9a, 0xe4, 0xe2, 0x5d, 0x90, 0x23, 0xd7, 0x5d, - 0xca, 0xec, 0x48, 0x38, 0x72, 0xeb, 0x85, 0xf4, 0xbb, 0xf6, 0xcb, 0x1d, 0x28, 0x8f, 0x69, 0x2a, - 0x5d, 0x54, 0x90, 0xb4, 0x63, 0x4a, 0x11, 0x2f, 0x36, 0xf6, 0x13, 0xb8, 0x76, 0xc9, 0x0d, 0x33, - 0xea, 0x6a, 0xda, 0x21, 0x51, 0x5d, 0x45, 0x3f, 0x81, 0xca, 0x65, 0xb7, 0x24, 0xca, 0xf9, 0x94, - 0xf2, 0xd5, 0x69, 0x07, 0x45, 0xda, 0xd5, 0x7f, 0x2d, 0x42, 0x59, 0x19, 0x0e, 0x7d, 0x3c, 0xb4, - 0x02, 0x2f, 0x8a, 0xc9, 0x0d, 0x80, 0xa1, 0xef, 0x45, 0x25, 0x3e, 0xed, 0xe1, 0x3c, 0xa3, 0xd6, - 0xbd, 0x11, 0x41, 0x3f, 0x85, 0xa2, 0xc5, 0x95, 0x1c, 0x2f, 0x99, 0x1c, 0x7e, 0x30, 0xdb, 0xc3, - 0xd3, 0x5b, 0x24, 0xcb, 0x0b, 0x8f, 0x4f, 0xe1, 0xa1, 0x8f, 0x78, 0x0d, 0xc7, 0xb6, 0x99, 0x32, - 0x45, 0x4c, 0x4c, 0x91, 0x39, 0xb7, 0x95, 0x58, 0xd4, 0xe2, 0x91, 0x92, 0x58, 0xa4, 0xbe, 0xfb, - 0xca, 0x96, 0x5c, 0x8e, 0xdb, 0xca, 0xcf, 0x32, 0x50, 0x48, 0x99, 0x47, 0x81, 0x0f, 0x43, 0x77, - 0xc0, 0xae, 0xfd, 0x3c, 0xc0, 0xcd, 0xd0, 0x1d, 0xc4, 0xc0, 0x14, 0x00, 0xad, 0x43, 0x2e, 0x6e, - 0x09, 0xec, 0xce, 0xc7, 0x71, 0x49, 0xa8, 0xe8, 0x03, 0x28, 0x1f, 0x3a, 0xa3, 0x00, 0xfb, 0xf4, - 0xb8, 0x6c, 0xfe, 0xa0, 0x25, 0xb5, 0x64, 0x14, 0x23, 0x6a, 0xdd, 0x1b, 0xd1, 0xe9, 0xe3, 0x1a, - 0x7b, 0x91, 0x30, 0xb6, 0xc4, 0x3a, 0xcd, 0xe2, 0x20, 0x62, 0xdc, 0x83, 0xbc, 0xe5, 0x0f, 0xc3, - 0x31, 0x76, 0x03, 0x52, 0x59, 0x64, 0x11, 0x99, 0x27, 0xe7, 0x2f, 0x94, 0x77, 0xc4, 0x5c, 0x56, - 0x16, 0xab, 0xbf, 0xcd, 0x80, 0x48, 0x4f, 0x81, 0x64, 0x28, 0x2a, 0xda, 0x23, 0x53, 0xd3, 0x7b, - 0xa6, 0xd6, 0xef, 0x74, 0xe4, 0x05, 0xb4, 0x04, 0x59, 0x65, 0xbf, 0x25, 0x0b, 0xa8, 0x08, 0xb9, - 0x9a, 0xae, 0x77, 0x4c, 0x45, 0x6b, 0xc8, 0x19, 0x54, 0x80, 0x25, 0xb6, 0xd2, 0x0d, 0x39, 0x8b, - 0xca, 0x00, 0x75, 0x5d, 0xab, 0x2b, 0x3d, 0x53, 0x69, 0xb5, 0x64, 0x11, 0xe5, 0x41, 0xaa, 0xeb, - 0x7d, 0xad, 0x27, 0x4b, 0x54, 0x7d, 0x57, 0xf9, 0x5c, 0x5e, 0x62, 0x3f, 0xda, 0x9a, 0x9c, 0x43, - 0x00, 0x8b, 0xdd, 0x5e, 0xa3, 0xa1, 0xee, 0xcb, 0x79, 0x4a, 0xec, 0xf6, 0x77, 0x65, 0xa0, 0x70, - 0xdd, 0xfe, 0xae, 0xd9, 0xd6, 0x7a, 0x72, 0x81, 0xee, 0xb4, 0xaf, 0x18, 0x6d, 0x45, 0xab, 0xab, - 0x72, 0x91, 0xb2, 0x3e, 0xd7, 0x0d, 0x86, 0x5c, 0x8a, 0x76, 0xea, 0x6b, 0x3d, 0xd3, 0xd0, 0x1f, - 0x76, 0xe5, 0x32, 0xd3, 0x7b, 0x60, 0x34, 0xda, 0xcd, 0xa6, 0xbc, 0x8c, 0x10, 0x94, 0x9b, 0x6d, - 0x4d, 0xe9, 0x98, 0x89, 0xb6, 0x4c, 0x0f, 0x14, 0xd1, 0xf8, 0x9e, 0xef, 0xa1, 0x12, 0xe4, 0x15, - 0xc3, 0x50, 0x1e, 0x31, 0x44, 0x44, 0x37, 0xdb, 0xe9, 0xea, 0x1a, 0x5b, 0x5d, 0xa1, 0x4c, 0xba, - 0xaa, 0xb1, 0xe5, 0x55, 0xba, 0x5d, 0xb7, 0x67, 0xb4, 0xb5, 0x16, 0x5b, 0xbf, 0x5f, 0xbd, 0x0b, - 0x22, 0xcd, 0x22, 0x94, 0x03, 0x51, 0xe9, 0xf7, 0x74, 0x79, 0x81, 0x9d, 0xa6, 0xae, 0x74, 0x14, - 0x43, 0x16, 0xa8, 0xb4, 0xa6, 0x6b, 0x26, 0x5f, 0x67, 0xaa, 0xff, 0x11, 0xe1, 0x7a, 0xdb, 0x0d, - 0xb0, 0x3f, 0xc2, 0xd6, 0x13, 0x6c, 0x47, 0xd3, 0x6b, 0xaa, 0x22, 0x3e, 0xba, 0xd4, 0xff, 0x3f, - 0x9d, 0x1d, 0xc2, 0x97, 0xc0, 0x44, 0xe3, 0xc1, 0xa5, 0xa1, 0x20, 0x35, 0x51, 0x67, 0x5e, 0xf4, - 0x9a, 0x9b, 0x7e, 0x86, 0x65, 0x5f, 0xfc, 0x0c, 0x7b, 0xab, 0x13, 0xad, 0x34, 0x77, 0x5d, 0x5d, - 0xf9, 0x53, 0x06, 0x24, 0x76, 0x38, 0xf4, 0x19, 0x88, 0x36, 0x26, 0x83, 0xd7, 0x1a, 0xf6, 0x99, - 0xe6, 0xab, 0xcc, 0xfa, 0x75, 0x10, 0x27, 0x1e, 0x89, 0xbc, 0xf1, 0xd2, 0xb7, 0xd1, 0x9e, 0x47, - 0x82, 0xbd, 0xe8, 0x5b, 0x03, 0x0d, 0x40, 0xbc, 0x0f, 0x55, 0x46, 0x0d, 0xc8, 0x25, 0xed, 0x5e, - 0x9c, 0xb3, 0xdd, 0x27, 0x9a, 0x17, 0xef, 0x34, 0xe9, 0x4d, 0xde, 0x69, 0xd5, 0x67, 0x02, 0x94, - 0xf7, 0x7c, 0xef, 0x0b, 0x3c, 0x08, 0xba, 0x38, 0x1a, 0x77, 0x3f, 0x03, 0x89, 0x06, 0x34, 0x4e, - 0xb9, 0x79, 0x22, 0x1a, 0x29, 0x22, 0x0c, 0xef, 0x0d, 0xb1, 0x8b, 0x7d, 0x2b, 0x48, 0x35, 0x3c, - 0xf6, 0xa5, 0xa3, 0xf6, 0x63, 0x2a, 0xf7, 0xd7, 0x6f, 0xd6, 0x3e, 0x1a, 0x3a, 0xc1, 0x51, 0x78, - 0xb0, 0x39, 0xf0, 0xc6, 0x5b, 0x09, 0xbe, 0x7d, 0x70, 0xf1, 0x7b, 0x6b, 0x72, 0x3c, 0xdc, 0x22, - 0x27, 0xa3, 0x2d, 0x1a, 0x67, 0xb2, 0xd9, 0x33, 0xe4, 0x04, 0x32, 0xee, 0x93, 0xb7, 0x40, 0x76, - 0xc3, 0x31, 0xeb, 0x06, 0xe6, 0x04, 0xfb, 0xe6, 0x10, 0xbb, 0xd1, 0x54, 0x6a, 0x94, 0xdc, 0x70, - 0x4c, 0x1b, 0xc1, 0x1e, 0xf6, 0x5b, 0xd8, 0xad, 0xfe, 0xae, 0x08, 0xc5, 0x87, 0x8e, 0x6b, 0x7b, - 0xa7, 0xfc, 0x5a, 0xad, 0x43, 0x61, 0x62, 0xf9, 0x81, 0xc3, 0x5a, 0xce, 0x39, 0x9f, 0xe6, 0xd3, - 0x24, 0xd4, 0x85, 0xfc, 0x29, 0xd3, 0x68, 0x26, 0x13, 0xf3, 0xd6, 0x6c, 0x47, 0xa4, 0xc1, 0xf9, - 0xa2, 0x99, 0x54, 0xd2, 0x04, 0x67, 0xe5, 0x0f, 0x02, 0xaf, 0xa1, 0x5d, 0x28, 0xc5, 0x1d, 0x0e, - 0x37, 0x5f, 0xb7, 0x9f, 0x18, 0xd3, 0x18, 0xe8, 0x01, 0x00, 0xdf, 0x8a, 0x22, 0x66, 0x18, 0xe2, - 0xf7, 0xe6, 0xb3, 0x99, 0xa2, 0xa6, 0x40, 0x3e, 0x11, 0x9f, 0xfe, 0x66, 0x4d, 0x58, 0xf9, 0xa7, - 0x04, 0x52, 0xd3, 0xb7, 0xc6, 0x18, 0xdd, 0x07, 0x71, 0xec, 0xd9, 0x98, 0x9b, 0xfb, 0xaa, 0xe0, - 0x4c, 0x77, 0x73, 0xd7, 0xb3, 0x93, 0xbb, 0x4b, 0x41, 0xd0, 0x03, 0x58, 0x3c, 0xf0, 0x42, 0xd7, - 0x26, 0x7c, 0xe8, 0xfd, 0xfe, 0x5c, 0x70, 0x35, 0xa6, 0x1a, 0x57, 0x92, 0x08, 0x68, 0xe5, 0xdf, - 0x02, 0x48, 0x8c, 0x81, 0x1e, 0x43, 0x9e, 0xd1, 0x68, 0xc5, 0xe0, 0xe6, 0xfe, 0x70, 0x7e, 0xfc, - 0x54, 0xbd, 0xb9, 0x80, 0xa3, 0x95, 0xd1, 0x71, 0x03, 0xd3, 0x3b, 0x3c, 0x24, 0x38, 0xea, 0xde, - 0xf1, 0x67, 0x9d, 0xbc, 0xe3, 0x06, 0x3a, 0x23, 0xa3, 0x1b, 0x50, 0xa4, 0x99, 0x6b, 0xc7, 0x62, - 0xb4, 0x64, 0x14, 0x8d, 0x02, 0xa3, 0x71, 0x91, 0x1d, 0x28, 0x44, 0x4c, 0xf6, 0x29, 0x93, 0xd7, - 0x82, 0x39, 0xbe, 0x28, 0x42, 0xa4, 0x4d, 0x6d, 0x5a, 0xf9, 0xb5, 0x00, 0x8b, 0x91, 0x4b, 0x90, - 0x06, 0x12, 0x09, 0x2c, 0x3f, 0xe0, 0xa5, 0x70, 0x7b, 0xfe, 0x63, 0x27, 0x25, 0x82, 0xc2, 0xa0, - 0x06, 0x64, 0xb1, 0x6b, 0xf3, 0x20, 0xbd, 0x06, 0x9a, 0x41, 0xd5, 0xab, 0xb7, 0x40, 0xa4, 0x19, - 0x40, 0x1b, 0xbf, 0xa1, 0x68, 0x2d, 0x55, 0x5e, 0xa0, 0x2d, 0x92, 0xf5, 0x68, 0x81, 0xb6, 0xc8, - 0x96, 0xa1, 0xf7, 0xf7, 0xba, 0x72, 0xa6, 0xfa, 0x25, 0xe4, 0x13, 0xdf, 0xa3, 0x6b, 0x70, 0xa5, - 0xaf, 0xd5, 0xf4, 0xbe, 0xd6, 0x50, 0x1b, 0xe6, 0x9e, 0xa1, 0xd6, 0xd5, 0x46, 0x5b, 0x6b, 0xc9, - 0x0b, 0xd3, 0x8c, 0xa6, 0xde, 0xe9, 0xe8, 0x0f, 0x29, 0x43, 0x40, 0x57, 0x41, 0xd6, 0x9b, 0xcd, - 0xae, 0xda, 0x4b, 0x89, 0x67, 0x52, 0xd4, 0x0b, 0xd9, 0x2c, 0x5a, 0x86, 0x42, 0xbd, 0x6f, 0x18, - 0x6a, 0x34, 0x2c, 0xc8, 0xe2, 0xca, 0x9f, 0x33, 0x90, 0x8b, 0xaf, 0x2f, 0x52, 0x53, 0xb3, 0x5e, - 0x61, 0xfb, 0xce, 0xab, 0x1e, 0xfc, 0xf2, 0xa4, 0xf7, 0x76, 0xca, 0x7d, 0x0d, 0xa4, 0x43, 0xea, - 0x52, 0xfe, 0x7c, 0xb9, 0x3b, 0x4f, 0x18, 0x8c, 0x48, 0x15, 0x6d, 0xc0, 0xd4, 0xec, 0xc8, 0xde, - 0x31, 0x52, 0x3c, 0x71, 0x4f, 0x4d, 0x95, 0x2b, 0x90, 0xb3, 0xfc, 0x21, 0x69, 0xdb, 0x67, 0xf4, - 0xa1, 0x42, 0x8b, 0x63, 0xb2, 0xa6, 0x28, 0xd1, 0x37, 0x16, 0x8e, 0x92, 0x4b, 0x75, 0xca, 0x29, - 0xce, 0x8e, 0x98, 0xcb, 0xc8, 0xd9, 0x78, 0x7c, 0x14, 0x00, 0x2e, 0x8a, 0x0c, 0x9d, 0x83, 0x0c, - 0xfd, 0xa1, 0xa9, 0xf5, 0x77, 0x6b, 0xaa, 0xc1, 0x53, 0x41, 0xd1, 0xee, 0x47, 0x13, 0x52, 0x43, - 0xd5, 0xba, 0xaa, 0xc9, 0xd6, 0x19, 0x3a, 0x9d, 0xed, 0xa9, 0x46, 0x9d, 0xc5, 0x88, 0x52, 0xb2, - 0x74, 0x00, 0xab, 0xf7, 0x77, 0x55, 0xb3, 0xd1, 0xee, 0xf6, 0xa2, 0x49, 0x52, 0xeb, 0xb5, 0x3b, - 0x6a, 0x34, 0x49, 0x76, 0x94, 0x96, 0xbc, 0x48, 0xe1, 0x3a, 0xaa, 0xd2, 0x90, 0x97, 0x68, 0x88, - 0x9b, 0x6d, 0xa3, 0xdb, 0x33, 0xf7, 0x95, 0x4e, 0x5f, 0x95, 0x73, 0x14, 0xbf, 0xa3, 0x24, 0xeb, - 0x3c, 0x45, 0xd3, 0x7a, 0xf7, 0xf8, 0x12, 0x3e, 0xfc, 0x11, 0x94, 0xa7, 0x3f, 0x7b, 0xd1, 0xdc, - 0xdc, 0xeb, 0xd7, 0x3a, 0xed, 0xba, 0xbc, 0x80, 0xfe, 0x1f, 0xde, 0x8f, 0x7e, 0xd3, 0x11, 0x97, - 0x8d, 0xc0, 0x9c, 0x25, 0xd4, 0xee, 0x3c, 0xfd, 0xc7, 0xea, 0xc2, 0xd3, 0x67, 0xab, 0xc2, 0x57, - 0xcf, 0x56, 0x85, 0xaf, 0x9f, 0xad, 0x0a, 0x7f, 0x7f, 0xb6, 0x2a, 0xfc, 0xe2, 0xf9, 0xea, 0xc2, - 0x57, 0xcf, 0x57, 0x17, 0xbe, 0x7e, 0xbe, 0xba, 0xf0, 0x38, 0x9f, 0xfc, 0x0d, 0xf1, 0xdf, 0x00, - 0x00, 0x00, 0xff, 0xff, 0x79, 0x23, 0x24, 0xa8, 0x29, 0x19, 0x00, 0x00, + proto.RegisterFile("sql/distsqlpb/processors_sql.proto", fileDescriptor_processors_sql_05381d0399cda248) +} + +var fileDescriptor_processors_sql_05381d0399cda248 = []byte{ + // 2299 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0xcd, 0x73, 0xdb, 0xc6, + 0x15, 0x17, 0x48, 0x90, 0x22, 0x1f, 0x3f, 0x04, 0xaf, 0x9d, 0x9a, 0x95, 0x3b, 0x92, 0x4c, 0xa7, + 0xb5, 0x1c, 0xbb, 0x52, 0xaa, 0x76, 0xd2, 0x26, 0xe9, 0x21, 0x20, 0x09, 0xd2, 0x94, 0x29, 0x40, + 0x06, 0x49, 0xf9, 0xa3, 0x33, 0xc5, 0x40, 0xc4, 0x8a, 0x42, 0x04, 0x02, 0x14, 0x3e, 0x2c, 0x2a, + 0xff, 0x40, 0x6f, 0x9d, 0x76, 0x7a, 0xef, 0xe4, 0xd2, 0xbf, 0xa0, 0x3d, 0xf4, 0xd4, 0xb3, 0x8f, + 0xb9, 0x35, 0xed, 0x74, 0x32, 0x8d, 0x7d, 0xef, 0xb5, 0xb7, 0x4e, 0x67, 0x17, 0x0b, 0x10, 0xd4, + 0x98, 0x1e, 0xd3, 0xf6, 0xc4, 0x37, 0xee, 0xfb, 0xf8, 0xed, 0xdb, 0xf7, 0xde, 0xbe, 0xf7, 0x16, + 0x84, 0xaa, 0x77, 0x6a, 0x6d, 0x1b, 0xa6, 0xe7, 0x7b, 0xa7, 0xd6, 0xf8, 0x70, 0x7b, 0xec, 0x3a, + 0x03, 0xec, 0x79, 0x8e, 0xeb, 0x69, 0xde, 0xa9, 0xb5, 0x35, 0x76, 0x1d, 0xdf, 0x41, 0x95, 0x81, + 0x33, 0x38, 0x71, 0x1d, 0x7d, 0x70, 0xbc, 0x45, 0x88, 0x4c, 0xda, 0x0d, 0xec, 0xd5, 0x1f, 0x10, + 0x6d, 0xef, 0xd4, 0x3a, 0xd4, 0x3d, 0xbc, 0xed, 0xf9, 0x6e, 0x30, 0xf0, 0x03, 0x17, 0x1b, 0xa1, + 0xde, 0xea, 0xb5, 0x24, 0xf7, 0x73, 0xc7, 0xb4, 0x35, 0xff, 0x7c, 0x8c, 0x19, 0xb3, 0x32, 0xbb, + 0xb1, 0xa1, 0xfb, 0x3a, 0xe3, 0xdc, 0x98, 0x6b, 0x12, 0x01, 0x62, 0x42, 0x57, 0x86, 0xce, 0xd0, + 0xa1, 0x3f, 0xb7, 0xc9, 0xaf, 0x90, 0x5a, 0xfd, 0x03, 0x07, 0xe5, 0x03, 0xdd, 0x0a, 0xb0, 0x57, + 0x77, 0x5c, 0xdc, 0x1d, 0xe3, 0x01, 0xaa, 0xc3, 0xf2, 0xc0, 0xb1, 0x82, 0x91, 0xed, 0x55, 0xb8, + 0x8d, 0xf4, 0x66, 0x61, 0xe7, 0xc6, 0xd6, 0xbc, 0xe3, 0x6c, 0x35, 0x74, 0x3f, 0x18, 0xb5, 0xed, + 0x23, 0xa7, 0xc6, 0x3f, 0xfd, 0x66, 0x7d, 0x49, 0x8d, 0x34, 0xd1, 0x35, 0xc8, 0xbb, 0xfa, 0x99, + 0x76, 0x78, 0xee, 0x63, 0xaf, 0x92, 0xda, 0x48, 0x6f, 0x16, 0xd5, 0x9c, 0xab, 0x9f, 0xd5, 0xc8, + 0x1a, 0xad, 0x43, 0xce, 0x0e, 0x46, 0x9a, 0xeb, 0x9c, 0x79, 0x95, 0xf4, 0x06, 0xb7, 0xc9, 0x47, + 0xda, 0x76, 0x30, 0x52, 0x9d, 0x33, 0xaf, 0xfa, 0x8f, 0x34, 0xac, 0xf4, 0xf4, 0x43, 0x0b, 0xab, + 0x58, 0x37, 0xb0, 0x4b, 0xcd, 0xaa, 0x41, 0xc6, 0x27, 0xa4, 0x0a, 0xb7, 0xc1, 0x6d, 0x16, 0x76, + 0x7e, 0x74, 0xc1, 0x28, 0xe6, 0xb5, 0x2d, 0xaa, 0xd6, 0xc0, 0xde, 0xc0, 0x35, 0xc7, 0xbe, 0xe3, + 0x32, 0xe4, 0x50, 0x15, 0x5d, 0x87, 0xbc, 0x69, 0x1b, 0x78, 0xa2, 0x99, 0xc6, 0xa4, 0x92, 0xda, + 0xe0, 0x36, 0x4b, 0x8c, 0x9f, 0xa3, 0xe4, 0xb6, 0x31, 0x41, 0x6b, 0xb0, 0xec, 0xe2, 0x27, 0xd8, + 0xf5, 0x30, 0x35, 0x2d, 0x17, 0x99, 0xc6, 0x88, 0x48, 0x82, 0x8c, 0x37, 0xd6, 0x6d, 0xaf, 0xc2, + 0x53, 0xdf, 0xdc, 0x9a, 0xef, 0x9b, 0x99, 0x03, 0xe8, 0x76, 0x64, 0x09, 0xd5, 0x46, 0x37, 0x00, + 0x2c, 0x73, 0x64, 0xfa, 0xda, 0xb1, 0x69, 0xfb, 0x95, 0xcc, 0x06, 0xb7, 0x99, 0x66, 0x02, 0x79, + 0x4a, 0xbf, 0x6b, 0xda, 0x3e, 0xf1, 0x93, 0xe9, 0x69, 0x83, 0x63, 0x3c, 0x38, 0xa9, 0x64, 0x93, + 0xc6, 0x98, 0x5e, 0x9d, 0x10, 0x91, 0x0c, 0xf0, 0xc4, 0xf4, 0xcc, 0x43, 0xd3, 0x32, 0xfd, 0xf3, + 0xca, 0xf2, 0x06, 0xb7, 0x59, 0xde, 0xd9, 0x9c, 0x6f, 0x51, 0x77, 0xa0, 0xdb, 0x07, 0xb1, 0x3c, + 0x03, 0x4b, 0x20, 0xa0, 0x1f, 0x42, 0x61, 0xa4, 0x4f, 0x34, 0x17, 0x7b, 0x81, 0xe5, 0x7b, 0x95, + 0x5c, 0x22, 0x36, 0x30, 0xd2, 0x27, 0x6a, 0x48, 0x47, 0x9f, 0xc2, 0x55, 0x22, 0xe6, 0x9b, 0x23, + 0xec, 0xf9, 0xfa, 0x68, 0xac, 0xe9, 0x43, 0xac, 0xd9, 0xba, 0xed, 0x78, 0x95, 0x7c, 0x42, 0xe5, + 0xca, 0x48, 0x9f, 0xf4, 0x22, 0x19, 0x71, 0x88, 0x65, 0x22, 0x51, 0xfd, 0x6b, 0x0a, 0x2a, 0x6d, + 0xe2, 0xed, 0xee, 0x89, 0x39, 0x7e, 0x47, 0x41, 0x8e, 0x83, 0x98, 0x7e, 0xa3, 0x20, 0xce, 0xba, + 0x9f, 0x7f, 0x63, 0xf7, 0x27, 0x72, 0x2f, 0xf3, 0x82, 0xdc, 0xab, 0xfe, 0x39, 0x0d, 0xe5, 0x5d, + 0xc7, 0xb4, 0xbf, 0x7b, 0x87, 0xdd, 0x82, 0xb2, 0xe5, 0x38, 0x27, 0xc1, 0x58, 0x8b, 0x4a, 0x03, + 0xf1, 0x5c, 0xa9, 0x96, 0x12, 0x38, 0xb5, 0x14, 0x72, 0xea, 0xec, 0xe6, 0xd7, 0x61, 0xd9, 0xb1, + 0x35, 0x3c, 0x19, 0xbb, 0xd4, 0x23, 0x85, 0x9d, 0xf7, 0xe7, 0x7b, 0x44, 0x9a, 0x8c, 0x5d, 0xec, + 0x79, 0xa6, 0x13, 0x39, 0x36, 0xeb, 0xd8, 0x84, 0x86, 0x3e, 0x06, 0x9e, 0x54, 0x3e, 0x9a, 0xf5, + 0xe5, 0x9d, 0xf5, 0x39, 0xa7, 0x22, 0xbe, 0xe8, 0x9d, 0x8f, 0x31, 0x53, 0xa6, 0x2a, 0x6f, 0xfd, + 0x4e, 0x7c, 0x0c, 0xdf, 0x9b, 0x3d, 0xba, 0xa6, 0xbb, 0x58, 0x3b, 0xc1, 0xe7, 0xf4, 0x7a, 0x44, + 0x31, 0xba, 0x3c, 0xe3, 0x04, 0xd1, 0xc5, 0xf7, 0xf0, 0xf9, 0x2e, 0x9f, 0xcb, 0x08, 0x59, 0x52, + 0x62, 0xa1, 0xeb, 0xb8, 0x3e, 0x8b, 0xd8, 0x7d, 0x58, 0x71, 0x02, 0x7f, 0x1c, 0xf8, 0x9a, 0xe3, + 0x1a, 0xd8, 0x35, 0xed, 0x21, 0x8b, 0x5d, 0x75, 0xbe, 0x91, 0x0a, 0x93, 0x64, 0x9b, 0x95, 0x43, + 0x80, 0x88, 0x8a, 0x76, 0x00, 0x45, 0x58, 0xda, 0x48, 0xf7, 0x07, 0xc7, 0x9a, 0x85, 0xed, 0x99, + 0x48, 0x0a, 0x11, 0x7f, 0x8f, 0xb0, 0x3b, 0xd8, 0xae, 0x1e, 0x42, 0xb1, 0x61, 0x7a, 0xbe, 0x69, + 0x0f, 0x7c, 0x6a, 0xd6, 0x4d, 0x58, 0xa1, 0x32, 0xd8, 0xd0, 0x92, 0xd5, 0xbf, 0xa4, 0x96, 0x19, + 0x39, 0x8a, 0xef, 0x2d, 0x10, 0x0c, 0xa6, 0x18, 0x4b, 0xa6, 0xa8, 0xe4, 0x4a, 0x44, 0x67, 0xa2, + 0x55, 0x01, 0xca, 0x8a, 0x6b, 0x98, 0xb6, 0x4e, 0x1c, 0x49, 0x76, 0xa9, 0xfe, 0x36, 0x0d, 0xc2, + 0x63, 0x73, 0xf8, 0x85, 0x3e, 0x24, 0xb1, 0x63, 0x1e, 0x69, 0x40, 0x96, 0x26, 0x62, 0xd4, 0x6f, + 0x16, 0x4b, 0x62, 0xa6, 0x8b, 0x9a, 0x00, 0xf8, 0x74, 0xc6, 0xa2, 0xc2, 0xce, 0xf5, 0xf9, 0x2e, + 0x65, 0x36, 0x46, 0x45, 0x17, 0x9f, 0x46, 0xe7, 0x5b, 0x9f, 0xde, 0x86, 0x64, 0x96, 0x47, 0x77, + 0xe1, 0x2d, 0x25, 0xf8, 0x3d, 0x28, 0x1e, 0x99, 0x13, 0x6c, 0x68, 0x4f, 0x68, 0xf3, 0xad, 0x64, + 0xa8, 0xbd, 0x2f, 0xc9, 0xd3, 0xd9, 0x26, 0xad, 0x16, 0xa8, 0x76, 0x48, 0x7c, 0x83, 0xdb, 0x52, + 0xfd, 0x57, 0x0a, 0x56, 0xf6, 0xb0, 0x3b, 0xc4, 0x89, 0x78, 0xec, 0x41, 0xc9, 0xc2, 0x47, 0x6f, + 0x90, 0x9f, 0x45, 0xa2, 0x1e, 0x67, 0xa7, 0x02, 0x65, 0xd7, 0x1c, 0x1e, 0x27, 0xf0, 0x52, 0x0b, + 0xe2, 0x95, 0xa8, 0x7e, 0x0c, 0x98, 0x08, 0x40, 0xe6, 0x5d, 0x54, 0x98, 0x5b, 0x50, 0xb2, 0x03, + 0xcb, 0xd2, 0xf0, 0x69, 0xa0, 0xc7, 0x45, 0x26, 0x2a, 0x04, 0x45, 0xc2, 0x92, 0x18, 0xa7, 0xfa, + 0xfb, 0x34, 0x94, 0xef, 0xea, 0xde, 0x71, 0xc2, 0xbb, 0x1f, 0xc0, 0x0a, 0xf5, 0x6e, 0x22, 0x59, + 0xb9, 0x44, 0x2d, 0xc5, 0x47, 0xbe, 0x14, 0xe7, 0xe2, 0x1d, 0x10, 0x42, 0xd7, 0x5d, 0xc8, 0xec, + 0x50, 0x38, 0x74, 0xeb, 0x54, 0xfa, 0x5d, 0xfb, 0xe5, 0x36, 0x94, 0x47, 0x24, 0x95, 0xa6, 0x15, + 0x24, 0xe9, 0x98, 0x52, 0xc8, 0x8b, 0x8c, 0xfd, 0x04, 0xae, 0x5e, 0x70, 0xc3, 0x9c, 0xba, 0x9a, + 0x74, 0x48, 0x58, 0x57, 0xd1, 0x2f, 0xa1, 0x72, 0xd1, 0x2d, 0xb1, 0x72, 0x3e, 0xa1, 0x7c, 0x65, + 0xd6, 0x41, 0xa1, 0x76, 0xf5, 0x3f, 0x59, 0x28, 0x8b, 0xc3, 0xa1, 0x8b, 0x87, 0xba, 0xef, 0x84, + 0x31, 0xb9, 0x0e, 0x30, 0x74, 0x9d, 0xb0, 0xc4, 0x27, 0x3d, 0x9c, 0xa7, 0xd4, 0xba, 0x63, 0x79, + 0xe8, 0xd7, 0x50, 0xd4, 0x99, 0x92, 0xe9, 0xc4, 0x93, 0xc3, 0xcf, 0xe6, 0x7b, 0x78, 0x76, 0x8b, + 0x78, 0x39, 0xf5, 0xf8, 0x0c, 0x1e, 0xfa, 0x90, 0xd5, 0x70, 0x6c, 0x68, 0x09, 0x53, 0xf8, 0xd8, + 0x14, 0x81, 0x71, 0x5b, 0xb1, 0x45, 0x2d, 0x16, 0xa9, 0x0c, 0x8d, 0xd4, 0x8f, 0x5f, 0xd9, 0x92, + 0x8b, 0x71, 0x5b, 0xfd, 0x4d, 0x0a, 0x0a, 0x09, 0xf3, 0x08, 0xf0, 0x51, 0x60, 0x0f, 0xe8, 0xb5, + 0x5f, 0x04, 0xb8, 0x19, 0xd8, 0x83, 0x08, 0x98, 0x00, 0xa0, 0x0d, 0xc8, 0x45, 0x2d, 0x81, 0xde, + 0xf9, 0x28, 0x2e, 0x31, 0x15, 0xbd, 0x0f, 0xe5, 0x23, 0xd3, 0xf2, 0xb1, 0x4b, 0x8e, 0x4b, 0xe7, + 0x0f, 0x52, 0x52, 0x4b, 0x6a, 0x31, 0xa4, 0xd6, 0x1d, 0x8b, 0x4c, 0x1f, 0x57, 0xe9, 0x8b, 0x84, + 0xb2, 0x33, 0xb4, 0xd3, 0x64, 0x07, 0x21, 0xe3, 0x2e, 0xe4, 0x75, 0x77, 0x18, 0x8c, 0xb0, 0xed, + 0x7b, 0x95, 0x2c, 0x8d, 0xc8, 0x22, 0x39, 0x3f, 0x55, 0xde, 0xe5, 0x73, 0x69, 0x81, 0xaf, 0xfe, + 0x29, 0x05, 0x3c, 0x39, 0x05, 0x12, 0xa0, 0x28, 0xca, 0x8f, 0x34, 0x59, 0xe9, 0x69, 0x72, 0xbf, + 0xd3, 0x11, 0x96, 0xd0, 0x32, 0xa4, 0xc5, 0x83, 0x96, 0xc0, 0xa1, 0x22, 0xe4, 0x6a, 0x8a, 0xd2, + 0xd1, 0x44, 0xb9, 0x21, 0xa4, 0x50, 0x01, 0x96, 0xe9, 0x4a, 0x51, 0x85, 0x34, 0x2a, 0x03, 0xd4, + 0x15, 0xb9, 0x2e, 0xf6, 0x34, 0xb1, 0xd5, 0x12, 0x78, 0x94, 0x87, 0x4c, 0x5d, 0xe9, 0xcb, 0x3d, + 0x21, 0x43, 0xd4, 0xf7, 0xc4, 0x87, 0xc2, 0x32, 0xfd, 0xd1, 0x96, 0x85, 0x1c, 0x02, 0xc8, 0x76, + 0x7b, 0x8d, 0x86, 0x74, 0x20, 0xe4, 0x09, 0xb1, 0xdb, 0xdf, 0x13, 0x80, 0xc0, 0x75, 0xfb, 0x7b, + 0x5a, 0x5b, 0xee, 0x09, 0x05, 0xb2, 0xd3, 0x81, 0xa8, 0xb6, 0x45, 0xb9, 0x2e, 0x09, 0x45, 0xc2, + 0x7a, 0xa8, 0xa8, 0x14, 0xb9, 0x14, 0xee, 0xd4, 0x97, 0x7b, 0x9a, 0xaa, 0x3c, 0xe8, 0x0a, 0x65, + 0xaa, 0x77, 0x5f, 0x6d, 0xb4, 0x9b, 0x4d, 0x61, 0x05, 0x21, 0x28, 0x37, 0xdb, 0xb2, 0xd8, 0xd1, + 0x62, 0x6d, 0x81, 0x1c, 0x28, 0xa4, 0xb1, 0x3d, 0x2f, 0xa1, 0x12, 0xe4, 0x45, 0x55, 0x15, 0x1f, + 0x51, 0x44, 0x44, 0x36, 0xdb, 0xed, 0x2a, 0x32, 0x5d, 0x5d, 0x26, 0x4c, 0xb2, 0xaa, 0xd1, 0xe5, + 0x15, 0xb2, 0x5d, 0xb7, 0xa7, 0xb6, 0xe5, 0x16, 0x5d, 0xbf, 0x57, 0xbd, 0x03, 0x3c, 0xc9, 0x22, + 0x94, 0x03, 0x5e, 0xec, 0xf7, 0x14, 0x61, 0x89, 0x9e, 0xa6, 0x2e, 0x76, 0x44, 0x55, 0xe0, 0x88, + 0xb4, 0xac, 0xc8, 0x1a, 0x5b, 0xa7, 0xaa, 0xff, 0xe3, 0xe1, 0x5a, 0xdb, 0xf6, 0xb1, 0x6b, 0x61, + 0xfd, 0x09, 0x36, 0xc2, 0xe9, 0x35, 0x51, 0x11, 0x1f, 0x5d, 0xe8, 0xff, 0x9f, 0xce, 0x0f, 0xe1, + 0x4b, 0x60, 0xc2, 0xf1, 0xe0, 0xc2, 0x50, 0x90, 0x98, 0xa8, 0x53, 0x2f, 0x7a, 0xcd, 0xcd, 0x3e, + 0xc3, 0xd2, 0x2f, 0x7e, 0x86, 0xbd, 0xd5, 0x89, 0x36, 0xb3, 0x70, 0x5d, 0x5d, 0xfd, 0x5b, 0x0a, + 0x32, 0xf4, 0x70, 0xe8, 0x33, 0xe0, 0x0d, 0xec, 0x0d, 0x5e, 0x6b, 0xd8, 0xa7, 0x9a, 0xaf, 0x32, + 0xeb, 0xd7, 0x81, 0x1f, 0x3b, 0x5e, 0xe8, 0x8d, 0x97, 0xbe, 0x8d, 0xf6, 0x1d, 0xcf, 0xdf, 0x0f, + 0xbf, 0x35, 0x90, 0x00, 0x44, 0xfb, 0x10, 0x65, 0xd4, 0x80, 0x5c, 0xdc, 0xee, 0xf9, 0x05, 0xdb, + 0x7d, 0xac, 0x39, 0x7d, 0xa7, 0x65, 0xde, 0xe4, 0x9d, 0x56, 0x7d, 0xc6, 0x41, 0x79, 0xdf, 0x75, + 0x3e, 0xc7, 0x03, 0xbf, 0x8b, 0xc3, 0x71, 0xf7, 0x33, 0xc8, 0x90, 0x80, 0x46, 0x29, 0xb7, 0x48, + 0x44, 0x43, 0x45, 0x84, 0xe1, 0xd2, 0x10, 0xdb, 0xd8, 0xd5, 0xfd, 0x44, 0xc3, 0xa3, 0x5f, 0x3a, + 0x6a, 0xbf, 0x20, 0x72, 0xff, 0xfc, 0x66, 0xfd, 0xc3, 0xa1, 0xe9, 0x1f, 0x07, 0x87, 0x5b, 0x03, + 0x67, 0xb4, 0x1d, 0xe3, 0x1b, 0x87, 0xd3, 0xdf, 0xdb, 0xe3, 0x93, 0xe1, 0xb6, 0x77, 0x6a, 0x6d, + 0x93, 0x38, 0x7b, 0x5b, 0x3d, 0x55, 0x88, 0x21, 0xa3, 0x3e, 0x79, 0x13, 0x04, 0x3b, 0x18, 0xd1, + 0x6e, 0xa0, 0x8d, 0xb1, 0xab, 0x0d, 0xb1, 0x1d, 0x4e, 0xa5, 0x6a, 0xc9, 0x0e, 0x46, 0xa4, 0x11, + 0xec, 0x63, 0xb7, 0x85, 0xed, 0xea, 0xb7, 0x25, 0x28, 0x3e, 0x30, 0x6d, 0xc3, 0x39, 0x63, 0xd7, + 0x6a, 0x03, 0x0a, 0x63, 0xdd, 0xf5, 0x4d, 0xda, 0x72, 0xce, 0xd9, 0x34, 0x9f, 0x24, 0xa1, 0x2e, + 0xe4, 0xcf, 0xa8, 0x46, 0x33, 0x9e, 0x98, 0xb7, 0xe7, 0x3b, 0x22, 0x09, 0xce, 0x16, 0xcd, 0xb8, + 0x92, 0xc6, 0x38, 0xab, 0x7f, 0xe1, 0x58, 0x0d, 0xed, 0x42, 0x29, 0xea, 0x70, 0xb8, 0xf9, 0xba, + 0xfd, 0x44, 0x9d, 0xc5, 0x40, 0xf7, 0x01, 0xd8, 0x56, 0x04, 0x31, 0x45, 0x11, 0x7f, 0xb2, 0x98, + 0xcd, 0x04, 0x35, 0x01, 0xf2, 0x09, 0xff, 0xf4, 0xcb, 0x75, 0x6e, 0xf5, 0xcb, 0x65, 0xc8, 0x34, + 0x5d, 0x7d, 0x84, 0xd1, 0x3d, 0xe0, 0x47, 0x8e, 0x81, 0x99, 0xb9, 0xaf, 0x0a, 0x4e, 0x75, 0xb7, + 0xf6, 0x1c, 0x23, 0xbe, 0xbb, 0x04, 0x04, 0xdd, 0x87, 0xec, 0xa1, 0x13, 0xd8, 0x86, 0xc7, 0x86, + 0xde, 0x9f, 0x2e, 0x04, 0x57, 0xa3, 0xaa, 0x51, 0x25, 0x09, 0x81, 0xd0, 0x63, 0xc8, 0xe3, 0xc9, + 0xc0, 0x0a, 0x48, 0x4a, 0xd2, 0x4b, 0x5a, 0xde, 0xf9, 0x68, 0x21, 0x54, 0x29, 0xd2, 0x8e, 0x1f, + 0x3f, 0x11, 0x61, 0xf5, 0xbf, 0x1c, 0x64, 0xe8, 0xa6, 0x64, 0x17, 0xba, 0x1f, 0xa9, 0x46, 0xcc, + 0x15, 0x1f, 0x2d, 0x6e, 0x7b, 0xa2, 0x96, 0x4d, 0xe1, 0x48, 0xd5, 0x35, 0x6d, 0x5f, 0x73, 0x8e, + 0x8e, 0x3c, 0x1c, 0x4e, 0x06, 0xd1, 0x27, 0xa3, 0xbc, 0x69, 0xfb, 0x0a, 0x25, 0xa3, 0xeb, 0x50, + 0x24, 0xb7, 0xc2, 0x88, 0xc4, 0xc8, 0x49, 0x8b, 0x6a, 0x81, 0xd2, 0x98, 0xc8, 0x2e, 0x14, 0x42, + 0x26, 0xfd, 0x4c, 0xca, 0xea, 0xcc, 0x02, 0x5f, 0x2b, 0x21, 0xd4, 0x26, 0x36, 0xad, 0xfe, 0x91, + 0x83, 0x6c, 0xe8, 0x6e, 0x24, 0x43, 0xc6, 0xf3, 0x75, 0xd7, 0x67, 0x65, 0x76, 0x67, 0xf1, 0x63, + 0xc7, 0xe5, 0x87, 0xc0, 0xa0, 0x06, 0xa4, 0xb1, 0x6d, 0xb0, 0x04, 0x78, 0x0d, 0x34, 0x95, 0xa8, + 0x57, 0x6f, 0x02, 0x4f, 0xb2, 0x8b, 0x0c, 0x15, 0xaa, 0x28, 0xb7, 0x24, 0x61, 0x89, 0xb4, 0x5f, + 0xda, 0xff, 0x39, 0xd2, 0x7e, 0x5b, 0xaa, 0xd2, 0xdf, 0xef, 0x0a, 0xa9, 0xea, 0x17, 0x90, 0x8f, + 0x7d, 0x8f, 0xae, 0xc2, 0xe5, 0xbe, 0x5c, 0x53, 0xfa, 0x72, 0x43, 0x6a, 0x68, 0xfb, 0xaa, 0x54, + 0x97, 0x1a, 0x6d, 0xb9, 0x25, 0x2c, 0xcd, 0x32, 0x9a, 0x4a, 0xa7, 0xa3, 0x3c, 0x20, 0x0c, 0x0e, + 0x5d, 0x01, 0x41, 0x69, 0x36, 0xbb, 0x52, 0x2f, 0x21, 0x9e, 0x4a, 0x50, 0xa7, 0xb2, 0x69, 0xb4, + 0x02, 0x85, 0x7a, 0x5f, 0x55, 0xa5, 0x70, 0x10, 0x11, 0xf8, 0xea, 0xaf, 0x20, 0x1f, 0x67, 0x17, + 0x99, 0x39, 0x64, 0x45, 0x93, 0x1e, 0xd6, 0x3b, 0xfd, 0x6e, 0x5b, 0x91, 0xc3, 0x4d, 0xe9, 0xb2, + 0x21, 0x69, 0x49, 0x3d, 0x0e, 0x5d, 0x82, 0x52, 0xc4, 0xa0, 0xe7, 0x10, 0x52, 0x44, 0x3b, 0x22, + 0xf5, 0xda, 0x52, 0x57, 0x48, 0xaf, 0xfe, 0x3d, 0x05, 0xb9, 0xa8, 0xee, 0x20, 0x29, 0x31, 0xa4, + 0x16, 0x76, 0x6e, 0xbf, 0xaa, 0x57, 0x2f, 0x8e, 0xa8, 0x6f, 0xa7, 0x4f, 0xd5, 0x20, 0x73, 0x44, + 0xe2, 0xc5, 0xde, 0x5d, 0x77, 0x16, 0x89, 0xb1, 0x1a, 0xaa, 0xa2, 0x4d, 0x98, 0x19, 0x7a, 0xe9, + 0x03, 0x2c, 0x13, 0x3d, 0x15, 0x66, 0xc6, 0xe1, 0x55, 0xc8, 0xe9, 0xee, 0xd0, 0x6b, 0x1b, 0x13, + 0xf2, 0xc2, 0x22, 0x55, 0x3d, 0x5e, 0x13, 0x94, 0xf0, 0xe3, 0x10, 0x43, 0xc9, 0x25, 0x5a, 0xfc, + 0x0c, 0x67, 0x97, 0xcf, 0xa5, 0x84, 0x74, 0x34, 0xf7, 0x72, 0x00, 0xd3, 0xea, 0x48, 0x06, 0x38, + 0x55, 0x79, 0xa0, 0xc9, 0xfd, 0xbd, 0x9a, 0xa4, 0xb2, 0x3c, 0x13, 0xe5, 0x7b, 0xe1, 0x68, 0xd7, + 0x90, 0xe4, 0xae, 0xa4, 0xd1, 0x35, 0x0d, 0xd2, 0xbe, 0xa4, 0xd6, 0x69, 0x20, 0x09, 0x25, 0x4d, + 0x26, 0xc7, 0x7a, 0x7f, 0x4f, 0xd2, 0x1a, 0xed, 0x6e, 0x2f, 0x1c, 0x81, 0xe5, 0x5e, 0xbb, 0x23, + 0x85, 0x23, 0x70, 0x47, 0x6c, 0x09, 0x59, 0x02, 0xd7, 0x91, 0xc4, 0x86, 0xb0, 0x4c, 0xf2, 0xa7, + 0xd9, 0x56, 0xbb, 0x3d, 0xed, 0x40, 0xec, 0xf4, 0x25, 0x21, 0x47, 0xf0, 0x3b, 0x62, 0xbc, 0xce, + 0x13, 0x34, 0xb9, 0x77, 0x97, 0x2d, 0xe1, 0x83, 0x9f, 0x43, 0x79, 0xf6, 0x7b, 0x1d, 0x49, 0xfc, + 0xfd, 0x7e, 0xad, 0xd3, 0xae, 0x0b, 0x4b, 0xe8, 0xfb, 0xf0, 0x5e, 0xf8, 0x9b, 0xcc, 0xe6, 0x74, + 0x76, 0x67, 0x2c, 0xae, 0x76, 0xfb, 0xe9, 0xb7, 0x6b, 0x4b, 0x4f, 0x9f, 0xad, 0x71, 0x5f, 0x3d, + 0x5b, 0xe3, 0xbe, 0x7e, 0xb6, 0xc6, 0xfd, 0xfb, 0xd9, 0x1a, 0xf7, 0xbb, 0xe7, 0x6b, 0x4b, 0x5f, + 0x3d, 0x5f, 0x5b, 0xfa, 0xfa, 0xf9, 0xda, 0xd2, 0xe3, 0x7c, 0xfc, 0xff, 0xc9, 0xff, 0x03, 0x00, + 0x00, 0xff, 0xff, 0x84, 0xd1, 0x4e, 0xf0, 0xe2, 0x19, 0x00, 0x00, } diff --git a/pkg/sql/distsqlpb/processors_sql.proto b/pkg/sql/distsqlpb/processors_sql.proto index f429dcee3a1e..695a73fb2fdd 100644 --- a/pkg/sql/distsqlpb/processors_sql.proto +++ b/pkg/sql/distsqlpb/processors_sql.proto @@ -611,6 +611,14 @@ message WindowerSpec { CURRENT_ROW = 4; } + // Exclusion specifies the type of frame exclusion. + enum Exclusion { + NO_EXCLUSION = 0; + EXCLUDE_CURRENT_ROW = 1; + EXCLUDE_GROUP = 2; + EXCLUDE_TIES = 3; + } + // Bound specifies the type of boundary and the offset (if present). message Bound { optional BoundType boundType = 1 [(gogoproto.nullable) = false]; @@ -628,8 +636,10 @@ message WindowerSpec { optional Bound start = 1 [(gogoproto.nullable) = false]; optional Bound end = 2; } + optional Mode mode = 1 [(gogoproto.nullable) = false]; optional Bounds bounds = 2 [(gogoproto.nullable) = false]; + optional Exclusion exclusion = 3 [(gogoproto.nullable) = false]; } // WindowFn is the specification of a single window function. diff --git a/pkg/sql/distsqlrun/windower.go b/pkg/sql/distsqlrun/windower.go index c664c3bf97c9..d635043530fd 100644 --- a/pkg/sql/distsqlrun/windower.go +++ b/pkg/sql/distsqlrun/windower.go @@ -584,12 +584,12 @@ func (w *windower) processPartition( frameRun.Rows = partition frameRun.RowIdx = 0 - if !frameRun.IsDefaultFrame() { - // We have a custom frame not equivalent to default one, so if we have - // an aggregate function, we want to reset it for each row. - // Not resetting is an optimization since we're not computing - // the result over the whole frame but only as a result of the current - // row and previous results of aggregation. + if !frameRun.NoFilter() || !frameRun.IsDefaultFrame() { + // We either have a filter or a custom frame not equivalent to default + // one, so if we have an aggregate function, we want to reset it for each + // row. Not resetting is an optimization since we're not computing the + // result over the whole frame but only as a result of the current row + // and previous results of aggregation. builtins.ShouldReset(builtin) } diff --git a/pkg/sql/logictest/testdata/logic_test/window b/pkg/sql/logictest/testdata/logic_test/window index 2fd272a30416..31db0aef92a2 100644 --- a/pkg/sql/logictest/testdata/logic_test/window +++ b/pkg/sql/logictest/testdata/logic_test/window @@ -3002,6 +3002,111 @@ Tablet iPad 700.00 NULL 700.00 Tablet Kindle Fire 150.00 NULL 150.00 Tablet Samsung 200.00 NULL 200.00 +query RTR +SELECT price, array_agg(price) OVER w, sum(price) OVER w FROM products WINDOW w AS (ORDER BY price RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW) ORDER BY price +---- +150.00 NULL NULL +200.00 {150.00,200.00} 350.00 +200.00 {150.00,200.00} 350.00 +400.00 {150.00,200.00,200.00} 550.00 +500.00 {150.00,200.00,200.00,400.00} 950.00 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00} 2850.00 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00} 2850.00 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00} 2850.00 +800.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00} 3550.00 +900.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00} 4350.00 +1200.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00,900.00} 5250.00 + +query RTR +SELECT price, array_agg(price) OVER w, max(price) OVER w FROM products WINDOW w AS (ORDER BY price RANGE UNBOUNDED PRECEDING EXCLUDE GROUP) ORDER BY price +---- +150.00 NULL NULL +200.00 {150.00} 150.00 +200.00 {150.00} 150.00 +400.00 {150.00,200.00,200.00} 200.00 +500.00 {150.00,200.00,200.00,400.00} 400.00 +700.00 {150.00,200.00,200.00,400.00,500.00} 500.00 +700.00 {150.00,200.00,200.00,400.00,500.00} 500.00 +700.00 {150.00,200.00,200.00,400.00,500.00} 500.00 +800.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00} 700.00 +900.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00} 800.00 +1200.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00,900.00} 900.00 + +query RTR +SELECT price, array_agg(price) OVER w, avg(price) OVER w FROM products WINDOW w AS (ORDER BY price RANGE UNBOUNDED PRECEDING EXCLUDE TIES) ORDER BY price +---- +150.00 {150.00} 150.00 +200.00 {150.00,200.00} 175.00 +200.00 {150.00,200.00} 175.00 +400.00 {150.00,200.00,200.00,400.00} 237.50 +500.00 {150.00,200.00,200.00,400.00,500.00} 290.00 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00} 358.33333333333333333 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00} 358.33333333333333333 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00} 358.33333333333333333 +800.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00} 483.33333333333333333 +900.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00,900.00} 525.00 +1200.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00,900.00,1200.00} 586.36363636363636364 + +query RTR +SELECT price, array_agg(price) OVER w, min(price) OVER w FROM products WINDOW w AS (ORDER BY price RANGE UNBOUNDED PRECEDING EXCLUDE NO OTHERS) ORDER BY price +---- +150.00 {150.00} 150.00 +200.00 {150.00,200.00,200.00} 150.00 +200.00 {150.00,200.00,200.00} 150.00 +400.00 {150.00,200.00,200.00,400.00} 150.00 +500.00 {150.00,200.00,200.00,400.00,500.00} 150.00 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00} 150.00 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00} 150.00 +700.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00} 150.00 +800.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00} 150.00 +900.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00,900.00} 150.00 +1200.00 {150.00,200.00,200.00,400.00,500.00,700.00,700.00,700.00,800.00,900.00,1200.00} 150.00 + +query TTTT +SELECT first_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW), first_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE GROUP), first_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE TIES), first_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE NO OTHERS) FROM products WINDOW w AS (ORDER BY group_id) ORDER BY group_id +---- +NULL NULL Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia Microsoft Lumia Microsoft Lumia + +query TTTT +SELECT last_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW), last_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE GROUP), last_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE TIES), last_value(product_name) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE NO OTHERS) FROM products WINDOW w AS (ORDER BY group_id) ORDER BY group_id +---- +NULL NULL Microsoft Lumia Microsoft Lumia +Microsoft Lumia Microsoft Lumia HTC One HTC One +HTC One HTC One Nexus Nexus +Nexus Nexus iPhone iPhone +iPhone iPhone HP Elite HP Elite +HP Elite HP Elite Lenovo Thinkpad Lenovo Thinkpad +Lenovo Thinkpad Lenovo Thinkpad Sony VAIO Sony VAIO +Sony VAIO Sony VAIO Dell Dell +Dell Dell iPad iPad +iPad iPad Kindle Fire Kindle Fire +Kindle Fire Kindle Fire Samsung Samsung + +query TTTT +SELECT nth_value(product_name, 2) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE CURRENT ROW), nth_value(product_name, 3) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE GROUP), nth_value(product_name, 4) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE TIES), nth_value(product_name, 5) OVER (w RANGE UNBOUNDED PRECEDING EXCLUDE NO OTHERS) FROM products WINDOW w AS (ORDER BY group_id) ORDER BY group_id +---- +NULL NULL NULL NULL +NULL NULL NULL NULL +HTC One NULL NULL NULL +HTC One Nexus iPhone NULL +HTC One Nexus iPhone HP Elite +HTC One Nexus iPhone HP Elite +HTC One Nexus iPhone HP Elite +HTC One Nexus iPhone HP Elite +HTC One Nexus iPhone HP Elite +HTC One Nexus iPhone HP Elite +HTC One Nexus iPhone HP Elite + # Test for #32702 statement ok diff --git a/pkg/sql/opt/exec/execbuilder/relational.go b/pkg/sql/opt/exec/execbuilder/relational.go index d7a733bfb972..c2ee4c680629 100644 --- a/pkg/sql/opt/exec/execbuilder/relational.go +++ b/pkg/sql/opt/exec/execbuilder/relational.go @@ -1559,6 +1559,7 @@ func (b *Builder) buildFrame(input execPlan, w *memo.WindowsItem) (*tree.WindowF BoundType: w.Frame.EndBoundType, }, }, + Exclusion: w.Frame.FrameExclusion, } if boundExpr, ok := b.extractFromOffset(w.Function); ok { if !b.isOffsetMode(w.Frame.StartBoundType) { diff --git a/pkg/sql/opt/memo/expr.go b/pkg/sql/opt/memo/expr.go index e01bb8f07b8d..9bacbbfee81d 100644 --- a/pkg/sql/opt/memo/expr.go +++ b/pkg/sql/opt/memo/expr.go @@ -403,6 +403,7 @@ type WindowFrame struct { Mode tree.WindowFrameMode StartBoundType tree.WindowFrameBoundType EndBoundType tree.WindowFrameBoundType + FrameExclusion tree.WindowFrameExclusion } // NeedResults returns true if the mutation operator can return the rows that diff --git a/pkg/sql/opt/memo/expr_format.go b/pkg/sql/opt/memo/expr_format.go index 7dd51c4fda4b..3016aa00e335 100644 --- a/pkg/sql/opt/memo/expr_format.go +++ b/pkg/sql/opt/memo/expr_format.go @@ -646,7 +646,8 @@ func (f *ExprFmtCtx) formatScalar(scalar opt.ScalarExpr, tp treeprinter.Node) { frame := scalar.Private().(*WindowsItemPrivate).Frame if frame.Mode == tree.RANGE && frame.StartBoundType == tree.UnboundedPreceding && - frame.EndBoundType == tree.CurrentRow { + frame.EndBoundType == tree.CurrentRow && + frame.FrameExclusion == tree.NoExclusion { scalar = scalar.Child(0).(opt.ScalarExpr) } } @@ -937,6 +938,18 @@ func frameBoundName(b tree.WindowFrameBoundType) string { panic(errors.AssertionFailedf("unexpected bound")) } +func frameExclusionMode(e tree.WindowFrameExclusion) string { + switch e { + case tree.ExcludeCurrentRow: + return "exclude current row" + case tree.ExcludeGroup: + return "exclude group" + case tree.ExcludeTies: + return "exclude ties" + } + panic(errors.AssertionFailedf("unexpected frame exclusion")) +} + // ScanIsReverseFn is a callback that is used to figure out if a scan needs to // happen in reverse (the code lives in the ordering package, and depending on // that directly would be a dependency loop). @@ -1035,6 +1048,9 @@ func FormatPrivate(f *ExprFmtCtx, private interface{}, physProps *physical.Requi frameBoundName(t.Frame.StartBoundType), frameBoundName(t.Frame.EndBoundType), ) + if t.Frame.FrameExclusion != tree.NoExclusion { + fmt.Fprintf(f.Buffer, " %s", frameExclusionMode(t.Frame.FrameExclusion)) + } case *WindowPrivate: fmt.Fprintf(f.Buffer, " partition=%s", t.Partition) diff --git a/pkg/sql/opt/memo/interner.go b/pkg/sql/opt/memo/interner.go index 78251ffd400a..d8c328b1cde0 100644 --- a/pkg/sql/opt/memo/interner.go +++ b/pkg/sql/opt/memo/interner.go @@ -514,6 +514,7 @@ func (h *hasher) HashWindowFrame(val WindowFrame) { h.HashInt(int(val.StartBoundType)) h.HashInt(int(val.EndBoundType)) h.HashInt(int(val.Mode)) + h.HashInt(int(val.FrameExclusion)) } func (h *hasher) HashTupleOrdinal(val TupleOrdinal) { @@ -819,7 +820,8 @@ func (h *hasher) IsViewDepsEqual(l, r opt.ViewDeps) bool { func (h *hasher) IsWindowFrameEqual(l, r WindowFrame) bool { return l.StartBoundType == r.StartBoundType && l.EndBoundType == r.EndBoundType && - l.Mode == r.Mode + l.Mode == r.Mode && + l.FrameExclusion == r.FrameExclusion } func (h *hasher) IsTupleOrdinalEqual(l, r TupleOrdinal) bool { diff --git a/pkg/sql/opt/memo/interner_test.go b/pkg/sql/opt/memo/interner_test.go index 24161b517531..9ef59f4c0b6b 100644 --- a/pkg/sql/opt/memo/interner_test.go +++ b/pkg/sql/opt/memo/interner_test.go @@ -111,11 +111,13 @@ func TestInterner(t *testing.T) { Mode: tree.RANGE, StartBoundType: tree.UnboundedPreceding, EndBoundType: tree.CurrentRow, + FrameExclusion: tree.NoExclusion, } frame2 := WindowFrame{ Mode: tree.ROWS, StartBoundType: tree.UnboundedPreceding, EndBoundType: tree.CurrentRow, + FrameExclusion: tree.NoExclusion, } wins1 := WindowsExpr{{ diff --git a/pkg/sql/opt/optbuilder/window.go b/pkg/sql/opt/optbuilder/window.go index 68b4615b9f27..715b557d2067 100644 --- a/pkg/sql/opt/optbuilder/window.go +++ b/pkg/sql/opt/optbuilder/window.go @@ -173,6 +173,7 @@ func (b *Builder) buildWindow(outScope *scope, inScope *scope) { Mode: windowFrames[i].Mode, StartBoundType: windowFrames[i].Bounds.StartBound.BoundType, EndBoundType: windowFrames[i].Bounds.EndBound.BoundType, + FrameExclusion: windowFrames[i].Exclusion, }, ColPrivate: memo.ColPrivate{Col: w.col.id}, }, diff --git a/pkg/sql/parser/parse_test.go b/pkg/sql/parser/parse_test.go index 750fc75c2e6a..848e58e336c1 100644 --- a/pkg/sql/parser/parse_test.go +++ b/pkg/sql/parser/parse_test.go @@ -935,6 +935,11 @@ func TestParse(t *testing.T) { {`SELECT avg(1) OVER (PARTITION BY b ORDER BY c GROUPS UNBOUNDED PRECEDING) FROM t`}, {`SELECT avg(1) OVER (w PARTITION BY b ORDER BY c GROUPS UNBOUNDED PRECEDING) FROM t`}, + {`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING EXCLUDE CURRENT ROW) FROM t`}, + {`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING EXCLUDE GROUP) FROM t`}, + {`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING EXCLUDE TIES) FROM t`}, + {`SELECT avg(1) OVER (ROWS UNBOUNDED PRECEDING EXCLUDE NO OTHERS) FROM t`}, + {`SELECT avg(1) FILTER (WHERE a > b)`}, {`SELECT avg(1) FILTER (WHERE a > b) OVER (ORDER BY c)`}, diff --git a/pkg/sql/parser/sql.y b/pkg/sql/parser/sql.y index 49fa2a4983c1..c15f153273ba 100644 --- a/pkg/sql/parser/sql.y +++ b/pkg/sql/parser/sql.y @@ -335,6 +335,9 @@ func (u *sqlSymUnion) windowFrameBounds() tree.WindowFrameBounds { func (u *sqlSymUnion) windowFrameBound() *tree.WindowFrameBound { return u.val.(*tree.WindowFrameBound) } +func (u *sqlSymUnion) windowFrameExclusion() tree.WindowFrameExclusion { + return u.val.(tree.WindowFrameExclusion) +} func (u *sqlSymUnion) distinctOn() tree.DistinctOn { return u.val.(tree.DistinctOn) } @@ -494,7 +497,7 @@ func newNameFromStr(s string) *tree.Name { %token DEALLOCATE DEFERRABLE DEFERRED DELETE DESC %token DISCARD DISTINCT DO DOMAIN DOUBLE DROP -%token ELSE ENCODING END ENUM ESCAPE EXCEPT +%token ELSE ENCODING END ENUM ESCAPE EXCEPT EXCLUDE %token EXISTS EXECUTE EXPERIMENTAL %token EXPERIMENTAL_FINGERPRINTS EXPERIMENTAL_REPLICA %token EXPERIMENTAL_AUDIT @@ -528,7 +531,7 @@ func newNameFromStr(s string) *tree.Name { %token NOT NOTHING NOTNULL NULL NULLIF NUMERIC %token OF OFF OFFSET OID OIDS OIDVECTOR ON ONLY OPT OPTION OPTIONS OR -%token ORDER ORDINALITY OUT OUTER OVER OVERLAPS OVERLAY OWNED OPERATOR +%token ORDER ORDINALITY OTHERS OUT OUTER OVER OVERLAPS OVERLAY OWNED OPERATOR %token PARENT PARTIAL PARTITION PARTITIONS PASSWORD PAUSE PHYSICAL PLACING %token PLAN PLANS POSITION PRECEDING PRECISION PREPARE PRIMARY PRIORITY @@ -551,7 +554,7 @@ func newNameFromStr(s string) *tree.Name { %token SYMMETRIC SYNTAX SYSTEM SUBSCRIPTION %token TABLE TABLES TEMP TEMPLATE TEMPORARY TESTING_RELOCATE EXPERIMENTAL_RELOCATE TEXT THEN -%token TIME TIMETZ TIMESTAMP TIMESTAMPTZ TO THROTTLING TRAILING TRACE TRANSACTION TREAT TRIGGER TRIM TRUE +%token TIES TIME TIMETZ TIMESTAMP TIMESTAMPTZ TO THROTTLING TRAILING TRACE TRANSACTION TREAT TRIGGER TRIM TRUE %token TRUNCATE TRUSTED TYPE %token TRACING @@ -968,6 +971,7 @@ func newNameFromStr(s string) *tree.Name { %type <*tree.WindowFrame> opt_frame_clause %type frame_extent %type <*tree.WindowFrameBound> frame_bound +%type opt_frame_exclusion %type <[]tree.ColumnID> opt_tableref_col_list tableref_col_list @@ -8088,31 +8092,29 @@ opt_partition_clause: $$.val = tree.Exprs(nil) } -// For frame clauses, we return a tree.WindowDef, but only some fields are used: -// frameOptions, startOffset, and endOffset. -// -// This is only a subset of the full SQL:2008 frame_clause grammar. We don't -// support yet. opt_frame_clause: - RANGE frame_extent + RANGE frame_extent opt_frame_exclusion { $$.val = &tree.WindowFrame{ Mode: tree.RANGE, Bounds: $2.windowFrameBounds(), + Exclusion: $3.windowFrameExclusion(), } } -| ROWS frame_extent +| ROWS frame_extent opt_frame_exclusion { $$.val = &tree.WindowFrame{ Mode: tree.ROWS, Bounds: $2.windowFrameBounds(), + Exclusion: $3.windowFrameExclusion(), } } -| GROUPS frame_extent +| GROUPS frame_extent opt_frame_exclusion { $$.val = &tree.WindowFrame{ Mode: tree.GROUPS, Bounds: $2.windowFrameBounds(), + Exclusion: $3.windowFrameExclusion(), } } | /* EMPTY */ @@ -8189,6 +8191,30 @@ frame_bound: } } +opt_frame_exclusion: + EXCLUDE CURRENT ROW + { + $$.val = (tree.WindowFrameExclusion)(tree.ExcludeCurrentRow) + } +| EXCLUDE GROUP + { + $$.val = (tree.WindowFrameExclusion)(tree.ExcludeGroup) + } +| EXCLUDE TIES + { + $$.val = (tree.WindowFrameExclusion)(tree.ExcludeTies) + } +| EXCLUDE NO OTHERS + { + // EXCLUDE NO OTHERS is equivalent to omitting the frame exclusion clause. + // TODO(yuzefovich): how do we match both cases? + $$.val = (tree.WindowFrameExclusion)(tree.NoExclusion) + } +| /* EMPTY */ + { + $$.val = (tree.WindowFrameExclusion)(tree.NoExclusion) + } + // Supporting nonterminals for expressions. // Explicit row production. @@ -9068,6 +9094,7 @@ unreserved_keyword: | ENCODING | ENUM | ESCAPE +| EXCLUDE | EXECUTE | EXPERIMENTAL | EXPERIMENTAL_AUDIT @@ -9151,6 +9178,7 @@ unreserved_keyword: | OPTION | OPTIONS | ORDINALITY +| OTHERS | OVER | OWNED | PARENT @@ -9237,6 +9265,7 @@ unreserved_keyword: | TEMPORARY | TESTING_RELOCATE | TEXT +| TIES | TRACE | TRANSACTION | TRIGGER diff --git a/pkg/sql/sem/builtins/window_builtins.go b/pkg/sql/sem/builtins/window_builtins.go index 89b126543c35..32460ab4e83a 100644 --- a/pkg/sql/sem/builtins/window_builtins.go +++ b/pkg/sql/sem/builtins/window_builtins.go @@ -174,8 +174,6 @@ var _ tree.WindowFunc = &firstValueWindow{} var _ tree.WindowFunc = &lastValueWindow{} var _ tree.WindowFunc = &nthValueWindow{} -const noFilterIdx = -1 - // aggregateWindowFunc aggregates over the the current row's window frame, using // the internal tree.AggregateFunc to perform the aggregation. type aggregateWindowFunc struct { @@ -196,25 +194,17 @@ func NewAggregateWindowFunc( func (w *aggregateWindowFunc) Compute( ctx context.Context, evalCtx *tree.EvalContext, wfr *tree.WindowFrameRun, ) (tree.Datum, error) { - if !wfr.FirstInPeerGroup() { + if !wfr.FirstInPeerGroup() && wfr.NoFilter() && wfr.DefaultFrameExclusion() { return w.peerRes, nil } // Accumulate all values in the peer group at the same time, as these // must return the same value. for i := 0; i < wfr.PeerHelper.GetRowCount(wfr.CurRowPeerGroupNum); i++ { - if wfr.FilterColIdx != noFilterIdx { - row, err := wfr.Rows.GetRow(ctx, wfr.RowIdx+i) - if err != nil { - return nil, err - } - datum, err := row.GetDatum(wfr.FilterColIdx) - if err != nil { - return nil, err - } - if datum != tree.DBoolTrue { - continue - } + if skipped, err := wfr.IsRowSkipped(ctx, wfr.RowIdx+i); err != nil { + return nil, err + } else if skipped { + continue } args, err := wfr.ArgsWithRowOffset(ctx, i) if err != nil { @@ -279,7 +269,7 @@ func newFramableAggregateWindow( func (w *framableAggregateWindowFunc) Compute( ctx context.Context, evalCtx *tree.EvalContext, wfr *tree.WindowFrameRun, ) (tree.Datum, error) { - if !wfr.FirstInPeerGroup() { + if !wfr.FirstInPeerGroup() && wfr.NoFilter() && wfr.DefaultFrameExclusion() { return w.agg.peerRes, nil } if wfr.FullPartitionIsInWindow() { @@ -313,18 +303,10 @@ func (w *framableAggregateWindowFunc) Compute( return nil, err } for i := frameStartIdx; i < frameEndIdx; i++ { - if wfr.FilterColIdx != noFilterIdx { - row, err := wfr.Rows.GetRow(ctx, i) - if err != nil { - return nil, err - } - datum, err := row.GetDatum(wfr.FilterColIdx) - if err != nil { - return nil, err - } - if datum != tree.DBoolTrue { - continue - } + if skipped, err := wfr.IsRowSkipped(ctx, i); err != nil { + return nil, err + } else if skipped { + continue } args, err := wfr.ArgsByRowIdx(ctx, i) if err != nil { @@ -649,11 +631,23 @@ func (firstValueWindow) Compute( if err != nil { return nil, err } - row, err := wfr.Rows.GetRow(ctx, frameStartIdx) + frameEndIdx, err := wfr.FrameEndIdx(ctx, evalCtx) if err != nil { return nil, err } - return row.GetDatum(int(wfr.ArgsIdxs[0])) + for idx := frameStartIdx; idx < frameEndIdx; idx++ { + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return nil, err + } else if !skipped { + row, err := wfr.Rows.GetRow(ctx, idx) + if err != nil { + return nil, err + } + return row.GetDatum(int(wfr.ArgsIdxs[0])) + } + } + // All rows are skipped from the frame, so it is empty, and we return NULL. + return tree.DNull, nil } // Reset implements tree.WindowFunc interface. @@ -671,15 +665,27 @@ func newLastValueWindow([]*types.T, *tree.EvalContext) tree.WindowFunc { func (lastValueWindow) Compute( ctx context.Context, evalCtx *tree.EvalContext, wfr *tree.WindowFrameRun, ) (tree.Datum, error) { - frameEndIdx, err := wfr.FrameEndIdx(ctx, evalCtx) + frameStartIdx, err := wfr.FrameStartIdx(ctx, evalCtx) if err != nil { return nil, err } - row, err := wfr.Rows.GetRow(ctx, frameEndIdx-1) + frameEndIdx, err := wfr.FrameEndIdx(ctx, evalCtx) if err != nil { return nil, err } - return row.GetDatum(int(wfr.ArgsIdxs[0])) + for idx := frameEndIdx - 1; idx >= frameStartIdx; idx-- { + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return nil, err + } else if !skipped { + row, err := wfr.Rows.GetRow(ctx, idx) + if err != nil { + return nil, err + } + return row.GetDatum(int(wfr.ArgsIdxs[0])) + } + } + // All rows are skipped from the frame, so it is empty, and we return NULL. + return tree.DNull, nil } // Reset implements tree.WindowFunc interface. @@ -715,19 +721,42 @@ func (nthValueWindow) Compute( return nil, errInvalidArgumentForNthValue } - frameSize, err := wfr.FrameSize(ctx, evalCtx) + frameStartIdx, err := wfr.FrameStartIdx(ctx, evalCtx) if err != nil { return nil, err } - if nth > frameSize { - return tree.DNull, nil - } - - frameStartIdx, err := wfr.FrameStartIdx(ctx, evalCtx) + frameEndIdx, err := wfr.FrameEndIdx(ctx, evalCtx) if err != nil { return nil, err } - row, err := wfr.Rows.GetRow(ctx, frameStartIdx+nth-1) + if nth > frameEndIdx-frameStartIdx { + // The requested index is definitely outside of the window frame, so we + // return NULL. + return tree.DNull, nil + } + var idx int + if wfr.NoFilter() && wfr.DefaultFrameExclusion() { + // We subtract 1 because nth is counting from 1. + idx = frameStartIdx + nth - 1 + } else { + ith := 0 + for idx = frameStartIdx; idx < frameEndIdx; idx++ { + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return nil, err + } else if !skipped { + ith++ + if ith == nth { + // idx now points at the desired row. + break + } + } + } + if idx == frameEndIdx { + // The requested index is outside of the window frame, so we return NULL. + return tree.DNull, nil + } + } + row, err := wfr.Rows.GetRow(ctx, idx) if err != nil { return nil, err } diff --git a/pkg/sql/sem/builtins/window_frame_builtins.go b/pkg/sql/sem/builtins/window_frame_builtins.go index 646f3a3e5759..f213e8c6ad2f 100644 --- a/pkg/sql/sem/builtins/window_frame_builtins.go +++ b/pkg/sql/sem/builtins/window_frame_builtins.go @@ -107,25 +107,47 @@ func (w *slidingWindowFunc) Compute( return nil, err } - // We need to discard all values that are no longer in the frame. - w.sw.removeAllBefore(frameStartIdx) - - // We need to add all values that just entered the frame and have not been - // added yet. - for idx := max(w.prevEnd, frameStartIdx); idx < frameEndIdx; idx++ { - if wfr.FilterColIdx != noFilterIdx { - row, err := wfr.Rows.GetRow(ctx, idx) - if err != nil { + if !wfr.DefaultFrameExclusion() { + // We cannot use sliding window approach because we have frame exclusion + // clause - some rows will be in and out of the frame which breaks the + // necessary assumption, so we fallback to naive quadratic approach. + var res tree.Datum + for idx := frameStartIdx; idx < frameEndIdx; idx++ { + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { return nil, err + } else if skipped { + continue } - datum, err := row.GetDatum(wfr.FilterColIdx) + args, err := wfr.ArgsByRowIdx(ctx, idx) if err != nil { return nil, err } - if datum != tree.DBoolTrue { - continue + if res == nil { + res = args[0] + } else { + if w.sw.cmp(evalCtx, args[0], res) > 0 { + res = args[0] + } } } + if res == nil { + // Spec: the frame is empty, so we return NULL. + return tree.DNull, nil + } + return res, nil + } + + // We need to discard all values that are no longer in the frame. + w.sw.removeAllBefore(frameStartIdx) + + // We need to add all values that just entered the frame and have not been + // added yet. + for idx := max(w.prevEnd, frameStartIdx); idx < frameEndIdx; idx++ { + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return nil, err + } else if skipped { + continue + } args, err := wfr.ArgsByRowIdx(ctx, idx) if err != nil { return nil, err @@ -201,18 +223,10 @@ func (w *slidingWindowSumFunc) removeAllBefore( return err } for idx := w.prevStart; idx < frameStartIdx && idx < w.prevEnd; idx++ { - if wfr.FilterColIdx != noFilterIdx { - row, err := wfr.Rows.GetRow(ctx, idx) - if err != nil { - return err - } - datum, err := row.GetDatum(wfr.FilterColIdx) - if err != nil { - return err - } - if datum != tree.DBoolTrue { - continue - } + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return err + } else if skipped { + continue } args, err := wfr.ArgsByRowIdx(ctx, idx) if err != nil { @@ -257,6 +271,27 @@ func (w *slidingWindowSumFunc) Compute( if err != nil { return nil, err } + if !wfr.DefaultFrameExclusion() { + // We cannot use sliding window approach because we have frame exclusion + // clause - some rows will be in and out of the frame which breaks the + // necessary assumption, so we fallback to naive quadratic approach. + w.agg.Reset(ctx) + for idx := frameStartIdx; idx < frameEndIdx; idx++ { + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return nil, err + } else if skipped { + continue + } + args, err := wfr.ArgsByRowIdx(ctx, idx) + if err != nil { + return nil, err + } + if err = w.agg.Add(ctx, args[0]); err != nil { + return nil, err + } + } + return w.agg.Result() + } // We need to discard all values that are no longer in the frame. if err = w.removeAllBefore(ctx, evalCtx, wfr); err != nil { @@ -266,18 +301,10 @@ func (w *slidingWindowSumFunc) Compute( // We need to sum all values that just entered the frame and have not been // added yet. for idx := max(w.prevEnd, frameStartIdx); idx < frameEndIdx; idx++ { - if wfr.FilterColIdx != noFilterIdx { - row, err := wfr.Rows.GetRow(ctx, idx) - if err != nil { - return nil, err - } - datum, err := row.GetDatum(wfr.FilterColIdx) - if err != nil { - return nil, err - } - if datum != tree.DBoolTrue { - continue - } + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return nil, err + } else if skipped { + continue } args, err := wfr.ArgsByRowIdx(ctx, idx) if err != nil { @@ -347,18 +374,10 @@ func (w *avgWindowFunc) Compute( return nil, err } for idx := frameStartIdx; idx < frameEndIdx; idx++ { - if wfr.FilterColIdx != noFilterIdx { - row, err := wfr.Rows.GetRow(ctx, idx) - if err != nil { - return nil, err - } - datum, err := row.GetDatum(wfr.FilterColIdx) - if err != nil { - return nil, err - } - if datum != tree.DBoolTrue { - continue - } + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return nil, err + } else if skipped { + continue } args, err := wfr.ArgsByRowIdx(ctx, idx) if err != nil { diff --git a/pkg/sql/sem/builtins/window_frame_builtins_test.go b/pkg/sql/sem/builtins/window_frame_builtins_test.go index 5a6f0f2ce564..8a8a35989b7e 100644 --- a/pkg/sql/sem/builtins/window_frame_builtins_test.go +++ b/pkg/sql/sem/builtins/window_frame_builtins_test.go @@ -217,6 +217,8 @@ func testSumAndAvg(t *testing.T, evalCtx *tree.EvalContext, wfr *tree.WindowFram } } +const noFilterIdx = -1 + func makeTestWindowFrameRun(count int) *tree.WindowFrameRun { return &tree.WindowFrameRun{ Rows: makeTestPartition(count), diff --git a/pkg/sql/sem/tree/pretty.go b/pkg/sql/sem/tree/pretty.go index 0a967c573cc9..8da72dbba3cb 100644 --- a/pkg/sql/sem/tree/pretty.go +++ b/pkg/sql/sem/tree/pretty.go @@ -745,6 +745,9 @@ func (wf *WindowFrame) docRow(p *PrettyCfg) pretty.TableRow { p.row("AND", p.Doc(wf.Bounds.EndBound)), ) } + if wf.Exclusion != NoExclusion { + d = pretty.Stack(d, p.Doc(wf.Exclusion)) + } return p.row(kw, d) } diff --git a/pkg/sql/sem/tree/select.go b/pkg/sql/sem/tree/select.go index 204e68f20564..c0717c3e3784 100644 --- a/pkg/sql/sem/tree/select.go +++ b/pkg/sql/sem/tree/select.go @@ -826,10 +826,25 @@ func (node *WindowFrameBounds) HasOffset() bool { return node.StartBound.HasOffset() || (node.EndBound != nil && node.EndBound.HasOffset()) } +// WindowFrameExclusion indicates which mode of exclusion is used. +type WindowFrameExclusion int + +const ( + // NoExclusion represents an omitted frame exclusion clause. + NoExclusion WindowFrameExclusion = iota + // ExcludeCurrentRow represents EXCLUDE CURRENT ROW mode of frame exclusion. + ExcludeCurrentRow + // ExcludeGroup represents EXCLUDE GROUP mode of frame exclusion. + ExcludeGroup + // ExcludeTies represents EXCLUDE TIES mode of frame exclusion. + ExcludeTies +) + // WindowFrame represents static state of window frame over which calculations are made. type WindowFrame struct { - Mode WindowFrameMode // the mode of framing being used - Bounds WindowFrameBounds // the bounds of the frame + Mode WindowFrameMode // the mode of framing being used + Bounds WindowFrameBounds // the bounds of the frame + Exclusion WindowFrameExclusion // optional frame exclusion } // Format implements the NodeFormatter interface. @@ -852,6 +867,24 @@ func (node *WindowFrameBound) Format(ctx *FmtCtx) { } } +// Format implements the NodeFormatter interface. +func (node WindowFrameExclusion) Format(ctx *FmtCtx) { + if node == NoExclusion { + return + } + ctx.WriteString("EXCLUDE ") + switch node { + case ExcludeCurrentRow: + ctx.WriteString("CURRENT ROW") + case ExcludeGroup: + ctx.WriteString("GROUP") + case ExcludeTies: + ctx.WriteString("TIES") + default: + panic(fmt.Sprintf("unhandled case: %d", node)) + } +} + // Format implements the NodeFormatter interface. func (node *WindowFrame) Format(ctx *FmtCtx) { switch node.Mode { @@ -872,4 +905,8 @@ func (node *WindowFrame) Format(ctx *FmtCtx) { } else { ctx.FormatNode(node.Bounds.StartBound) } + if node.Exclusion != NoExclusion { + ctx.WriteByte(' ') + ctx.FormatNode(node.Exclusion) + } } diff --git a/pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden b/pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden new file mode 100644 index 000000000000..3ea40a232de7 --- /dev/null +++ b/pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden @@ -0,0 +1,353 @@ +1: +- +SELECT + sum( + a + ) OVER w, + avg( + b + ) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min( + f + ) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +11: +----------- +SELECT sum( + a + ) OVER w, + avg( + b + ) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min( + f + ) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +18: +------------------ +SELECT sum( + a + ) OVER w, + avg( + b + ) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min( + f + ) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +20: +-------------------- +SELECT sum( + a + ) OVER w, + avg(b) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +21: +--------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +22: +---------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +40: +---------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +44: +-------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING + AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +50: +-------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c ORDER BY d ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING + AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +64: +---------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING + AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +73: +------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +74: +-------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +81: +--------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +83: +----------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +89: +----------------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +94: +---------------------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) + FROM t +WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +167: +----------------------------------------------------------------------------------------------------------------------------------------------------------------------- +SELECT sum(a) OVER w, avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) + FROM t +WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +264: +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +SELECT sum(a) OVER w, avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) FROM t WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) diff --git a/pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden.short b/pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden.short new file mode 100644 index 000000000000..00d3edeeb4f9 --- /dev/null +++ b/pkg/sql/sem/tree/testdata/pretty/window.align-deindent.golden.short @@ -0,0 +1,26 @@ +// Code generated by TestPretty. DO NOT EDIT. +// GENERATED FILE DO NOT EDIT +1: +- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING + EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW + ) + + diff --git a/pkg/sql/sem/tree/testdata/pretty/window.align-only.golden b/pkg/sql/sem/tree/testdata/pretty/window.align-only.golden new file mode 100644 index 000000000000..3ea40a232de7 --- /dev/null +++ b/pkg/sql/sem/tree/testdata/pretty/window.align-only.golden @@ -0,0 +1,353 @@ +1: +- +SELECT + sum( + a + ) OVER w, + avg( + b + ) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min( + f + ) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +11: +----------- +SELECT sum( + a + ) OVER w, + avg( + b + ) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min( + f + ) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +18: +------------------ +SELECT sum( + a + ) OVER w, + avg( + b + ) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min( + f + ) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +20: +-------------------- +SELECT sum( + a + ) OVER w, + avg(b) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +21: +--------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +22: +---------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +40: +---------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +44: +-------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING + AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +50: +-------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c ORDER BY d ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING + AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +64: +---------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING + AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +73: +------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW EXCLUDE NO OTHERS + ) + +74: +-------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +81: +--------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +83: +----------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +89: +----------------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) + FROM t +WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +94: +---------------------------------------------------------------------------------------------- +SELECT sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) + FROM t +WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +167: +----------------------------------------------------------------------------------------------------------------------------------------------------------------------- +SELECT sum(a) OVER w, avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) + FROM t +WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +264: +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +SELECT sum(a) OVER w, avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) FROM t WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) diff --git a/pkg/sql/sem/tree/testdata/pretty/window.align-only.golden.short b/pkg/sql/sem/tree/testdata/pretty/window.align-only.golden.short new file mode 100644 index 000000000000..00d3edeeb4f9 --- /dev/null +++ b/pkg/sql/sem/tree/testdata/pretty/window.align-only.golden.short @@ -0,0 +1,26 @@ +// Code generated by TestPretty. DO NOT EDIT. +// GENERATED FILE DO NOT EDIT +1: +- +SELECT sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c + ORDER BY d + ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY g + RANGE BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING + EXCLUDE TIES + ) + FROM t +WINDOW w AS ( + PARTITION BY i + GROUPS BETWEEN j PRECEDING + AND CURRENT ROW + ) + + diff --git a/pkg/sql/sem/tree/testdata/pretty/window.ref.golden b/pkg/sql/sem/tree/testdata/pretty/window.ref.golden new file mode 100644 index 000000000000..de03da861127 --- /dev/null +++ b/pkg/sql/sem/tree/testdata/pretty/window.ref.golden @@ -0,0 +1,280 @@ +1: +- +SELECT + sum( + a + ) OVER w, + avg( + b + ) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min( + f + ) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +17: +----------------- +SELECT + sum( + a + ) OVER w, + avg(b) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min(f) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +18: +------------------ +SELECT + sum(a) OVER w, + avg(b) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min(f) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +50: +-------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER ( + PARTITION BY c ORDER BY d ROWS e PRECEDING + ), + min(f) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +61: +------------------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW EXCLUDE NO OTHERS + ) + +65: +----------------------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +68: +-------------------------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY + g + RANGE + BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +81: +--------------------------------------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +83: +----------------------------------------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS + ) + +86: +-------------------------------------------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER ( + ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES + ) +FROM + t +WINDOW + w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +91: +------------------------------------------------------------------------------------------- +SELECT + sum(a) OVER w, + avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), + min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) +FROM + t +WINDOW + w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +164: +-------------------------------------------------------------------------------------------------------------------------------------------------------------------- +SELECT + sum(a) OVER w, avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) +FROM + t +WINDOW + w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) + +264: +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +SELECT sum(a) OVER w, avg(b) OVER (PARTITION BY c ORDER BY d ROWS e PRECEDING), min(f) OVER (ORDER BY g RANGE BETWEEN UNBOUNDED PRECEDING AND h FOLLOWING EXCLUDE TIES) FROM t WINDOW w AS (PARTITION BY i GROUPS BETWEEN j PRECEDING AND CURRENT ROW EXCLUDE NO OTHERS) diff --git a/pkg/sql/sem/tree/testdata/pretty/window.ref.golden.short b/pkg/sql/sem/tree/testdata/pretty/window.ref.golden.short new file mode 100644 index 000000000000..8b9122a18357 --- /dev/null +++ b/pkg/sql/sem/tree/testdata/pretty/window.ref.golden.short @@ -0,0 +1,38 @@ +// Code generated by TestPretty. DO NOT EDIT. +// GENERATED FILE DO NOT EDIT +1: +- +SELECT + sum(a) OVER w, + avg(b) OVER ( + PARTITION BY + c + ORDER BY + d + ROWS + e PRECEDING + ), + min(f) OVER ( + ORDER BY + g + RANGE + BETWEEN + UNBOUNDED PRECEDING + AND + h FOLLOWING + EXCLUDE TIES + ) +FROM + t +WINDOW + w AS ( + PARTITION BY + i + GROUPS + BETWEEN + j PRECEDING + AND + CURRENT ROW + ) + + diff --git a/pkg/sql/sem/tree/testdata/pretty/window.sql b/pkg/sql/sem/tree/testdata/pretty/window.sql new file mode 100644 index 000000000000..b489638c6b4c --- /dev/null +++ b/pkg/sql/sem/tree/testdata/pretty/window.sql @@ -0,0 +1 @@ +select sum(a) over w, avg(b) over (partition by c order by d rows e preceding), min(f) over (order by g range between unbounded preceding and h following exclude ties) from t window w as (partition by i groups between j preceding and current row exclude no others) diff --git a/pkg/sql/sem/tree/window_funcs.go b/pkg/sql/sem/tree/window_funcs.go index 46bdc4892967..ccb1f928bcc6 100644 --- a/pkg/sql/sem/tree/window_funcs.go +++ b/pkg/sql/sem/tree/window_funcs.go @@ -254,7 +254,8 @@ func (wfr *WindowFrameRun) IsDefaultFrame() bool { return true } if wfr.Frame.Bounds.StartBound.BoundType == UnboundedPreceding { - return wfr.Frame.Bounds.EndBound == nil || wfr.Frame.Bounds.EndBound.BoundType == CurrentRow + return wfr.DefaultFrameExclusion() && + (wfr.Frame.Bounds.EndBound == nil || wfr.Frame.Bounds.EndBound.BoundType == CurrentRow) } return false } @@ -419,7 +420,8 @@ func (wfr *WindowFrameRun) FrameEndIdx(ctx context.Context, evalCtx *EvalContext } } -// FrameSize returns the number of rows in the current frame. +// FrameSize returns the number of rows in the current frame (taking into +// account - if present - a filter and a frame exclusion). func (wfr *WindowFrameRun) FrameSize(ctx context.Context, evalCtx *EvalContext) (int, error) { if wfr.Frame == nil { return wfr.DefaultFrameSize(), nil @@ -433,6 +435,17 @@ func (wfr *WindowFrameRun) FrameSize(ctx context.Context, evalCtx *EvalContext) return 0, err } size := frameEndIdx - frameStartIdx + if !wfr.NoFilter() || !wfr.DefaultFrameExclusion() { + size = 0 + for idx := frameStartIdx; idx < frameEndIdx; idx++ { + if skipped, err := wfr.IsRowSkipped(ctx, idx); err != nil { + return 0, err + } else if skipped { + continue + } + size++ + } + } if size <= 0 { size = 0 } @@ -510,7 +523,7 @@ func (wfr *WindowFrameRun) RangeModeWithOffsets() bool { // FullPartitionIsInWindow checks whether we have such a window frame that all // rows of the partition are inside of the window for each of the rows. func (wfr *WindowFrameRun) FullPartitionIsInWindow() bool { - if wfr.Frame == nil { + if wfr.Frame == nil || !wfr.NoFilter() || !wfr.DefaultFrameExclusion() { return false } if wfr.Frame.Bounds.EndBound == nil { @@ -552,6 +565,64 @@ func (wfr *WindowFrameRun) FullPartitionIsInWindow() bool { return precedingConfirmed && followingConfirmed } +const noFilterIdx = -1 + +// NoFilter returns whether a filter is present. +func (wfr *WindowFrameRun) NoFilter() bool { + return wfr.FilterColIdx == noFilterIdx +} + +// DefaultFrameExclusion returns true if optional frame exclusion is omitted. +func (wfr *WindowFrameRun) DefaultFrameExclusion() bool { + return wfr.Frame == nil || wfr.Frame.Exclusion == NoExclusion +} + +// isRowExcluded returns whether the row at index idx should be excluded from +// the window frame of the current row. +func (wfr *WindowFrameRun) isRowExcluded(idx int) bool { + if wfr.Frame == nil || wfr.Frame.Exclusion == NoExclusion { + // By default, no rows are excluded. + return false + } + switch wfr.Frame.Exclusion { + case ExcludeCurrentRow: + return idx == wfr.RowIdx + case ExcludeGroup: + curRowFirstPeerIdx := wfr.PeerHelper.GetFirstPeerIdx(wfr.CurRowPeerGroupNum) + curRowPeerGroupRowCount := wfr.PeerHelper.GetRowCount(wfr.CurRowPeerGroupNum) + return curRowFirstPeerIdx <= idx && idx < curRowFirstPeerIdx+curRowPeerGroupRowCount + case ExcludeTies: + curRowFirstPeerIdx := wfr.PeerHelper.GetFirstPeerIdx(wfr.CurRowPeerGroupNum) + curRowPeerGroupRowCount := wfr.PeerHelper.GetRowCount(wfr.CurRowPeerGroupNum) + return curRowFirstPeerIdx <= idx && idx < curRowFirstPeerIdx+curRowPeerGroupRowCount && idx != wfr.RowIdx + default: + panic("unexpected WindowFrameExclusion") + } +} + +// IsRowSkipped returns whether a row at index idx is skipped from the window +// frame (it can either be filtered out according to the filter clause or +// excluded according to the frame exclusion clause) and any error if it +// occurs. +func (wfr *WindowFrameRun) IsRowSkipped(ctx context.Context, idx int) (bool, error) { + if !wfr.NoFilter() { + row, err := wfr.Rows.GetRow(ctx, idx) + if err != nil { + return false, err + } + d, err := row.GetDatum(wfr.FilterColIdx) + if err != nil { + return false, err + } + if d != DBoolTrue { + // Row idx is filtered out from the window frame, so it is skipped. + return true, nil + } + } + // If row is excluded from the window frame, it is skipped. + return wfr.isRowExcluded(idx), nil +} + // WindowFunc performs a computation on each row using data from a provided *WindowFrameRun. type WindowFunc interface { // Compute computes the window function for the provided window frame, given the