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 }