// automatically generated by the FlatBuffers compiler, do not modify


#ifndef FLATBUFFERS_GENERATED_RELATION_ORG_APACHE_ARROW_COMPUTEIR_FLATBUF_H_
#define FLATBUFFERS_GENERATED_RELATION_ORG_APACHE_ARROW_COMPUTEIR_FLATBUF_H_

#include "flatbuffers/flatbuffers.h"

#include "Schema_generated.h"
#include "Expression_generated.h"
#include "Literal_generated.h"

namespace org {
namespace apache {
namespace arrow {
namespace computeir {
namespace flatbuf {

struct RelId;
struct RelIdBuilder;

struct Filter;
struct FilterBuilder;

struct Project;
struct ProjectBuilder;

struct Grouping;
struct GroupingBuilder;

struct Aggregate;
struct AggregateBuilder;

struct Join;
struct JoinBuilder;

struct OrderBy;
struct OrderByBuilder;

struct Limit;
struct LimitBuilder;

struct SetOperation;
struct SetOperationBuilder;

struct LiteralColumn;
struct LiteralColumnBuilder;

struct LiteralRelation;
struct LiteralRelationBuilder;

struct Source;
struct SourceBuilder;

struct Relation;
struct RelationBuilder;

enum class JoinKind : uint8_t {
  Anti = 0,
  Cross = 1,
  FullOuter = 2,
  Inner = 3,
  LeftOuter = 4,
  LeftSemi = 5,
  RightOuter = 6,
  MIN = Anti,
  MAX = RightOuter
};

inline const JoinKind (&EnumValuesJoinKind())[7] {
  static const JoinKind values[] = {
    JoinKind::Anti,
    JoinKind::Cross,
    JoinKind::FullOuter,
    JoinKind::Inner,
    JoinKind::LeftOuter,
    JoinKind::LeftSemi,
    JoinKind::RightOuter
  };
  return values;
}

inline const char * const *EnumNamesJoinKind() {
  static const char * const names[8] = {
    "Anti",
    "Cross",
    "FullOuter",
    "Inner",
    "LeftOuter",
    "LeftSemi",
    "RightOuter",
    nullptr
  };
  return names;
}

inline const char *EnumNameJoinKind(JoinKind e) {
  if (flatbuffers::IsOutRange(e, JoinKind::Anti, JoinKind::RightOuter)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesJoinKind()[index];
}

/// The kind of set operation being performed.
enum class SetOpKind : uint8_t {
  Union = 0,
  Intersection = 1,
  Difference = 2,
  MIN = Union,
  MAX = Difference
};

inline const SetOpKind (&EnumValuesSetOpKind())[3] {
  static const SetOpKind values[] = {
    SetOpKind::Union,
    SetOpKind::Intersection,
    SetOpKind::Difference
  };
  return values;
}

inline const char * const *EnumNamesSetOpKind() {
  static const char * const names[4] = {
    "Union",
    "Intersection",
    "Difference",
    nullptr
  };
  return names;
}

inline const char *EnumNameSetOpKind(SetOpKind e) {
  if (flatbuffers::IsOutRange(e, SetOpKind::Union, SetOpKind::Difference)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesSetOpKind()[index];
}

/// The varieties of relations
enum class RelationImpl : uint8_t {
  NONE = 0,
  Aggregate = 1,
  Filter = 2,
  Join = 3,
  Limit = 4,
  LiteralRelation = 5,
  OrderBy = 6,
  Project = 7,
  SetOperation = 8,
  Source = 9,
  MIN = NONE,
  MAX = Source
};

inline const RelationImpl (&EnumValuesRelationImpl())[10] {
  static const RelationImpl values[] = {
    RelationImpl::NONE,
    RelationImpl::Aggregate,
    RelationImpl::Filter,
    RelationImpl::Join,
    RelationImpl::Limit,
    RelationImpl::LiteralRelation,
    RelationImpl::OrderBy,
    RelationImpl::Project,
    RelationImpl::SetOperation,
    RelationImpl::Source
  };
  return values;
}

inline const char * const *EnumNamesRelationImpl() {
  static const char * const names[11] = {
    "NONE",
    "Aggregate",
    "Filter",
    "Join",
    "Limit",
    "LiteralRelation",
    "OrderBy",
    "Project",
    "SetOperation",
    "Source",
    nullptr
  };
  return names;
}

inline const char *EnumNameRelationImpl(RelationImpl e) {
  if (flatbuffers::IsOutRange(e, RelationImpl::NONE, RelationImpl::Source)) return "";
  const size_t index = static_cast<size_t>(e);
  return EnumNamesRelationImpl()[index];
}

template<typename T> struct RelationImplTraits {
  static const RelationImpl enum_value = RelationImpl::NONE;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::Aggregate> {
  static const RelationImpl enum_value = RelationImpl::Aggregate;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::Filter> {
  static const RelationImpl enum_value = RelationImpl::Filter;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::Join> {
  static const RelationImpl enum_value = RelationImpl::Join;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::Limit> {
  static const RelationImpl enum_value = RelationImpl::Limit;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::LiteralRelation> {
  static const RelationImpl enum_value = RelationImpl::LiteralRelation;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::OrderBy> {
  static const RelationImpl enum_value = RelationImpl::OrderBy;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::Project> {
  static const RelationImpl enum_value = RelationImpl::Project;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::SetOperation> {
  static const RelationImpl enum_value = RelationImpl::SetOperation;
};

template<> struct RelationImplTraits<org::apache::arrow::computeir::flatbuf::Source> {
  static const RelationImpl enum_value = RelationImpl::Source;
};

bool VerifyRelationImpl(flatbuffers::Verifier &verifier, const void *obj, RelationImpl type);
bool VerifyRelationImplVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);

/// An identifier for relations in a query.
///
/// A table is used here to allow plan implementations optionality.
struct RelId FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef RelIdBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4
  };
  uint64_t id() const {
    return GetField<uint64_t>(VT_ID, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint64_t>(verifier, VT_ID) &&
           verifier.EndTable();
  }
};

struct RelIdBuilder {
  typedef RelId Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(uint64_t id) {
    fbb_.AddElement<uint64_t>(RelId::VT_ID, id, 0);
  }
  explicit RelIdBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RelIdBuilder &operator=(const RelIdBuilder &);
  flatbuffers::Offset<RelId> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<RelId>(end);
    return o;
  }
};

inline flatbuffers::Offset<RelId> CreateRelId(
    flatbuffers::FlatBufferBuilder &_fbb,
    uint64_t id = 0) {
  RelIdBuilder builder_(_fbb);
  builder_.add_id(id);
  return builder_.Finish();
}

/// Filter operation
struct Filter FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef FilterBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_REL = 6,
    VT_PREDICATE = 8
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// Child relation
  const org::apache::arrow::computeir::flatbuf::Relation *rel() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Relation *>(VT_REL);
  }
  /// The expression which will be evaluated against input rows
  /// to determine whether they should be excluded from the
  /// filter relation's output.
  const org::apache::arrow::computeir::flatbuf::Expression *predicate() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Expression *>(VT_PREDICATE);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_REL) &&
           verifier.VerifyTable(rel()) &&
           VerifyOffsetRequired(verifier, VT_PREDICATE) &&
           verifier.VerifyTable(predicate()) &&
           verifier.EndTable();
  }
};

struct FilterBuilder {
  typedef Filter Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(Filter::VT_ID, id);
  }
  void add_rel(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel) {
    fbb_.AddOffset(Filter::VT_REL, rel);
  }
  void add_predicate(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression> predicate) {
    fbb_.AddOffset(Filter::VT_PREDICATE, predicate);
  }
  explicit FilterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  FilterBuilder &operator=(const FilterBuilder &);
  flatbuffers::Offset<Filter> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Filter>(end);
    fbb_.Required(o, Filter::VT_REL);
    fbb_.Required(o, Filter::VT_PREDICATE);
    return o;
  }
};

inline flatbuffers::Offset<Filter> CreateFilter(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression> predicate = 0) {
  FilterBuilder builder_(_fbb);
  builder_.add_predicate(predicate);
  builder_.add_rel(rel);
  builder_.add_id(id);
  return builder_.Finish();
}

/// Projection
struct Project FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef ProjectBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_REL = 6,
    VT_EXPRESSIONS = 8
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// Child relation
  const org::apache::arrow::computeir::flatbuf::Relation *rel() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Relation *>(VT_REL);
  }
  /// Expressions which will be evaluated to produce to
  /// the rows of the project relation's output.
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *expressions() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *>(VT_EXPRESSIONS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_REL) &&
           verifier.VerifyTable(rel()) &&
           VerifyOffsetRequired(verifier, VT_EXPRESSIONS) &&
           verifier.VerifyVector(expressions()) &&
           verifier.VerifyVectorOfTables(expressions()) &&
           verifier.EndTable();
  }
};

struct ProjectBuilder {
  typedef Project Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(Project::VT_ID, id);
  }
  void add_rel(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel) {
    fbb_.AddOffset(Project::VT_REL, rel);
  }
  void add_expressions(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>> expressions) {
    fbb_.AddOffset(Project::VT_EXPRESSIONS, expressions);
  }
  explicit ProjectBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  ProjectBuilder &operator=(const ProjectBuilder &);
  flatbuffers::Offset<Project> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Project>(end);
    fbb_.Required(o, Project::VT_REL);
    fbb_.Required(o, Project::VT_EXPRESSIONS);
    return o;
  }
};

inline flatbuffers::Offset<Project> CreateProject(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>> expressions = 0) {
  ProjectBuilder builder_(_fbb);
  builder_.add_expressions(expressions);
  builder_.add_rel(rel);
  builder_.add_id(id);
  return builder_.Finish();
}

inline flatbuffers::Offset<Project> CreateProjectDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *expressions = nullptr) {
  auto expressions__ = expressions ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>(*expressions) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateProject(
      _fbb,
      id,
      rel,
      expressions__);
}

