]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/arrow/go/parquet/schema/helpers.go
import quincy 17.2.0
[ceph.git] / ceph / src / arrow / go / parquet / schema / helpers.go
diff --git a/ceph/src/arrow/go/parquet/schema/helpers.go b/ceph/src/arrow/go/parquet/schema/helpers.go
new file mode 100644 (file)
index 0000000..7c8faa3
--- /dev/null
@@ -0,0 +1,109 @@
+// 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.
+//
+// <list-repetition> group <name> (LIST) {
+//   repeated group list {
+//     <element-repetition> <element-type> element;
+//   }
+// }
+//
+// <list-repetition> can only be optional or required. panics if repeated.
+// <element-repetition> 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.
+//
+// <map-repetition> group <name> (MAP) {
+//      repeated group key_value {
+//        required <key-type> key;
+//     <value-repetition> <value-type> value;
+//   }
+// }
+//
+// key node will be renamed to "key", value node if not nil will be renamed to "value"
+//
+// <map-repetition> 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)
+}