github.com/mithrandie/csvq@v1.18.1/lib/query/eval.go (about) 1 package query 2 3 import ( 4 "bytes" 5 "context" 6 "os" 7 "strings" 8 9 "github.com/mithrandie/csvq/lib/constant" 10 "github.com/mithrandie/csvq/lib/excmd" 11 "github.com/mithrandie/csvq/lib/json" 12 "github.com/mithrandie/csvq/lib/option" 13 "github.com/mithrandie/csvq/lib/parser" 14 "github.com/mithrandie/csvq/lib/value" 15 16 "github.com/mithrandie/ternary" 17 ) 18 19 func Evaluate(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression) (value.Primary, error) { 20 if expr == nil { 21 return value.NewTernary(ternary.TRUE), nil 22 } 23 24 var val value.Primary 25 var err error 26 27 switch expr.(type) { 28 case parser.PrimitiveType: 29 val = expr.(parser.PrimitiveType).Value 30 case parser.FieldReference, parser.ColumnNumber: 31 val, err = evalFieldReference(expr, scope) 32 case parser.Parentheses: 33 val, err = Evaluate(ctx, scope, expr.(parser.Parentheses).Expr) 34 case parser.Arithmetic: 35 val, err = evalArithmetic(ctx, scope, expr.(parser.Arithmetic)) 36 case parser.UnaryArithmetic: 37 val, err = evalUnaryArithmetic(ctx, scope, expr.(parser.UnaryArithmetic)) 38 case parser.Concat: 39 val, err = evalConcat(ctx, scope, expr.(parser.Concat)) 40 case parser.Comparison: 41 val, err = evalComparison(ctx, scope, expr.(parser.Comparison)) 42 case parser.Is: 43 val, err = evalIs(ctx, scope, expr.(parser.Is)) 44 case parser.Between: 45 val, err = evalBetween(ctx, scope, expr.(parser.Between)) 46 case parser.Like: 47 val, err = evalLike(ctx, scope, expr.(parser.Like)) 48 case parser.In: 49 val, err = evalIn(ctx, scope, expr.(parser.In)) 50 case parser.Any: 51 val, err = evalAny(ctx, scope, expr.(parser.Any)) 52 case parser.All: 53 val, err = evalAll(ctx, scope, expr.(parser.All)) 54 case parser.Exists: 55 val, err = evalExists(ctx, scope, expr.(parser.Exists)) 56 case parser.Subquery: 57 val, err = evalSubqueryForValue(ctx, scope, expr.(parser.Subquery)) 58 case parser.Function: 59 val, err = evalFunction(ctx, scope, expr.(parser.Function)) 60 case parser.AggregateFunction: 61 val, err = evalAggregateFunction(ctx, scope, expr.(parser.AggregateFunction)) 62 case parser.ListFunction: 63 val, err = evalListFunction(ctx, scope, expr.(parser.ListFunction)) 64 case parser.AnalyticFunction: 65 val, err = evalAnalyticFunction(scope, expr.(parser.AnalyticFunction)) 66 case parser.CaseExpr: 67 val, err = evalCaseExpr(ctx, scope, expr.(parser.CaseExpr)) 68 case parser.Logic: 69 val, err = evalLogic(ctx, scope, expr.(parser.Logic)) 70 case parser.UnaryLogic: 71 val, err = evalUnaryLogic(ctx, scope, expr.(parser.UnaryLogic)) 72 case parser.Variable: 73 val, err = scope.GetVariable(expr.(parser.Variable)) 74 case parser.EnvironmentVariable: 75 val = value.NewString(os.Getenv(expr.(parser.EnvironmentVariable).Name)) 76 case parser.RuntimeInformation: 77 val, err = GetRuntimeInformation(scope.Tx, expr.(parser.RuntimeInformation)) 78 case parser.Constant: 79 val, err = constant.Get(expr.(parser.Constant)) 80 if err != nil { 81 err = NewUndefinedConstantError(expr.(parser.Constant)) 82 } 83 case parser.Flag: 84 if v, ok := scope.Tx.GetFlag(expr.(parser.Flag).Name); ok { 85 val = v 86 } else { 87 err = NewInvalidFlagNameError(expr.(parser.Flag)) 88 } 89 case parser.VariableSubstitution: 90 val, err = scope.SubstituteVariable(ctx, expr.(parser.VariableSubstitution)) 91 case parser.CursorStatus: 92 val, err = evalCursorStatus(expr.(parser.CursorStatus), scope) 93 case parser.CursorAttrebute: 94 val, err = evalCursorAttribute(expr.(parser.CursorAttrebute), scope) 95 case parser.Placeholder: 96 val, err = evalPlaceholder(ctx, scope, expr.(parser.Placeholder)) 97 default: 98 err = NewInvalidValueExpressionError(expr) 99 } 100 101 return val, err 102 } 103 104 func evaluateSequentialRoutine(ctx context.Context, scope *ReferenceScope, view *View, fn func(*ReferenceScope, int) error, thIdx int, gm *GoroutineTaskManager) { 105 defer func() { 106 if !gm.HasError() { 107 if panicReport := recover(); panicReport != nil { 108 gm.SetError(NewFatalError(panicReport)) 109 } 110 } 111 112 if 1 < gm.Number { 113 gm.Done() 114 } 115 }() 116 117 start, end := gm.RecordRange(thIdx) 118 seqScope := scope.CreateScopeForSequentialEvaluation( 119 &View{ 120 Header: view.Header, 121 RecordSet: view.RecordSet[start:end], 122 isGrouped: view.isGrouped, 123 }, 124 ) 125 126 i := 0 127 for seqScope.NextRecord() { 128 if gm.HasError() { 129 break 130 } 131 if i&15 == 0 && ctx.Err() != nil { 132 break 133 } 134 135 if err := fn(seqScope, start+seqScope.Records[0].recordIndex); err != nil { 136 gm.SetError(err) 137 break 138 } 139 140 i++ 141 } 142 } 143 144 func EvaluateSequentially(ctx context.Context, scope *ReferenceScope, view *View, fn func(*ReferenceScope, int) error) error { 145 gm := NewGoroutineTaskManager(view.Len(), -1, scope.Tx.Flags.CPU) 146 if 1 < gm.Number { 147 for i := 0; i < gm.Number; i++ { 148 gm.Add() 149 go evaluateSequentialRoutine(ctx, scope, view, fn, i, gm) 150 } 151 gm.Wait() 152 } else { 153 evaluateSequentialRoutine(ctx, scope, view, fn, 0, gm) 154 } 155 156 if gm.HasError() { 157 return gm.Err() 158 } 159 if ctx.Err() != nil { 160 return ConvertContextError(ctx.Err()) 161 } 162 return nil 163 } 164 165 func evalFieldReference(expr parser.QueryExpression, scope *ReferenceScope) (value.Primary, error) { 166 var p value.Primary 167 for i := range scope.Records { 168 if idx, ok := scope.Records[i].cache.Get(expr); ok { 169 if scope.Records[i].IsInRange() { 170 p = scope.Records[i].view.RecordSet[scope.Records[i].recordIndex][idx][0] 171 } else { 172 p = value.NewNull() 173 } 174 break 175 } 176 177 idx, err := scope.Records[i].view.Header.SearchIndex(expr) 178 if err == nil { 179 if scope.Records[i].view.isGrouped && scope.Records[i].view.Header[idx].IsFromTable && !scope.Records[i].view.Header[idx].IsGroupKey { 180 return nil, NewFieldNotGroupKeyError(expr) 181 } 182 if scope.Records[i].IsInRange() { 183 p = scope.Records[i].view.RecordSet[scope.Records[i].recordIndex][idx][0] 184 } else { 185 p = value.NewNull() 186 } 187 scope.Records[i].cache.Add(expr, idx) 188 break 189 } else if err == errFieldAmbiguous { 190 return nil, NewFieldAmbiguousError(expr) 191 } 192 } 193 if p == nil { 194 return nil, NewFieldNotExistError(expr) 195 } 196 return p, nil 197 } 198 199 func evalArithmetic(ctx context.Context, scope *ReferenceScope, expr parser.Arithmetic) (value.Primary, error) { 200 lhs, err := Evaluate(ctx, scope, expr.LHS) 201 if err != nil { 202 return nil, err 203 } 204 if value.IsNull(lhs) { 205 return value.NewNull(), nil 206 } 207 208 rhs, err := Evaluate(ctx, scope, expr.RHS) 209 if err != nil { 210 return nil, err 211 } 212 213 ret, err := Calculate(lhs, rhs, expr.Operator.Token) 214 if err != nil { 215 return nil, NewIntegerDevidedByZeroError(expr) 216 } 217 218 return ret, nil 219 } 220 221 func evalUnaryArithmetic(ctx context.Context, scope *ReferenceScope, expr parser.UnaryArithmetic) (value.Primary, error) { 222 ope, err := Evaluate(ctx, scope, expr.Operand) 223 if err != nil { 224 return nil, err 225 } 226 227 if pi := value.ToIntegerStrictly(ope); !value.IsNull(pi) { 228 val := pi.(*value.Integer).Raw() 229 value.Discard(pi) 230 switch expr.Operator.Token { 231 case '-': 232 val = val * -1 233 } 234 return value.NewInteger(val), nil 235 } 236 237 pf := value.ToFloat(ope) 238 if value.IsNull(pf) { 239 return value.NewNull(), nil 240 } 241 242 val := pf.(*value.Float).Raw() 243 value.Discard(pf) 244 245 switch expr.Operator.Token { 246 case '-': 247 val = val * -1 248 } 249 250 return value.NewFloat(val), nil 251 } 252 253 func evalConcat(ctx context.Context, scope *ReferenceScope, expr parser.Concat) (value.Primary, error) { 254 items := make([]string, len(expr.Items)) 255 for i, v := range expr.Items { 256 p, err := Evaluate(ctx, scope, v) 257 if err != nil { 258 return nil, err 259 } 260 s := value.ToString(p) 261 if value.IsNull(s) { 262 return value.NewNull(), nil 263 } 264 items[i] = s.(*value.String).Raw() 265 value.Discard(s) 266 } 267 return value.NewString(strings.Join(items, "")), nil 268 } 269 270 func evalRowOrSingleValue(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression) (value.RowValue, value.Primary, error) { 271 var rv value.RowValue 272 var sv value.Primary 273 274 switch expr.(type) { 275 case parser.Subquery, parser.JsonQuery, parser.ValueList, parser.RowValue: 276 row, err := EvalRowValue(ctx, scope, expr) 277 if err != nil { 278 return nil, nil, err 279 } 280 if row == nil { 281 sv = value.NewNull() 282 } else { 283 if 1 == len(row) { 284 sv = row[0] 285 } else { 286 rv = row 287 } 288 } 289 default: 290 val, err := Evaluate(ctx, scope, expr) 291 if err != nil { 292 return nil, nil, err 293 } 294 sv = val 295 } 296 297 return rv, sv, nil 298 } 299 300 func evalComparison(ctx context.Context, scope *ReferenceScope, expr parser.Comparison) (value.Primary, error) { 301 var t ternary.Value 302 303 rv, sv, err := evalRowOrSingleValue(ctx, scope, expr.LHS) 304 if err != nil { 305 return nil, err 306 } 307 308 if sv != nil { 309 if value.IsNull(sv) { 310 return value.NewTernary(ternary.UNKNOWN), nil 311 } 312 313 rhs, err := Evaluate(ctx, scope, expr.RHS) 314 if err != nil { 315 return nil, err 316 } 317 318 t = value.Compare(sv, rhs, expr.Operator.Literal, scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 319 } else { 320 rhs, err := EvalRowValue(ctx, scope, expr.RHS.(parser.RowValue)) 321 if err != nil { 322 return nil, err 323 } 324 325 t, err = value.CompareRowValues(rv, rhs, expr.Operator.Literal, scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 326 if err != nil { 327 return nil, NewRowValueLengthInComparisonError(expr.RHS.(parser.RowValue), len(rv)) 328 } 329 } 330 331 return value.NewTernary(t), nil 332 } 333 334 func evalIs(ctx context.Context, scope *ReferenceScope, expr parser.Is) (value.Primary, error) { 335 lhs, err := Evaluate(ctx, scope, expr.LHS) 336 if err != nil { 337 return nil, err 338 } 339 rhs, err := Evaluate(ctx, scope, expr.RHS) 340 if err != nil { 341 return nil, err 342 } 343 344 t := Is(lhs, rhs) 345 if expr.IsNegated() { 346 t = ternary.Not(t) 347 } 348 return value.NewTernary(t), nil 349 } 350 351 func evalBetween(ctx context.Context, scope *ReferenceScope, expr parser.Between) (value.Primary, error) { 352 var t ternary.Value 353 354 rv, sv, err := evalRowOrSingleValue(ctx, scope, expr.LHS) 355 if err != nil { 356 return nil, err 357 } 358 359 if sv != nil { 360 if value.IsNull(sv) { 361 return value.NewTernary(ternary.UNKNOWN), nil 362 } 363 364 low, err := Evaluate(ctx, scope, expr.Low) 365 if err != nil { 366 return nil, err 367 } 368 369 lowResult := value.GreaterOrEqual(sv, low, scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 370 if lowResult == ternary.FALSE { 371 t = ternary.FALSE 372 } else { 373 high, err := Evaluate(ctx, scope, expr.High) 374 if err != nil { 375 return nil, err 376 } 377 378 highResult := value.LessOrEqual(sv, high, scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 379 t = ternary.And(lowResult, highResult) 380 } 381 } else { 382 low, err := EvalRowValue(ctx, scope, expr.Low.(parser.RowValue)) 383 if err != nil { 384 return nil, err 385 } 386 lowResult, err := value.CompareRowValues(rv, low, ">=", scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 387 if err != nil { 388 return nil, NewRowValueLengthInComparisonError(expr.Low.(parser.RowValue), len(rv)) 389 } 390 391 if lowResult == ternary.FALSE { 392 t = ternary.FALSE 393 } else { 394 high, err := EvalRowValue(ctx, scope, expr.High.(parser.RowValue)) 395 if err != nil { 396 return nil, err 397 } 398 399 highResult, err := value.CompareRowValues(rv, high, "<=", scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 400 if err != nil { 401 return nil, NewRowValueLengthInComparisonError(expr.High.(parser.RowValue), len(rv)) 402 } 403 404 t = ternary.And(lowResult, highResult) 405 } 406 } 407 408 if expr.IsNegated() { 409 t = ternary.Not(t) 410 } 411 return value.NewTernary(t), nil 412 } 413 414 func valuesForRowValueListComparison(ctx context.Context, scope *ReferenceScope, lhs parser.QueryExpression, values parser.QueryExpression) (value.RowValue, []value.RowValue, error) { 415 var rowValue value.RowValue 416 var list []value.RowValue 417 var err error 418 419 rowValue, err = EvalRowValue(ctx, scope, lhs) 420 if err != nil { 421 return rowValue, list, err 422 } 423 424 if rowValue != nil && 1 < len(rowValue) { 425 list, err = evalRowValueList(ctx, scope, values) 426 } else { 427 list, err = evalArray(ctx, scope, values) 428 } 429 430 return rowValue, list, err 431 } 432 433 func evalIn(ctx context.Context, scope *ReferenceScope, expr parser.In) (value.Primary, error) { 434 val, list, err := valuesForRowValueListComparison(ctx, scope, expr.LHS, expr.Values) 435 if err != nil { 436 return nil, err 437 } 438 439 var t ternary.Value 440 if expr.IsNegated() { 441 t, err = All(val, list, "<>", scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 442 } else { 443 t, err = Any(val, list, "=", scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 444 } 445 if err != nil { 446 if subquery, ok := expr.Values.(parser.Subquery); ok { 447 return nil, NewSelectFieldLengthInComparisonError(subquery, len(val)) 448 } else if jsonQuery, ok := expr.Values.(parser.JsonQuery); ok { 449 return nil, NewRowValueLengthInComparisonError(jsonQuery, len(val)) 450 } 451 452 rvlist, _ := expr.Values.(parser.RowValueList) 453 rverr, _ := err.(*RowValueLengthInListError) 454 return nil, NewRowValueLengthInComparisonError(rvlist.RowValues[rverr.Index], len(val)) 455 } 456 return value.NewTernary(t), nil 457 } 458 459 func evalAny(ctx context.Context, scope *ReferenceScope, expr parser.Any) (value.Primary, error) { 460 val, list, err := valuesForRowValueListComparison(ctx, scope, expr.LHS, expr.Values) 461 if err != nil { 462 return nil, err 463 } 464 465 t, err := Any(val, list, expr.Operator.Literal, scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 466 if err != nil { 467 if subquery, ok := expr.Values.(parser.Subquery); ok { 468 return nil, NewSelectFieldLengthInComparisonError(subquery, len(val)) 469 } else if jsonQuery, ok := expr.Values.(parser.JsonQuery); ok { 470 return nil, NewRowValueLengthInComparisonError(jsonQuery, len(val)) 471 } 472 473 rvlist, _ := expr.Values.(parser.RowValueList) 474 rverr, _ := err.(*RowValueLengthInListError) 475 return nil, NewRowValueLengthInComparisonError(rvlist.RowValues[rverr.Index], len(val)) 476 } 477 return value.NewTernary(t), nil 478 } 479 480 func evalAll(ctx context.Context, scope *ReferenceScope, expr parser.All) (value.Primary, error) { 481 val, list, err := valuesForRowValueListComparison(ctx, scope, expr.LHS, expr.Values) 482 if err != nil { 483 return nil, err 484 } 485 486 t, err := All(val, list, expr.Operator.Literal, scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 487 if err != nil { 488 if subquery, ok := expr.Values.(parser.Subquery); ok { 489 return nil, NewSelectFieldLengthInComparisonError(subquery, len(val)) 490 } else if jsonQuery, ok := expr.Values.(parser.JsonQuery); ok { 491 return nil, NewRowValueLengthInComparisonError(jsonQuery, len(val)) 492 } 493 494 rvlist, _ := expr.Values.(parser.RowValueList) 495 rverr, _ := err.(*RowValueLengthInListError) 496 return nil, NewRowValueLengthInComparisonError(rvlist.RowValues[rverr.Index], len(val)) 497 } 498 return value.NewTernary(t), nil 499 } 500 501 func evalLike(ctx context.Context, scope *ReferenceScope, expr parser.Like) (value.Primary, error) { 502 lhs, err := Evaluate(ctx, scope, expr.LHS) 503 if err != nil { 504 return nil, err 505 } 506 pattern, err := Evaluate(ctx, scope, expr.Pattern) 507 if err != nil { 508 return nil, err 509 } 510 511 t := Like(lhs, pattern) 512 if expr.IsNegated() { 513 t = ternary.Not(t) 514 } 515 return value.NewTernary(t), nil 516 } 517 518 func evalExists(ctx context.Context, scope *ReferenceScope, expr parser.Exists) (value.Primary, error) { 519 view, err := Select(ctx, scope, expr.Query.Query) 520 if err != nil { 521 return nil, err 522 } 523 if view.RecordLen() < 1 { 524 return value.NewTernary(ternary.FALSE), nil 525 } 526 return value.NewTernary(ternary.TRUE), nil 527 } 528 529 func evalSubqueryForValue(ctx context.Context, scope *ReferenceScope, expr parser.Subquery) (value.Primary, error) { 530 view, err := Select(ctx, scope, expr.Query) 531 if err != nil { 532 return nil, err 533 } 534 535 if 1 < view.FieldLen() { 536 return nil, NewSubqueryTooManyFieldsError(expr) 537 } 538 539 if 1 < view.RecordLen() { 540 return nil, NewSubqueryTooManyRecordsError(expr) 541 } 542 543 if view.RecordLen() < 1 { 544 return value.NewNull(), nil 545 } 546 547 return view.RecordSet[0][0][0], nil 548 } 549 550 func evalFunction(ctx context.Context, scope *ReferenceScope, expr parser.Function) (value.Primary, error) { 551 name := strings.ToUpper(expr.Name) 552 553 var fn BuiltInFunction 554 var udfn *UserDefinedFunction 555 var ok bool 556 var err error 557 558 if fn, ok = Functions[name]; !ok && name != "CALL" && name != "NOW" && name != "JSON_OBJECT" { 559 udfn, err = scope.GetFunction(expr, name) 560 if err != nil { 561 return nil, NewFunctionNotExistError(expr, expr.Name) 562 } 563 if udfn.IsAggregate { 564 aggrdcl := parser.AggregateFunction{ 565 BaseExpr: expr.BaseExpr, 566 Name: expr.Name, 567 Args: expr.Args, 568 } 569 return evalAggregateFunction(ctx, scope, aggrdcl) 570 } 571 572 if err = udfn.CheckArgsLen(expr, expr.Name, len(expr.Args)); err != nil { 573 return nil, err 574 } 575 } 576 577 if name == "JSON_OBJECT" { 578 return JsonObject(ctx, scope, expr) 579 } 580 581 args := make([]value.Primary, len(expr.Args)) 582 for i, v := range expr.Args { 583 arg, err := Evaluate(ctx, scope, v) 584 if err != nil { 585 return nil, err 586 } 587 args[i] = arg 588 } 589 590 if name == "CALL" { 591 return Call(ctx, expr, args) 592 } else if name == "NOW" { 593 return Now(scope, expr, args) 594 } 595 596 if fn != nil { 597 return fn(expr, args, scope.Tx.Flags) 598 } 599 return udfn.Execute(ctx, scope, args) 600 } 601 602 func evalAggregateFunction(ctx context.Context, scope *ReferenceScope, expr parser.AggregateFunction) (value.Primary, error) { 603 var aggfn func([]value.Primary, *option.Flags) value.Primary 604 var udfn *UserDefinedFunction 605 var err error 606 607 uname := strings.ToUpper(expr.Name) 608 if fn, ok := AggregateFunctions[uname]; ok { 609 aggfn = fn 610 } else { 611 if udfn, err = scope.GetFunction(expr, uname); err != nil || !udfn.IsAggregate { 612 return nil, NewFunctionNotExistError(expr, expr.Name) 613 } 614 } 615 616 if aggfn == nil { 617 if err = udfn.CheckArgsLen(expr, expr.Name, len(expr.Args)-1); err != nil { 618 return nil, err 619 } 620 } else { 621 if len(expr.Args) != 1 { 622 return nil, NewFunctionArgumentLengthError(expr, expr.Name, []int{1}) 623 } 624 } 625 626 var list []value.Primary 627 if 0 < len(scope.Records) { 628 if !scope.Records[0].view.isGrouped { 629 return nil, NewNotGroupingRecordsError(expr, expr.Name) 630 } 631 632 listExpr := expr.Args[0] 633 if _, ok := listExpr.(parser.AllColumns); ok { 634 listExpr = parser.NewIntegerValue(1) 635 } 636 637 if uname == "COUNT" { 638 if pt, ok := listExpr.(parser.PrimitiveType); ok { 639 v := pt.Value 640 if !value.IsNull(v) && !value.IsUnknown(v) && scope.Records[0].IsInRange() { 641 return value.NewInteger(int64(scope.Records[0].view.RecordSet[scope.Records[0].recordIndex].GroupLen())), nil 642 } else { 643 return value.NewInteger(0), nil 644 } 645 } 646 } 647 648 if scope.Records[0].IsInRange() { 649 view, err := NewViewFromGroupedRecord(ctx, scope.Tx.Flags, scope.Records[0]) 650 if err != nil { 651 return nil, err 652 } 653 list, err = view.ListValuesForAggregateFunctions(ctx, scope, expr, listExpr, expr.IsDistinct()) 654 if err != nil { 655 return nil, err 656 } 657 } 658 } 659 660 if aggfn == nil { 661 argsExprs := expr.Args[1:] 662 args := make([]value.Primary, len(argsExprs)) 663 for i, v := range argsExprs { 664 arg, err := Evaluate(ctx, scope, v) 665 if err != nil { 666 return nil, err 667 } 668 args[i] = arg 669 } 670 return udfn.ExecuteAggregate(ctx, scope, list, args) 671 } 672 673 return aggfn(list, scope.Tx.Flags), nil 674 } 675 676 func evalListFunction(ctx context.Context, scope *ReferenceScope, expr parser.ListFunction) (value.Primary, error) { 677 var separator string 678 var err error 679 680 switch strings.ToUpper(expr.Name) { 681 case "JSON_AGG": 682 err = checkArgsForJsonAgg(expr) 683 default: // LISTAGG 684 separator, err = checkArgsForListFunction(ctx, scope, expr) 685 } 686 687 if err != nil { 688 return nil, err 689 } 690 691 var list []value.Primary 692 if 0 < len(scope.Records) { 693 if !scope.Records[0].view.isGrouped { 694 return nil, NewNotGroupingRecordsError(expr, expr.Name) 695 } 696 697 view, err := NewViewFromGroupedRecord(ctx, scope.Tx.Flags, scope.Records[0]) 698 if err != nil { 699 return nil, err 700 } 701 if expr.OrderBy != nil { 702 err := view.OrderBy(ctx, scope, expr.OrderBy.(parser.OrderByClause)) 703 if err != nil { 704 return nil, err 705 } 706 } 707 708 list, err = view.ListValuesForAggregateFunctions(ctx, scope, expr, expr.Args[0], expr.IsDistinct()) 709 if err != nil { 710 return nil, err 711 } 712 } 713 714 switch strings.ToUpper(expr.Name) { 715 case "JSON_AGG": 716 return JsonAgg(list), nil 717 } 718 return ListAgg(list, separator), nil 719 } 720 721 func evalAnalyticFunction(scope *ReferenceScope, expr parser.AnalyticFunction) (value.Primary, error) { 722 if 0 < len(scope.Records) { 723 fieldIndex, ok := scope.Records[0].view.Header.ContainsObject(expr) 724 if ok { 725 if !scope.Records[0].IsInRange() { 726 return value.NewNull(), nil 727 } 728 return scope.Records[0].view.RecordSet[scope.Records[0].recordIndex][fieldIndex][0], nil 729 } 730 } 731 return nil, NewNotAllowedAnalyticFunctionError(expr) 732 } 733 734 func checkArgsForListFunction(ctx context.Context, scope *ReferenceScope, expr parser.ListFunction) (string, error) { 735 var separator string 736 737 if expr.Args == nil || 2 < len(expr.Args) { 738 return "", NewFunctionArgumentLengthError(expr, expr.Name, []int{1, 2}) 739 } 740 741 if len(expr.Args) == 2 { 742 p, err := Evaluate(ctx, scope, expr.Args[1]) 743 if err != nil { 744 return separator, NewFunctionInvalidArgumentError(expr, expr.Name, "the second argument must be a string") 745 } 746 s := value.ToString(p) 747 if value.IsNull(s) { 748 return separator, NewFunctionInvalidArgumentError(expr, expr.Name, "the second argument must be a string") 749 } 750 separator = s.(*value.String).Raw() 751 value.Discard(s) 752 } 753 return separator, nil 754 } 755 756 func checkArgsForJsonAgg(expr parser.ListFunction) error { 757 if 1 != len(expr.Args) { 758 return NewFunctionArgumentLengthError(expr, expr.Name, []int{1}) 759 } 760 return nil 761 } 762 763 func evalCaseExpr(ctx context.Context, scope *ReferenceScope, expr parser.CaseExpr) (value.Primary, error) { 764 var val value.Primary 765 var err error 766 if expr.Value != nil { 767 val, err = Evaluate(ctx, scope, expr.Value) 768 if err != nil { 769 return nil, err 770 } 771 } 772 773 for _, v := range expr.When { 774 when := v.(parser.CaseExprWhen) 775 var t ternary.Value 776 777 cond, err := Evaluate(ctx, scope, when.Condition) 778 if err != nil { 779 return nil, err 780 } 781 782 if val == nil { 783 t = cond.Ternary() 784 } else { 785 t = value.Equal(val, cond, scope.Tx.Flags.DatetimeFormat, scope.Tx.Flags.GetTimeLocation()) 786 } 787 788 if t == ternary.TRUE { 789 result, err := Evaluate(ctx, scope, when.Result) 790 if err != nil { 791 return nil, err 792 } 793 return result, nil 794 } 795 } 796 797 if expr.Else == nil { 798 return value.NewNull(), nil 799 } 800 result, err := Evaluate(ctx, scope, expr.Else.(parser.CaseExprElse).Result) 801 if err != nil { 802 return nil, err 803 } 804 return result, nil 805 } 806 807 func evalLogic(ctx context.Context, scope *ReferenceScope, expr parser.Logic) (value.Primary, error) { 808 lhs, err := Evaluate(ctx, scope, expr.LHS) 809 if err != nil { 810 return nil, err 811 } 812 switch expr.Operator.Token { 813 case parser.AND: 814 if lhs.Ternary() == ternary.FALSE { 815 return value.NewTernary(ternary.FALSE), nil 816 } 817 case parser.OR: 818 if lhs.Ternary() == ternary.TRUE { 819 return value.NewTernary(ternary.TRUE), nil 820 } 821 } 822 823 rhs, err := Evaluate(ctx, scope, expr.RHS) 824 if err != nil { 825 return nil, err 826 } 827 828 var t ternary.Value 829 switch expr.Operator.Token { 830 case parser.AND: 831 t = ternary.And(lhs.Ternary(), rhs.Ternary()) 832 case parser.OR: 833 t = ternary.Or(lhs.Ternary(), rhs.Ternary()) 834 } 835 return value.NewTernary(t), nil 836 } 837 838 func evalUnaryLogic(ctx context.Context, scope *ReferenceScope, expr parser.UnaryLogic) (value.Primary, error) { 839 ope, err := Evaluate(ctx, scope, expr.Operand) 840 if err != nil { 841 return nil, err 842 } 843 844 var t ternary.Value 845 switch expr.Operator.Token { 846 case parser.NOT, '!': 847 t = ternary.Not(ope.Ternary()) 848 } 849 return value.NewTernary(t), nil 850 } 851 852 func evalCursorStatus(expr parser.CursorStatus, scope *ReferenceScope) (value.Primary, error) { 853 var t ternary.Value 854 var err error 855 856 switch expr.Type.Token { 857 case parser.OPEN: 858 t, err = scope.CursorIsOpen(expr.Cursor) 859 if err != nil { 860 return nil, err 861 } 862 case parser.RANGE: 863 t, err = scope.CursorIsInRange(expr.Cursor) 864 if err != nil { 865 return nil, err 866 } 867 } 868 869 if !expr.Negation.IsEmpty() { 870 t = ternary.Not(t) 871 } 872 return value.NewTernary(t), nil 873 } 874 875 func evalCursorAttribute(expr parser.CursorAttrebute, scope *ReferenceScope) (value.Primary, error) { 876 var i int 877 var err error 878 879 switch expr.Attrebute.Token { 880 case parser.COUNT: 881 i, err = scope.CursorCount(expr.Cursor) 882 if err != nil { 883 return nil, err 884 } 885 } 886 return value.NewInteger(int64(i)), nil 887 } 888 889 func evalPlaceholder(ctx context.Context, scope *ReferenceScope, expr parser.Placeholder) (value.Primary, error) { 890 v := ctx.Value(StatementReplaceValuesContextKey) 891 if v == nil { 892 return nil, NewStatementReplaceValueNotSpecifiedError(expr) 893 } 894 replace := v.(*ReplaceValues) 895 896 var idx int 897 if 0 < len(expr.Name) { 898 i, ok := replace.Names[expr.Name] 899 if !ok { 900 return nil, NewStatementReplaceValueNotSpecifiedError(expr) 901 } 902 idx = i 903 } else { 904 idx = expr.Ordinal - 1 905 if len(replace.Values) <= idx { 906 return nil, NewStatementReplaceValueNotSpecifiedError(expr) 907 } 908 } 909 return Evaluate(ctx, scope, replace.Values[idx]) 910 } 911 912 // EvalRowValue returns single or multiple fields, single record 913 func EvalRowValue(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression) (value.RowValue, error) { 914 var rowValue value.RowValue 915 var err error 916 917 switch expr.(type) { 918 case parser.Subquery: 919 rowValue, err = evalSubqueryForRowValue(ctx, scope, expr.(parser.Subquery)) 920 case parser.JsonQuery: 921 rowValue, err = evalJsonQueryForRowValue(ctx, scope, expr.(parser.JsonQuery)) 922 case parser.ValueList: 923 rowValue, err = evalValueList(ctx, scope, expr.(parser.ValueList)) 924 case parser.RowValue: 925 rowValue, err = EvalRowValue(ctx, scope, expr.(parser.RowValue).Value) 926 default: 927 var p value.Primary 928 p, err = Evaluate(ctx, scope, expr) 929 if err == nil { 930 rowValue = value.RowValue{p} 931 } 932 } 933 934 return rowValue, err 935 } 936 937 // evalRowValueList returns multiple fields, multiple records 938 func evalRowValueList(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression) ([]value.RowValue, error) { 939 var list []value.RowValue 940 var err error 941 942 switch expr.(type) { 943 case parser.Subquery: 944 list, err = evalSubqueryForRowValueList(ctx, scope, expr.(parser.Subquery)) 945 case parser.JsonQuery: 946 list, err = evalJsonQueryForRowValueList(ctx, scope, expr.(parser.JsonQuery)) 947 case parser.RowValueList: 948 rowValueList := expr.(parser.RowValueList) 949 list = make([]value.RowValue, len(rowValueList.RowValues)) 950 for i, v := range rowValueList.RowValues { 951 rowValue, e := EvalRowValue(ctx, scope, v.(parser.RowValue)) 952 if e != nil { 953 return list, e 954 } 955 list[i] = rowValue 956 } 957 } 958 959 return list, err 960 } 961 962 /* 963 * Returns single fields, multiple records 964 */ 965 func evalArray(ctx context.Context, scope *ReferenceScope, expr parser.QueryExpression) ([]value.RowValue, error) { 966 var array []value.RowValue 967 var err error 968 969 switch expr.(type) { 970 case parser.Subquery: 971 array, err = evalSubqueryForArray(ctx, scope, expr.(parser.Subquery)) 972 case parser.JsonQuery: 973 array, err = evalJsonQueryForArray(ctx, scope, expr.(parser.JsonQuery)) 974 case parser.ValueList: 975 values, e := evalValueList(ctx, scope, expr.(parser.ValueList)) 976 if e != nil { 977 return array, e 978 } 979 array = make([]value.RowValue, len(values)) 980 for i, v := range values { 981 array[i] = value.RowValue{v} 982 } 983 case parser.RowValue: 984 array, err = evalArray(ctx, scope, expr.(parser.RowValue).Value) 985 } 986 987 return array, err 988 } 989 990 func evalSubqueryForRowValue(ctx context.Context, scope *ReferenceScope, expr parser.Subquery) (value.RowValue, error) { 991 view, err := Select(ctx, scope, expr.Query) 992 if err != nil { 993 return nil, err 994 } 995 996 if view.RecordLen() < 1 { 997 return nil, nil 998 } 999 1000 if 1 < view.RecordLen() { 1001 return nil, NewSubqueryTooManyRecordsError(expr) 1002 } 1003 1004 rowValue := make(value.RowValue, view.FieldLen()) 1005 for i := range view.RecordSet[0] { 1006 rowValue[i] = view.RecordSet[0][i][0] 1007 } 1008 1009 return rowValue, nil 1010 } 1011 1012 func evalJsonQueryForRowValue(ctx context.Context, scope *ReferenceScope, expr parser.JsonQuery) (value.RowValue, error) { 1013 query, jsonText, err := evalJsonQueryParameters(ctx, scope, expr) 1014 if err != nil { 1015 return nil, err 1016 } 1017 1018 if value.IsNull(query) || value.IsNull(jsonText) { 1019 return nil, nil 1020 } 1021 1022 _, values, _, err := json.LoadTable(query.(*value.String).Raw(), jsonText.(*value.String).Raw()) 1023 if err != nil { 1024 return nil, NewLoadJsonError(expr, err.Error()) 1025 } 1026 1027 if len(values) < 1 { 1028 return nil, nil 1029 } 1030 1031 if 1 < len(values) { 1032 return nil, NewJsonQueryTooManyRecordsError(expr) 1033 } 1034 1035 rowValue := make(value.RowValue, len(values[0])) 1036 for i, cell := range values[0] { 1037 rowValue[i] = cell 1038 } 1039 1040 return rowValue, nil 1041 } 1042 1043 func evalValueList(ctx context.Context, scope *ReferenceScope, expr parser.ValueList) (value.RowValue, error) { 1044 values := make(value.RowValue, len(expr.Values)) 1045 for i, v := range expr.Values { 1046 val, err := Evaluate(ctx, scope, v) 1047 if err != nil { 1048 return nil, err 1049 } 1050 values[i] = val 1051 } 1052 return values, nil 1053 } 1054 1055 func evalSubqueryForRowValueList(ctx context.Context, scope *ReferenceScope, expr parser.Subquery) ([]value.RowValue, error) { 1056 view, err := Select(ctx, scope, expr.Query) 1057 if err != nil { 1058 return nil, err 1059 } 1060 1061 if view.RecordLen() < 1 { 1062 return nil, nil 1063 } 1064 1065 list := make([]value.RowValue, view.RecordLen()) 1066 for i, r := range view.RecordSet { 1067 rowValue := make(value.RowValue, view.FieldLen()) 1068 for j := range r { 1069 rowValue[j] = r[j][0] 1070 } 1071 list[i] = rowValue 1072 } 1073 1074 return list, nil 1075 } 1076 1077 func evalJsonQueryForRowValueList(ctx context.Context, scope *ReferenceScope, expr parser.JsonQuery) ([]value.RowValue, error) { 1078 query, jsonText, err := evalJsonQueryParameters(ctx, scope, expr) 1079 if err != nil { 1080 return nil, err 1081 } 1082 1083 if value.IsNull(query) || value.IsNull(jsonText) { 1084 return nil, nil 1085 } 1086 1087 _, values, _, err := json.LoadTable(query.(*value.String).Raw(), jsonText.(*value.String).Raw()) 1088 if err != nil { 1089 return nil, NewLoadJsonError(expr, err.Error()) 1090 } 1091 1092 if len(values) < 1 { 1093 return nil, nil 1094 } 1095 1096 list := make([]value.RowValue, len(values)) 1097 for i, row := range values { 1098 list[i] = row 1099 } 1100 1101 return list, nil 1102 } 1103 1104 func evalSubqueryForArray(ctx context.Context, scope *ReferenceScope, expr parser.Subquery) ([]value.RowValue, error) { 1105 view, err := Select(ctx, scope, expr.Query) 1106 if err != nil { 1107 return nil, err 1108 } 1109 1110 if 1 < view.FieldLen() { 1111 return nil, NewSubqueryTooManyFieldsError(expr) 1112 } 1113 1114 if view.RecordLen() < 1 { 1115 return nil, nil 1116 } 1117 1118 list := make([]value.RowValue, view.RecordLen()) 1119 for i := range view.RecordSet { 1120 list[i] = value.RowValue{view.RecordSet[i][0][0]} 1121 } 1122 1123 return list, nil 1124 } 1125 1126 func evalJsonQueryForArray(ctx context.Context, scope *ReferenceScope, expr parser.JsonQuery) ([]value.RowValue, error) { 1127 query, jsonText, err := evalJsonQueryParameters(ctx, scope, expr) 1128 if err != nil { 1129 return nil, err 1130 } 1131 1132 if value.IsNull(query) || value.IsNull(jsonText) { 1133 return nil, nil 1134 } 1135 1136 values, err := json.LoadArray(query.(*value.String).Raw(), jsonText.(*value.String).Raw()) 1137 if err != nil { 1138 return nil, NewLoadJsonError(expr, err.Error()) 1139 } 1140 1141 if len(values) < 1 { 1142 return nil, nil 1143 } 1144 1145 list := make([]value.RowValue, len(values)) 1146 for i, v := range values { 1147 list[i] = value.RowValue{v} 1148 } 1149 1150 return list, nil 1151 } 1152 1153 func evalJsonQueryParameters(ctx context.Context, scope *ReferenceScope, expr parser.JsonQuery) (value.Primary, value.Primary, error) { 1154 queryValue, err := Evaluate(ctx, scope, expr.Query) 1155 if err != nil { 1156 return nil, nil, err 1157 } 1158 query := value.ToString(queryValue) 1159 1160 jsonTextValue, err := Evaluate(ctx, scope, expr.JsonText) 1161 if err != nil { 1162 return nil, nil, err 1163 } 1164 jsonText := value.ToString(jsonTextValue) 1165 1166 return query, jsonText, nil 1167 } 1168 1169 func EvaluateEmbeddedString(ctx context.Context, scope *ReferenceScope, embedded string) (string, error) { 1170 enclosure := rune(0) 1171 if 1 < len(embedded) { 1172 if embedded[0] == '\'' && embedded[len(embedded)-1] == '\'' { 1173 embedded = embedded[1 : len(embedded)-1] 1174 enclosure = '\'' 1175 } else if embedded[0] == '"' && embedded[len(embedded)-1] == '"' { 1176 embedded = embedded[1 : len(embedded)-1] 1177 enclosure = '"' 1178 } 1179 } 1180 1181 scanner := new(excmd.ArgumentScanner).Init(embedded) 1182 buf := &bytes.Buffer{} 1183 var err error 1184 1185 for scanner.Scan() { 1186 switch scanner.ElementType() { 1187 case excmd.FixedString: 1188 buf.WriteString(option.UnescapeString(scanner.Text(), enclosure)) 1189 case excmd.Variable: 1190 if err = writeEmbeddedExpression(ctx, scope, buf, parser.Variable{Name: scanner.Text()}); err != nil { 1191 return buf.String(), err 1192 } 1193 case excmd.EnvironmentVariable: 1194 buf.WriteString(os.Getenv(scanner.Text())) 1195 case excmd.RuntimeInformation: 1196 if err = writeEmbeddedExpression(ctx, scope, buf, parser.RuntimeInformation{Name: scanner.Text()}); err != nil { 1197 return buf.String(), err 1198 } 1199 case excmd.CsvqExpression: 1200 expr := scanner.Text() 1201 if 0 < len(expr) { 1202 statements, _, err := parser.Parse(expr, expr, false, scope.Tx.Flags.AnsiQuotes) 1203 if err != nil { 1204 if syntaxErr, ok := err.(*parser.SyntaxError); ok { 1205 err = NewSyntaxError(syntaxErr) 1206 } 1207 return buf.String(), err 1208 } 1209 1210 switch len(statements) { 1211 case 1: 1212 qexpr, ok := statements[0].(parser.QueryExpression) 1213 if !ok { 1214 return buf.String(), NewInvalidValueExpressionError(parser.NewStringValue(expr)) 1215 } 1216 if err = writeEmbeddedExpression(ctx, scope, buf, qexpr); err != nil { 1217 return buf.String(), err 1218 } 1219 default: 1220 return buf.String(), NewInvalidValueExpressionError(parser.NewStringValue(expr)) 1221 } 1222 } 1223 } 1224 } 1225 if err = scanner.Err(); err != nil { 1226 return buf.String(), err 1227 } 1228 1229 return buf.String(), nil 1230 } 1231 1232 func writeEmbeddedExpression(ctx context.Context, scope *ReferenceScope, buf *bytes.Buffer, expr parser.QueryExpression) error { 1233 p, err := Evaluate(ctx, scope, expr) 1234 if err != nil { 1235 return err 1236 } 1237 s, _ := NewStringFormatter().Format("%s", []value.Primary{p}) 1238 buf.WriteString(s) 1239 return nil 1240 }