@@ -259,60 +259,124 @@ func (f *SliceFilter) Rows() ResultRows {
259259 var r ResultRows
260260
261261 source := f .intermediate .Result ()
262-
263262 source = source .Filter (f .filter )
264263
264+ if len (source .Rows ) == 0 {
265+ return r
266+ }
267+
265268 // Transform our intermediate columns into a lookup table
266269 lookup := make (map [string ]int )
267270 for idx , column := range source .Columns {
268271 lookup [column ] = idx
269272 }
270273
271- for _ , row := range source .Rows {
272- var narrow ResultRow
274+ // Find column positions to narrow
275+ var narrowColumns []int
276+ for _ , column := range f .resultColumns {
277+ if column .Star .Line > 0 {
278+ for idx , _ := range source .Rows [0 ] {
279+ narrowColumns = append (narrowColumns , idx )
280+ }
281+ break
282+ }
273283
274- for _ , column := range f .resultColumns {
275- if column .Star .Line > 0 {
276- narrow = row
284+ switch t := column .Expr .(type ) {
285+ case * sql.Ident :
286+ index , ok := lookup [t .Name ]
287+ if ! ok {
288+ // FIXME: There should be a better way
289+ parts := strings .Split (source .Columns [0 ], "." )
290+ if len (parts ) > 1 {
291+ index = lookup [parts [0 ]+ "." + t .Name ]
292+ }
277293 }
278294
279- switch t := column .Expr .(type ) {
280- case * sql.Ident :
281- index , ok := lookup [t .Name ]
295+ narrowColumns = append (narrowColumns , index )
296+ case * sql.QualifiedRef :
297+ if t .Star .Line != 0 {
298+ // FIXME: Implement
299+ continue
300+ }
301+
302+ lh := t .Table .Name
303+ rh := t .Column .Name
304+
305+ var index int
306+ var ok bool
307+ if source .Source != nil {
308+ index , ok = lookup [rh ]
309+ } else {
310+ index , ok = lookup [lh + "." + rh ]
282311 if ! ok {
312+ index = lookup [source .Aliases [lh ]+ "." + rh ]
313+ }
314+ }
315+
316+ narrowColumns = append (narrowColumns , index )
317+ default :
318+ narrowColumns = append (narrowColumns , 0 )
319+ }
320+ }
321+
322+ // Find aggregations
323+ var aggregations []AggregateFunctionColumn
324+ for idx , column := range f .resultColumns {
325+ switch t := column .Expr .(type ) {
326+ case * sql.Call :
327+ var underlying string
328+ if t .Star .Line == 0 {
329+ if len (t .Args ) != 1 {
330+ panic ("unexpected number of args to function" )
331+ }
332+
333+ switch arg := t .Args [0 ].(type ) {
334+ case * sql.Ident :
335+ // Validate?
336+ index , ok := lookup [arg .Name ]
337+ if ok {
338+ underlying = arg .Name
339+ break
340+ }
341+
283342 // FIXME: There should be a better way
284343 parts := strings .Split (source .Columns [0 ], "." )
285344 if len (parts ) > 1 {
286- index = lookup [parts [0 ]+ "." + t .Name ]
345+ index , ok = lookup [parts [0 ]+ "." + arg .Name ]
346+ if ok {
347+ underlying = parts [0 ] + "." + arg .Name
348+ }
287349 }
288- }
289350
290- narrow = append (narrow , row [index ])
291- case * sql.QualifiedRef :
292- if t .Star .Line != 0 {
293- // FIXME: Implement
294- continue
351+ narrowColumns [idx ] = index
295352 }
353+ } else {
354+ narrowColumns [idx ] = 0
355+ }
296356
297- lh := t .Table .Name
298- rh := t .Column .Name
299-
300- var index int
301- var ok bool
302- if source .Source != nil {
303- index , ok = lookup [rh ]
304- } else {
305- index , ok = lookup [lh + "." + rh ]
306- if ! ok {
307- index = lookup [source .Aliases [lh ]+ "." + rh ]
308- }
309- }
357+ aggregations = append (aggregations , AggregateFunctionColumn {
358+ UnderlyingColumn : underlying ,
359+ ResultPosition : idx ,
360+ Function : functionMap [t .Name .Name ],
361+ })
362+ }
363+ }
310364
311- narrow = append (narrow , row [index ])
312- }
365+ for _ , row := range source .Rows {
366+ if len (row ) == len (narrowColumns ) {
367+ r = append (r , row )
368+ continue
369+ }
370+
371+ var newRow ResultRow
372+ for _ , column := range narrowColumns {
373+ newRow = append (newRow , row [column ])
313374 }
375+ r = append (r , newRow )
376+ }
314377
315- r = append (r , narrow )
378+ for _ , aggregation := range aggregations {
379+ r = aggregation .Call (r )
316380 }
317381
318382 f .resultColumns = []* sql.ResultColumn {}
0 commit comments