github.com/rohankumardubey/aresdb@v0.0.2-0.20190517170215-e54e3ca06b9c/query/aql_postprocessor_test.go (about)

     1  //  Copyright (c) 2017-2018 Uber Technologies, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package query
    16  
    17  import (
    18  	"github.com/onsi/ginkgo"
    19  	. "github.com/onsi/gomega"
    20  	memCom "github.com/uber/aresdb/memstore/common"
    21  	queryCom "github.com/uber/aresdb/query/common"
    22  	"github.com/uber/aresdb/query/expr"
    23  	"github.com/uber/aresdb/utils"
    24  	"time"
    25  	"unsafe"
    26  )
    27  
    28  var _ = ginkgo.Describe("AQL postprocessor", func() {
    29  	ginkgo.It("works on empty result", func() {
    30  		ctx := &AQLQueryContext{}
    31  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{}))
    32  	})
    33  
    34  	ginkgo.It("works on one dimension and one row", func() {
    35  		ctx := &AQLQueryContext{
    36  			Query: &AQLQuery{
    37  				Dimensions: []Dimension{
    38  					{Expr: ""},
    39  				},
    40  			},
    41  		}
    42  		oopkContext := OOPKContext{
    43  			Dimensions: []expr.Expr{
    44  				&expr.VarRef{
    45  					ExprType: expr.Unsigned,
    46  					DataType: memCom.Uint32,
    47  				},
    48  			},
    49  			Measure: &expr.NumberLiteral{
    50  				ExprType: expr.Float,
    51  			},
    52  			MeasureBytes:         4,
    53  			DimRowBytes:          5,
    54  			DimensionVectorIndex: []int{0},
    55  			NumDimsPerDimWidth:   queryCom.DimCountsPerDimWidth{0, 0, 1, 0, 0},
    56  			ResultSize:           1,
    57  			dimensionVectorH:     unsafe.Pointer(&[]uint8{12, 0, 0, 0, 1}[0]),
    58  			measureVectorH:       unsafe.Pointer(&[]float32{3.2}[0]),
    59  		}
    60  
    61  		ctx.OOPK = oopkContext
    62  
    63  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
    64  			"12": float64(float32(3.2)),
    65  		}))
    66  	})
    67  
    68  	ginkgo.It("works on two dimensions and two rows", func() {
    69  		ctx := &AQLQueryContext{
    70  			Query: &AQLQuery{
    71  				Dimensions: []Dimension{
    72  					{Expr: ""},
    73  					{Expr: ""},
    74  				},
    75  			},
    76  		}
    77  		oopkContext := OOPKContext{
    78  			Dimensions: []expr.Expr{
    79  				&expr.VarRef{
    80  					ExprType:        expr.Unsigned,
    81  					DataType:        memCom.BigEnum,
    82  					EnumReverseDict: []string{"zero", "one", "two"},
    83  				},
    84  				&expr.NumberLiteral{
    85  					ExprType: expr.Signed,
    86  				},
    87  			},
    88  			Measure: &expr.NumberLiteral{
    89  				ExprType: expr.Float,
    90  			},
    91  			MeasureBytes:       4,
    92  			DimRowBytes:        8,
    93  			NumDimsPerDimWidth: queryCom.DimCountsPerDimWidth{0, 0, 1, 1, 0},
    94  			DimensionVectorIndex: []int{
    95  				1,
    96  				0,
    97  			},
    98  			ResultSize:       2,
    99  			dimensionVectorH: unsafe.Pointer(&[]uint8{12, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 1, 0, 1, 1}[0]),
   100  			measureVectorH:   unsafe.Pointer(&[]float32{3.2, 6.4}[0]),
   101  		}
   102  
   103  		ctx.OOPK = oopkContext
   104  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   105  			"two": map[string]interface{}{
   106  				"12":   float64(float32(3.2)),
   107  				"NULL": float64(float32(6.4)),
   108  			},
   109  		}))
   110  	})
   111  
   112  	ginkgo.It("works on float dimension and nil measure", func() {
   113  		ctx := &AQLQueryContext{
   114  			Query: &AQLQuery{
   115  				Dimensions: []Dimension{
   116  					{Expr: ""},
   117  				},
   118  			},
   119  		}
   120  		oopkContext := OOPKContext{
   121  			Dimensions: []expr.Expr{
   122  				&expr.VarRef{
   123  					ExprType: expr.Float,
   124  					DataType: memCom.Float32,
   125  				},
   126  			},
   127  			Measure: &expr.NumberLiteral{
   128  				ExprType: expr.UnknownType,
   129  			},
   130  			DimRowBytes:        5,
   131  			NumDimsPerDimWidth: queryCom.DimCountsPerDimWidth{0, 0, 1, 0, 0},
   132  			DimensionVectorIndex: []int{
   133  				0,
   134  			},
   135  			ResultSize:       1,
   136  			dimensionVectorH: unsafe.Pointer(&[]uint8{0, 0, 0, 0, 0}[0]),
   137  			measureVectorH:   unsafe.Pointer(&[]float32{3.2}[0]),
   138  		}
   139  
   140  		ctx.OOPK = oopkContext
   141  		*(*float32)(oopkContext.dimensionVectorH) = 3.2
   142  		*(*uint8)(utils.MemAccess(oopkContext.dimensionVectorH, 4)) = 1
   143  
   144  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   145  			"3.2": nil,
   146  		}))
   147  	})
   148  
   149  	ginkgo.It("works for non agg queries", func() {
   150  		ctx := &AQLQueryContext{
   151  			Query: &AQLQuery{
   152  				Dimensions: []Dimension{
   153  					{Expr: "someField"},
   154  				},
   155  			},
   156  			isNonAggregationQuery: true,
   157  		}
   158  		oopkContext := OOPKContext{
   159  			Dimensions: []expr.Expr{
   160  				&expr.VarRef{
   161  					ExprType: expr.Float,
   162  					DataType: memCom.Float32,
   163  				},
   164  			},
   165  			DimRowBytes:        5,
   166  			NumDimsPerDimWidth: queryCom.DimCountsPerDimWidth{0, 0, 1, 0, 0},
   167  			DimensionVectorIndex: []int{
   168  				0,
   169  			},
   170  			ResultSize:       1,
   171  			dimensionVectorH: unsafe.Pointer(&[]uint8{0, 0, 0, 0, 0}[0]),
   172  		}
   173  
   174  		ctx.OOPK = oopkContext
   175  		*(*float32)(oopkContext.dimensionVectorH) = 3.2
   176  		*(*uint8)(utils.MemAccess(oopkContext.dimensionVectorH, 4)) = 1
   177  
   178  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   179  			"headers":    []string{"someField"},
   180  			"matrixData": [][]interface{}{{"3.2"}},
   181  		}))
   182  	})
   183  
   184  	ginkgo.It("time Unit formatting works", func() {
   185  		query := &AQLQuery{
   186  			Dimensions: []Dimension{
   187  				{
   188  					TimeBucketizer: "h",
   189  				},
   190  				{
   191  					Expr: "",
   192  				},
   193  			},
   194  		}
   195  		ctx := &AQLQueryContext{
   196  			Query: query,
   197  		}
   198  		oopkContext := OOPKContext{
   199  			Dimensions: []expr.Expr{
   200  				&expr.VarRef{
   201  					ExprType: expr.Unsigned,
   202  					DataType: memCom.Uint32,
   203  				},
   204  				&expr.NumberLiteral{
   205  					ExprType: expr.Signed,
   206  				},
   207  			},
   208  			Measure: &expr.NumberLiteral{
   209  				ExprType: expr.Float,
   210  			},
   211  			MeasureBytes:       4,
   212  			DimRowBytes:        10,
   213  			NumDimsPerDimWidth: queryCom.DimCountsPerDimWidth{0, 0, 2, 0, 0},
   214  			DimensionVectorIndex: []int{
   215  				0,
   216  				1,
   217  			},
   218  			ResultSize:       2,
   219  			dimensionVectorH: unsafe.Pointer(&[]uint8{190, 0, 0, 0, 250, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1}[0]),
   220  			measureVectorH:   unsafe.Pointer(&[]float32{3.2, 6.4}[0]),
   221  		}
   222  
   223  		ctx.OOPK = oopkContext
   224  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   225  			"1970-01-01 00:00": map[string]interface{}{
   226  				"2": 6.400000095367432,
   227  			},
   228  		}))
   229  
   230  		ctx.Query.Dimensions[0].TimeBucketizer = "time of day"
   231  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   232  			"00:03": map[string]interface{}{
   233  				"2": float64(float32(3.2)),
   234  			},
   235  			"00:04": map[string]interface{}{
   236  				"2": 6.400000095367432,
   237  			},
   238  		}))
   239  
   240  		ctx.Query.Dimensions[0].TimeBucketizer = "hour of day"
   241  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   242  			"00:00": map[string]interface{}{
   243  				"2": 6.400000095367432,
   244  			},
   245  		}))
   246  
   247  		ctx.Query.Dimensions[0].TimeBucketizer = "hour of week"
   248  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   249  			"Monday 00:03": map[string]interface{}{
   250  				"2": float64(float32(3.2)),
   251  			},
   252  			"Monday 00:04": map[string]interface{}{
   253  				"2": 6.400000095367432,
   254  			},
   255  		}))
   256  
   257  		ctx.Query.Dimensions[0].TimeBucketizer = "minute"
   258  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   259  			"1970-01-01 00:03": map[string]interface{}{
   260  				"2": float64(float32(3.2)),
   261  			},
   262  			"1970-01-01 00:04": map[string]interface{}{
   263  				"2": 6.400000095367432,
   264  			},
   265  		}))
   266  
   267  		ctx.Query.Dimensions[0].TimeBucketizer = "hour"
   268  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   269  			"1970-01-01 00:00": map[string]interface{}{
   270  				"2": 6.400000095367432,
   271  			},
   272  		}))
   273  
   274  		ctx.Query.Dimensions[0].TimeBucketizer = "some invalid bucketizer"
   275  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   276  			"190": map[string]interface{}{
   277  				"2": float64(float32(3.2)),
   278  			},
   279  			"250": map[string]interface{}{
   280  				"2": 6.400000095367432,
   281  			},
   282  		}))
   283  
   284  		ctx.OOPK.dimensionVectorH = unsafe.Pointer(&[]uint8{1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1}[0])
   285  		ctx.Query.Dimensions[0].TimeBucketizer = "day of week"
   286  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   287  			"Tuesday": map[string]interface{}{
   288  				"2": float64(float32(3.2)),
   289  			},
   290  			"Wednesday": map[string]interface{}{
   291  				"2": 6.400000095367432,
   292  			},
   293  		}))
   294  
   295  	})
   296  
   297  	ginkgo.It("time dimension remedy should work", func() {
   298  		query := &AQLQuery{
   299  			Dimensions: []Dimension{
   300  				{
   301  					Expr:           "reqeust_at",
   302  					TimeBucketizer: "d",
   303  					TimeUnit:       "second",
   304  				},
   305  				{
   306  					Expr: "1",
   307  				},
   308  			},
   309  			TimeFilter: TimeFilter{
   310  				Column: "request_at",
   311  				From:   "-1d",
   312  				To:     "0d",
   313  			},
   314  		}
   315  		tzloc, _ := time.LoadLocation("Africa/Algiers")
   316  		ctx := &AQLQueryContext{
   317  			Query:         query,
   318  			fixedTimezone: time.UTC,
   319  		}
   320  		ctx1 := &AQLQueryContext{
   321  			Query:         query,
   322  			fixedTimezone: tzloc,
   323  		}
   324  		ctx.parseExprs()
   325  		Ω(ctx.Error).Should(BeNil())
   326  		ctx1.parseExprs()
   327  		Ω(ctx1.Error).Should(BeNil())
   328  		oopkContext := OOPKContext{
   329  			Dimensions: []expr.Expr{
   330  				&expr.VarRef{
   331  					ExprType: expr.Unsigned,
   332  					DataType: memCom.Uint32,
   333  				},
   334  				&expr.NumberLiteral{
   335  					ExprType: expr.Signed,
   336  				},
   337  			},
   338  			Measure: &expr.NumberLiteral{
   339  				ExprType: expr.Float,
   340  			},
   341  			MeasureBytes:       4,
   342  			DimRowBytes:        10,
   343  			NumDimsPerDimWidth: queryCom.DimCountsPerDimWidth{0, 0, 2, 0, 0},
   344  			DimensionVectorIndex: []int{
   345  				0,
   346  				1,
   347  			},
   348  			ResultSize:       2,
   349  			dimensionVectorH: unsafe.Pointer(&[]uint8{12, 100, 0, 0, 13, 100, 0, 0, 2, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 1}[0]),
   350  			measureVectorH:   unsafe.Pointer(&[]float32{3.2, 6.4}[0]),
   351  		}
   352  
   353  		ctx.OOPK = oopkContext
   354  		Ω(ctx.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   355  			"25612": map[string]interface{}{
   356  				"2": float64(float32(3.2)),
   357  			},
   358  			"25613": map[string]interface{}{
   359  				"2": 6.400000095367432,
   360  			},
   361  		}))
   362  
   363  		ctx1.OOPK = oopkContext
   364  		Ω(ctx1.Postprocess()).Should(Equal(queryCom.AQLQueryResult{
   365  			"22012": map[string]interface{}{
   366  				"2": float64(float32(3.2)),
   367  			},
   368  			"22013": map[string]interface{}{
   369  				"2": 6.400000095367432,
   370  			},
   371  		}))
   372  	})
   373  
   374  	ginkgo.It("readMeasure should work", func() {
   375  		// read an 8 bytes int64
   376  		measureVectorInt := [1]int64{1}
   377  		measureAST := &expr.NumberLiteral{
   378  			ExprType: expr.Signed,
   379  		}
   380  
   381  		measureVal := readMeasure(unsafe.Pointer(&measureVectorInt[0]), measureAST, 8)
   382  		Ω(measureVal).ShouldNot(BeNil())
   383  		Ω(*measureVal).Should(Equal(1.0))
   384  
   385  		// read a 4 bytes float
   386  		measureVectorFloat := [2]float32{1.0, 0}
   387  		measureAST = &expr.NumberLiteral{
   388  			ExprType: expr.Float,
   389  		}
   390  		measureVal = readMeasure(unsafe.Pointer(&measureVectorFloat[0]), measureAST, 4)
   391  		Ω(measureVal).ShouldNot(BeNil())
   392  		Ω(*measureVal).Should(BeEquivalentTo(1.0))
   393  	})
   394  })