/// A set of grouping keys
struct Grouping FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef GroupingBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_KEYS = 4
  };
  /// Expressions to group by
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *keys() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *>(VT_KEYS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffsetRequired(verifier, VT_KEYS) &&
           verifier.VerifyVector(keys()) &&
           verifier.VerifyVectorOfTables(keys()) &&
           verifier.EndTable();
  }
};

struct GroupingBuilder {
  typedef Grouping Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_keys(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>> keys) {
    fbb_.AddOffset(Grouping::VT_KEYS, keys);
  }
  explicit GroupingBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  GroupingBuilder &operator=(const GroupingBuilder &);
  flatbuffers::Offset<Grouping> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Grouping>(end);
    fbb_.Required(o, Grouping::VT_KEYS);
    return o;
  }
};

inline flatbuffers::Offset<Grouping> CreateGrouping(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>> keys = 0) {
  GroupingBuilder builder_(_fbb);
  builder_.add_keys(keys);
  return builder_.Finish();
}

inline flatbuffers::Offset<Grouping> CreateGroupingDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *keys = nullptr) {
  auto keys__ = keys ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>(*keys) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateGrouping(
      _fbb,
      keys__);
}

/// Aggregate operation
struct Aggregate FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef AggregateBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_REL = 6,
    VT_MEASURES = 8,
    VT_GROUPINGS = 10
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// Child relation
  const org::apache::arrow::computeir::flatbuf::Relation *rel() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Relation *>(VT_REL);
  }
  /// Expressions which will be evaluated to produce to
  /// the rows of the aggregate relation's output.
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *measures() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *>(VT_MEASURES);
  }
  /// Keys by which `aggregations` will be grouped.
  ///
  /// The nested list here is to support grouping sets
  /// eg
  ///
  /// SELECT a, b, c, sum(d)
  /// FROM t
  /// GROUP BY
  ///   GROUPING SETS (
  ///     (a, b, c),
  ///     (a, b),
  ///     (a),
  ///     ()
  ///   );
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Grouping>> *groupings() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Grouping>> *>(VT_GROUPINGS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_REL) &&
           verifier.VerifyTable(rel()) &&
           VerifyOffsetRequired(verifier, VT_MEASURES) &&
           verifier.VerifyVector(measures()) &&
           verifier.VerifyVectorOfTables(measures()) &&
           VerifyOffsetRequired(verifier, VT_GROUPINGS) &&
           verifier.VerifyVector(groupings()) &&
           verifier.VerifyVectorOfTables(groupings()) &&
           verifier.EndTable();
  }
};

