github.com/apache/arrow/go/v14@v14.0.2/parquet/schema/helpers.go (about) 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 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 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. 16 17 package schema 18 19 import ( 20 "github.com/apache/arrow/go/v14/parquet" 21 "golang.org/x/xerrors" 22 ) 23 24 // ListOf is a convenience helper function to create a properly structured 25 // list structure according to the Parquet Spec. 26 // 27 // <list-repetition> group <name> (LIST) { 28 // repeated group list { 29 // <element-repetition> <element-type> element; 30 // } 31 // } 32 // 33 // <list-repetition> can only be optional or required. 34 // <element-repetition> can only be optional or required. 35 func ListOf(n Node, rep parquet.Repetition, fieldID int32) (*GroupNode, error) { 36 return ListOfWithName(n.Name(), n, rep, fieldID) 37 } 38 39 // ListOf is a convenience helper function to create a properly structured 40 // list structure according to the Parquet Spec. 41 // 42 // <list-repetition> group <name> (LIST) { 43 // repeated group list { 44 // <element-repetition> <element-type> element; 45 // } 46 // } 47 // 48 // <list-repetition> can only be optional or required. 49 // <element-repetition> can only be optional or required. 50 func ListOfWithName(listName string, element Node, rep parquet.Repetition, fieldID int32) (*GroupNode, error) { 51 if rep == parquet.Repetitions.Repeated { 52 return nil, xerrors.Errorf("parquet: listof repetition must not be repeated, got :%s", rep) 53 } 54 55 if element.RepetitionType() == parquet.Repetitions.Repeated { 56 return nil, xerrors.Errorf("parquet: element repetition must not be repeated, got: %s", element.RepetitionType()) 57 } 58 59 switch n := element.(type) { 60 case *PrimitiveNode: 61 n.name = "element" 62 case *GroupNode: 63 n.name = "element" 64 } 65 66 list, err := NewGroupNode("list" /* name */, parquet.Repetitions.Repeated, FieldList{element}, -1 /* fieldID */) 67 if err != nil { 68 return nil, err 69 } 70 71 return NewGroupNodeLogical(listName, rep, FieldList{list}, ListLogicalType{}, fieldID) 72 } 73 74 // MapOf is a convenience helper function to create a properly structured 75 // parquet map node setup according to the Parquet Spec. 76 // 77 // <map-repetition> group <name> (MAP) { 78 // repeated group key_value { 79 // required <key-type> key; 80 // <value-repetition> <value-type> value; 81 // } 82 // } 83 // 84 // key node will be renamed to "key", value node if not nil will be renamed to "value" 85 // 86 // <map-repetition> must be only optional or required. panics if repeated is passed. 87 // 88 // the key node *must* be required repetition. panics if optional or repeated 89 // 90 // value node can be nil (omitted) or have a repetition of required or optional *only*. 91 func MapOf(name string, key Node, value Node, mapRep parquet.Repetition, fieldID int32) (*GroupNode, error) { 92 if mapRep == parquet.Repetitions.Repeated { 93 return nil, xerrors.Errorf("parquet: map repetition cannot be Repeated, got: %s", mapRep) 94 } 95 96 if key.RepetitionType() != parquet.Repetitions.Required { 97 return nil, xerrors.Errorf("parquet: map key repetition must be Required, got: %s", key.RepetitionType()) 98 } 99 100 if value != nil { 101 if value.RepetitionType() == parquet.Repetitions.Repeated { 102 return nil, xerrors.New("parquet: map value cannot have repetition Repeated") 103 } 104 switch value := value.(type) { 105 case *PrimitiveNode: 106 value.name = "value" 107 case *GroupNode: 108 value.name = "value" 109 } 110 } 111 112 switch key := key.(type) { 113 case *PrimitiveNode: 114 key.name = "key" 115 case *GroupNode: 116 key.name = "key" 117 } 118 119 keyval := FieldList{key} 120 if value != nil { 121 keyval = append(keyval, value) 122 } 123 124 kvNode, err := NewGroupNode("key_value" /* name */, parquet.Repetitions.Repeated, keyval, -1 /* fieldID */) 125 if err != nil { 126 return nil, err 127 } 128 return NewGroupNodeLogical(name, mapRep, FieldList{kvNode}, MapLogicalType{}, fieldID) 129 }