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  }