struct AggregateBuilder {
  typedef Aggregate Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(Aggregate::VT_ID, id);
  }
  void add_rel(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel) {
    fbb_.AddOffset(Aggregate::VT_REL, rel);
  }
  void add_measures(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>> measures) {
    fbb_.AddOffset(Aggregate::VT_MEASURES, measures);
  }
  void add_groupings(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Grouping>>> groupings) {
    fbb_.AddOffset(Aggregate::VT_GROUPINGS, groupings);
  }
  explicit AggregateBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  AggregateBuilder &operator=(const AggregateBuilder &);
  flatbuffers::Offset<Aggregate> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Aggregate>(end);
    fbb_.Required(o, Aggregate::VT_REL);
    fbb_.Required(o, Aggregate::VT_MEASURES);
    fbb_.Required(o, Aggregate::VT_GROUPINGS);
    return o;
  }
};

inline flatbuffers::Offset<Aggregate> CreateAggregate(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>> measures = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Grouping>>> groupings = 0) {
  AggregateBuilder builder_(_fbb);
  builder_.add_groupings(groupings);
  builder_.add_measures(measures);
  builder_.add_rel(rel);
  builder_.add_id(id);
  return builder_.Finish();
}

inline flatbuffers::Offset<Aggregate> CreateAggregateDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>> *measures = nullptr,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Grouping>> *groupings = nullptr) {
  auto measures__ = measures ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression>>(*measures) : 0;
  auto groupings__ = groupings ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Grouping>>(*groupings) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateAggregate(
      _fbb,
      id,
      rel,
      measures__,
      groupings__);
}

