github.com/apache/arrow/go/v7@v7.0.1/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/v7/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. panics if repeated. 34 // <element-repetition> can only be optional or required. panics if repeated. 35 func ListOf(n Node, rep parquet.Repetition, fieldID int32) (*GroupNode, error) { 36 if rep == parquet.Repetitions.Repeated || n.RepetitionType() == parquet.Repetitions.Repeated { 37 return nil, xerrors.New("parquet: listof repetition and element repetition must not be repeated.") 38 } 39 listName := n.Name() 40 41 switch n := n.(type) { 42 case *PrimitiveNode: 43 n.name = "element" 44 case *GroupNode: 45 n.name = "element" 46 } 47 48 list, err := NewGroupNode("list" /* name */, parquet.Repetitions.Repeated, FieldList{n}, -1 /* fieldID */) 49 if err != nil { 50 return nil, err 51 } 52 return NewGroupNodeLogical(listName, rep, FieldList{list}, ListLogicalType{}, fieldID) 53 } 54 55 // MapOf is a convenience helper function to create a properly structured 56 // parquet map node setup according to the Parquet Spec. 57 // 58 // <map-repetition> group <name> (MAP) { 59 // repeated group key_value { 60 // required <key-type> key; 61 // <value-repetition> <value-type> value; 62 // } 63 // } 64 // 65 // key node will be renamed to "key", value node if not nil will be renamed to "value" 66 // 67 // <map-repetition> must be only optional or required. panics if repeated is passed. 68 // 69 // the key node *must* be required repetition. panics if optional or repeated 70 // 71 // value node can be nil (omitted) or have a repetition of required or optional *only*. 72 // panics if value node is not nil and has a repetition of repeated. 73 func MapOf(name string, key Node, value Node, mapRep parquet.Repetition, fieldID int32) (*GroupNode, error) { 74 if mapRep == parquet.Repetitions.Repeated { 75 return nil, xerrors.New("parquet: map repetition cannot be Repeated") 76 } 77 if key.RepetitionType() != parquet.Repetitions.Required { 78 return nil, xerrors.New("parquet: map key repetition must be Required") 79 } 80 if value != nil { 81 if value.RepetitionType() == parquet.Repetitions.Repeated { 82 return nil, xerrors.New("parquet: map value cannot have repetition Repeated") 83 } 84 switch value := value.(type) { 85 case *PrimitiveNode: 86 value.name = "value" 87 case *GroupNode: 88 value.name = "value" 89 } 90 } 91 92 switch key := key.(type) { 93 case *PrimitiveNode: 94 key.name = "key" 95 case *GroupNode: 96 key.name = "key" 97 } 98 99 keyval := FieldList{key} 100 if value != nil { 101 keyval = append(keyval, value) 102 } 103 104 kvNode, err := NewGroupNode("key_value" /* name */, parquet.Repetitions.Repeated, keyval, -1 /* fieldID */) 105 if err != nil { 106 return nil, err 107 } 108 return NewGroupNodeLogical(name, mapRep, FieldList{kvNode}, MapLogicalType{}, fieldID) 109 }