@@ -12,6 +12,7 @@ import (
12
12
"github.com/davecgh/go-spew/spew"
13
13
"github.com/influxdata/influxdb/v2/influxql/query"
14
14
"github.com/influxdata/influxdb/v2/pkg/deep"
15
+ "github.com/influxdata/influxdb/v2/pkg/testing/assert"
15
16
"github.com/influxdata/influxql"
16
17
)
17
18
@@ -880,6 +881,170 @@ func TestGroupByIterator_DST(t *testing.T) {
880
881
}
881
882
}
882
883
884
+ // A count() GROUP BY query with an offset that caused an interval
885
+ // to cross a daylight savings change back to standard time dropped
886
+ // rows in a grouped count() expression.
887
+
888
+ func TestGroupByIterator_DST_End (t * testing.T ) {
889
+ // const RFC822 string = "02 Jan 06 15:04 MST"
890
+ inputIter := & IntegerIterator {
891
+ Points : []query.IntegerPoint {
892
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T00:00:01Z" ).UnixNano (), Value : 1 },
893
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T01:00:01Z" ).UnixNano (), Value : 1 },
894
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T02:00:01Z" ).UnixNano (), Value : 1 },
895
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T03:00:01Z" ).UnixNano (), Value : 1 },
896
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T04:00:01Z" ).UnixNano (), Value : 1 },
897
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T05:00:01Z" ).UnixNano (), Value : 1 },
898
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T06:00:01Z" ).UnixNano (), Value : 1 },
899
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T07:00:01Z" ).UnixNano (), Value : 1 },
900
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T08:00:01Z" ).UnixNano (), Value : 1 },
901
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T09:00:01Z" ).UnixNano (), Value : 1 },
902
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T10:00:01Z" ).UnixNano (), Value : 1 },
903
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T11:00:01Z" ).UnixNano (), Value : 1 },
904
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T12:00:01Z" ).UnixNano (), Value : 1 },
905
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T13:00:01Z" ).UnixNano (), Value : 1 },
906
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T14:00:01Z" ).UnixNano (), Value : 1 },
907
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T15:00:01Z" ).UnixNano (), Value : 1 },
908
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T16:00:01Z" ).UnixNano (), Value : 1 },
909
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T17:00:01Z" ).UnixNano (), Value : 1 },
910
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T18:00:01Z" ).UnixNano (), Value : 1 },
911
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T19:00:01Z" ).UnixNano (), Value : 1 },
912
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T20:00:01Z" ).UnixNano (), Value : 1 },
913
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T21:00:01Z" ).UnixNano (), Value : 1 },
914
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T22:00:01Z" ).UnixNano (), Value : 1 },
915
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-02T23:00:01Z" ).UnixNano (), Value : 1 },
916
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T00:00:01Z" ).UnixNano (), Value : 1 },
917
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T01:00:01Z" ).UnixNano (), Value : 1 },
918
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T02:00:01Z" ).UnixNano (), Value : 1 },
919
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T03:00:01Z" ).UnixNano (), Value : 1 },
920
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T04:00:01Z" ).UnixNano (), Value : 1 },
921
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T05:00:01Z" ).UnixNano (), Value : 1 },
922
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T06:00:01Z" ).UnixNano (), Value : 1 },
923
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T07:00:01Z" ).UnixNano (), Value : 1 },
924
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T08:00:01Z" ).UnixNano (), Value : 1 },
925
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T09:00:01Z" ).UnixNano (), Value : 1 },
926
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T10:00:01Z" ).UnixNano (), Value : 1 },
927
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T11:00:01Z" ).UnixNano (), Value : 1 },
928
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T12:00:01Z" ).UnixNano (), Value : 1 },
929
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T13:00:01Z" ).UnixNano (), Value : 1 },
930
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T14:00:01Z" ).UnixNano (), Value : 1 },
931
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T15:00:01Z" ).UnixNano (), Value : 1 },
932
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T16:00:01Z" ).UnixNano (), Value : 1 },
933
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T17:00:01Z" ).UnixNano (), Value : 1 },
934
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T18:00:01Z" ).UnixNano (), Value : 1 },
935
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T19:00:01Z" ).UnixNano (), Value : 1 },
936
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T20:00:01Z" ).UnixNano (), Value : 1 },
937
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T21:00:01Z" ).UnixNano (), Value : 1 },
938
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T22:00:01Z" ).UnixNano (), Value : 1 },
939
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-03T23:00:01Z" ).UnixNano (), Value : 1 },
940
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T00:00:01Z" ).UnixNano (), Value : 1 },
941
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T01:00:01Z" ).UnixNano (), Value : 1 },
942
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T02:00:01Z" ).UnixNano (), Value : 1 },
943
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T03:00:01Z" ).UnixNano (), Value : 1 },
944
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T04:00:01Z" ).UnixNano (), Value : 1 },
945
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T05:00:01Z" ).UnixNano (), Value : 1 },
946
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T06:00:01Z" ).UnixNano (), Value : 1 },
947
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T07:00:01Z" ).UnixNano (), Value : 1 },
948
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T08:00:01Z" ).UnixNano (), Value : 1 },
949
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T09:00:01Z" ).UnixNano (), Value : 1 },
950
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T10:00:01Z" ).UnixNano (), Value : 1 },
951
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T11:00:01Z" ).UnixNano (), Value : 1 },
952
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T12:00:01Z" ).UnixNano (), Value : 1 },
953
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T13:00:01Z" ).UnixNano (), Value : 1 },
954
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T14:00:01Z" ).UnixNano (), Value : 1 },
955
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T15:00:01Z" ).UnixNano (), Value : 1 },
956
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T16:00:01Z" ).UnixNano (), Value : 1 },
957
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T17:00:01Z" ).UnixNano (), Value : 1 },
958
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T18:00:01Z" ).UnixNano (), Value : 1 },
959
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T19:00:01Z" ).UnixNano (), Value : 1 },
960
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T20:00:01Z" ).UnixNano (), Value : 1 },
961
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T21:00:01Z" ).UnixNano (), Value : 1 },
962
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T22:00:01Z" ).UnixNano (), Value : 1 },
963
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-04T23:00:01Z" ).UnixNano (), Value : 1 },
964
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T00:00:01Z" ).UnixNano (), Value : 1 },
965
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T01:00:01Z" ).UnixNano (), Value : 1 },
966
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T02:00:01Z" ).UnixNano (), Value : 1 },
967
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T03:00:01Z" ).UnixNano (), Value : 1 },
968
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T04:00:01Z" ).UnixNano (), Value : 1 },
969
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T05:00:01Z" ).UnixNano (), Value : 1 },
970
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T06:00:01Z" ).UnixNano (), Value : 1 },
971
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T07:00:01Z" ).UnixNano (), Value : 1 },
972
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T08:00:01Z" ).UnixNano (), Value : 1 },
973
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T09:00:01Z" ).UnixNano (), Value : 1 },
974
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T10:00:01Z" ).UnixNano (), Value : 1 },
975
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T11:00:01Z" ).UnixNano (), Value : 1 },
976
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T12:00:01Z" ).UnixNano (), Value : 1 },
977
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T13:00:01Z" ).UnixNano (), Value : 1 },
978
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T14:00:01Z" ).UnixNano (), Value : 1 },
979
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T15:00:01Z" ).UnixNano (), Value : 1 },
980
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T16:00:01Z" ).UnixNano (), Value : 1 },
981
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T17:00:01Z" ).UnixNano (), Value : 1 },
982
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T18:00:01Z" ).UnixNano (), Value : 1 },
983
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T19:00:01Z" ).UnixNano (), Value : 1 },
984
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T20:00:01Z" ).UnixNano (), Value : 1 },
985
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T21:00:01Z" ).UnixNano (), Value : 1 },
986
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T22:00:01Z" ).UnixNano (), Value : 1 },
987
+ {Name : "a" , Tags : ParseTags ("t=a" ), Time : mustParseTime ("2023-11-05T23:00:01Z" ).UnixNano (), Value : 1 },
988
+ },
989
+ }
990
+ const location = "America/Los_Angeles"
991
+ loc , err := time .LoadLocation (location )
992
+ if err != nil {
993
+ t .Fatalf ("Cannot find timezone for %s: %s" , location , err )
994
+ }
995
+ opt := query.IteratorOptions {
996
+ StartTime : mustParseTime ("2023-11-02T00:00:00Z" ).UnixNano (),
997
+ EndTime : mustParseTime ("2023-11-06T00:00:00Z" ).UnixNano (),
998
+ Ascending : true ,
999
+
1000
+ Ordered : true ,
1001
+ StripName : false ,
1002
+ Fill : influxql .NoFill ,
1003
+ FillValue : nil ,
1004
+ Dedupe : false ,
1005
+ Interval : query.Interval {
1006
+ Duration : 24 * time .Hour ,
1007
+ Offset : 12 * time .Hour ,
1008
+ },
1009
+ Expr : MustParseExpr ("count(Value)" ),
1010
+ Location : loc ,
1011
+ }
1012
+
1013
+ groupByIter , err := query .NewCallIterator (inputIter , opt )
1014
+ if err != nil {
1015
+ t .Fatalf ("Cannot create Count and Group By iterator: %s" , err )
1016
+ } else {
1017
+ groupByIter = query .NewFillIterator (groupByIter , MustParseExpr ("count(Value)" ), opt )
1018
+ }
1019
+
1020
+ if all , err := (Iterators {groupByIter }).ReadAll (); err != nil {
1021
+ t .Fatalf ("unexpected error: %s" , err )
1022
+ } else {
1023
+ results := [][]query.IntegerPoint {
1024
+ {query.IntegerPoint {Name : "a" , Aggregated : 19 , Time : mustParseTime ("2023-11-01T12:00:00-07:00" ).UnixNano (), Value : 19 }},
1025
+ {query.IntegerPoint {Name : "a" , Aggregated : 24 , Time : mustParseTime ("2023-11-02T12:00:00-07:00" ).UnixNano (), Value : 24 }},
1026
+ {query.IntegerPoint {Name : "a" , Aggregated : 24 , Time : mustParseTime ("2023-11-03T12:00:00-07:00" ).UnixNano (), Value : 24 }},
1027
+ // The extra time from falling back means more than 24 hours counted
1028
+ {query.IntegerPoint {Name : "a" , Aggregated : 25 , Time : mustParseTime ("2023-11-04T12:00:00-07:00" ).UnixNano (), Value : 25 }},
1029
+ {query.IntegerPoint {Name : "a" , Aggregated : 04 , Time : mustParseTime ("2023-11-05T12:00:00-08:00" ).UnixNano (), Value : 4 }},
1030
+ }
1031
+
1032
+ for i , a := range all {
1033
+ for j , p := range a {
1034
+ switch ip := p .(type ) {
1035
+ case * query.IntegerPoint :
1036
+ assert .Equal (t , results [i ][j ].Time , ip .Time ,
1037
+ "Time mismatch at i=%d j=%d: expect %v, got %v" , i , j , time .Unix (0 , results [i ][j ].Time ), time .Unix (0 , ip .Time ))
1038
+ assert .Equal (t , results [i ][j ].Value , ip .Value ,
1039
+ "Value mismatch at i=%d j=%d: expect %d, got %d" , i , j , results [i ][j ].Value , ip .Value )
1040
+ assert .Equal (t , results [i ][j ].Aggregated , ip .Aggregated ,
1041
+ "Aggregated mismatch at i=%d j=%d: expect %d, got %d" , i , j , results [i ][j ].Aggregated , ip .Aggregated )
1042
+ }
1043
+ }
1044
+ }
1045
+ }
1046
+ }
1047
+
883
1048
func TestFillIterator_DST (t * testing.T ) {
884
1049
for _ , tt := range []struct {
885
1050
name string
0 commit comments