/// Join between two tables
struct Join FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef JoinBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_LEFT = 6,
    VT_RIGHT = 8,
    VT_ON_EXPRESSION = 10,
    VT_JOIN_KIND = 12
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// Left relation
  const org::apache::arrow::computeir::flatbuf::Relation *left() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Relation *>(VT_LEFT);
  }
  /// Right relation
  const org::apache::arrow::computeir::flatbuf::Relation *right() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Relation *>(VT_RIGHT);
  }
  /// The expression which will be evaluated against rows from each
  /// input to determine whether they should be included in the
  /// join relation's output.
  const org::apache::arrow::computeir::flatbuf::Expression *on_expression() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Expression *>(VT_ON_EXPRESSION);
  }
  /// The kind of join to use.
  org::apache::arrow::computeir::flatbuf::JoinKind join_kind() const {
    return static_cast<org::apache::arrow::computeir::flatbuf::JoinKind>(GetField<uint8_t>(VT_JOIN_KIND, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_LEFT) &&
           verifier.VerifyTable(left()) &&
           VerifyOffsetRequired(verifier, VT_RIGHT) &&
           verifier.VerifyTable(right()) &&
           VerifyOffsetRequired(verifier, VT_ON_EXPRESSION) &&
           verifier.VerifyTable(on_expression()) &&
           VerifyField<uint8_t>(verifier, VT_JOIN_KIND) &&
           verifier.EndTable();
  }
};

struct JoinBuilder {
  typedef Join Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(Join::VT_ID, id);
  }
  void add_left(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> left) {
    fbb_.AddOffset(Join::VT_LEFT, left);
  }
  void add_right(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> right) {
    fbb_.AddOffset(Join::VT_RIGHT, right);
  }
  void add_on_expression(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression> on_expression) {
    fbb_.AddOffset(Join::VT_ON_EXPRESSION, on_expression);
  }
  void add_join_kind(org::apache::arrow::computeir::flatbuf::JoinKind join_kind) {
    fbb_.AddElement<uint8_t>(Join::VT_JOIN_KIND, static_cast<uint8_t>(join_kind), 0);
  }
  explicit JoinBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  JoinBuilder &operator=(const JoinBuilder &);
  flatbuffers::Offset<Join> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Join>(end);
    fbb_.Required(o, Join::VT_LEFT);
    fbb_.Required(o, Join::VT_RIGHT);
    fbb_.Required(o, Join::VT_ON_EXPRESSION);
    return o;
  }
};

inline flatbuffers::Offset<Join> CreateJoin(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> left = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> right = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression> on_expression = 0,
    org::apache::arrow::computeir::flatbuf::JoinKind join_kind = org::apache::arrow::computeir::flatbuf::JoinKind::Anti) {
  JoinBuilder builder_(_fbb);
  builder_.add_on_expression(on_expression);
  builder_.add_right(right);
  builder_.add_left(left);
  builder_.add_id(id);
  builder_.add_join_kind(join_kind);
  return builder_.Finish();
}

/// Order by relation
struct OrderBy FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef OrderByBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_REL = 6,
    VT_KEYS = 8
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// Child relation
  const org::apache::arrow::computeir::flatbuf::Relation *rel() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Relation *>(VT_REL);
  }
  /// Define sort order for rows of output.
  /// Keys with higher precedence are ordered ahead of other keys.
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::SortKey>> *keys() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::SortKey>> *>(VT_KEYS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_REL) &&
           verifier.VerifyTable(rel()) &&
           VerifyOffsetRequired(verifier, VT_KEYS) &&
           verifier.VerifyVector(keys()) &&
           verifier.VerifyVectorOfTables(keys()) &&
           verifier.EndTable();
  }
};

struct OrderByBuilder {
  typedef OrderBy Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(OrderBy::VT_ID, id);
  }
  void add_rel(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel) {
    fbb_.AddOffset(OrderBy::VT_REL, rel);
  }
  void add_keys(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::SortKey>>> keys) {
    fbb_.AddOffset(OrderBy::VT_KEYS, keys);
  }
  explicit OrderByBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  OrderByBuilder &operator=(const OrderByBuilder &);
  flatbuffers::Offset<OrderBy> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<OrderBy>(end);
    fbb_.Required(o, OrderBy::VT_REL);
    fbb_.Required(o, OrderBy::VT_KEYS);
    return o;
  }
};

inline flatbuffers::Offset<OrderBy> CreateOrderBy(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::SortKey>>> keys = 0) {
  OrderByBuilder builder_(_fbb);
  builder_.add_keys(keys);
  builder_.add_rel(rel);
  builder_.add_id(id);
  return builder_.Finish();
}

inline flatbuffers::Offset<OrderBy> CreateOrderByDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::SortKey>> *keys = nullptr) {
  auto keys__ = keys ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::SortKey>>(*keys) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateOrderBy(
      _fbb,
      id,
      rel,
      keys__);
}

