1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
24 // ListType describes a nested type in which each array slot contains
25 // a variable-size sequence of values, all having the same relative type.
26 type ListType struct {
30 func ListOfField(f Field) *ListType {
32 panic("arrow: nil type for list field")
34 return &ListType{elem: f}
37 // ListOf returns the list type with element type t.
38 // For example, if t represents int32, ListOf(t) represents []int32.
40 // ListOf panics if t is nil or invalid. NullableElem defaults to true
41 func ListOf(t DataType) *ListType {
43 panic("arrow: nil DataType")
45 return &ListType{elem: Field{Name: "item", Type: t, Nullable: true}}
48 // ListOfNonNullable is like ListOf but NullableElem defaults to false, indicating
49 // that the child type should be marked as non-nullable.
50 func ListOfNonNullable(t DataType) *ListType {
52 panic("arrow: nil DataType")
54 return &ListType{elem: Field{Name: "item", Type: t, Nullable: false}}
57 func (*ListType) ID() Type { return LIST }
58 func (*ListType) Name() string { return "list" }
60 func (t *ListType) String() string {
62 return fmt.Sprintf("list<%s: %s, nullable>", t.elem.Name, t.elem.Type)
64 return fmt.Sprintf("list<%s: %s>", t.elem.Name, t.elem.Type)
67 func (t *ListType) Fingerprint() string {
68 child := t.elem.Type.Fingerprint()
70 return typeFingerprint(t) + "{" + child + "}"
75 func (t *ListType) SetElemMetadata(md Metadata) { t.elem.Metadata = md }
77 func (t *ListType) SetElemNullable(n bool) { t.elem.Nullable = n }
79 // Elem returns the ListType's element type.
80 func (t *ListType) Elem() DataType { return t.elem.Type }
82 func (t *ListType) ElemField() Field {
86 // FixedSizeListType describes a nested type in which each array slot contains
87 // a fixed-size sequence of values, all having the same relative type.
88 type FixedSizeListType struct {
89 n int32 // number of elements in the list
93 func FixedSizeListOfField(n int32, f Field) *FixedSizeListType {
95 panic("arrow: nil DataType")
98 panic("arrow: invalid size")
100 return &FixedSizeListType{n: n, elem: f}
103 // FixedSizeListOf returns the list type with element type t.
104 // For example, if t represents int32, FixedSizeListOf(10, t) represents [10]int32.
106 // FixedSizeListOf panics if t is nil or invalid.
107 // FixedSizeListOf panics if n is <= 0.
108 // NullableElem defaults to true
109 func FixedSizeListOf(n int32, t DataType) *FixedSizeListType {
111 panic("arrow: nil DataType")
114 panic("arrow: invalid size")
116 return &FixedSizeListType{n: n, elem: Field{Name: "item", Type: t, Nullable: true}}
119 // FixedSizeListOfNonNullable is like FixedSizeListOf but NullableElem defaults to false
120 // indicating that the child type should be marked as non-nullable.
121 func FixedSizeListOfNonNullable(n int32, t DataType) *FixedSizeListType {
123 panic("arrow: nil DataType")
126 panic("arrow: invalid size")
128 return &FixedSizeListType{n: n, elem: Field{Name: "item", Type: t, Nullable: false}}
131 func (*FixedSizeListType) ID() Type { return FIXED_SIZE_LIST }
132 func (*FixedSizeListType) Name() string { return "fixed_size_list" }
133 func (t *FixedSizeListType) String() string {
135 return fmt.Sprintf("fixed_size_list<%s: %s, nullable>[%d]", t.elem.Name, t.elem.Type, t.n)
137 return fmt.Sprintf("fixed_size_list<%s: %s>[%d]", t.elem.Name, t.elem.Type, t.n)
140 // Elem returns the FixedSizeListType's element type.
141 func (t *FixedSizeListType) Elem() DataType { return t.elem.Type }
143 // Len returns the FixedSizeListType's size.
144 func (t *FixedSizeListType) Len() int32 { return t.n }
146 func (t *FixedSizeListType) ElemField() Field {
150 func (t *FixedSizeListType) Fingerprint() string {
151 child := t.elem.Type.Fingerprint()
153 return fmt.Sprintf("%s[%d]{%s}", typeFingerprint(t), t.n, child)
158 // StructType describes a nested type parameterized by an ordered sequence
159 // of relative types, called its fields.
160 type StructType struct {
166 // StructOf returns the struct type with fields fs.
168 // StructOf panics if there are duplicated fields.
169 // StructOf panics if there is a field with an invalid DataType.
170 func StructOf(fs ...Field) *StructType {
177 fields: make([]Field, n),
178 index: make(map[string]int, n),
180 for i, f := range fs {
182 panic("arrow: field with nil DataType")
187 Nullable: f.Nullable,
188 Metadata: f.Metadata.clone(),
190 if _, dup := t.index[f.Name]; dup {
191 panic(fmt.Errorf("arrow: duplicate field with name %q", f.Name))
199 func (*StructType) ID() Type { return STRUCT }
200 func (*StructType) Name() string { return "struct" }
202 func (t *StructType) String() string {
203 o := new(strings.Builder)
204 o.WriteString("struct<")
205 for i, f := range t.fields {
209 o.WriteString(fmt.Sprintf("%s: %v", f.Name, f.Type))
215 func (t *StructType) Fields() []Field { return t.fields }
216 func (t *StructType) Field(i int) Field { return t.fields[i] }
218 func (t *StructType) FieldByName(name string) (Field, bool) {
219 i, ok := t.index[name]
221 return Field{}, false
223 return t.fields[i], true
226 func (t *StructType) FieldIdx(name string) (int, bool) {
227 i, ok := t.index[name]
231 func (t *StructType) Fingerprint() string {
232 var b strings.Builder
233 b.WriteString(typeFingerprint(t))
235 for _, c := range t.fields {
236 child := c.Fingerprint()
247 type MapType struct {
252 func MapOf(key, item DataType) *MapType {
253 if key == nil || item == nil {
254 panic("arrow: nil key or item type for MapType")
257 return &MapType{value: ListOf(StructOf(Field{Name: "key", Type: key}, Field{Name: "value", Type: item, Nullable: true}))}
260 func (*MapType) ID() Type { return MAP }
261 func (*MapType) Name() string { return "map" }
263 func (t *MapType) String() string {
264 var o strings.Builder
265 o.WriteString(fmt.Sprintf("map<%s, %s",
266 t.value.Elem().(*StructType).Field(0).Type,
267 t.value.Elem().(*StructType).Field(1).Type))
269 o.WriteString(", keys_sorted")
275 func (t *MapType) KeyField() Field { return t.value.Elem().(*StructType).Field(0) }
276 func (t *MapType) KeyType() DataType { return t.KeyField().Type }
277 func (t *MapType) ItemField() Field { return t.value.Elem().(*StructType).Field(1) }
278 func (t *MapType) ItemType() DataType { return t.ItemField().Type }
279 func (t *MapType) ValueType() *StructType { return t.value.Elem().(*StructType) }
280 func (t *MapType) ValueField() Field {
287 func (t *MapType) SetItemNullable(nullable bool) {
288 t.value.Elem().(*StructType).fields[1].Nullable = nullable
291 func (t *MapType) Fingerprint() string {
292 keyFingerprint := t.KeyType().Fingerprint()
293 itemFingerprint := t.ItemType().Fingerprint()
294 if keyFingerprint == "" || itemFingerprint == "" {
298 fingerprint := typeFingerprint(t)
302 return fingerprint + "{" + keyFingerprint + itemFingerprint + "}"
306 Name string // Field name
307 Type DataType // The field's data type
308 Nullable bool // Fields can be nullable
309 Metadata Metadata // The field's metadata, if any
312 func (f Field) Fingerprint() string {
313 typeFingerprint := f.Type.Fingerprint()
314 if typeFingerprint == "" {
318 var b strings.Builder
325 b.WriteString(f.Name)
327 b.WriteString(typeFingerprint)
332 func (f Field) HasMetadata() bool { return f.Metadata.Len() != 0 }
334 func (f Field) Equal(o Field) bool {
336 case f.Name != o.Name:
338 case f.Nullable != o.Nullable:
340 case !TypeEqual(f.Type, o.Type, CheckMetadata()):
342 case !f.Metadata.Equal(o.Metadata):
348 func (f Field) String() string {
349 o := new(strings.Builder)
352 nullable = ", nullable"
354 fmt.Fprintf(o, "%s: type=%v%v", f.Name, f.Type, nullable)
356 fmt.Fprintf(o, "\n%*.smetadata: %v", len(f.Name)+2, "", f.Metadata)
362 _ DataType = (*ListType)(nil)
363 _ DataType = (*StructType)(nil)
364 _ DataType = (*MapType)(nil)