Eval implements the sql.Expression interface.
(ctx *sql.Context, row sql.Row)
| 72 | |
| 73 | // Eval implements the sql.Expression interface. |
| 74 | func (c *ExplicitCast) Eval(ctx *sql.Context, row sql.Row) (any, error) { |
| 75 | if !c.castToType.IsResolvedType() { |
| 76 | return nil, errors.Errorf("cannot call ExplicitCast.Eval with unresolved cast to type: %s", c.castToType.String()) |
| 77 | } |
| 78 | |
| 79 | val, err := c.sqlChild.Eval(ctx, row) |
| 80 | if err != nil { |
| 81 | return nil, err |
| 82 | } |
| 83 | sourceType, ok := c.sqlChild.Type(ctx).(*pgtypes.DoltgresType) |
| 84 | if !ok { |
| 85 | // We'll leverage GMSCast to handle the conversion from a GMS type to a Doltgres type. |
| 86 | // Rather than re-evaluating the expression, we put the result in a literal. |
| 87 | gmsCast := NewGMSCast(expression.NewLiteral(val, c.sqlChild.Type(ctx))) |
| 88 | val, err = gmsCast.Eval(ctx, row) |
| 89 | if err != nil { |
| 90 | return nil, err |
| 91 | } |
| 92 | sourceType = gmsCast.DoltgresType(ctx) |
| 93 | } |
| 94 | |
| 95 | baseCastToType := checkForDomainType(c.castToType) |
| 96 | castsColl, err := core.GetCastsCollectionFromContext(ctx, "") |
| 97 | if err != nil { |
| 98 | return nil, err |
| 99 | } |
| 100 | cast, err := castsColl.GetExplicitCast(ctx, sourceType, baseCastToType) |
| 101 | if err != nil { |
| 102 | return nil, err |
| 103 | } |
| 104 | if !cast.ID.IsValid() { |
| 105 | return nil, errors.Errorf( |
| 106 | "EXPLICIT CAST: cast from `%s` to `%s` does not exist: %s", |
| 107 | sourceType.String(), c.castToType.String(), c.sqlChild.String(), |
| 108 | ) |
| 109 | } |
| 110 | if val == nil { |
| 111 | if c.castToType.TypType == pgtypes.TypeType_Domain && !c.domainNullable { |
| 112 | return nil, pgtypes.ErrDomainDoesNotAllowNullValues.New(c.castToType.Name()) |
| 113 | } |
| 114 | if !cast.Function.IsValid() { |
| 115 | return nil, nil |
| 116 | } |
| 117 | } |
| 118 | castResult, err := cast.Eval(ctx, val, sourceType, c.castToType) |
| 119 | if err != nil { |
| 120 | // For string types and string array types, we intentionally ignore the error as using a length-restricted cast |
| 121 | // is a way to intentionally truncate the data. All string types will always return the truncated result, even |
| 122 | // during an error, so it's safe to use. |
| 123 | castToType := c.castToType |
| 124 | if c.castToType.IsArrayType() { |
| 125 | castToType = c.castToType.ArrayBaseType() |
| 126 | } |
| 127 | // A nil result will be returned if there's a critical error, which we should never ignore. |
| 128 | if castToType.TypCategory != pgtypes.TypeCategory_StringTypes || castResult == nil { |
| 129 | return nil, err |
| 130 | } |
| 131 | } |
nothing calls this directly
no test coverage detected