/// Limit operation
struct Limit FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LimitBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_REL = 6,
    VT_OFFSET = 8,
    VT_COUNT = 10
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// Child relation
  const org::apache::arrow::computeir::flatbuf::Relation *rel() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Relation *>(VT_REL);
  }
  /// Starting index of rows
  uint32_t offset() const {
    return GetField<uint32_t>(VT_OFFSET, 0);
  }
  /// The maximum number of rows of output.
  uint32_t count() const {
    return GetField<uint32_t>(VT_COUNT, 0);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_REL) &&
           verifier.VerifyTable(rel()) &&
           VerifyField<uint32_t>(verifier, VT_OFFSET) &&
           VerifyField<uint32_t>(verifier, VT_COUNT) &&
           verifier.EndTable();
  }
};

struct LimitBuilder {
  typedef Limit Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(Limit::VT_ID, id);
  }
  void add_rel(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel) {
    fbb_.AddOffset(Limit::VT_REL, rel);
  }
  void add_offset(uint32_t offset) {
    fbb_.AddElement<uint32_t>(Limit::VT_OFFSET, offset, 0);
  }
  void add_count(uint32_t count) {
    fbb_.AddElement<uint32_t>(Limit::VT_COUNT, count, 0);
  }
  explicit LimitBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LimitBuilder &operator=(const LimitBuilder &);
  flatbuffers::Offset<Limit> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Limit>(end);
    fbb_.Required(o, Limit::VT_REL);
    return o;
  }
};

inline flatbuffers::Offset<Limit> CreateLimit(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> rel = 0,
    uint32_t offset = 0,
    uint32_t count = 0) {
  LimitBuilder builder_(_fbb);
  builder_.add_count(count);
  builder_.add_offset(offset);
  builder_.add_rel(rel);
  builder_.add_id(id);
  return builder_.Finish();
}

/// A set operation on two or more relations
struct SetOperation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SetOperationBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_RELS = 6,
    VT_SET_OP = 8
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// Child relations
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation>> *rels() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation>> *>(VT_RELS);
  }
  /// The kind of set operation
  org::apache::arrow::computeir::flatbuf::SetOpKind set_op() const {
    return static_cast<org::apache::arrow::computeir::flatbuf::SetOpKind>(GetField<uint8_t>(VT_SET_OP, 0));
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_RELS) &&
           verifier.VerifyVector(rels()) &&
           verifier.VerifyVectorOfTables(rels()) &&
           VerifyField<uint8_t>(verifier, VT_SET_OP) &&
           verifier.EndTable();
  }
};

struct SetOperationBuilder {
  typedef SetOperation Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(SetOperation::VT_ID, id);
  }
  void add_rels(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation>>> rels) {
    fbb_.AddOffset(SetOperation::VT_RELS, rels);
  }
  void add_set_op(org::apache::arrow::computeir::flatbuf::SetOpKind set_op) {
    fbb_.AddElement<uint8_t>(SetOperation::VT_SET_OP, static_cast<uint8_t>(set_op), 0);
  }
  explicit SetOperationBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SetOperationBuilder &operator=(const SetOperationBuilder &);
  flatbuffers::Offset<SetOperation> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<SetOperation>(end);
    fbb_.Required(o, SetOperation::VT_RELS);
    return o;
  }
};

inline flatbuffers::Offset<SetOperation> CreateSetOperation(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation>>> rels = 0,
    org::apache::arrow::computeir::flatbuf::SetOpKind set_op = org::apache::arrow::computeir::flatbuf::SetOpKind::Union) {
  SetOperationBuilder builder_(_fbb);
  builder_.add_rels(rels);
  builder_.add_id(id);
  builder_.add_set_op(set_op);
  return builder_.Finish();
}

inline flatbuffers::Offset<SetOperation> CreateSetOperationDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation>> *rels = nullptr,
    org::apache::arrow::computeir::flatbuf::SetOpKind set_op = org::apache::arrow::computeir::flatbuf::SetOpKind::Union) {
  auto rels__ = rels ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation>>(*rels) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateSetOperation(
      _fbb,
      id,
      rels__,
      set_op);
}

/// A single column of literal values.
struct LiteralColumn FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LiteralColumnBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ELEMENTS = 4
  };
  /// The literal values of the column
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Literal>> *elements() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Literal>> *>(VT_ELEMENTS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffsetRequired(verifier, VT_ELEMENTS) &&
           verifier.VerifyVector(elements()) &&
           verifier.VerifyVectorOfTables(elements()) &&
           verifier.EndTable();
  }
};

struct LiteralColumnBuilder {
  typedef LiteralColumn Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_elements(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Literal>>> elements) {
    fbb_.AddOffset(LiteralColumn::VT_ELEMENTS, elements);
  }
  explicit LiteralColumnBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LiteralColumnBuilder &operator=(const LiteralColumnBuilder &);
  flatbuffers::Offset<LiteralColumn> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LiteralColumn>(end);
    fbb_.Required(o, LiteralColumn::VT_ELEMENTS);
    return o;
  }
};

inline flatbuffers::Offset<LiteralColumn> CreateLiteralColumn(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Literal>>> elements = 0) {
  LiteralColumnBuilder builder_(_fbb);
  builder_.add_elements(elements);
  return builder_.Finish();
}

