@@ -22,8 +22,9 @@ import (
2222// Grouping of input data.
2323type InitialGroup struct {
2424 base
25- plan * plan.InitialGroup
26- groups map [string ]value.AnnotatedValue
25+ plan * plan.InitialGroup
26+ aggNames []string
27+ groups map [string ]value.AnnotatedValue
2728}
2829
2930func NewInitialGroup (plan * plan.InitialGroup , context * Context ) * InitialGroup {
@@ -58,6 +59,13 @@ func (this *InitialGroup) RunOnce(context *Context, parent value.Value) {
5859 this .runConsumer (this , context , parent , this .Release )
5960}
6061
62+ func (this * InitialGroup ) beforeItems (context * Context , parent value.Value ) bool {
63+ if len (this .plan .Aggregates ()) > 0 {
64+ this .aggNames = make ([]string , len (this .plan .Aggregates ()))
65+ }
66+ return true
67+ }
68+
6169func (this * InitialGroup ) processItem (item value.AnnotatedValue , context * Context ) bool {
6270 // Generate the group key
6371 var gk string
@@ -99,9 +107,20 @@ func (this *InitialGroup) processItem(item value.AnnotatedValue, context *Contex
99107 return false
100108 }
101109
102- for _ , agg := range this .plan .Aggregates () {
103- // WARNING: do not cache agg.String() - it may change during CumulateInitial
104- a := agg .String ()
110+ for i , agg := range this .plan .Aggregates () {
111+ var a string
112+ if i < len (this .aggNames ) {
113+ a = this .aggNames [i ]
114+ }
115+ if a == "" {
116+ a = agg .String ()
117+ // do not cache aggregate string if aggregate has subquery references, since
118+ // the string may change (e.g. COVER transformation), and we don't know when
119+ // the subquery may be executed for the first time (e.g. under a CASE)
120+ if ! agg .HasFlags (algebra .AGGREGATE_HAS_SUBQ ) && i < len (this .aggNames ) {
121+ this .aggNames [i ] = a
122+ }
123+ }
105124 pv := aggregates [a ]
106125 if pv == nil {
107126 // Log an error and explicitly panic
@@ -133,12 +152,16 @@ func (this *InitialGroup) processItem(item value.AnnotatedValue, context *Contex
133152 pv .Recycle ()
134153 }
135154 }
136- b := agg .String ()
137- aggregates [b ] = v
138- // delete the previous key if agg.String() has changed
139- if a != b {
140- delete (aggregates , a )
155+ b := a
156+ if agg .HasFlags (algebra .AGGREGATE_HAS_SUBQ ) {
157+ // do not use cached agg string if agg has subquery references
158+ b = agg .String ()
159+ // delete the previous key if agg.String() has changed
160+ if a != b {
161+ delete (aggregates , a )
162+ }
141163 }
164+ aggregates [b ] = v
142165 }
143166
144167 // Update the Group Key's entry in the Map with the Group As field in the item
@@ -213,6 +236,9 @@ func (this *InitialGroup) reopen(context *Context) bool {
213236 rv := this .baseReopen (context )
214237 if rv {
215238 this .groups = make (map [string ]value.AnnotatedValue )
239+ for i := range this .aggNames {
240+ this .aggNames [i ] = ""
241+ }
216242 }
217243 return rv
218244}
@@ -224,4 +250,10 @@ func (this *InitialGroup) Release() {
224250 }
225251 this .groups = nil
226252 }
253+ if this .aggNames != nil {
254+ for i := range this .aggNames {
255+ this .aggNames [i ] = ""
256+ }
257+ this .aggNames = nil
258+ }
227259}
0 commit comments