RowIter implements the interface sql.ExecSourceRel.
(ctx *sql.Context, r sql.Row)
| 78 | |
| 79 | // RowIter implements the interface sql.ExecSourceRel. |
| 80 | func (c *CreateCast) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) { |
| 81 | castCollection, err := core.GetCastsCollectionFromContext(ctx, "") |
| 82 | if err != nil { |
| 83 | return nil, err |
| 84 | } |
| 85 | newCast := casts.Cast{ |
| 86 | ID: id.NewCast(c.Source.ID, c.Target.ID), |
| 87 | CastType: c.Type, |
| 88 | } |
| 89 | if c.Source.ID == c.Target.ID { |
| 90 | return nil, errors.New("source data type and target data type are the same") |
| 91 | } |
| 92 | switch c.CreateType { |
| 93 | case tree.CreateCastType_WithFunction: |
| 94 | if len(c.FuncParams) < 1 || len(c.FuncParams) > 3 { |
| 95 | return nil, errors.New("cast function must take one to three arguments") |
| 96 | } |
| 97 | if len(c.FuncParams) >= 2 && c.FuncParams[1].Type.ID != pgtypes.Int32.ID { |
| 98 | return nil, errors.New("second argument of cast function must be type integer") |
| 99 | } |
| 100 | if len(c.FuncParams) >= 3 && c.FuncParams[2].Type.ID != pgtypes.Bool.ID { |
| 101 | return nil, errors.New("third argument of cast function must be type boolean") |
| 102 | } |
| 103 | schemaName, err := core.GetSchemaName(ctx, nil, c.FuncSchema) |
| 104 | if err != nil { |
| 105 | return nil, err |
| 106 | } |
| 107 | paramTypes := make([]id.Type, len(c.FuncParams)) |
| 108 | for i, param := range c.FuncParams { |
| 109 | paramTypes[i] = param.Type.ID |
| 110 | } |
| 111 | funcID := id.NewFunction(schemaName, c.FuncName, paramTypes...) |
| 112 | funcCollection, err := core.GetFunctionsCollectionFromContext(ctx, "") |
| 113 | if err != nil { |
| 114 | return nil, err |
| 115 | } |
| 116 | if !funcCollection.HasFunction(ctx, funcID) { |
| 117 | return nil, errors.Errorf("function %s does not exist", funcID.DisplayString()) |
| 118 | } |
| 119 | f, err := funcCollection.GetFunction(ctx, funcID) |
| 120 | if err != nil { |
| 121 | return nil, err |
| 122 | } |
| 123 | if f.ParameterTypes[0] != c.Source.ID { |
| 124 | // Although the error mentions binary-coercible, we can't actually support that due to how types work in Go. |
| 125 | // Our bit representations of values will differ from Postgres. |
| 126 | return nil, errors.New("argument of cast function must match or be binary-coercible from source data type") |
| 127 | } |
| 128 | if f.ReturnType != c.Target.ID { |
| 129 | // Although the error mentions binary-coercible, we can't actually support that due to how types work in Go. |
| 130 | // Our bit representations of values will differ from Postgres. |
| 131 | return nil, errors.New("return data type of cast function must match or be binary-coercible to target data type") |
| 132 | } |
| 133 | newCast.Function = funcID |
| 134 | case tree.CreateCastType_WithoutFunction: |
| 135 | if c.Source.IsCompositeType() || c.Target.IsCompositeType() { |
| 136 | return nil, errors.New("composite data types are not binary-compatible") |
| 137 | } |
nothing calls this directly
no test coverage detected