inline flatbuffers::Offset<LiteralColumn> CreateLiteralColumnDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Literal>> *elements = nullptr) {
  auto elements__ = elements ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Literal>>(*elements) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateLiteralColumn(
      _fbb,
      elements__);
}

/// Literal relation
struct LiteralRelation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef LiteralRelationBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_COLUMNS = 6
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  /// The columns of this literal relation.
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::LiteralColumn>> *columns() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::LiteralColumn>> *>(VT_COLUMNS);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_COLUMNS) &&
           verifier.VerifyVector(columns()) &&
           verifier.VerifyVectorOfTables(columns()) &&
           verifier.EndTable();
  }
};

struct LiteralRelationBuilder {
  typedef LiteralRelation Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(LiteralRelation::VT_ID, id);
  }
  void add_columns(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::LiteralColumn>>> columns) {
    fbb_.AddOffset(LiteralRelation::VT_COLUMNS, columns);
  }
  explicit LiteralRelationBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  LiteralRelationBuilder &operator=(const LiteralRelationBuilder &);
  flatbuffers::Offset<LiteralRelation> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<LiteralRelation>(end);
    fbb_.Required(o, LiteralRelation::VT_COLUMNS);
    return o;
  }
};

inline flatbuffers::Offset<LiteralRelation> CreateLiteralRelation(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::LiteralColumn>>> columns = 0) {
  LiteralRelationBuilder builder_(_fbb);
  builder_.add_columns(columns);
  builder_.add_id(id);
  return builder_.Finish();
}

inline flatbuffers::Offset<LiteralRelation> CreateLiteralRelationDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::LiteralColumn>> *columns = nullptr) {
  auto columns__ = columns ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::LiteralColumn>>(*columns) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateLiteralRelation(
      _fbb,
      id,
      columns__);
}

/// An external source of tabular data
struct Source FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef SourceBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_ID = 4,
    VT_NAME = 6,
    VT_FILTER = 8,
    VT_SCHEMA = 10,
    VT_PROJECTION = 12
  };
  /// An identifiier for the relation. The identifier should be unique over the
  /// entire plan. Optional.
  const org::apache::arrow::computeir::flatbuf::RelId *id() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::RelId *>(VT_ID);
  }
  const flatbuffers::String *name() const {
    return GetPointer<const flatbuffers::String *>(VT_NAME);
  }
  /// An optional expression used to filter out rows directly from the source.
  ///
  /// Useful for consumers that implement predicate pushdown.
  ///
  /// A missing filter value indicates no filter, i.e., all rows are
  /// returned from the source.
  const org::apache::arrow::computeir::flatbuf::Expression *filter() const {
    return GetPointer<const org::apache::arrow::computeir::flatbuf::Expression *>(VT_FILTER);
  }
  /// Schemas are explicitly optional
  const org::apache::arrow::flatbuf::Schema *schema() const {
    return GetPointer<const org::apache::arrow::flatbuf::Schema *>(VT_SCHEMA);
  }
  /// An optional list of field indices indicating which columns should be read
  /// from the source. Columns excluded from this listing will instead be replaced
  /// with all-null placeholders to guarantee that the schema of the source is
  /// unaffected by this projection.
  ///
  /// A missing value indicates all columns should be read.
  ///
  /// The behavior of an empty list is undefined.
  const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::FieldIndex>> *projection() const {
    return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::FieldIndex>> *>(VT_PROJECTION);
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyOffset(verifier, VT_ID) &&
           verifier.VerifyTable(id()) &&
           VerifyOffsetRequired(verifier, VT_NAME) &&
           verifier.VerifyString(name()) &&
           VerifyOffset(verifier, VT_FILTER) &&
           verifier.VerifyTable(filter()) &&
           VerifyOffset(verifier, VT_SCHEMA) &&
           verifier.VerifyTable(schema()) &&
           VerifyOffset(verifier, VT_PROJECTION) &&
           verifier.VerifyVector(projection()) &&
           verifier.VerifyVectorOfTables(projection()) &&
           verifier.EndTable();
  }
};

struct SourceBuilder {
  typedef Source Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_id(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id) {
    fbb_.AddOffset(Source::VT_ID, id);
  }
  void add_name(flatbuffers::Offset<flatbuffers::String> name) {
    fbb_.AddOffset(Source::VT_NAME, name);
  }
  void add_filter(flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression> filter) {
    fbb_.AddOffset(Source::VT_FILTER, filter);
  }
  void add_schema(flatbuffers::Offset<org::apache::arrow::flatbuf::Schema> schema) {
    fbb_.AddOffset(Source::VT_SCHEMA, schema);
  }
  void add_projection(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::FieldIndex>>> projection) {
    fbb_.AddOffset(Source::VT_PROJECTION, projection);
  }
  explicit SourceBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  SourceBuilder &operator=(const SourceBuilder &);
  flatbuffers::Offset<Source> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Source>(end);
    fbb_.Required(o, Source::VT_NAME);
    return o;
  }
};

