// Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package schema import ( "github.com/apache/arrow/go/v6/parquet" "golang.org/x/xerrors" ) // ListOf is a convenience helper function to create a properly structured // list structure according to the Parquet Spec. // // group (LIST) { // repeated group list { // element; // } // } // // can only be optional or required. panics if repeated. // can only be optional or required. panics if repeated. func ListOf(n Node, rep parquet.Repetition, fieldID int32) (*GroupNode, error) { if rep == parquet.Repetitions.Repeated || n.RepetitionType() == parquet.Repetitions.Repeated { return nil, xerrors.New("parquet: listof repetition and element repetition must not be repeated.") } listName := n.Name() switch n := n.(type) { case *PrimitiveNode: n.name = "element" case *GroupNode: n.name = "element" } list, err := NewGroupNode("list" /* name */, parquet.Repetitions.Repeated, FieldList{n}, -1 /* fieldID */) if err != nil { return nil, err } return NewGroupNodeLogical(listName, rep, FieldList{list}, ListLogicalType{}, fieldID) } // MapOf is a convenience helper function to create a properly structured // parquet map node setup according to the Parquet Spec. // // group (MAP) { // repeated group key_value { // required key; // value; // } // } // // key node will be renamed to "key", value node if not nil will be renamed to "value" // // must be only optional or required. panics if repeated is passed. // // the key node *must* be required repetition. panics if optional or repeated // // value node can be nil (omitted) or have a repetition of required or optional *only*. // panics if value node is not nil and has a repetition of repeated. func MapOf(name string, key Node, value Node, mapRep parquet.Repetition, fieldID int32) (*GroupNode, error) { if mapRep == parquet.Repetitions.Repeated { return nil, xerrors.New("parquet: map repetition cannot be Repeated") } if key.RepetitionType() != parquet.Repetitions.Required { return nil, xerrors.New("parquet: map key repetition must be Required") } if value != nil { if value.RepetitionType() == parquet.Repetitions.Repeated { return nil, xerrors.New("parquet: map value cannot have repetition Repeated") } switch value := value.(type) { case *PrimitiveNode: value.name = "value" case *GroupNode: value.name = "value" } } switch key := key.(type) { case *PrimitiveNode: key.name = "key" case *GroupNode: key.name = "key" } keyval := FieldList{key} if value != nil { keyval = append(keyval, value) } kvNode, err := NewGroupNode("key_value" /* name */, parquet.Repetitions.Repeated, keyval, -1 /* fieldID */) if err != nil { return nil, err } return NewGroupNodeLogical(name, mapRep, FieldList{kvNode}, MapLogicalType{}, fieldID) }