RowIter implements the interface sql.ExecSourceRel.
(ctx *sql.Context, r sql.Row)
| 86 | |
| 87 | // RowIter implements the interface sql.ExecSourceRel. |
| 88 | func (c *CreateType) RowIter(ctx *sql.Context, r sql.Row) (sql.RowIter, error) { |
| 89 | var userRole auth.Role |
| 90 | auth.LockRead(func() { |
| 91 | userRole = auth.GetRole(ctx.Client().User) |
| 92 | }) |
| 93 | if !userRole.IsValid() { |
| 94 | return nil, errors.Errorf(`role "%s" does not exist`, ctx.Client().User) |
| 95 | } |
| 96 | |
| 97 | schema, err := core.GetSchemaName(ctx, nil, c.SchemaName) |
| 98 | if err != nil { |
| 99 | return nil, err |
| 100 | } |
| 101 | collection, err := core.GetTypesCollectionFromContext(ctx, "") |
| 102 | if err != nil { |
| 103 | return nil, err |
| 104 | } |
| 105 | |
| 106 | typeID := id.NewType(schema, c.Name) |
| 107 | arrayID := id.NewType(schema, "_"+c.Name) |
| 108 | |
| 109 | if collection.HasType(ctx, typeID) { |
| 110 | // TODO: if the existing type is array type, it updates the array type name and creates the new type. |
| 111 | return nil, types.ErrTypeAlreadyExists.New(c.Name) |
| 112 | } |
| 113 | |
| 114 | var newType *types.DoltgresType |
| 115 | switch c.typType { |
| 116 | case types.TypeType_Pseudo: |
| 117 | newType = types.NewShellType(ctx, typeID) |
| 118 | case types.TypeType_Enum: |
| 119 | enumLabelMap := make(map[string]types.EnumLabel) |
| 120 | for i, l := range c.Labels { |
| 121 | if _, ok := enumLabelMap[l]; ok { |
| 122 | // DETAIL: Key (enumtypid, enumlabel)=(16702, ok) already exists. |
| 123 | return nil, errors.Errorf(`duplicate key value violates unique constraint "pg_enum_typid_label_index"`) |
| 124 | } |
| 125 | labelID := id.NewEnumLabel(typeID, l) |
| 126 | el := types.NewEnumLabel(ctx, labelID, float32(i+1)) |
| 127 | enumLabelMap[l] = el |
| 128 | } |
| 129 | newType = types.NewEnumType(ctx, arrayID, typeID, enumLabelMap) |
| 130 | // TODO: store labels somewhere |
| 131 | case types.TypeType_Composite: |
| 132 | // TODO: non-composite types have a zero oid for their relID, which for us would be a null ID. |
| 133 | // We need to find a way to distinguish a null ID from a composite type that does not reference a table |
| 134 | // (which is what relID points to if it represents a table row's composite type) |
| 135 | relID := id.Null |
| 136 | attrs := make([]types.CompositeAttribute, len(c.AsTypes)) |
| 137 | for i, a := range c.AsTypes { |
| 138 | attrs[i] = types.NewCompositeAttribute(ctx, relID, a.AttrName, a.Typ, int16(i+1), a.Collation) |
| 139 | } |
| 140 | newType = types.NewCompositeType(ctx, relID, &types.DoltgresType{ID: arrayID, IsUnresolved: true}, typeID, attrs) |
| 141 | default: |
| 142 | return nil, errors.Errorf("create type as %s is not supported", c.typType) |
| 143 | } |
| 144 | |
| 145 | err = collection.CreateType(ctx, newType) |
nothing calls this directly
no test coverage detected