inline flatbuffers::Offset<Source> CreateSource(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    flatbuffers::Offset<flatbuffers::String> name = 0,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression> filter = 0,
    flatbuffers::Offset<org::apache::arrow::flatbuf::Schema> schema = 0,
    flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::FieldIndex>>> projection = 0) {
  SourceBuilder builder_(_fbb);
  builder_.add_projection(projection);
  builder_.add_schema(schema);
  builder_.add_filter(filter);
  builder_.add_name(name);
  builder_.add_id(id);
  return builder_.Finish();
}

inline flatbuffers::Offset<Source> CreateSourceDirect(
    flatbuffers::FlatBufferBuilder &_fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::RelId> id = 0,
    const char *name = nullptr,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Expression> filter = 0,
    flatbuffers::Offset<org::apache::arrow::flatbuf::Schema> schema = 0,
    const std::vector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::FieldIndex>> *projection = nullptr) {
  auto name__ = name ? _fbb.CreateString(name) : 0;
  auto projection__ = projection ? _fbb.CreateVector<flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::FieldIndex>>(*projection) : 0;
  return org::apache::arrow::computeir::flatbuf::CreateSource(
      _fbb,
      id,
      name__,
      filter,
      schema,
      projection__);
}

/// A table holding an instance of the possible relation types.
struct Relation FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
  typedef RelationBuilder Builder;
  enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
    VT_IMPL_TYPE = 4,
    VT_IMPL = 6
  };
  org::apache::arrow::computeir::flatbuf::RelationImpl impl_type() const {
    return static_cast<org::apache::arrow::computeir::flatbuf::RelationImpl>(GetField<uint8_t>(VT_IMPL_TYPE, 0));
  }
  const void *impl() const {
    return GetPointer<const void *>(VT_IMPL);
  }
  template<typename T> const T *impl_as() const;
  const org::apache::arrow::computeir::flatbuf::Aggregate *impl_as_Aggregate() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::Aggregate ? static_cast<const org::apache::arrow::computeir::flatbuf::Aggregate *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::Filter *impl_as_Filter() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::Filter ? static_cast<const org::apache::arrow::computeir::flatbuf::Filter *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::Join *impl_as_Join() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::Join ? static_cast<const org::apache::arrow::computeir::flatbuf::Join *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::Limit *impl_as_Limit() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::Limit ? static_cast<const org::apache::arrow::computeir::flatbuf::Limit *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::LiteralRelation *impl_as_LiteralRelation() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::LiteralRelation ? static_cast<const org::apache::arrow::computeir::flatbuf::LiteralRelation *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::OrderBy *impl_as_OrderBy() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::OrderBy ? static_cast<const org::apache::arrow::computeir::flatbuf::OrderBy *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::Project *impl_as_Project() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::Project ? static_cast<const org::apache::arrow::computeir::flatbuf::Project *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::SetOperation *impl_as_SetOperation() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::SetOperation ? static_cast<const org::apache::arrow::computeir::flatbuf::SetOperation *>(impl()) : nullptr;
  }
  const org::apache::arrow::computeir::flatbuf::Source *impl_as_Source() const {
    return impl_type() == org::apache::arrow::computeir::flatbuf::RelationImpl::Source ? static_cast<const org::apache::arrow::computeir::flatbuf::Source *>(impl()) : nullptr;
  }
  bool Verify(flatbuffers::Verifier &verifier) const {
    return VerifyTableStart(verifier) &&
           VerifyField<uint8_t>(verifier, VT_IMPL_TYPE) &&
           VerifyOffsetRequired(verifier, VT_IMPL) &&
           VerifyRelationImpl(verifier, impl(), impl_type()) &&
           verifier.EndTable();
  }
};

template<> inline const org::apache::arrow::computeir::flatbuf::Aggregate *Relation::impl_as<org::apache::arrow::computeir::flatbuf::Aggregate>() const {
  return impl_as_Aggregate();
}

template<> inline const org::apache::arrow::computeir::flatbuf::Filter *Relation::impl_as<org::apache::arrow::computeir::flatbuf::Filter>() const {
  return impl_as_Filter();
}

template<> inline const org::apache::arrow::computeir::flatbuf::Join *Relation::impl_as<org::apache::arrow::computeir::flatbuf::Join>() const {
  return impl_as_Join();
}

template<> inline const org::apache::arrow::computeir::flatbuf::Limit *Relation::impl_as<org::apache::arrow::computeir::flatbuf::Limit>() const {
  return impl_as_Limit();
}

template<> inline const org::apache::arrow::computeir::flatbuf::LiteralRelation *Relation::impl_as<org::apache::arrow::computeir::flatbuf::LiteralRelation>() const {
  return impl_as_LiteralRelation();
}

