(c *ast.CaseExpr, inType super.Type)
| 678 | } |
| 679 | |
| 680 | func (t *translator) semCaseExpr(c *ast.CaseExpr, inType super.Type) (sem.Expr, super.Type) { |
| 681 | e, exprType := t.exprNullable(c.Expr, inType) |
| 682 | var out sem.Expr |
| 683 | var elseType super.Type |
| 684 | if c.Else != nil { |
| 685 | out, elseType = t.expr(c.Else, inType) |
| 686 | } else if t.scope.sql != nil { |
| 687 | out = &sem.PrimitiveExpr{Node: c, Value: "null"} |
| 688 | elseType = super.TypeNull |
| 689 | } else if e != nil { |
| 690 | out = sem.NewStructuredError(c, "case: no clause matched and no else provided", e) |
| 691 | elseType = t.checker.unknown |
| 692 | } else { |
| 693 | out = sem.NewStringError(c, "case: no clause matched and no else provided") |
| 694 | elseType = t.checker.unknown |
| 695 | } |
| 696 | types := []super.Type{elseType} |
| 697 | var thenErrs [][]errloc |
| 698 | for _, when := range slices.Backward(c.Whens) { |
| 699 | cond, condType := t.expr(when.Cond, inType) |
| 700 | if e != nil { |
| 701 | cond = sem.NewBinaryExpr(c, "==", e, cond) |
| 702 | t.checker.comparison(exprType, condType) |
| 703 | } else { |
| 704 | t.checker.boolean(when.Cond, condType) |
| 705 | } |
| 706 | t.checker.pushErrs() |
| 707 | then, thenType := t.expr(when.Then, inType) |
| 708 | out = &sem.CondExpr{ |
| 709 | Node: c, |
| 710 | Cond: cond, |
| 711 | Then: then, |
| 712 | Else: out, |
| 713 | } |
| 714 | if errs := t.checker.popErrs(); len(errs) != 0 { |
| 715 | thenErrs = append(thenErrs, errs) |
| 716 | } |
| 717 | types = append(types, thenType) |
| 718 | } |
| 719 | if len(thenErrs) == len(c.Whens) { |
| 720 | // All the paths have errors so report them. |
| 721 | // If at least one path is ok, then we deem the overall expression valid |
| 722 | // an do not report any errors. |
| 723 | for _, errs := range thenErrs { |
| 724 | t.checker.keepErrs(errs) |
| 725 | } |
| 726 | } |
| 727 | return out, t.checker.fuse(types) |
| 728 | } |
| 729 | |
| 730 | func (t *translator) semCall(call *ast.CallExpr, inType super.Type) (sem.Expr, super.Type) { |
| 731 | if e, typ := t.maybeConvertAgg(call, inType); e != nil { |
no test coverage detected