github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/es/query/queryparser.go (about)

     1  /*
     2  Copyright 2023.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package query
    18  
    19  import (
    20  	"bytes"
    21  	"encoding/json"
    22  	"errors"
    23  	"fmt"
    24  	"strconv"
    25  	"strings"
    26  	"time"
    27  	"unicode"
    28  
    29  	jsoniter "github.com/json-iterator/go"
    30  	dtu "github.com/siglens/siglens/pkg/common/dtypeutils"
    31  	"github.com/siglens/siglens/pkg/config"
    32  	rutils "github.com/siglens/siglens/pkg/readerUtils"
    33  	"github.com/siglens/siglens/pkg/scroll"
    34  	. "github.com/siglens/siglens/pkg/scroll"
    35  	"github.com/siglens/siglens/pkg/segment/structs"
    36  	. "github.com/siglens/siglens/pkg/segment/structs"
    37  	. "github.com/siglens/siglens/pkg/segment/utils"
    38  	"github.com/siglens/siglens/pkg/utils"
    39  	log "github.com/sirupsen/logrus"
    40  )
    41  
    42  // flag passed here
    43  func ParseRequest(json_body []byte, qid uint64, isJaegerQuery bool, scrollTimeout ...string) (*ASTNode, *QueryAggregators, uint64, *Scroll, error) {
    44  	var sizeLimit uint64 = 10
    45  	if json_body == nil {
    46  		err := fmt.Errorf("ParseRequest: Error parsing JSON expected a value, got: %v", json_body)
    47  		return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, err
    48  	}
    49  	var results map[string]interface{}
    50  	var jsonc = jsoniter.ConfigCompatibleWithStandardLibrary
    51  	decoder := jsonc.NewDecoder(bytes.NewReader(json_body))
    52  	decoder.UseNumber()
    53  	err := decoder.Decode(&results)
    54  	if err != nil {
    55  		log.Errorf("qid=%d, ParseRequest: Invalid json/query: %v", qid, err)
    56  		return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, errors.New("ParseRequest: Invalid json/query")
    57  	}
    58  	var leafNode *ASTNode
    59  	var queryAggregations *QueryAggregators
    60  	var sortOrder *SortRequest
    61  	var parsingError error
    62  	var scrollRecord *Scroll
    63  	var scroll_id string
    64  
    65  	for key, value := range results {
    66  		switch valtype := value.(type) {
    67  		case map[string]interface{}:
    68  			if key == "query" {
    69  				leafNode, parsingError = parseQuery(value, qid, isJaegerQuery)
    70  			} else if key == "aggs" || key == "aggregations" {
    71  				queryAggregations, parsingError = parseAggregations(value, qid)
    72  			}
    73  		case string:
    74  			if key == "scroll" {
    75  				scrollTimeout[0] = valtype
    76  			} else if key == "scroll_id" {
    77  				scroll_id = valtype
    78  			}
    79  		case json.Number:
    80  			if key == "size" {
    81  				sizeLimit, err = parseSize(value, qid)
    82  				if err != nil {
    83  					log.Errorf("qid=%d, Failed to parse size: %v", qid, err)
    84  				}
    85  				log.Infof("qid=%d, ParseRequest: Limiting the size to [%v]", qid, sizeLimit)
    86  			}
    87  		case []interface{}:
    88  			if key == "sort" {
    89  				sortOrder, parsingError = parseSort(value, qid)
    90  			}
    91  		case bool:
    92  			if key == "rest_total_hits_as_int" {
    93  				if queryAggregations == nil {
    94  					queryAggregations = structs.InitDefaultQueryAggregations()
    95  				}
    96  				queryAggregations.EarlyExit = !valtype
    97  			}
    98  		default:
    99  			if key == "seq_no_primary_term" || key == "version" || key == "stored_fields" ||
   100  				key == "script_fields" || key == "docvalue_fields" || key == "highlight" || key == "_source" ||
   101  				key == "timeout" {
   102  				log.Infof("qid=%d, ParseRequest: Ignoring tags other than query [%v]", qid, key)
   103  			} else {
   104  				log.Errorf("qid=%d, ParseRequest: Invalid query key=[%v]", qid, key)
   105  				return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, errors.New("ParseRequest: Invalid Query")
   106  			}
   107  		}
   108  		if parsingError != nil {
   109  			return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, parsingError
   110  		}
   111  	}
   112  	if len(scrollTimeout) > 0 && scrollTimeout[0] != "" {
   113  		if scroll_id != "" {
   114  			if !scroll.IsScrollIdValid(scroll_id) {
   115  				return nil, nil, sizeLimit, nil, errors.New("ParseRequest: Scroll Timeout : Invalid Search context")
   116  			}
   117  		}
   118  		timeOut, err := GetScrollTimeOut(scrollTimeout[0], qid)
   119  		if err != nil {
   120  			return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, err
   121  		}
   122  		scrollRecord = GetScrollRecord(scroll_id, scrollTimeout[0], sizeLimit)
   123  		scrollRecord.TimeOut = timeOut
   124  		//For scroll query, query body is empty , get sizelimit from scrollRecord
   125  		sizeLimit = scrollRecord.Size
   126  	}
   127  
   128  	if sortOrder != nil {
   129  		if queryAggregations != nil {
   130  			queryAggregations.Sort = sortOrder
   131  		} else {
   132  			queryAggregations = &QueryAggregators{
   133  				Sort: sortOrder,
   134  			}
   135  		}
   136  	}
   137  
   138  	if queryAggregations == nil {
   139  		queryAggregations = structs.InitDefaultQueryAggregations()
   140  	}
   141  
   142  	return leafNode, queryAggregations, sizeLimit, scrollRecord, nil
   143  }
   144  
   145  func ParseOpenDistroRequest(json_body []byte, qid uint64, isJaegerQuery bool, scrollTimeout ...string) (*ASTNode, *QueryAggregators, uint64, *Scroll, error) {
   146  	var sizeLimit uint64 = 10
   147  	if json_body == nil {
   148  		err := fmt.Errorf("ParseOpenDistroRequest: Error parsing JSON expected a value, got: %v", json_body)
   149  		return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, err
   150  	}
   151  	var results map[string]interface{}
   152  	var jsonc = jsoniter.ConfigCompatibleWithStandardLibrary
   153  	if len(json_body) != 0 {
   154  		decoder := jsonc.NewDecoder(bytes.NewReader(json_body))
   155  		decoder.UseNumber()
   156  		err := decoder.Decode(&results)
   157  		if err != nil {
   158  			log.Errorf("qid=%d, ParseOpenDistroRequest: Invalid json/query: %v", qid, err)
   159  			return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, errors.New("ParseOpenDistroRequest: Invalid json/query")
   160  		}
   161  	}
   162  	var leafNode *ASTNode
   163  	var queryAggregations *QueryAggregators
   164  	var sortOrder *SortRequest
   165  	var parsingError error
   166  	var scrollRecord *Scroll
   167  	var scroll_id string
   168  
   169  	for key, value := range results {
   170  		switch valtype := value.(type) {
   171  		case map[string]interface{}:
   172  			if key == "query" {
   173  				leafNode, parsingError = parseQuery(value, qid, isJaegerQuery)
   174  			} else if key == "aggs" || key == "aggregations" {
   175  				queryAggregations, parsingError = parseAggregations(value, qid)
   176  			}
   177  		case string:
   178  			if key == "scroll" {
   179  				scrollTimeout[0] = valtype
   180  			} else if key == "scroll_id" {
   181  				scroll_id = valtype
   182  			}
   183  		case json.Number:
   184  			if key == "size" {
   185  				sizeLimit, err := parseSize(value, qid)
   186  				if err != nil {
   187  					log.Errorf("qid=%d, Failed to parse size: %v", qid, err)
   188  				}
   189  				log.Infof("qid=%d, ParseOpenDistroRequest: Limiting the size to [%v]", qid, sizeLimit)
   190  			}
   191  		case []interface{}:
   192  			if key == "sort" {
   193  				sortOrder, parsingError = parseSort(value, qid)
   194  			}
   195  		case bool:
   196  			if key == "rest_total_hits_as_int" {
   197  				if queryAggregations == nil {
   198  					queryAggregations = structs.InitDefaultQueryAggregations()
   199  				}
   200  				queryAggregations.EarlyExit = !valtype
   201  			}
   202  		default:
   203  			if key == "seq_no_primary_term" || key == "version" || key == "stored_fields" ||
   204  				key == "script_fields" || key == "docvalue_fields" || key == "highlight" || key == "_source" ||
   205  				key == "timeout" {
   206  				log.Infof("qid=%d, ParseOpenDistroRequest: Ignoring tags other than query [%v]", qid, key)
   207  			} else {
   208  				log.Errorf("qid=%d, ParseOpenDistroRequest: Invalid query key=[%v]", qid, key)
   209  				return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, errors.New("ParseOpenDistroRequest: Invalid Query")
   210  			}
   211  		}
   212  		if parsingError != nil {
   213  			return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, parsingError
   214  		}
   215  	}
   216  	if len(scrollTimeout) > 0 && scrollTimeout[0] != "" {
   217  		if scroll_id != "" {
   218  			if !scroll.IsScrollIdValid(scroll_id) {
   219  				return nil, nil, sizeLimit, nil, errors.New("ParseOpenDistroRequest: Scroll Timeout : Invalid Search context")
   220  			}
   221  		}
   222  		timeOut, err := GetScrollTimeOut(scrollTimeout[0], qid)
   223  		if err != nil {
   224  			return nil, structs.InitDefaultQueryAggregations(), sizeLimit, nil, err
   225  		}
   226  		scrollRecord = GetScrollRecord(scroll_id, scrollTimeout[0], sizeLimit)
   227  		scrollRecord.TimeOut = timeOut
   228  		//For scroll query, query body is empty , get sizelimit from scrollRecord
   229  		sizeLimit = scrollRecord.Size
   230  	}
   231  
   232  	if sortOrder != nil {
   233  		if queryAggregations != nil {
   234  			queryAggregations.Sort = sortOrder
   235  		} else {
   236  			queryAggregations = &QueryAggregators{
   237  				Sort: sortOrder,
   238  			}
   239  		}
   240  	}
   241  
   242  	if queryAggregations == nil {
   243  		queryAggregations = structs.InitDefaultQueryAggregations()
   244  	}
   245  
   246  	return leafNode, queryAggregations, sizeLimit, scrollRecord, nil
   247  }
   248  
   249  func parseSize(value interface{}, qid uint64) (uint64, error) {
   250  	int64SizeLimit, err := value.(json.Number).Int64()
   251  	if err != nil {
   252  		log.Errorf("qid=%d, Failed to convert [%v] to int64", qid, int64SizeLimit)
   253  		return 0, err
   254  	} else {
   255  		return uint64(int64SizeLimit), nil
   256  	}
   257  }
   258  
   259  func parseSort(value interface{}, qid uint64) (*SortRequest, error) {
   260  
   261  	switch t := value.(type) {
   262  	case []interface{}:
   263  		if len(t) > 1 {
   264  			log.Errorf("qid=%d, Sort request has more than one requirement", qid)
   265  			return nil, errors.New("sort request has more than one requirement")
   266  		}
   267  		return processSortRequirements(t[0], qid)
   268  	}
   269  
   270  	log.Errorf("qid=%d, sort request is not a list", qid)
   271  	return nil, errors.New("sort request is not a list")
   272  }
   273  
   274  func processSortRequirements(value interface{}, qid uint64) (*SortRequest, error) {
   275  
   276  	switch sort := value.(type) {
   277  	case map[string]interface{}:
   278  		if len(sort) > 1 {
   279  			return nil, errors.New("sort request has more than one column")
   280  		}
   281  		for colName, conditions := range sort {
   282  			request := &SortRequest{
   283  				ColName: colName,
   284  			}
   285  			switch conds := conditions.(type) {
   286  			case map[string]interface{}:
   287  				order, ok := conds["order"]
   288  				if !ok {
   289  					request.Ascending = false // default to descending order
   290  				} else {
   291  					orderStr, ok := order.(string)
   292  					if !ok {
   293  						log.Errorf("qid=%d, order condition in sort is not a string", qid)
   294  						return nil, errors.New("order condition in sort is not a string")
   295  					}
   296  					if orderStr == "asc" {
   297  						request.Ascending = true
   298  					} else if orderStr == "desc" {
   299  						request.Ascending = false
   300  					} else {
   301  						log.Errorf("qid=%d, order condition is not `asc` or `desc`", qid)
   302  						return nil, errors.New("order condition is not `asc` or `desc`")
   303  					}
   304  				}
   305  			}
   306  			return request, nil
   307  		}
   308  	}
   309  	log.Errorf("qid=%d, sort condition is not a map", qid)
   310  	return nil, errors.New("sort condition is not a map")
   311  }
   312  
   313  func parseAggregations(json_body interface{}, qid uint64) (*QueryAggregators, error) {
   314  
   315  	queryAgg := &QueryAggregators{}
   316  	switch t := json_body.(type) {
   317  	case map[string]interface{}:
   318  		err := processAggregation(t, qid, queryAgg)
   319  		if err != nil {
   320  			return nil, err
   321  		}
   322  
   323  		var aggName string
   324  		for key := range t {
   325  			aggName = key
   326  		}
   327  		if queryAgg.GroupByRequest != nil {
   328  			queryAgg.GroupByRequest.AggName = aggName
   329  		} else if queryAgg.TimeHistogram != nil {
   330  			queryAgg.TimeHistogram.AggName = aggName
   331  		}
   332  
   333  		tempMeasureAggArray := make([]*MeasureAggregator, 0)
   334  		if queryAgg.GroupByRequest != nil && queryAgg.GroupByRequest.GroupByColumns != nil {
   335  			if queryAgg.GroupByRequest.MeasureOperations == nil {
   336  				for gIdx := range queryAgg.GroupByRequest.GroupByColumns {
   337  					var tempMeasureAgg = &MeasureAggregator{}
   338  					tempMeasureAgg.MeasureCol = queryAgg.GroupByRequest.GroupByColumns[gIdx]
   339  					tempMeasureAgg.MeasureFunc = Count
   340  					tempMeasureAggArray = append(tempMeasureAggArray, tempMeasureAgg)
   341  				}
   342  				queryAgg.GroupByRequest.MeasureOperations = append(queryAgg.GroupByRequest.MeasureOperations, tempMeasureAggArray...)
   343  			}
   344  		}
   345  
   346  		return queryAgg, nil
   347  	}
   348  	return nil, nil
   349  }
   350  
   351  func processAggregation(params map[string]interface{}, qid uint64, aggNode *QueryAggregators) error {
   352  	for key, value := range params {
   353  		switch aggInfo := value.(type) {
   354  		case map[string]interface{}:
   355  			for aggType, aggField := range aggInfo {
   356  				if isTypeStatisticFunction(aggType) {
   357  					err := processStatisticAggregation(aggType, aggField, key, aggNode)
   358  					if err != nil {
   359  						log.Errorf("QID: %d Error when processing statistic aggregation! %s", qid, err.Error())
   360  						return err
   361  					}
   362  				} else {
   363  					err := processNestedAggregation(aggType, aggField, key, qid, aggNode)
   364  					if err != nil {
   365  						log.Errorf("QID: %d Error when processing bucket aggregation! %s", qid, err.Error())
   366  						return err
   367  					}
   368  				}
   369  			}
   370  		}
   371  	}
   372  
   373  	return nil
   374  }
   375  
   376  func processNestedAggregation(aggType string, aggField interface{}, key string, qid uint64, aggNode *QueryAggregators) error {
   377  	switch aggType {
   378  	case "date_histogram":
   379  		err := processDateHistogram(aggField, qid, aggNode)
   380  		if err != nil {
   381  			return err
   382  		}
   383  		aggNode.TimeHistogram.AggName = key
   384  		return nil
   385  	case "terms":
   386  		err := processTermsHistogram(aggField, qid, aggNode)
   387  		if err != nil {
   388  			return err
   389  		}
   390  		aggNode.GroupByRequest.AggName = key
   391  		return nil
   392  	case "aggs", "aggregations":
   393  		switch subAgg := aggField.(type) {
   394  		case map[string]interface{}:
   395  			err := processAggregation(subAgg, qid, aggNode)
   396  			if err != nil {
   397  				return err
   398  			}
   399  			return nil
   400  		}
   401  		return errors.New("subaggregation is not a map")
   402  
   403  	case "histogram":
   404  		return errors.New("histogram aggregation is not supported")
   405  	case "filters":
   406  		return errors.New("filters aggregation is not supported")
   407  	default:
   408  		return fmt.Errorf("bucket key %+v is not supported", aggType)
   409  	}
   410  }
   411  
   412  func isTypeStatisticFunction(aggType string) bool {
   413  	_, err := aggTypeToAggregateFunction(aggType)
   414  	return err == nil
   415  }
   416  
   417  func aggTypeToAggregateFunction(aggType string) (AggregateFunctions, error) {
   418  	var aggFunc AggregateFunctions
   419  
   420  	if aggType == "avg" {
   421  		aggFunc = Avg
   422  	} else if aggType == "min" {
   423  		aggFunc = Min
   424  	} else if aggType == "max" {
   425  		aggFunc = Max
   426  	} else if aggType == "sum" {
   427  		aggFunc = Sum
   428  	} else if aggType == "cardinality" {
   429  		aggFunc = Cardinality
   430  	} else if aggType == "count" {
   431  		aggFunc = Count
   432  	} else {
   433  		return aggFunc, errors.New("unsupported statistic aggregation type")
   434  	}
   435  	return aggFunc, nil
   436  }
   437  
   438  func processStatisticAggregation(aggType string, params interface{}, name string, aggNode *QueryAggregators) error {
   439  
   440  	aggFunc, err := aggTypeToAggregateFunction(aggType)
   441  	if err != nil {
   442  		return err
   443  	}
   444  
   445  	switch aggInfo := params.(type) {
   446  	case map[string]interface{}:
   447  		if colName, ok := aggInfo["field"]; ok {
   448  			colStr, isStr := colName.(string)
   449  			if !isStr {
   450  				return errors.New("field is not a string for average")
   451  			}
   452  			if aggNode.GroupByRequest == nil {
   453  				aggNode.GroupByRequest = &GroupByRequest{}
   454  				aggNode.GroupByRequest.MeasureOperations = make([]*structs.MeasureAggregator, 0)
   455  			}
   456  			var tempMeasureAgg = &MeasureAggregator{}
   457  			tempMeasureAgg.MeasureCol = colStr
   458  			tempMeasureAgg.MeasureFunc = aggFunc
   459  			aggNode.GroupByRequest.MeasureOperations = append(aggNode.GroupByRequest.MeasureOperations, tempMeasureAgg)
   460  			return nil
   461  		}
   462  	}
   463  	return errors.New("no fields are defined for statistic")
   464  }
   465  
   466  // es terms aggregation is parsed into GroupByRequest (same as siglens GroupBy aggregation )
   467  func processTermsHistogram(params interface{}, qid uint64, aggNode *QueryAggregators) error {
   468  	switch t := params.(type) {
   469  	case map[string]interface{}:
   470  		// remove .raw from column names
   471  		for k, v := range t {
   472  			if strings.HasSuffix(k, ".raw") {
   473  				t[strings.TrimSuffix(k, ".raw")] = v
   474  				delete(t, k)
   475  			}
   476  		}
   477  		if aggNode.GroupByRequest == nil {
   478  			aggNode.GroupByRequest = &GroupByRequest{}
   479  		}
   480  		fieldName, ok := t["field"]
   481  		if !ok {
   482  			log.Errorf("qid=%d, Required key 'field' is missing for terms aggregation", qid)
   483  			return errors.New("required key 'field' is missing for terms aggregation")
   484  		}
   485  		fieldStr, ok := fieldName.(string)
   486  		if !ok {
   487  			log.Errorf("qid=%d, Required key 'field' is not a string for terms aggregation", qid)
   488  			return errors.New("required key 'field' is not a string for terms aggregation")
   489  		}
   490  		aggNode.GroupByRequest.GroupByColumns = append(aggNode.GroupByRequest.GroupByColumns, fieldStr)
   491  		size, ok := t["size"]
   492  		var finalSize = 10_000
   493  		if ok {
   494  			cVal, err := CreateDtypeEnclosure(size, qid)
   495  			if err != nil {
   496  				log.Errorf("qid=%d, Error extracting size limit! Defaulting to 10_000. Err: %v", qid, err)
   497  			} else {
   498  				if !cVal.IsNumeric() {
   499  					log.Errorf("qid=%d, Aggregation size limit is not numeric! Defaulting to 10_000. cVal: %+v", qid, cVal)
   500  				} else {
   501  					finalSize = int(cVal.SignedVal)
   502  				}
   503  			}
   504  		}
   505  		aggNode.GroupByRequest.BucketCount = finalSize
   506  		return nil
   507  	}
   508  	return errors.New("unable to extract terms histogram")
   509  }
   510  
   511  func processDateHistogram(params interface{}, qid uint64, aggNode *QueryAggregators) error {
   512  
   513  	switch t := params.(type) {
   514  	case map[string]interface{}:
   515  		if aggNode.TimeHistogram == nil {
   516  			aggNode.TimeHistogram = &TimeBucket{}
   517  		}
   518  		err := getIntervalForDateHistogram(aggNode.TimeHistogram, t)
   519  		if err != nil {
   520  			log.Errorf("qid=%d, Failed to get interval for date histogram %s, %s", qid, t, err.Error())
   521  			return errors.New("failed to get interval for date histogram")
   522  		}
   523  		_ = getBoundsForDateHistogram(aggNode.TimeHistogram, t["extended_bounds"])
   524  		return nil
   525  	}
   526  	return errors.New("unable to extract date histogram")
   527  }
   528  
   529  func getIntervalForDateHistogram(timeHist *TimeBucket, inVal map[string]interface{}) error {
   530  	if inVal == nil {
   531  		return errors.New("inVal was null")
   532  	}
   533  
   534  	var val interface{}
   535  	var ok bool
   536  
   537  	if val, ok = inVal["interval"]; !ok {
   538  		if val, ok = inVal["fixed_interval"]; !ok {
   539  			if val, ok = inVal["calendar_interval"]; !ok {
   540  				return errors.New("neither 'interval', 'fixed_interval' or 'calender_interval' was present")
   541  			}
   542  		}
   543  	}
   544  
   545  	strVal, ok := val.(string)
   546  	if !ok {
   547  		return errors.New("key `interval` is not a string")
   548  	}
   549  
   550  	runeStr := []rune(strVal)
   551  	for i := 0; i < len(runeStr); i++ {
   552  
   553  		if !unicode.IsDigit(runeStr[i]) {
   554  			numStr := string(runeStr[:i])
   555  			numFloat, err := strconv.ParseFloat(numStr, 64)
   556  			if err != nil {
   557  				return err
   558  			}
   559  
   560  			text := string(runeStr[i:])
   561  			switch text {
   562  			case "ms":
   563  				timeHist.IntervalMillis = uint64(numFloat)
   564  			case "s":
   565  				timeHist.IntervalMillis = uint64(numFloat) * 1000
   566  			case "m":
   567  				timeHist.IntervalMillis = uint64(numFloat) * 1000 * 60
   568  			case "h":
   569  				timeHist.IntervalMillis = uint64(numFloat) * 1000 * 60 * 60
   570  			case "d":
   571  				timeHist.IntervalMillis = uint64(numFloat) * 1000 * 60 * 60 * 24
   572  			case "w":
   573  				timeHist.IntervalMillis = uint64(numFloat) * 1000 * 60 * 60 * 24 * 7
   574  			case "M":
   575  				timeHist.IntervalMillis = uint64(numFloat) * 1000 * 60 * 60 * 24 * 7 * 4
   576  			case "q":
   577  				timeHist.IntervalMillis = uint64(numFloat) * 1000 * 60 * 60 * 24 * 7 * 4 * 3
   578  			case "y":
   579  				timeHist.IntervalMillis = uint64(numFloat) * 1000 * 60 * 60 * 24 * 7 * 4 * 3 * 4
   580  			default:
   581  				return errors.New("requested unit is not supported")
   582  			}
   583  			return nil
   584  		}
   585  	}
   586  	return errors.New("invalid interval request! No digits occur")
   587  }
   588  
   589  func getBoundsForDateHistogram(timeHist *TimeBucket, val interface{}) error {
   590  	if val == nil {
   591  		return errors.New("key `extended_bounds` not found")
   592  	}
   593  	switch time := val.(type) {
   594  	case map[string]interface{}:
   595  		maxVal, ok := time["max"]
   596  		if !ok {
   597  			return errors.New("`extended_bounds` does not have key max")
   598  		}
   599  
   600  		minVal, ok := time["min"]
   601  		if !ok {
   602  			return errors.New("`extended_bounds` does not have key min")
   603  		}
   604  
   605  		jsonNumMax, ok := maxVal.(json.Number)
   606  		if !ok {
   607  			return errors.New("invalid type for max val")
   608  		}
   609  		maxUint, err := strconv.ParseUint(jsonNumMax.String(), 10, 64)
   610  		if err != nil {
   611  			return err
   612  		}
   613  
   614  		jsonNumMin, ok := minVal.(json.Number)
   615  		if !ok {
   616  			return errors.New("invalid type for min val")
   617  		}
   618  		minUint, err := strconv.ParseUint(jsonNumMin.String(), 10, 64)
   619  		if err != nil {
   620  			return err
   621  		}
   622  		if !utils.IsTimeInMilli(maxUint) {
   623  			maxUint *= 1000
   624  		}
   625  		if !utils.IsTimeInMilli(minUint) {
   626  			minUint *= 1000
   627  		}
   628  		log.Infof("aggregation time histogram range: max %+v min %+v", maxUint, minUint)
   629  
   630  		timeHist.EndTime = maxUint
   631  		timeHist.StartTime = minUint
   632  
   633  	default:
   634  		log.Errorf("`extended_bounds` is not a map")
   635  		return errors.New("`extended_bounds` is not a map")
   636  	}
   637  	return nil
   638  }
   639  
   640  func parseQuery(json_body interface{}, qid uint64, isJaegerQuery bool) (*ASTNode, error) {
   641  	// var err error
   642  	switch t := json_body.(type) {
   643  	case map[string]interface{}:
   644  		for key, value := range t {
   645  			//		leafNode := &ASTNode{}
   646  			switch value.(type) {
   647  			case map[string]interface{}:
   648  				if key == "bool" {
   649  					leafNode, err := parseBool(value, qid, isJaegerQuery)
   650  					if err != nil {
   651  						log.Errorf("qid=%d, parseQuery: Error in parseQuery-parseBool: %v", qid, err)
   652  					}
   653  					return leafNode, err
   654  				} else if key == "match" {
   655  					leafNode, err := parseMatchScroll(value, qid)
   656  					if err != nil {
   657  						log.Errorf("qid=%d, parseQuery: Error in parseQuery-parseMatchScroll: %v", qid, err)
   658  					}
   659  					return leafNode, err
   660  				} else if key == "match_all" {
   661  					leafNode, err := parseMatchall(value, qid)
   662  					if err != nil {
   663  						log.Errorf("qid=%d, parseQuery: Error in parseQuery-parseMatchall: %v", qid, err)
   664  					}
   665  					return leafNode, err
   666  				} else if key == "match_phrase" {
   667  					leafNode, err := parseMatchPhrase(value, qid)
   668  					if err != nil {
   669  						log.Errorf("qid=%d, parseQuery: Error in parseQuery-parseMatchPhrase: %v", qid, err)
   670  					}
   671  					return leafNode, err
   672  				}
   673  			case []map[string]interface{}:
   674  				if key == "bool" {
   675  					leafNode, err := parseBool(value, qid, isJaegerQuery)
   676  					if err != nil {
   677  						log.Errorf("qid=%d, parseQuery: Error in parseQuery-parseBool: %v", qid, err)
   678  					}
   679  					return leafNode, err
   680  				}
   681  			case []interface{}:
   682  				return nil, errors.New("parseQuery: Invalid query,does not support array of values")
   683  			default:
   684  				return nil, errors.New("parseQuery: Invalid Bool query")
   685  			}
   686  		}
   687  	default:
   688  		return nil, errors.New("parseQuery: Invalid Bool query")
   689  	}
   690  	return nil, nil
   691  }
   692  
   693  /*
   694  Example Json_body for bool query
   695  
   696  	"bool": {
   697  		"must" : [
   698  			{"term" : { "user.id" : "kimchy" }},
   699  			{"term" : { "host.id" : "abc" }},
   700  		  ],
   701  		  "filter": {
   702  			"term" : { "tags" : "production" }
   703  		  }
   704  	}
   705  */
   706  func parseBool(json_body interface{}, qid uint64, isJaegerQuery bool) (*ASTNode, error) {
   707  	if json_body == nil {
   708  		err := fmt.Errorf("parseBool: Error parsing JSON expected a value, got: %v", json_body)
   709  		return nil, err
   710  	}
   711  	boolNode := &ASTNode{}
   712  	var err error
   713  	//set timeRange
   714  	boolNode.TimeRange = rutils.GetESDefaultQueryTimeRange()
   715  	switch t := json_body.(type) {
   716  	case map[string]interface{}:
   717  		for key, value := range t {
   718  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
   719  			switch key {
   720  			case "must", "filter":
   721  				andFilter, err := parseMustOrFilter(value, boolNode, qid, isJaegerQuery)
   722  				if err != nil {
   723  					return nil, err
   724  				}
   725  				if boolNode.AndFilterCondition == nil {
   726  					boolNode.AndFilterCondition = andFilter
   727  				} else {
   728  					boolNode.AndFilterCondition.JoinCondition(andFilter)
   729  				}
   730  			case "must_not":
   731  				filterCond, err := parseMustNot(value, boolNode, qid, isJaegerQuery)
   732  				if err != nil {
   733  					return nil, err
   734  				}
   735  				if boolNode.ExclusionFilterCondition == nil {
   736  					boolNode.ExclusionFilterCondition = filterCond
   737  				} else {
   738  					boolNode.ExclusionFilterCondition.JoinCondition(filterCond)
   739  				}
   740  			case "should":
   741  				shouldCond, err := parseShould(value, boolNode, qid, isJaegerQuery)
   742  				if err != nil {
   743  					return nil, err
   744  				}
   745  				if boolNode.OrFilterCondition == nil {
   746  					boolNode.OrFilterCondition = shouldCond
   747  				} else {
   748  					boolNode.OrFilterCondition.JoinCondition(shouldCond)
   749  				}
   750  			}
   751  		}
   752  	default:
   753  		err := fmt.Errorf("parseBool: Error parsing bool query, expected a map")
   754  		return nil, err
   755  	}
   756  	// Below if loop -> For exclusionFilterCriteria/must_not only query
   757  	if boolNode.ExclusionFilterCondition != nil && boolNode.AndFilterCondition == nil && boolNode.OrFilterCondition == nil {
   758  		colName := "*"
   759  		colValue := "*"
   760  		criteria := createTermFilterCriteria(colName, colValue, Equals, qid)
   761  		boolNode.AndFilterCondition = &Condition{FilterCriteria: []*FilterCriteria{criteria}}
   762  	}
   763  
   764  	return boolNode, err
   765  }
   766  
   767  /*
   768  Example Json_body for match_all query
   769  
   770  	"query": {
   771  			"match_all": {}
   772  		}
   773  */
   774  func parseMatchScroll(json_body interface{}, qid uint64) (*ASTNode, error) {
   775  	if json_body == nil {
   776  		err := fmt.Errorf("parseMatchScroll: Error parsing JSON expected a value, got: %v", json_body)
   777  		return nil, err
   778  	}
   779  	rootNode := &ASTNode{}
   780  	var err error
   781  	//set timeRange
   782  	rootNode.TimeRange = rutils.GetESDefaultQueryTimeRange()
   783  	criteria, err := parseMatch(json_body, qid)
   784  	if err != nil {
   785  		err := fmt.Errorf("parseMatchScroll: error creating criteria : %v", err.Error())
   786  		return nil, err
   787  	}
   788  	rootNode.AndFilterCondition = &Condition{FilterCriteria: criteria}
   789  	return rootNode, err
   790  }
   791  
   792  func parseMatchall(json_body interface{}, qid uint64) (*ASTNode, error) {
   793  	if json_body == nil {
   794  		err := fmt.Errorf("parseMatchall: Error parsing JSON expected a value, got: %v", json_body)
   795  		return nil, err
   796  	}
   797  	rootNode := &ASTNode{}
   798  	var err error
   799  	//set timeRange
   800  	rootNode.TimeRange = rutils.GetESDefaultQueryTimeRange()
   801  	colName := "*"
   802  	colValue := "*"
   803  	criteria := createTermFilterCriteria(colName, colValue, Equals, qid)
   804  	rootNode.AndFilterCondition = &Condition{FilterCriteria: []*FilterCriteria{criteria}}
   805  	return rootNode, err
   806  }
   807  
   808  func GetMatchAllASTNode(qid uint64) (*ASTNode, error) {
   809  	rootNode := &ASTNode{}
   810  	//set timeRange
   811  	rootNode.TimeRange = rutils.GetESDefaultQueryTimeRange()
   812  	colName := "*"
   813  	colValue := "*"
   814  
   815  	criteria := createTermFilterCriteria(colName, colValue, Equals, qid)
   816  	rootNode.AndFilterCondition = &Condition{FilterCriteria: []*FilterCriteria{criteria}}
   817  	return rootNode, nil
   818  }
   819  
   820  /*
   821  Example Json_body for filter query
   822  {
   823  	"filter": [
   824  			{ "term":  { "status": "published" }},
   825  			{ "range": { "publish_date": { "gte": "2015-01-01" }}}
   826  		  ]
   827  }
   828  */
   829  /*
   830  Example Json_body for must query
   831  {
   832  	"must" :
   833  		{"term" : { "user.id" : "kimchy" }}
   834  }
   835  */
   836  
   837  func parseMustOrFilter(json_body interface{}, boolNode *ASTNode, qid uint64, isJaegerQuery bool) (*Condition, error) {
   838  	if json_body == nil {
   839  		err := fmt.Errorf("parseMustOrFilter: Error parsing JSON expected a value, got: %v", json_body)
   840  		log.Errorf("qid=%d, parseMustOrFilter: Invalid json/query: %v", qid, err)
   841  	}
   842  	var currCondition *Condition
   843  	switch t := json_body.(type) {
   844  	case map[string]interface{}:
   845  		for key, value := range t {
   846  			if value == nil {
   847  				err := fmt.Errorf("parseMustOrFilter: Error parsing Filter query")
   848  				return nil, err
   849  			}
   850  			filtercond, err := parseLeafNodes(key, value, boolNode, qid, isJaegerQuery)
   851  			if err != nil {
   852  				return nil, err
   853  			}
   854  			if filtercond == nil {
   855  				continue
   856  			}
   857  			if currCondition == nil {
   858  				currCondition = filtercond
   859  			} else {
   860  				currCondition.JoinCondition(filtercond)
   861  			}
   862  
   863  		}
   864  	case []interface{}:
   865  		for _, nvalue := range json_body.([]interface{}) {
   866  			switch t := nvalue.(type) {
   867  			case map[string]interface{}:
   868  				for key, value := range t {
   869  					filtercond, err := parseLeafNodes(key, value, boolNode, qid, isJaegerQuery)
   870  					if err != nil {
   871  						return nil, err
   872  					}
   873  					if filtercond == nil {
   874  						continue
   875  					}
   876  					if currCondition == nil {
   877  						currCondition = filtercond
   878  					} else {
   879  						currCondition.JoinCondition(filtercond)
   880  					}
   881  				}
   882  			default:
   883  				err := fmt.Errorf("parseMustOrFilter: Error parsing Filter query")
   884  				return nil, err
   885  			}
   886  		}
   887  	default:
   888  		err := fmt.Errorf("parseMustOrFilter: Error parsing Filter query")
   889  		return nil, err
   890  	}
   891  	return currCondition, nil
   892  }
   893  
   894  /*
   895  Example Json_body for nested query
   896  {
   897    "query": {
   898  		  "bool": {
   899  			"must": {
   900  			  "nested": {
   901  				"path": "tags",
   902  				"query": {
   903  				  "bool": {
   904  					"must": [
   905  					  {
   906  						"match": {
   907  						  "tags.key": {
   908  							"query": "sampler.type"
   909  						  }
   910  						}
   911  					  },
   912  					  {
   913  						"regexp": {
   914  						  "tags.value": {
   915  							"value": "const"
   916  						  }
   917  						}
   918  					  }
   919  					]
   920  				  }
   921  				}
   922  			  }
   923  			}
   924  		  }
   925  		}
   926  	  }
   927  */
   928  
   929  func parseNestedDictArray(json_body interface{}, qid uint64, path string) (string, *DtypeEnclosure, error) {
   930  
   931  	if json_body == nil {
   932  		err := fmt.Errorf("qid=%d, parseNestedDictArray: Error parsing JSON, expected a value, got nil", qid)
   933  		log.Error(err)
   934  		return "", nil, err
   935  	}
   936  	var matchKey string
   937  	matchValue := &DtypeEnclosure{}
   938  	var err error
   939  	switch t := json_body.(type) {
   940  	case map[string]interface{}:
   941  		for _, nestedValue := range t {
   942  			switch nestedValue := nestedValue.(type) {
   943  			case map[string]interface{}:
   944  				matchKey, matchValue, err = parseNestedDictArray(nestedValue, qid, path)
   945  				if err != nil {
   946  					return "", nil, err
   947  				}
   948  			case []interface{}:
   949  				for _, nv := range nestedValue {
   950  					switch qv := nv.(type) {
   951  					case map[string]interface{}:
   952  						for k, v := range qv {
   953  							switch v := v.(type) {
   954  							case map[string]interface{}:
   955  								if k == "match" {
   956  									for mk := range v {
   957  										if mk == path+".key" {
   958  											for _, nv := range v {
   959  												switch nv := nv.(type) {
   960  												case map[string]interface{}:
   961  													for qk, qv := range nv {
   962  														switch qv := qv.(type) {
   963  														case string:
   964  															if qk == "query" {
   965  																matchKey = qv
   966  															}
   967  														default:
   968  															return "", nil, errors.New("parseNestedDictArray: Invalid fields in nested match query")
   969  														}
   970  													}
   971  												default:
   972  													return "", nil, errors.New("parseNestedDictArray: Invalid fields in nested match query")
   973  												}
   974  											}
   975  										}
   976  									}
   977  								} else if k == "regexp" {
   978  									for mk := range v {
   979  										if mk == path+".value" {
   980  											for _, nv := range v {
   981  												switch nv := nv.(type) {
   982  												case map[string]interface{}:
   983  													for qk, qv := range nv {
   984  														if qk == "value" {
   985  															matchValue, err = CreateDtypeEnclosure(qv, qid)
   986  															if err != nil {
   987  																log.Errorf("qid=%d, parseNestedDictArray: error creating DtypeEnclosure: %+v", qid, err)
   988  															}
   989  														}
   990  													}
   991  												default:
   992  													return "", nil, errors.New("parseNestedDictArray: Invalid fields in nested match query")
   993  												}
   994  											}
   995  										}
   996  									}
   997  								}
   998  							default:
   999  								return "", nil, errors.New("parseNestedDictArray: Invalid fields in nested match query")
  1000  							}
  1001  						}
  1002  					default:
  1003  						return "", nil, errors.New("parseNestedDictArray: Invalid fields in nested match query")
  1004  					}
  1005  				}
  1006  			case string:
  1007  				path = nestedValue
  1008  			default:
  1009  				return "", nil, errors.New("parseNestedDictArray: Invalid fields in nested match query")
  1010  			}
  1011  		}
  1012  	default:
  1013  		return "", nil, errors.New("parseNestedDictArray: Invalid fields in nested match query")
  1014  	}
  1015  	return matchKey, matchValue, nil
  1016  }
  1017  
  1018  /*
  1019  Example Json_body for should query
  1020  {
  1021  	"should": [
  1022  			{ "term":  { "status": "published" }},
  1023  			{ "range": { "publish_date": { "gte": "2015-01-01" }}}
  1024  		  ]
  1025  }
  1026  */
  1027  
  1028  func parseShould(json_body interface{}, boolNode *ASTNode, qid uint64, isJaegerReq bool) (*Condition, error) {
  1029  	if json_body == nil {
  1030  		err := fmt.Errorf("parseShould: Error parsing JSON expected a value, got: %v", json_body)
  1031  		log.Errorf("qid=%d, parseShould: Invalid json/query: %v", qid, err)
  1032  	}
  1033  	var currCondition *Condition
  1034  	switch t := json_body.(type) {
  1035  	case map[string]interface{}:
  1036  		for key, value := range t {
  1037  			if value == nil {
  1038  				err := fmt.Errorf("parseShould: Error parsing Filter query")
  1039  				return nil, err
  1040  			}
  1041  			filtercond, err := parseLeafNodes(key, value, boolNode, qid, isJaegerReq)
  1042  			if err != nil {
  1043  				return nil, err
  1044  			}
  1045  			if filtercond == nil {
  1046  				continue
  1047  			}
  1048  			if currCondition == nil {
  1049  				currCondition = filtercond
  1050  			} else {
  1051  				currCondition.JoinCondition(filtercond)
  1052  			}
  1053  		}
  1054  	case []interface{}:
  1055  		for _, nvalue := range json_body.([]interface{}) {
  1056  			switch t := nvalue.(type) {
  1057  			case map[string]interface{}:
  1058  				for key, value := range t {
  1059  					filtercond, err := parseLeafNodes(key, value, boolNode, qid, isJaegerReq)
  1060  					if err != nil {
  1061  						return nil, err
  1062  					}
  1063  					if filtercond == nil {
  1064  						continue
  1065  					}
  1066  					if currCondition == nil {
  1067  						currCondition = filtercond
  1068  					} else {
  1069  						currCondition.JoinCondition(filtercond)
  1070  					}
  1071  				}
  1072  			default:
  1073  				err := fmt.Errorf("parseShould: Error parsing should query")
  1074  				return nil, err
  1075  			}
  1076  		}
  1077  	default:
  1078  		err := fmt.Errorf("parseShould: Error parsing should query")
  1079  		return nil, err
  1080  	}
  1081  	return currCondition, nil
  1082  }
  1083  
  1084  /*
  1085  Example Json_body for must not query
  1086  "must_not" : {
  1087  	"range" : {"age" : { "gte" : 10, "lte" : 20 }
  1088  	}
  1089    }, */
  1090  
  1091  func parseMustNot(json_body interface{}, boolNode *ASTNode, qid uint64, isJaegerQuery bool) (*Condition, error) {
  1092  	if json_body == nil {
  1093  		err := fmt.Errorf("parseMustNot: Error parsing JSON expected a value, got: %v", json_body)
  1094  		log.Errorf("qid=%d, parseMustNot: Invalid json/query: %v", qid, err)
  1095  		return nil, err
  1096  	}
  1097  	var currCondition *Condition
  1098  	switch t := json_body.(type) {
  1099  	case map[string]interface{}:
  1100  		for key, value := range t {
  1101  			if value == nil {
  1102  				err := fmt.Errorf("parseMustNot: Error parsing Filter query")
  1103  				return nil, err
  1104  			}
  1105  			filtercond, err := parseLeafNodes(key, value, boolNode, qid, isJaegerQuery)
  1106  			if err != nil {
  1107  				return nil, err
  1108  			}
  1109  			if filtercond == nil {
  1110  				continue
  1111  			}
  1112  			if currCondition == nil {
  1113  				currCondition = filtercond
  1114  			} else {
  1115  				currCondition.JoinCondition(filtercond)
  1116  			}
  1117  		}
  1118  	case []interface{}:
  1119  		for _, nvalue := range json_body.([]interface{}) {
  1120  			switch t := nvalue.(type) {
  1121  			case map[string]interface{}:
  1122  				for key, value := range t {
  1123  					filtercond, err := parseLeafNodes(key, value, boolNode, qid, isJaegerQuery)
  1124  					if err != nil {
  1125  						return nil, err
  1126  					}
  1127  					if filtercond == nil {
  1128  						continue
  1129  					}
  1130  					if currCondition == nil {
  1131  						currCondition = filtercond
  1132  					} else {
  1133  						currCondition.JoinCondition(filtercond)
  1134  					}
  1135  				}
  1136  			default:
  1137  				err := fmt.Errorf("parseMustNot: Error parsing must_not query")
  1138  				return nil, err
  1139  			}
  1140  		}
  1141  	default:
  1142  		err := fmt.Errorf("parseMustNot: Error parsing must_not query")
  1143  		return nil, err
  1144  	}
  1145  	return currCondition, nil
  1146  }
  1147  
  1148  func parseLeafNodes(key, value interface{}, boolNode *ASTNode, qid uint64, isJaegerQuery bool) (*Condition, error) {
  1149  	switch key {
  1150  	case "term":
  1151  		criteria, err := parseTerm(value, qid)
  1152  		if err != nil {
  1153  			log.Errorf("qid=%d, parseLeafNodes error: %v", qid, err)
  1154  			return nil, err
  1155  		}
  1156  		return &Condition{
  1157  			FilterCriteria: []*FilterCriteria(criteria),
  1158  		}, nil
  1159  
  1160  	case "range":
  1161  		criteria, tRange, err := parseRange(value, qid, isJaegerQuery)
  1162  		if tRange != nil {
  1163  			boolNode.TimeRange = tRange
  1164  		}
  1165  		if err != nil {
  1166  			log.Errorf("qid=%d, parseRange error: %v", qid, err)
  1167  			return nil, err
  1168  		}
  1169  		return &Condition{
  1170  			FilterCriteria: []*FilterCriteria(criteria),
  1171  		}, nil
  1172  
  1173  	case "match":
  1174  		criteria, err := parseMatch(value, qid)
  1175  		if err != nil {
  1176  			log.Errorf("qid=%d, parseMatch error: %v", qid, err)
  1177  			return nil, err
  1178  		}
  1179  		return &Condition{
  1180  			FilterCriteria: []*FilterCriteria(criteria),
  1181  		}, nil
  1182  	case "nested":
  1183  
  1184  		var path string
  1185  		andFilterCondition := make([]*FilterCriteria, 0)
  1186  
  1187  		switch t := value.(type) {
  1188  		case map[string]interface{}:
  1189  			for nestedKey, nestedValue := range t {
  1190  				switch nestedValue := nestedValue.(type) {
  1191  				case string:
  1192  					if nestedKey == "path" {
  1193  						path = nestedValue
  1194  					}
  1195  				case map[string]interface{}:
  1196  					mk, mv, err := parseNestedDictArray(value, qid, path)
  1197  					if err != nil {
  1198  						log.Errorf("qid=%d, parseNestedDictArray error: %v", qid, err)
  1199  						return nil, err
  1200  					}
  1201  					criteria := FilterCriteria{MatchFilter: &MatchFilter{
  1202  						MatchColumn: path,
  1203  						MatchDictArray: &MatchDictArrayRequest{
  1204  							MatchKey:   []byte(mk),
  1205  							MatchValue: mv,
  1206  						},
  1207  						MatchType: MATCH_DICT_ARRAY},
  1208  					}
  1209  					andFilterCondition = append(andFilterCondition, &criteria)
  1210  					return &Condition{
  1211  						FilterCriteria: []*FilterCriteria(andFilterCondition),
  1212  					}, nil
  1213  				}
  1214  			}
  1215  		}
  1216  		return nil, nil
  1217  	case "multi_match":
  1218  		criteria, err := parseMultiMatch_nested(value, qid)
  1219  		if err != nil {
  1220  			log.Errorf("qid=%d, parseMultiMatch error: %v", qid, err)
  1221  			return nil, err
  1222  		}
  1223  		return criteria, nil
  1224  	case "match_all":
  1225  		criteria, err := parseMatchall_nested(value, qid)
  1226  		if err != nil {
  1227  			log.Errorf("qid=%d, parseMatchall_nested error: %v", qid, err)
  1228  			return nil, err
  1229  		}
  1230  		return &Condition{
  1231  			FilterCriteria: []*FilterCriteria(criteria),
  1232  		}, nil
  1233  	case "match_phrase":
  1234  		criteria, err := parseMatchPhrase_nested(value, qid)
  1235  		if err != nil {
  1236  			log.Errorf("qid=%d, parseMatchall_nested error: %v", qid, err)
  1237  			return nil, err
  1238  		}
  1239  		return &Condition{
  1240  			FilterCriteria: []*FilterCriteria(criteria),
  1241  		}, nil
  1242  	case "terms":
  1243  		criteria, err := parseTerms(value, qid)
  1244  		if err != nil {
  1245  			log.Errorf("qid=%d, parseTerms error: %v", qid, err)
  1246  			return nil, err
  1247  		}
  1248  		return &Condition{
  1249  			FilterCriteria: []*FilterCriteria(criteria),
  1250  		}, nil
  1251  
  1252  	case "prefix":
  1253  		criteria, err := parsePrefix(value, qid)
  1254  		if err != nil {
  1255  			log.Errorf("qid=%d, parsePrefix error: %v", qid, err)
  1256  			return nil, err
  1257  		}
  1258  		return &Condition{
  1259  			FilterCriteria: []*FilterCriteria(criteria),
  1260  		}, nil
  1261  
  1262  	case "regexp":
  1263  		criteria, err := parseRegexp(value, qid)
  1264  		if err != nil {
  1265  			log.Errorf("qid=%d, parseRegexp error: %v", qid, err)
  1266  			return nil, err
  1267  		}
  1268  		return &Condition{
  1269  			FilterCriteria: []*FilterCriteria(criteria),
  1270  		}, nil
  1271  
  1272  	case "wildcard":
  1273  		criteria, err := parseWildcard(value, qid)
  1274  		if err != nil {
  1275  			log.Errorf("qid=%d, parseWildcard error: %v", qid, err)
  1276  			return nil, err
  1277  		}
  1278  		return &Condition{
  1279  			FilterCriteria: []*FilterCriteria(criteria),
  1280  		}, nil
  1281  
  1282  		// todo hack, the simple_query_string supports bunch more stuff
  1283  		// but just to get the kibana interop going, using a simpler parsing of it
  1284  	case "query_string", "simple_query_string":
  1285  		qsSubNode, criteria, err := parseQuerystring(value, qid)
  1286  		// andCond, orCond, err := parseQuerystring(value, qid)
  1287  		if err != nil {
  1288  			log.Errorf("qid=%d, parseQuerystring error: %v", qid, err)
  1289  			return nil, err
  1290  		}
  1291  		if qsSubNode != nil {
  1292  			return &Condition{
  1293  				NestedNodes: []*ASTNode{qsSubNode},
  1294  			}, nil
  1295  		} else {
  1296  			return &Condition{
  1297  				FilterCriteria: []*FilterCriteria(criteria),
  1298  			}, nil
  1299  		}
  1300  	case "exists":
  1301  		criteria, err := parseExists(value, qid)
  1302  		if err != nil {
  1303  			log.Errorf("qid=%d, parseExists error: %v", qid, err)
  1304  			return nil, err
  1305  		}
  1306  		return &Condition{
  1307  			FilterCriteria: []*FilterCriteria(criteria),
  1308  		}, nil
  1309  	case "bool":
  1310  		boolSubNode, err := parseBool(value, qid, isJaegerQuery)
  1311  		if err != nil {
  1312  			log.Errorf("qid=%d, parseBool error: %v", qid, err)
  1313  			return nil, err
  1314  		}
  1315  		return &Condition{
  1316  			NestedNodes: []*ASTNode{boolSubNode},
  1317  		}, nil
  1318  	default:
  1319  		err := fmt.Errorf("error parsing Must/Filter query")
  1320  		log.Errorf("qid=%d, parseLeafNodes: can't parse unknown key=%v", qid, key)
  1321  		return nil, err
  1322  	}
  1323  }
  1324  
  1325  func processQueryStringMap(colName string, colValue interface{}, qid uint64) (*Condition, error) {
  1326  
  1327  	var filtercond *Condition
  1328  	kvMap := make(map[string]interface{})
  1329  	if colValue != "" {
  1330  		if colName == "" {
  1331  			colName = "*"
  1332  			if strings.Contains(colValue.(string), "\"") {
  1333  				colValue = strings.ReplaceAll(strings.TrimSpace(colValue.(string)), "\"", "")
  1334  				kvMap[colName] = colValue
  1335  
  1336  				criteria := createMatchPhraseFilterCriteria(colName, colValue, And, qid)
  1337  				filtercond = &Condition{
  1338  					FilterCriteria: []*FilterCriteria{criteria},
  1339  				}
  1340  			} else {
  1341  				colValue = strings.ReplaceAll(strings.TrimSpace(colValue.(string)), "\"", "")
  1342  				kvMap[colName] = colValue
  1343  
  1344  				criteria, err := parseMatch(kvMap, qid)
  1345  				if err != nil {
  1346  					log.Errorf("parseMatch error: %v", err)
  1347  					return nil, err
  1348  				}
  1349  				filtercond = &Condition{
  1350  					FilterCriteria: []*FilterCriteria(criteria),
  1351  				}
  1352  
  1353  			}
  1354  		} else {
  1355  			colValue = strings.ReplaceAll(strings.TrimSpace(colValue.(string)), "\"", "")
  1356  			kvMap[colName] = colValue
  1357  			criteria, err := parseTerm(kvMap, qid)
  1358  			if err != nil {
  1359  				log.Errorf("parseTerm error: %v", err)
  1360  				return nil, err
  1361  			}
  1362  			filtercond = &Condition{
  1363  				FilterCriteria: []*FilterCriteria(criteria),
  1364  			}
  1365  
  1366  		}
  1367  	}
  1368  	return filtercond, nil
  1369  }
  1370  
  1371  //few example query string patterns
  1372  // col1 : val1
  1373  //(col1: val2) AND val2
  1374  //col1: (val1 OR val2)
  1375  
  1376  func convertAndParseQuerystring(value interface{}, qid uint64) (*ASTNode, []*FilterCriteria, error) {
  1377  	// var query = "eventType:pageview AND geo_country:KR"
  1378  	if value == nil {
  1379  		err := fmt.Errorf("parseBool: Error parsing JSON expected a value, got: %v", value)
  1380  		return nil, nil, err
  1381  	}
  1382  	boolNode := &ASTNode{}
  1383  	boolNode.TimeRange = rutils.GetESDefaultQueryTimeRange()
  1384  
  1385  	var currCondition, filtercond *Condition
  1386  	var orCurrCondition *Condition
  1387  	var colName string
  1388  
  1389  	token_openBrackets := strings.Split(value.(string), "(")
  1390  
  1391  	for _, openBracket := range token_openBrackets {
  1392  		token_closeBrackets := strings.Split(openBracket, ")")
  1393  
  1394  		for ic, closeBracket := range token_closeBrackets {
  1395  			//reset colName after first group of tokens inside brackets () have been processed with colName = col1
  1396  			//col1: (val1 OR val2) AND val3
  1397  			if ic > 0 {
  1398  				colName = ""
  1399  			}
  1400  			ands := strings.Split(closeBracket, " AND ")
  1401  			for _, and := range ands {
  1402  				//no brackets in the query , then reset colName after each sub expression separated by AND
  1403  				// col1:val1 AND val2
  1404  				if len(token_openBrackets) == 1 {
  1405  					colName = ""
  1406  				}
  1407  				if strings.TrimSpace(and) != "" {
  1408  					//first process all the sub expressions joined by AND
  1409  					if !strings.Contains(and, "OR") {
  1410  						var err error
  1411  						if strings.Contains(and, ":") {
  1412  							//col:val query string
  1413  							kv := strings.Split(and, ":")
  1414  							if len(kv) > 1 {
  1415  								colName = strings.TrimSpace(string(kv[0]))
  1416  								colValue := strings.TrimSpace(kv[1])
  1417  								filtercond, err = processQueryStringMap(colName, colValue, qid)
  1418  								if err != nil {
  1419  									log.Errorf("processMap error: %v", err)
  1420  									return nil, nil, err
  1421  								}
  1422  								if currCondition == nil {
  1423  									currCondition = filtercond
  1424  								} else {
  1425  									currCondition.JoinCondition(filtercond)
  1426  								}
  1427  							}
  1428  						} else {
  1429  							// free text search
  1430  							filtercond, err = processQueryStringMap(colName, strings.TrimSpace(and), qid)
  1431  							if err != nil {
  1432  								log.Errorf("processMap error: %v", err)
  1433  								return nil, nil, err
  1434  							}
  1435  							if currCondition == nil {
  1436  								currCondition = filtercond
  1437  							} else {
  1438  								currCondition.JoinCondition(filtercond)
  1439  							}
  1440  						}
  1441  					}
  1442  				}
  1443  				ors := strings.Split(and, " OR ")
  1444  				if len(ors) > 1 {
  1445  					for _, or := range ors {
  1446  						//no brackets in the query , then reset colName after each sub expression separated by OR
  1447  						// col1:val1 OR val2
  1448  						if len(token_openBrackets) == 1 {
  1449  							colName = ""
  1450  						}
  1451  						if !strings.Contains(or, "AND") {
  1452  							var err error
  1453  							if strings.TrimSpace(or) != "" {
  1454  								if strings.Contains(or, ":") {
  1455  									kv := strings.Split(or, ":")
  1456  									if len(kv) > 1 {
  1457  										colName = strings.TrimSpace(string(kv[0]))
  1458  										colValue := strings.TrimSpace(kv[1])
  1459  										filtercond, err = processQueryStringMap(colName, colValue, qid)
  1460  										if err != nil {
  1461  											log.Errorf("processMap error: %v", err)
  1462  											return nil, nil, err
  1463  										}
  1464  										if orCurrCondition == nil {
  1465  											orCurrCondition = filtercond
  1466  										} else {
  1467  											orCurrCondition.JoinCondition(filtercond)
  1468  										}
  1469  									}
  1470  								} else {
  1471  									filtercond, err = processQueryStringMap(colName, strings.TrimSpace(or), qid)
  1472  									if err != nil {
  1473  										log.Errorf("processMap error: %v", err)
  1474  										return nil, nil, err
  1475  									}
  1476  									if orCurrCondition == nil {
  1477  										orCurrCondition = filtercond
  1478  									} else {
  1479  										orCurrCondition.JoinCondition(filtercond)
  1480  									}
  1481  								}
  1482  							}
  1483  						}
  1484  					}
  1485  				}
  1486  			}
  1487  		}
  1488  	}
  1489  	//complex query string
  1490  	if strings.Contains(value.(string), " AND ") || strings.Contains(value.(string), " OR ") || strings.Contains(value.(string), "\"") {
  1491  
  1492  		if boolNode.AndFilterCondition == nil {
  1493  			boolNode.AndFilterCondition = currCondition
  1494  		} else {
  1495  			boolNode.AndFilterCondition.JoinCondition(currCondition)
  1496  		}
  1497  		if boolNode.OrFilterCondition == nil {
  1498  			boolNode.OrFilterCondition = orCurrCondition
  1499  		} else {
  1500  			boolNode.OrFilterCondition.JoinCondition(orCurrCondition)
  1501  		}
  1502  		return boolNode, nil, nil
  1503  	} else {
  1504  		return nil, currCondition.FilterCriteria, nil
  1505  
  1506  	}
  1507  }
  1508  
  1509  /*
  1510  Example Json_body for term query
  1511  "term": {
  1512    <<column-name>>: {
  1513  	"value": <<column-value>>,
  1514    }
  1515  }
  1516  OR
  1517  "term" : { <<column-name>> : <<column-value>> }
  1518  */
  1519  
  1520  func parseTerm(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  1521  	if json_body == nil {
  1522  		err := fmt.Errorf("parseTerm: Error parsing JSON expected a value, got: %v", json_body)
  1523  		return nil, err
  1524  	}
  1525  	switch t := json_body.(type) {
  1526  	case map[string]interface{}:
  1527  		for key, value := range t {
  1528  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  1529  			andFilterCondition := make([]*FilterCriteria, 0)
  1530  			switch innerTerm := value.(type) {
  1531  			case string:
  1532  				criteria := createTermFilterCriteria(key, value, Equals, qid)
  1533  				andFilterCondition = append(andFilterCondition, criteria)
  1534  			case bool:
  1535  				criteria := createTermFilterCriteria(key, value.(bool), Equals, qid)
  1536  				andFilterCondition = append(andFilterCondition, criteria)
  1537  			case json.Number:
  1538  				criteria := createTermFilterCriteria(key, value.(json.Number), Equals, qid)
  1539  				andFilterCondition = append(andFilterCondition, criteria)
  1540  			case map[string]interface{}:
  1541  				if len(innerTerm) > 1 {
  1542  					if qVal, ok := innerTerm["value"]; !ok {
  1543  						return nil, fmt.Errorf("parseTerm: Invalid Term query, nested query not found in %+v", innerTerm)
  1544  					} else {
  1545  						criteria := createTermFilterCriteria(key, qVal, Equals, qid)
  1546  						andFilterCondition = append(andFilterCondition, criteria)
  1547  					}
  1548  				} else {
  1549  					for _, v := range innerTerm {
  1550  						criteria := createTermFilterCriteria(key, v, Equals, qid)
  1551  						andFilterCondition = append(andFilterCondition, criteria)
  1552  					}
  1553  					break
  1554  				}
  1555  			case []interface{}:
  1556  				return nil, errors.New("parseTerm: Invalid Term query, [term] query does not support array of values")
  1557  			default:
  1558  				return nil, errors.New("parseTerm: Invalid Term query")
  1559  			}
  1560  			return andFilterCondition, nil
  1561  		}
  1562  	default:
  1563  		return nil, errors.New("parseTerm: Invalid Term query")
  1564  	}
  1565  	return nil, nil
  1566  }
  1567  
  1568  /*
  1569  "range": {
  1570    <<column-name>>: {
  1571  	"gte" || "gt": <<lower-bound>>
  1572  	"lte" || "lt": <<upper-bound>>,
  1573    }
  1574  }
  1575  // at least one condition is present
  1576  // case1: only one condition is present (not timestamp key)
  1577  "range":{
  1578  	"age":{
  1579  		"gte": 10
  1580  		}
  1581  }
  1582  // case2: both gt(e) and lt(e) exist
  1583  "range":{
  1584  	"age":{
  1585  		"gte": 10,
  1586  		"lte": 20
  1587  		}
  1588  }
  1589  */
  1590  
  1591  func parseRange(json_body interface{}, qid uint64, isJaegerQuery bool) ([]*FilterCriteria, *dtu.TimeRange, error) {
  1592  	if json_body == nil {
  1593  		err := fmt.Errorf("parseRange: Error parsing JSON expected a value, got: %v", json_body)
  1594  		return nil, nil, err
  1595  	}
  1596  	switch t := json_body.(type) {
  1597  	case map[string]interface{}:
  1598  		for key, value := range t {
  1599  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  1600  			andFilterCondition := make([]*FilterCriteria, 0)
  1601  			switch t := value.(type) {
  1602  			case map[string]interface{}:
  1603  				if len(t) < 1 {
  1604  					return nil, nil, errors.New("parseRange: Invalid Range query")
  1605  				}
  1606  				tsKey := config.GetTimeStampKey()
  1607  				if isJaegerQuery {
  1608  					tsKey = "startTimeMillis"
  1609  				}
  1610  				if key == tsKey {
  1611  					tRange := new(dtu.TimeRange)
  1612  					for nestedKey, nestedValue := range t {
  1613  						if nestedKey == "format" {
  1614  							//todo Handle timestamp format
  1615  							log.Infof("qid=%d, parseRange:Handle timestamp format", qid)
  1616  						} else {
  1617  							val, _ := getEpochFromRangeExprValue(nestedValue, qid)
  1618  							switch nestedKey {
  1619  							case "gt":
  1620  								tRange.StartEpochMs = uint64(val)
  1621  							case "gte":
  1622  								tRange.StartEpochMs = uint64(val)
  1623  							case "lt":
  1624  								tRange.EndEpochMs = uint64(val)
  1625  							case "lte":
  1626  								tRange.EndEpochMs = uint64(val)
  1627  							case "from":
  1628  								tRange.StartEpochMs = uint64(val)
  1629  							case "to":
  1630  								tRange.EndEpochMs = uint64(val)
  1631  							case "include_upper", "include_lower":
  1632  							default:
  1633  								log.Infof("qid=%d, parseRange: invalid range option %+v", qid, nestedKey)
  1634  							}
  1635  						}
  1636  					}
  1637  					return nil, tRange, nil
  1638  				} else {
  1639  					for nestedKey, nestedValue := range t {
  1640  						var opr FilterOperator
  1641  						switch nestedKey {
  1642  						case "gt":
  1643  							opr = GreaterThan
  1644  						case "gte":
  1645  							opr = GreaterThanOrEqualTo
  1646  						case "lt":
  1647  							opr = LessThan
  1648  						case "lte":
  1649  							opr = LessThanOrEqualTo
  1650  						case "from":
  1651  							opr = GreaterThanOrEqualTo
  1652  						case "to":
  1653  							opr = LessThanOrEqualTo
  1654  						case "include_upper", "include_lower":
  1655  						default:
  1656  							log.Infof("qid=%d, parseRange: invalid range option %+v", qid, nestedKey)
  1657  							continue
  1658  						}
  1659  						criteria := createTermFilterCriteria(key, nestedValue, opr, qid)
  1660  						andFilterCondition = append(andFilterCondition, criteria)
  1661  					}
  1662  					return andFilterCondition, nil, nil
  1663  
  1664  				}
  1665  			case []interface{}:
  1666  				return nil, nil, errors.New("parseRange: Invalid Range query, range query does not support array of values")
  1667  			default:
  1668  				return nil, nil, errors.New("parseRange: Invalid Range query")
  1669  			}
  1670  		}
  1671  	default:
  1672  		return nil, nil, errors.New("parseRange: Invalid Range query")
  1673  	}
  1674  	return nil, nil, nil
  1675  }
  1676  
  1677  func getEpochFromRangeExprValue(incoming interface{}, qid uint64) (int64, error) {
  1678  
  1679  	switch incomingtype := incoming.(type) {
  1680  	case json.Number:
  1681  		val, _ := (incomingtype).Int64()
  1682  		return val, nil
  1683  	case string:
  1684  		valTime, err := time.Parse(time.RFC3339, incomingtype)
  1685  		if err != nil {
  1686  			log.Errorf("qid=%d, getEpochFromRangeExprValue: failed to parse time, in=%v, err=%v", qid, incomingtype, err)
  1687  			return 0, err
  1688  		}
  1689  		return valTime.UnixNano() / int64(time.Millisecond), nil
  1690  	}
  1691  
  1692  	return 0, errors.New("getEpochFromRangeExprValue bad input")
  1693  }
  1694  
  1695  /*
  1696  "match": {
  1697    <<column-name>>: {
  1698  	"query": <<column-value>>,
  1699  		"operator": "and/or" (optional and defaults to "or")
  1700    }
  1701  }
  1702  
  1703  OR
  1704  
  1705  "match": {
  1706  	 <<column-name>>: <<column-value>>,
  1707  	 "operator": "and/or" (optional and defaults to "or")
  1708  }
  1709  
  1710  */
  1711  
  1712  func parseMatch(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  1713  	if json_body == nil {
  1714  		err := fmt.Errorf("qid=%d, parseMatch: Error parsing JSON, expected a value, got nil", qid)
  1715  		log.Error(err)
  1716  		return nil, err
  1717  	}
  1718  
  1719  	andFilterCondition := make([]*FilterCriteria, 0)
  1720  	var opr = Or
  1721  	var colName string
  1722  	var colValue interface{}
  1723  	switch t := json_body.(type) {
  1724  	case map[string]interface{}:
  1725  		for key, value := range t {
  1726  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  1727  			switch t := value.(type) {
  1728  			case string:
  1729  				if key == "operator" && value == "and" {
  1730  					opr = And
  1731  				} else if key == "operator" && value == "or" {
  1732  					opr = Or
  1733  				} else {
  1734  					colValue = value
  1735  					colName = key
  1736  				}
  1737  			case map[string]interface{}:
  1738  				if len(t) == 0 {
  1739  					return nil, errors.New("invalid Match query")
  1740  				}
  1741  				for nestedKey, nestedValue := range t {
  1742  					if nestedKey == "query" {
  1743  						colValue = nestedValue
  1744  					} else if nestedKey == "operator" && nestedValue == "and" {
  1745  						opr = And
  1746  					} else if nestedKey == "operator" && nestedValue == "or" {
  1747  						opr = Or
  1748  					} else {
  1749  						return nil, errors.New("parseMatch: Invalid Match query")
  1750  					}
  1751  				}
  1752  				colName = key
  1753  			case []interface{}:
  1754  				return nil, errors.New("parseMatch: Invalid Match query")
  1755  			default:
  1756  				return nil, errors.New("parseMatch: Invalid Match query")
  1757  			}
  1758  		}
  1759  	default:
  1760  		return nil, errors.New("parseMatch: Invalid Match query")
  1761  	}
  1762  	criteria := createMatchFilterCriteria(colName, colValue, opr, qid)
  1763  	andFilterCondition = append(andFilterCondition, criteria)
  1764  	return andFilterCondition, nil
  1765  
  1766  }
  1767  
  1768  /*
  1769  Example Json_body for match_phrase query
  1770  
  1771  	"query": {
  1772  			"match_phrase": {
  1773  				"foo": "Hello World"
  1774  			  }
  1775  		}
  1776  */
  1777  func parseMatchPhrase(json_body interface{}, qid uint64) (*ASTNode, error) {
  1778  	if json_body == nil {
  1779  		err := errors.New("parseMatchPhrase: Error parsing JSON expected a value, got nil")
  1780  		return nil, err
  1781  	}
  1782  	rootNode := &ASTNode{}
  1783  	var err error
  1784  	//set timeRange
  1785  	rootNode.TimeRange = rutils.GetESDefaultQueryTimeRange()
  1786  	opr := And
  1787  
  1788  	var colName string
  1789  	var colValue interface{}
  1790  	switch t := json_body.(type) {
  1791  	case map[string]interface{}:
  1792  		for key, value := range t {
  1793  			switch value.(type) {
  1794  			case string:
  1795  				colValue = value
  1796  				colName = key
  1797  			default:
  1798  				err = fmt.Errorf("qid=%d parseMatch: Invalid Match_phrase query, value expected to be string, got %v", qid, value)
  1799  				log.Error(err)
  1800  				return nil, err
  1801  			}
  1802  		}
  1803  	default:
  1804  		err = fmt.Errorf("parseMatch: Invalid Match_phrase query, unexpected json body %v", json_body)
  1805  		return nil, err
  1806  	}
  1807  	criteria := createMatchPhraseFilterCriteria(colName, colValue, opr, qid)
  1808  	rootNode.AndFilterCondition = &Condition{FilterCriteria: []*FilterCriteria{criteria}}
  1809  	return rootNode, err
  1810  }
  1811  
  1812  func parseMatchPhrase_nested(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  1813  	if json_body == nil {
  1814  		err := errors.New("parseMatchPhrase: Error parsing JSON expected a value, got nil")
  1815  		return nil, err
  1816  	}
  1817  	andFilterCondition := make([]*FilterCriteria, 0)
  1818  	var err error
  1819  	opr := And
  1820  
  1821  	var colName string
  1822  	var colValue interface{}
  1823  	switch t := json_body.(type) {
  1824  	case map[string]interface{}:
  1825  		for key, value := range t {
  1826  			switch value.(type) {
  1827  			case string:
  1828  				colValue = value
  1829  				colName = key
  1830  			default:
  1831  				err = fmt.Errorf("qid=%d parseMatch: Invalid Match_phrase query, value expected to be string, got %v", qid, value)
  1832  				log.Error(err)
  1833  				return nil, err
  1834  			}
  1835  		}
  1836  	default:
  1837  		err = fmt.Errorf("parseMatch: Invalid Match_phrase query, unexpected json body %v", json_body)
  1838  		return nil, err
  1839  	}
  1840  	criteria := createMatchPhraseFilterCriteria(colName, colValue, opr, qid)
  1841  	andFilterCondition = append(andFilterCondition, criteria)
  1842  	return andFilterCondition, nil
  1843  }
  1844  
  1845  /*
  1846  "query": {
  1847    "bool": {
  1848  	"must":
  1849  	  {
  1850  		"match_all": {
  1851  		}
  1852  	  }
  1853  	}
  1854    }
  1855  */
  1856  
  1857  func parseMatchall_nested(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  1858  	andFilterCondition := make([]*FilterCriteria, 0)
  1859  	//set timeRange
  1860  	colName := "*"
  1861  	colValue := "*"
  1862  	criteria := createTermFilterCriteria(colName, colValue, Equals, qid)
  1863  	andFilterCondition = append(andFilterCondition, criteria)
  1864  	return andFilterCondition, nil
  1865  
  1866  }
  1867  
  1868  /*
  1869  	"query_string": {
  1870  		  "query": "(<<column-value1>>) OR (<<column-value2>>)",
  1871  		  "default_field": <<column-name>>
  1872  				"default_operator": OR/AND
  1873  		}
  1874  
  1875  or
  1876  
  1877  	query_string": {
  1878  		  "query": "<<column-name>>: <<column-value>>",
  1879  		  "analyze_wildcard": true,
  1880  		  "default_field": "*"
  1881  		}
  1882  */
  1883  func parseQuerystring(json_body interface{}, qid uint64) (*ASTNode, []*FilterCriteria, error) {
  1884  	if json_body == nil {
  1885  		err := fmt.Errorf("parseQuerystring: Error parsing JSON expected a value, got: %v", json_body)
  1886  		return nil, nil, err
  1887  	}
  1888  
  1889  	// andFilterCondition := make([]*FilterCriteria, 0)
  1890  	boolNode := &ASTNode{}
  1891  	var err error
  1892  	//set timeRange
  1893  	boolNode.TimeRange = rutils.GetESDefaultQueryTimeRange()
  1894  
  1895  	var opr = Or
  1896  	switch t := json_body.(type) {
  1897  	case map[string]interface{}:
  1898  		for key, value := range t {
  1899  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  1900  			switch valtype := value.(type) {
  1901  			case bool:
  1902  				if key == "analyze_wildcard" {
  1903  					log.Infof("qid=%d, parseQuerystring: Ignoring query_string analyze_wildcard", qid)
  1904  				}
  1905  			case []interface{}:
  1906  				if key == "fields" {
  1907  					// fieldsArray := valtype
  1908  					log.Infof("qid=%d, parseQuerystring: Ignoring query_string fields", valtype...)
  1909  				} else {
  1910  					log.Errorf("qid=%d, parseQuerystring: Invalid query_string, value.(type)=%T, key=%v", qid, value, key)
  1911  					return nil, nil, errors.New("parseQuerystring: Invalid query_string")
  1912  				}
  1913  			case string:
  1914  				switch key {
  1915  				case "default_operator":
  1916  					if value == "AND" {
  1917  						opr = And
  1918  					}
  1919  					log.Infof("qid=%d, parseQuerystring: Ignoring query_string default_operator %v", qid, opr)
  1920  				case "default_field":
  1921  					colName := value.(string)
  1922  					log.Infof("parseQuerystring: Ignoring query_string default_field %v", colName)
  1923  				case "query":
  1924  					var filterCond []*FilterCriteria
  1925  					boolNode, filterCond, err = convertAndParseQuerystring(value, qid)
  1926  					if err != nil {
  1927  						log.Errorf("convertAndParseQuerystring: failed to parse queryString, in=%v, err=%v", value.(string), err)
  1928  						return nil, nil, err
  1929  					}
  1930  					return boolNode, filterCond, nil
  1931  				default:
  1932  					log.Infof("qid=%d, parseQuerystring: query_string format not supported", qid)
  1933  				}
  1934  			default:
  1935  				log.Errorf("qid=%d, parseQuerystring: Invalid query_string, unhandled value.(type)=%T, key=%v", qid, value, key)
  1936  				return nil, nil, errors.New("parseQuerystring: Invalid query_string")
  1937  			}
  1938  
  1939  		}
  1940  	default:
  1941  		log.Errorf("qid=%d, parseQuerystring: unhandled v.type=%v", qid, t)
  1942  		return nil, nil, errors.New("parseQuerystring: Invalid query_string query")
  1943  	}
  1944  	return boolNode, nil, nil
  1945  
  1946  }
  1947  
  1948  func parseExists(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  1949  	if json_body == nil {
  1950  		log.Errorf("qid=%d, parseExists: got nil json body", qid)
  1951  		return nil, errors.New("read nil json body for exists condition")
  1952  	}
  1953  
  1954  	switch v := json_body.(type) {
  1955  	case map[string]interface{}:
  1956  		colName, ok := v["field"]
  1957  		if !ok {
  1958  			log.Errorf("qid=%d, required parameter 'field' is not present for exists query", qid)
  1959  			return nil, errors.New("required parameter 'field' is not present for exists query")
  1960  		}
  1961  		colStr, ok := colName.(string)
  1962  		if !ok {
  1963  			log.Errorf("qid=%d, parameter 'field' is not a string", qid)
  1964  			return nil, errors.New("parameter 'field' is not a string")
  1965  		}
  1966  		colStr = strings.TrimSuffix(colStr, ".raw") // remove any .raw postfix from column name
  1967  		existsCriteria := &FilterCriteria{
  1968  			ExpressionFilter: &ExpressionFilter{
  1969  				LeftInput: &FilterInput{
  1970  					Expression: &Expression{
  1971  						LeftInput: &ExpressionInput{
  1972  							ColumnName: colStr,
  1973  						},
  1974  					},
  1975  				},
  1976  				FilterOperator: IsNotNull,
  1977  			},
  1978  		}
  1979  		return []*FilterCriteria{existsCriteria}, nil
  1980  	default:
  1981  		log.Errorf("qid=%d, parseExists: Exists parameter is not a map", qid)
  1982  		return nil, errors.New("parseExists: Exists parameter is not a map")
  1983  	}
  1984  }
  1985  
  1986  /*
  1987  "terms": {
  1988    <<column-name>>: {
  1989  	[ <<column-value1>> , <<column-value2>>]
  1990  	}
  1991  }
  1992  
  1993  */
  1994  
  1995  func parseTerms(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  1996  	if json_body == nil {
  1997  		err := fmt.Errorf("parseTerms: Error parsing JSON expected a value, got: %v", json_body)
  1998  		return nil, err
  1999  	}
  2000  	andFilterCondition := make([]*FilterCriteria, 0)
  2001  
  2002  	var opr = Or
  2003  	switch t := json_body.(type) {
  2004  	case map[string]interface{}:
  2005  		for key, value := range t {
  2006  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  2007  			switch valtype := value.(type) {
  2008  			case []interface{}:
  2009  				if len(valtype) == 0 {
  2010  					return nil, errors.New("parseTerms : Invalid Terms query")
  2011  				}
  2012  				criteria := createTermsFilterCriteria(key, valtype, opr)
  2013  				andFilterCondition = append(andFilterCondition, criteria)
  2014  				return andFilterCondition, nil
  2015  			default:
  2016  				return nil, errors.New("parseTerms: Invalid Terms query")
  2017  			}
  2018  		}
  2019  	default:
  2020  		return nil, errors.New("parseTerms: Invalid Terms query")
  2021  	}
  2022  	return nil, nil
  2023  }
  2024  
  2025  /*
  2026  Example Json_body for prefix query
  2027  "prefix": {
  2028    <<column-name>>: {
  2029  	"value": <<column-value>>,
  2030    }
  2031  }
  2032  OR
  2033  "prefix" : { <<column-name>> : <<column-value>> }
  2034  */
  2035  
  2036  func parsePrefix(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  2037  	if json_body == nil {
  2038  		err := fmt.Errorf("parsePrefix: Error parsing JSON expected a value, got: %v", json_body)
  2039  		return nil, err
  2040  	}
  2041  	andFilterCondition := make([]*FilterCriteria, 0)
  2042  	switch t := json_body.(type) {
  2043  	case map[string]interface{}:
  2044  		for key, value := range t {
  2045  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  2046  			switch nt := value.(type) {
  2047  
  2048  			case string:
  2049  				criteria := createTermFilterCriteria(key, value.(string)+"*", Equals, qid)
  2050  				andFilterCondition = append(andFilterCondition, criteria)
  2051  				return andFilterCondition, nil
  2052  			case json.Number:
  2053  				criteria := createTermFilterCriteria(key, value.(json.Number)+"*", Equals, qid)
  2054  				andFilterCondition = append(andFilterCondition, criteria)
  2055  				return andFilterCondition, nil
  2056  			case map[string]interface{}:
  2057  				if len(t) > 1 {
  2058  					return nil, errors.New("parsePrefix:Invalid Prefix query len(t) > 1")
  2059  				}
  2060  				for _, v := range nt {
  2061  					switch vtype := v.(type) {
  2062  					case string:
  2063  						criteria := createTermFilterCriteria(key, vtype+"*", Equals, qid)
  2064  						andFilterCondition = append(andFilterCondition, criteria)
  2065  						return andFilterCondition, nil
  2066  
  2067  					default:
  2068  						return nil, errors.New("parsePrefix: Invalid Prefix query")
  2069  					}
  2070  				}
  2071  			case []interface{}:
  2072  				return nil, errors.New("parsePrefix: Invalid Prefix query")
  2073  			default:
  2074  
  2075  				return nil, errors.New("parsePrefix: Invalid Prefix query")
  2076  			}
  2077  		}
  2078  		return nil, errors.New("parsePrefix: Invalid Prefix query")
  2079  	}
  2080  	return nil, nil
  2081  }
  2082  
  2083  /*
  2084  Example Json_body for regexp query
  2085  "regexp": {
  2086    <<column-name>>: {
  2087  	"value": <<regex>>,
  2088    }
  2089  }
  2090  */
  2091  
  2092  func parseRegexp(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  2093  	if json_body == nil {
  2094  		err := fmt.Errorf("parseRegexp: Error parsing JSON expected a value, got: %v", json_body)
  2095  		return nil, err
  2096  	}
  2097  
  2098  	switch t := json_body.(type) {
  2099  	case map[string]interface{}:
  2100  		for key, value := range t {
  2101  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  2102  			andFilterCondition := make([]*FilterCriteria, 0)
  2103  
  2104  			switch t := value.(type) {
  2105  			case map[string]interface{}:
  2106  				for nestedKey, nestedValue := range t {
  2107  					if nestedKey == "value" {
  2108  						switch nestedvaltype := nestedValue.(type) {
  2109  						case string:
  2110  							criteria := createTermFilterCriteria(key, nestedvaltype, Equals, qid)
  2111  							andFilterCondition = append(andFilterCondition, criteria)
  2112  							return andFilterCondition, nil
  2113  						case json.Number:
  2114  							criteria := createTermFilterCriteria(key, nestedvaltype, Equals, qid)
  2115  							andFilterCondition = append(andFilterCondition, criteria)
  2116  							return andFilterCondition, nil
  2117  						default:
  2118  							return nil, errors.New("parseRegexp: Invalid regexp query")
  2119  						}
  2120  					}
  2121  				}
  2122  			case []interface{}:
  2123  				return nil, errors.New("parseRegexp: Invalid Regexp query")
  2124  			default:
  2125  				return nil, errors.New("parseRegexp: Invalid Regexp query")
  2126  			}
  2127  		}
  2128  		return nil, errors.New("parseRegexp: Invalid Regexp query")
  2129  	}
  2130  	return nil, nil
  2131  }
  2132  
  2133  /*
  2134  Example Json_body for wildcard query
  2135  "wildcard": {
  2136    <<column-name>>: {
  2137  	"value": <<regex>>,
  2138    }
  2139  }
  2140  */
  2141  
  2142  func parseWildcard(json_body interface{}, qid uint64) ([]*FilterCriteria, error) {
  2143  	if json_body == nil {
  2144  		err := fmt.Errorf("parseWildcard: Error parsing JSON expected a value, got: %v", json_body)
  2145  		return nil, err
  2146  	}
  2147  
  2148  	switch t := json_body.(type) {
  2149  	case map[string]interface{}:
  2150  		for key, value := range t {
  2151  			key = strings.TrimSuffix(key, ".raw") // remove any .raw postfix from column name
  2152  			andFilterCondition := make([]*FilterCriteria, 0)
  2153  
  2154  			switch t := value.(type) {
  2155  			case map[string]interface{}:
  2156  				if len(t) > 1 {
  2157  					return nil, errors.New("parseWildcard: Invalid wildcard query")
  2158  				}
  2159  				for nestedKey, nestedValue := range t {
  2160  					if nestedKey == "value" {
  2161  						switch nestedvaltype := nestedValue.(type) {
  2162  						case string:
  2163  							criteria := createTermFilterCriteria(key, nestedvaltype, Equals, qid)
  2164  							andFilterCondition = append(andFilterCondition, criteria)
  2165  							return andFilterCondition, nil
  2166  						case json.Number:
  2167  							criteria := createTermFilterCriteria(key, nestedvaltype, Equals, qid)
  2168  							andFilterCondition = append(andFilterCondition, criteria)
  2169  							return andFilterCondition, nil
  2170  						default:
  2171  							return nil, errors.New("parseWildcard: Invalid wildcard query")
  2172  						}
  2173  					}
  2174  				}
  2175  			case []interface{}:
  2176  				return nil, errors.New("parseWildcard: Invalid wildcard query")
  2177  			default:
  2178  				return nil, errors.New("parseWildcard: Invalid wildcard query")
  2179  			}
  2180  		}
  2181  		return nil, errors.New("parseWildcard: Invalid wildcard query")
  2182  	}
  2183  	return nil, nil
  2184  }
  2185  
  2186  func createTermFilterCriteria(k interface{}, v interface{}, opr FilterOperator, qid uint64) *FilterCriteria {
  2187  	cVal, err := CreateDtypeEnclosure(v, qid)
  2188  	if err != nil {
  2189  		log.Errorf("qid=%d, createTermFilterCriteria: error creating DtypeEnclosure: %+v", qid, err)
  2190  	}
  2191  	criteria := FilterCriteria{ExpressionFilter: &ExpressionFilter{
  2192  		LeftInput: &FilterInput{Expression: &Expression{
  2193  			LeftInput: &ExpressionInput{ColumnName: k.(string)}}},
  2194  		FilterOperator: opr,
  2195  		RightInput: &FilterInput{Expression: &Expression{
  2196  			LeftInput: &ExpressionInput{ColumnValue: cVal}}}}}
  2197  
  2198  	return &criteria
  2199  }
  2200  
  2201  func createMatchFilterCriteria(k, v interface{}, opr LogicalOperator, qid uint64) *FilterCriteria {
  2202  	var rtInput string
  2203  	switch vtype := v.(type) {
  2204  	case json.Number:
  2205  		rtInput = string(vtype)
  2206  	case string:
  2207  		rtInput = vtype
  2208  	default:
  2209  		log.Errorf("qid=%d, createMatchFilterCriteria: invalid value ", qid)
  2210  	}
  2211  	words := strings.Split(rtInput, " ")
  2212  	var matchWords = make([][]byte, 0)
  2213  	for _, word := range words {
  2214  		word = strings.TrimSpace(word)
  2215  		if word != "" {
  2216  			matchWords = append(matchWords, []byte(word))
  2217  		}
  2218  	}
  2219  
  2220  	_, ok := k.(string)
  2221  	if !ok {
  2222  		log.Errorf("qid=%d, createMatchFilterCriteria: invalid type for key %+v", qid, k)
  2223  		return nil
  2224  	}
  2225  
  2226  	criteria := FilterCriteria{MatchFilter: &MatchFilter{
  2227  		MatchColumn:   k.(string),
  2228  		MatchWords:    matchWords,
  2229  		MatchOperator: opr}}
  2230  
  2231  	return &criteria
  2232  }
  2233  
  2234  func createMatchPhraseFilterCriteria(k, v interface{}, opr LogicalOperator, qid uint64) *FilterCriteria {
  2235  	//match_phrase value will always be string
  2236  	var rtInput = strings.TrimSpace(v.(string))
  2237  	var matchWords = make([][]byte, 0)
  2238  	for _, word := range strings.Split(rtInput, " ") {
  2239  		matchWords = append(matchWords, [][]byte{[]byte(word)}...)
  2240  	}
  2241  
  2242  	criteria := FilterCriteria{MatchFilter: &MatchFilter{
  2243  		MatchColumn:   k.(string),
  2244  		MatchWords:    matchWords,
  2245  		MatchOperator: opr,
  2246  		MatchPhrase:   []byte(rtInput),
  2247  		MatchType:     MATCH_PHRASE}}
  2248  
  2249  	return &criteria
  2250  }
  2251  func createTermsFilterCriteria(k interface{}, val []interface{}, opr LogicalOperator) *FilterCriteria {
  2252  	var matchWords = make([][]byte, 0)
  2253  	for _, v := range val {
  2254  		matchWords = append(matchWords, [][]byte{[]byte(v.(string))}...)
  2255  	}
  2256  
  2257  	criteria := FilterCriteria{MatchFilter: &MatchFilter{
  2258  		MatchColumn:   k.(string),
  2259  		MatchWords:    matchWords,
  2260  		MatchOperator: opr}}
  2261  
  2262  	return &criteria
  2263  
  2264  }
  2265  
  2266  /*
  2267  "multi_match" : {
  2268        "query" : "quick brown",
  2269  	  "type":       "phrase",
  2270        "fields" : [ "subject", "message" ]
  2271      }
  2272  
  2273  OR
  2274  
  2275  "multi_match" : {
  2276        "query":      "quick brown f",
  2277        "type":       "phrase_prefix",
  2278        "fields":     [ "subject", "message" ]
  2279      }
  2280  
  2281  */
  2282  
  2283  func parseMultiMatch_nested(json_body interface{}, qid uint64) (*Condition, error) {
  2284  	if json_body == nil {
  2285  		err := errors.New("parseMatchPhrase: Error parsing JSON expected a value, got nil")
  2286  		return nil, err
  2287  	}
  2288  
  2289  	if json_body == nil {
  2290  		err := fmt.Errorf("qid=%d, parseMultiMatch: Error parsing JSON, expected a value, got nil", qid)
  2291  		log.Error(err)
  2292  		return nil, err
  2293  	}
  2294  	var opr = Or
  2295  	var matchType string
  2296  	var matchFields = make([]string, 0)
  2297  
  2298  	var colValue interface{}
  2299  	switch t := json_body.(type) {
  2300  	case map[string]interface{}:
  2301  		for nestedKey, nestedValue := range t {
  2302  			if nestedKey == "query" {
  2303  				colValue = nestedValue.(string)
  2304  			} else if nestedKey == "type" {
  2305  				matchType = nestedValue.(string)
  2306  			} else if nestedKey == "fields" {
  2307  				switch nvaltype := nestedValue.(type) {
  2308  				case []interface{}:
  2309  					for _, v := range nvaltype {
  2310  						switch v := v.(type) {
  2311  						case string:
  2312  							matchFields = append(matchFields, []string{v}...)
  2313  						default:
  2314  							return nil, errors.New("parseMultiMatch: Invalid fields in multi_match query")
  2315  						}
  2316  					}
  2317  				default:
  2318  					return nil, errors.New("parseMultiMatch: Invalid multi_match query")
  2319  				}
  2320  			} else if nestedKey == "operator" && nestedValue == "and" {
  2321  				opr = And
  2322  			} else if nestedKey == "operator" && nestedValue == "or" {
  2323  				opr = Or
  2324  			}
  2325  		}
  2326  		if matchType == "" || colValue == nil {
  2327  			return nil, errors.New("parseMultiMatch: Invalid multi_match query")
  2328  		}
  2329  		filterCondition := createMultiMatchFilterCriteria(matchFields, colValue, matchType, opr, qid)
  2330  		return filterCondition, nil
  2331  	default:
  2332  		return nil, errors.New("parseMultiMatch: Invalid multi_match query")
  2333  	}
  2334  
  2335  }
  2336  
  2337  func createMultiMatchFilterCriteria(matchFields []string, colValue interface{}, matchType string, opr LogicalOperator, qid uint64) *Condition {
  2338  	var colName string
  2339  	filterCondition := make([]*FilterCriteria, 0)
  2340  	if len(matchFields) == 0 {
  2341  		matchFields = append(matchFields, "*")
  2342  	}
  2343  	if matchType == "phrase_prefix" {
  2344  		temp := strings.ReplaceAll(strings.TrimSpace(colValue.(string)), ".", "")
  2345  		colValue = temp + ".*"
  2346  		for _, colName = range matchFields {
  2347  			criteria := createTermFilterCriteria(colName, colValue, Equals, qid)
  2348  			filterCondition = append(filterCondition, criteria)
  2349  		}
  2350  		return &Condition{
  2351  			FilterCriteria: []*FilterCriteria(filterCondition),
  2352  		}
  2353  	} else if matchType == "phrase" {
  2354  		for _, colName = range matchFields {
  2355  			criteria := createMatchPhraseFilterCriteria(colName, colValue, opr, qid)
  2356  			filterCondition = append(filterCondition, criteria)
  2357  		}
  2358  		return &Condition{
  2359  			FilterCriteria: []*FilterCriteria(filterCondition),
  2360  		}
  2361  	} else if matchType == "best_fields" || matchType == "most_fields" {
  2362  		allFieldConditions := make([]*FilterCriteria, 0)
  2363  		for _, colName = range matchFields {
  2364  			criteria := createMatchFilterCriteria(colName, colValue, opr, qid)
  2365  			allFieldConditions = append(allFieldConditions, criteria)
  2366  		}
  2367  		fieldASTNode := &ASTNode{
  2368  			OrFilterCondition: &Condition{
  2369  				FilterCriteria: []*FilterCriteria(allFieldConditions),
  2370  			},
  2371  		}
  2372  		return &Condition{
  2373  			NestedNodes: []*ASTNode{fieldASTNode},
  2374  		}
  2375  	}
  2376  	return &Condition{
  2377  		FilterCriteria: []*FilterCriteria(filterCondition),
  2378  	}
  2379  }