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  }