ResolveAsType implements the Constant interface.
(ctx *SemaContext, typ *types.T)
| 286 | |
| 287 | // ResolveAsType implements the Constant interface. |
| 288 | func (expr *NumVal) ResolveAsType(ctx *SemaContext, typ *types.T) (Datum, error) { |
| 289 | switch typ.Family() { |
| 290 | case types.IntFamily: |
| 291 | // We may have already set expr.resInt in AsInt64. |
| 292 | if expr.resInt == 0 { |
| 293 | if _, err := expr.AsInt64(); err != nil { |
| 294 | return nil, err |
| 295 | } |
| 296 | } |
| 297 | return &expr.resInt, nil |
| 298 | case types.FloatFamily: |
| 299 | f, _ := constant.Float64Val(expr.value) |
| 300 | if expr.negative { |
| 301 | f = -f |
| 302 | } |
| 303 | expr.resFloat = DFloat(f) |
| 304 | return &expr.resFloat, nil |
| 305 | case types.DecimalFamily: |
| 306 | dd := &expr.resDecimal |
| 307 | s := expr.origString |
| 308 | if s == "" { |
| 309 | // TODO(nvanbenschoten): We should propagate width through constant folding so that we |
| 310 | // can control precision on folded values as well. |
| 311 | s = expr.ExactString() |
| 312 | } |
| 313 | if idx := strings.IndexRune(s, '/'); idx != -1 { |
| 314 | // Handle constant.ratVal, which will return a rational string |
| 315 | // like 6/7. If only we could call big.Rat.FloatString() on it... |
| 316 | num, den := s[:idx], s[idx+1:] |
| 317 | if err := dd.SetString(num); err != nil { |
| 318 | return nil, pgerror.Wrapf(err, pgcode.Syntax, |
| 319 | "could not evaluate numerator of %v as Datum type DDecimal from string %q", |
| 320 | expr, num) |
| 321 | } |
| 322 | // TODO(nvanbenschoten): Should we try to avoid this allocation? |
| 323 | denDec, err := ParseDDecimal(den) |
| 324 | if err != nil { |
| 325 | return nil, pgerror.Wrapf(err, pgcode.Syntax, |
| 326 | "could not evaluate denominator %v as Datum type DDecimal from string %q", |
| 327 | expr, den) |
| 328 | } |
| 329 | if cond, err := DecimalCtx.Quo(&dd.Decimal, &dd.Decimal, &denDec.Decimal); err != nil { |
| 330 | if cond.DivisionByZero() { |
| 331 | return nil, ErrDivByZero |
| 332 | } |
| 333 | return nil, err |
| 334 | } |
| 335 | } else { |
| 336 | if err := dd.SetString(s); err != nil { |
| 337 | return nil, pgerror.Wrapf(err, pgcode.Syntax, |
| 338 | "could not evaluate %v as Datum type DDecimal from string %q", expr, s) |
| 339 | } |
| 340 | } |
| 341 | if !dd.IsZero() { |
| 342 | // Negative zero does not exist for DECIMAL, in that case we ignore the |
| 343 | // sign. Otherwise XOR the signs of the expr and the decimal value |
| 344 | // contained in the expr, since the negative may have been folded into the |
| 345 | // inner decimal. |
nothing calls this directly
no test coverage detected