github.com/siglens/siglens@v0.0.0-20240328180423-f7ce9ae441ed/pkg/ast/pipesearch/searchQuery.peg (about) 1 { 2 package pipesearch 3 import ( 4 "strconv" 5 "github.com/siglens/siglens/pkg/segment/structs" 6 "github.com/siglens/siglens/pkg/segment/utils" 7 "github.com/siglens/siglens/pkg/ast" 8 "fmt" 9 ) 10 // helper method to exfiltrate pigeon's generated error type 11 func getParseError(err error) error { 12 switch ev := err.(type) { 13 case errList: 14 if pe, ok := ev[0].(*parserError); ok { 15 return &ast.ParseError{ 16 Inner: pe.Inner, 17 Line: pe.pos.line, 18 Column: pe.pos.col, 19 Offset: pe.pos.offset, 20 Prefix: pe.prefix, 21 Expected: pe.expected, 22 } 23 } 24 } 25 return err 26 } 27 28 } 29 30 Start <- maggs:measureAggsList? EOF { 31 var q ast.QueryStruct 32 if maggs !=nil { 33 q.PipeCommands = maggs.(*structs.QueryAggregators) 34 } 35 return q, nil 36 } / groupBy:groupByList? space? lim:Limit? EOF { 37 var q ast.QueryStruct 38 if groupBy != nil { 39 q.PipeCommands = groupBy.(*structs.QueryAggregators) 40 q.PipeCommands.BucketLimit = groupBy.(*structs.QueryAggregators).BucketLimit 41 } 42 return q, nil 43 44 } / query:Query? aggs:AggClause? EOF { 45 var q ast.QueryStruct 46 if query !=nil{ 47 q.SearchFilter = query.(*ast.Node) 48 } 49 if aggs !=nil { 50 q.PipeCommands = aggs.(*structs.QueryAggregators) 51 } 52 return q, nil 53 } / query:Query? EOF { 54 var q ast.QueryStruct 55 if query !=nil{ 56 q.SearchFilter = query.(*ast.Node) 57 } 58 return q, nil 59 } / aggs:AggClause? EOF { 60 var q ast.QueryStruct 61 if aggs !=nil { 62 q.PipeCommands = aggs.(*structs.QueryAggregators) 63 } 64 return q, nil 65 } 66 67 Query <- _ clause:OrClause _ { 68 return clause, nil 69 } 70 71 /**** 72 NODES 73 *****/ 74 75 OrClause <- lhs:AndClause space logicalOR space rhs:OrClause { 76 return & ast.Node { 77 NodeType: ast.NodeOr, 78 Left: lhs.(*ast.Node), 79 Right: rhs.(*ast.Node), 80 }, nil 81 } / AndClause 82 83 84 measureAggsList <- space? first:MeasureAggClause rest:( space? ',' space? MeasureAggClause )* space? { 85 return ast.GetMeasureAggsTokens(first, rest, 3), nil 86 } 87 88 groupByList <- space? first:MeasureAggClause rest:( space? ',' space? MeasureAggClause )* space? GroupBy cols:(ColList)? space? lim:Limit? { 89 limit := int(3000) 90 if lim != nil { 91 limit = int(lim.(int64)) 92 } 93 return ast.GetGroupByTokens(cols, first, rest, 3, limit), nil 94 } 95 96 Limit <- "limit" space first:Identifier{ 97 limit, err := strconv.ParseInt(first.(string), 10, 64) 98 if err != nil { 99 return nil, err 100 } 101 return limit, err 102 } 103 104 105 MeasureAggClause <- space? funcs:MeasureAggsFunc '(' cols:Identifier ')' { 106 107 tempMeasureAgg := &structs.MeasureAggregator{} 108 tempMeasureAgg.MeasureCol = cols.(string) 109 tempMeasureAgg.MeasureFunc = funcs.(utils.AggregateFunctions) 110 return tempMeasureAgg, nil 111 } 112 113 114 AggClause <- opPipe space? Column space newCol:Identifier space? '=' space? oldCol:Identifier { 115 aggNode := &structs.QueryAggregators{} 116 aggNode.PipeCommandType = structs.OutputTransformType 117 aggNode.OutputTransforms = &structs.OutputTransforms{} 118 aggNode.OutputTransforms.OutputColumns = &structs.ColumnsRequest{} 119 aggNode.OutputTransforms.OutputColumns.RenameColumns = make(map[string]string) 120 aggNode.OutputTransforms.OutputColumns.RenameColumns[oldCol.(string)]= newCol.(string) 121 return aggNode, nil 122 } 123 / opPipe space? Column space cols:ColList { 124 aggNode := &structs.QueryAggregators{} 125 aggNode.PipeCommandType = structs.OutputTransformType 126 aggNode.OutputTransforms = &structs.OutputTransforms{} 127 aggNode.OutputTransforms.OutputColumns = &structs.ColumnsRequest{} 128 aggNode.OutputTransforms.OutputColumns.IncludeColumns = cols.([]string) 129 return aggNode, nil 130 } 131 / opPipe space? Column space '-' space cols:ColList { 132 aggNode := &structs.QueryAggregators{} 133 aggNode.PipeCommandType = structs.OutputTransformType 134 aggNode.OutputTransforms = &structs.OutputTransforms{} 135 aggNode.OutputTransforms.OutputColumns = &structs.ColumnsRequest{} 136 aggNode.OutputTransforms.OutputColumns.ExcludeColumns = cols.([]string) 137 return aggNode, nil 138 } 139 / opPipe space? maggs:measureAggsList EOF{ 140 aggNode := &structs.QueryAggregators{} 141 aggNode = maggs.(*structs.QueryAggregators) 142 return aggNode, nil 143 } 144 / opPipe space? groupBy:groupByList space? lim:Limit? EOF{ 145 aggNode := &structs.QueryAggregators{} 146 aggNode = groupBy.(*structs.QueryAggregators) 147 return aggNode, nil 148 } 149 / opPipe space? Let space newCol:Identifier space? '=' space? '('? space? lhs:Identifier space? operation:LetOpr 150 space? rhs:LetIdentifier space? ')'? { 151 aggNode := &structs.QueryAggregators{} 152 aggNode.PipeCommandType = structs.OutputTransformType 153 aggNode.OutputTransforms = &structs.OutputTransforms{} 154 aggNode.OutputTransforms.LetColumns = &structs.LetColumnsRequest{} 155 aggNode.OutputTransforms.LetColumns.NewColName = newCol.(string) 156 aggNode.OutputTransforms.LetColumns.SingleColRequest = &structs.SingleColLetRequest{} 157 aggNode.OutputTransforms.LetColumns.SingleColRequest.CName = lhs.(string) 158 aggNode.OutputTransforms.LetColumns.SingleColRequest.Oper = operation.(utils.LogicalAndArithmeticOperator) 159 aggNode.OutputTransforms.LetColumns.SingleColRequest.Value = rhs.(*utils.DtypeEnclosure) 160 return aggNode, nil 161 } 162 / opPipe space? Let space newCol:Identifier space? '=' space? '('? space? lhs:Identifier space? operation:LetOpr 163 space? rhs:Identifier space? ')'? { 164 aggNode := &structs.QueryAggregators{} 165 aggNode.PipeCommandType = structs.OutputTransformType 166 aggNode.OutputTransforms = &structs.OutputTransforms{} 167 aggNode.OutputTransforms.LetColumns = &structs.LetColumnsRequest{} 168 aggNode.OutputTransforms.LetColumns.NewColName = newCol.(string) 169 aggNode.OutputTransforms.LetColumns.MultiColsRequest = &structs.MultiColLetRequest{} 170 aggNode.OutputTransforms.LetColumns.MultiColsRequest.LeftCName = lhs.(string) 171 aggNode.OutputTransforms.LetColumns.MultiColsRequest.Oper = operation.(utils.LogicalAndArithmeticOperator) 172 aggNode.OutputTransforms.LetColumns.MultiColsRequest.RightCName = rhs.(string) 173 return aggNode, nil 174 } 175 176 MeasureAggsFunc <- mfunc: ("avg" / "min" / "max" / "sum" / "cardinality" / "count" ){ 177 aggFunc, _ := ast.AggTypeToAggregateFunction(string(c.text)) 178 return aggFunc, nil 179 } 180 181 182 Column <- "columns" 183 184 GroupBy <- "groupby" 185 186 Let <- "let" 187 188 LetOpr <- [>] '=' { 189 return utils.LetGreaterThanOrEqualTo, nil 190 } / '>' { 191 return utils.LetGreaterThan, nil 192 } / [<] '=' { 193 return utils.LetLessThanOrEqualTo, nil 194 } / '<' { 195 return utils.LetLessThan, nil 196 } / [=] '=' { 197 return utils.LetEquals, nil 198 } / [!] '=' { 199 return utils.LetNotEquals, nil 200 } / '+' { 201 return utils.LetAdd, nil 202 } / '-' { 203 return utils.LetSubtract, nil 204 } / '/' { 205 return utils.LetDivide, nil 206 } / '*' { 207 return utils.LetMultiply, nil 208 } / '%' { 209 return utils.LetModulo, nil 210 } 211 212 LetIdentifier <- '-'? Float { 213 var dte utils.DtypeEnclosure 214 dte.Dtype = utils.SS_DT_FLOAT 215 dte.FloatVal,_ = strconv.ParseFloat(string(c.text), 64) 216 dte.StringVal = string(c.text) 217 return &dte, nil 218 } / '-'+ Integer { 219 var dte utils.DtypeEnclosure 220 dte.Dtype = utils.SS_DT_SIGNED_NUM 221 dte.SignedVal,_ = strconv.ParseInt(string(c.text),10, 64) 222 dte.StringVal = string(c.text) 223 return &dte, nil 224 } / Integer { 225 var dte utils.DtypeEnclosure 226 dte.Dtype = utils.SS_DT_UNSIGNED_NUM 227 dte.UnsignedVal,_ = strconv.ParseUint(string(c.text),10, 64) 228 dte.StringVal = string(c.text) 229 return &dte, nil 230 } / BoolValue { 231 var dte utils.DtypeEnclosure 232 dte.Dtype = utils.SS_DT_BOOL 233 bVal ,_ := strconv.ParseBool(string(c.text)) 234 if bVal == true { 235 dte.BoolVal = 1 236 } else { 237 dte.BoolVal = 0 238 } 239 dte.StringVal = string(c.text) 240 return &dte, nil 241 } 242 243 BoolValue <- "false" / "true" 244 245 Float <- [0-9]+ '.' [0-9]+ 246 247 Integer <- [0-9]+ 248 249 ColList <- space? first:Identifier rest:( space? ',' space? Identifier )* space? { 250 return ast.GetTokens(first, rest, 3), nil 251 } 252 253 AndClause <- lhs:NotClause space logicalAND space rhs:AndClause { 254 return &ast.Node { 255 NodeType: ast.NodeAnd, 256 Left: lhs.(*ast.Node), 257 Right: rhs.(*ast.Node), 258 }, nil 259 } / NotClause 260 261 NotClause <- logicalNOT cmp:Comparison { 262 return &ast.Node { 263 NodeType: ast.NodeNot, 264 Left: cmp.(*ast.Node), 265 Right: nil, 266 }, nil 267 } / Comparison 268 269 Comparison <- '(' space? query:OrClause space? ')'{ 270 return query, nil 271 } / field:Field space? operation:opCOMP space? field1:Field { 272 var opOut string 273 if operation == nil && field!=nil { 274 opOut = "=" 275 } else { 276 opOut = operation.(string) 277 } 278 return &ast.Node{ 279 NodeType: ast.NodeTerminal, 280 Comparison:ast.Comparison{ 281 Op: opOut, 282 Field: field.(string), 283 Values: field1, 284 }, 285 }, nil 286 } / values:ValueList { 287 return &ast.Node{ 288 NodeType: ast.NodeTerminal, 289 Comparison:ast.Comparison{ 290 Op: "=", 291 Field: "*", 292 Values: values, 293 }, 294 }, nil 295 } / field:Field { 296 return &ast.Node{ 297 NodeType: ast.NodeTerminal, 298 Comparison:ast.Comparison{ 299 Op: "=", 300 Field: "*", 301 Values: field, 302 }, 303 }, nil 304 } 305 306 /***** 307 FIELDS 308 ******/ 309 310 Field <- Value / pieces:(FieldPiece ('.' FieldPiece)*) { 311 if pieces == nil { 312 return "*", nil 313 } 314 315 return string(c.text), nil 316 } 317 318 FieldPiece <- QuotedFieldPiece / UnquotedFieldPiece / Star 319 320 UnquotedFieldPiece <- [-a-zA-Z0-9$&,?#%_@;[\]{}+-./*:]i+ { 321 return string(c.text), nil 322 } 323 324 325 QuotedFieldPiece <- QuotedValue 326 327 Star <- '*' { 328 return "*", nil 329 } 330 QuotedValue <- '"' ( !EscapedChar . / '\\' EscapeSequence )* '"' { 331 c.text = bytes.Replace(c.text, []byte(`\/`), []byte(`/`), -1) 332 return strconv.Unquote(string(c.text)) 333 } 334 EscapedChar <- [\x00-\x1f"\\] 335 336 EscapeSequence <- SingleCharEscape / UnicodeEscape 337 338 SingleCharEscape <- ["\\/bfnrt] 339 340 UnicodeEscape <- 'u' HexDigit HexDigit HexDigit HexDigit 341 342 HexDigit <- [0-9a-f]i 343 344 /***** 345 VALUES 346 ******/ 347 348 ValueList <- '[' space? first:Value rest:( space? ',' space? Value )* space? ']' { 349 return ast.GetTokens(first, rest, 3), nil 350 } / value:Value 351 352 Value <- val:( 353 Float 354 / Integer 355 356 ){ 357 return ast.MakeValue(val) 358 } 359 360 String 361 = '"' chars:[^"]* '"' { 362 return ast.StringFromChars(chars), nil 363 } 364 365 Integer <- [+-]? [0-9]+ { 366 return json.Number(string(c.text)), nil 367 } 368 369 Float <- [+-]? ([0-9]* "." [0-9]+ ) { 370 return json.Number(string(c.text)), nil 371 } 372 373 374 Identifier <- 375 [a-zA-Z0-9_@./*]i+ { 376 return string(c.text), nil 377 } 378 379 380 opPipe <- "|" 381 382 /**************** 383 LOGICAL OPERATORS 384 *****************/ 385 386 logicalOR <- "OR" 387 388 logicalAND <- "AND" 389 390 logicalNOT <- "NOT" space / '!' space? 391 392 /******************* 393 COMPARISON OPERATORS 394 ********************/ 395 396 397 398 opCOMP <- opCustom 399 / "<=" { 400 return string(c.text), nil 401 } / ">=" { 402 return string(c.text), nil 403 } / "=" { 404 return string(c.text), nil 405 } / "<" { 406 return string(c.text), nil 407 } / ">" { 408 return string(c.text), nil 409 } / "!=" { 410 return string(c.text), nil 411 } 412 413 414 opCustom <- '=' opname:[a-z]i+ '='{ 415 return ast.OpNameToString(opname) 416 } 417 418 /********************** 419 WHITESPACE AND TERMINAL 420 ***********************/ 421 422 _ "whitespace" <- [ \n\t\r]* 423 424 space <- [ \n\t\r]+ 425 426 EOL <- '\n' 427 428 EOF = !. 429 430 /***************************** 431 TERMINAL ERROR HANDLING STATES 432 ******************************/ 433 434 /* 435 ErrOp <- #{ 436 return fmt.Errorf("invalid operator") 437 } 438 */