template<> inline const org::apache::arrow::computeir::flatbuf::OrderBy *Relation::impl_as<org::apache::arrow::computeir::flatbuf::OrderBy>() const {
  return impl_as_OrderBy();
}

template<> inline const org::apache::arrow::computeir::flatbuf::Project *Relation::impl_as<org::apache::arrow::computeir::flatbuf::Project>() const {
  return impl_as_Project();
}

template<> inline const org::apache::arrow::computeir::flatbuf::SetOperation *Relation::impl_as<org::apache::arrow::computeir::flatbuf::SetOperation>() const {
  return impl_as_SetOperation();
}

template<> inline const org::apache::arrow::computeir::flatbuf::Source *Relation::impl_as<org::apache::arrow::computeir::flatbuf::Source>() const {
  return impl_as_Source();
}

struct RelationBuilder {
  typedef Relation Table;
  flatbuffers::FlatBufferBuilder &fbb_;
  flatbuffers::uoffset_t start_;
  void add_impl_type(org::apache::arrow::computeir::flatbuf::RelationImpl impl_type) {
    fbb_.AddElement<uint8_t>(Relation::VT_IMPL_TYPE, static_cast<uint8_t>(impl_type), 0);
  }
  void add_impl(flatbuffers::Offset<void> impl) {
    fbb_.AddOffset(Relation::VT_IMPL, impl);
  }
  explicit RelationBuilder(flatbuffers::FlatBufferBuilder &_fbb)
        : fbb_(_fbb) {
    start_ = fbb_.StartTable();
  }
  RelationBuilder &operator=(const RelationBuilder &);
  flatbuffers::Offset<Relation> Finish() {
    const auto end = fbb_.EndTable(start_);
    auto o = flatbuffers::Offset<Relation>(end);
    fbb_.Required(o, Relation::VT_IMPL);
    return o;
  }
};

inline flatbuffers::Offset<Relation> CreateRelation(
    flatbuffers::FlatBufferBuilder &_fbb,
    org::apache::arrow::computeir::flatbuf::RelationImpl impl_type = org::apache::arrow::computeir::flatbuf::RelationImpl::NONE,
    flatbuffers::Offset<void> impl = 0) {
  RelationBuilder builder_(_fbb);
  builder_.add_impl(impl);
  builder_.add_impl_type(impl_type);
  return builder_.Finish();
}

inline bool VerifyRelationImpl(flatbuffers::Verifier &verifier, const void *obj, RelationImpl type) {
  switch (type) {
    case RelationImpl::NONE: {
      return true;
    }
    case RelationImpl::Aggregate: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::Aggregate *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::Filter: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::Filter *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::Join: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::Join *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::Limit: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::Limit *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::LiteralRelation: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::LiteralRelation *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::OrderBy: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::OrderBy *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::Project: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::Project *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::SetOperation: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::SetOperation *>(obj);
      return verifier.VerifyTable(ptr);
    }
    case RelationImpl::Source: {
      auto ptr = reinterpret_cast<const org::apache::arrow::computeir::flatbuf::Source *>(obj);
      return verifier.VerifyTable(ptr);
    }
    default: return true;
  }
}

inline bool VerifyRelationImplVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
  if (!values || !types) return !values && !types;
  if (values->size() != types->size()) return false;
  for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
    if (!VerifyRelationImpl(
        verifier,  values->Get(i), types->GetEnum<RelationImpl>(i))) {
      return false;
    }
  }
  return true;
}

inline const org::apache::arrow::computeir::flatbuf::Relation *GetRelation(const void *buf) {
  return flatbuffers::GetRoot<org::apache::arrow::computeir::flatbuf::Relation>(buf);
}

inline const org::apache::arrow::computeir::flatbuf::Relation *GetSizePrefixedRelation(const void *buf) {
  return flatbuffers::GetSizePrefixedRoot<org::apache::arrow::computeir::flatbuf::Relation>(buf);
}

inline bool VerifyRelationBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifyBuffer<org::apache::arrow::computeir::flatbuf::Relation>(nullptr);
}

inline bool VerifySizePrefixedRelationBuffer(
    flatbuffers::Verifier &verifier) {
  return verifier.VerifySizePrefixedBuffer<org::apache::arrow::computeir::flatbuf::Relation>(nullptr);
}

inline void FinishRelationBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> root) {
  fbb.Finish(root);
}

inline void FinishSizePrefixedRelationBuffer(
    flatbuffers::FlatBufferBuilder &fbb,
    flatbuffers::Offset<org::apache::arrow::computeir::flatbuf::Relation> root) {
  fbb.FinishSizePrefixed(root);
}

}  // namespace flatbuf
}  // namespace computeir
}  // namespace arrow
}  // namespace apache
}  // namespace org

#endif  // FLATBUFFERS_GENERATED_RELATION_ORG_APACHE_ARROW_COMPUTEIR_FLATBUF_H_
