如何利用C++镶木库逻辑课

发布于 2025-02-03 04:45:02 字数 2506 浏览 4 评论 0原文

我需要在派生类中调用一种方法。这在抽象中很简单。但是,我利用Parquet C ++库。围绕镶木逻辑类型有一系列类。他们的基类只是逻辑类型,其派生类从该基类公开继承。因为他们的逻辑类型相当长,所以我将在此处包含其中的相关部分:

class PARQUET_EXPORT LogicalType {
 public:
  struct Type {
    enum type {
      UNDEFINED = 0,  // Not a real logical type
      STRING = 1,
      MAP,
      LIST,
      ENUM,
      DECIMAL,
      DATE,
      TIME,
      TIMESTAMP,
      INTERVAL,
      INT,
      NIL,  // Thrift NullType: annotates data that is always null
      JSON,
      BSON,
      UUID,
      NONE  // Not a real logical type; should always be last element
    };
  };

  struct TimeUnit {
    enum unit { UNKNOWN = 0, MILLIS = 1, MICROS, NANOS };
  };
  LogicalType(const LogicalType&) = delete;
  LogicalType& operator=(const LogicalType&) = delete;
  virtual ~LogicalType() noexcept;

[snipped for brevity reasons]

 protected:
  LogicalType();

  class Impl;
  std::unique_ptr<const Impl> impl_;
};

我感兴趣的类是timestAmplogicalType类,该类的定义如下:

class PARQUET_EXPORT TimestampLogicalType : public LogicalType {
 public:
  static std::shared_ptr<const LogicalType> Make(bool is_adjusted_to_utc,
                                                 LogicalType::TimeUnit::unit time_unit,
                                                 bool is_from_converted_type = false,
                                                 bool force_set_converted_type = false);
  bool is_adjusted_to_utc() const;
  LogicalType::TimeUnit::unit time_unit() const;

  /// \brief If true, will not set LogicalType in Thrift metadata
  bool is_from_converted_type() const;

  /// \brief If true, will set ConvertedType for micros and millis
  /// resolution in legacy ConvertedType Thrift metadata
  bool force_set_converted_type() const;

 private:
  TimestampLogicalType() = default;
};

我' d喜欢使用time_unit()方法。但是,您发现列的元数据(ERGO列描述符的逻辑类型方法)的方式将返回您LogicalType对象,无论该列实际上是什么逻辑类型。确切地说,它返回给您一个共享指针,指向const logicalType对象。但是,LogicalType类没有我需要的方法(自然),因此您需要timestAmplogicalType对象才能调用time_unit()。因为LogicalType具有虚拟驱动器,所以我想我可以使用dynamic_cast&gt;&gt;logicalType对象转换为timeStAmplogicalType对象。但是,这行不通。

所以我不知道。当我考虑这个问题时,我会感觉到答案是显而易见的,基本的/基本的,而且我应该可以立即看到的东西。但是,经过三到四天的玩法,我仍然看不到如何完成这项工作。有反馈吗?我只是以错误的方式考虑这一点吗?

我正在使用箭头/镶木库,版本4.0.1。建立在宽松盒上,X86_64,GCC/G ++ 7.4.0。

谢谢

I have a need to invoke a method within a derived class. This is straightforward enough in the abstract. However I am utilizing the Parquet C++ library. There are a series of classes surrounding the Parquet logical types. Their base class is simply LogicalType with the derived classes inheriting publicly from that base class. Because their LogicalType is rather long, I will include the relevant portions of it here:

class PARQUET_EXPORT LogicalType {
 public:
  struct Type {
    enum type {
      UNDEFINED = 0,  // Not a real logical type
      STRING = 1,
      MAP,
      LIST,
      ENUM,
      DECIMAL,
      DATE,
      TIME,
      TIMESTAMP,
      INTERVAL,
      INT,
      NIL,  // Thrift NullType: annotates data that is always null
      JSON,
      BSON,
      UUID,
      NONE  // Not a real logical type; should always be last element
    };
  };

  struct TimeUnit {
    enum unit { UNKNOWN = 0, MILLIS = 1, MICROS, NANOS };
  };
  LogicalType(const LogicalType&) = delete;
  LogicalType& operator=(const LogicalType&) = delete;
  virtual ~LogicalType() noexcept;

[snipped for brevity reasons]

 protected:
  LogicalType();

  class Impl;
  std::unique_ptr<const Impl> impl_;
};

The class I am interested in is the TimestampLogicalType class, which is defined as follows:

class PARQUET_EXPORT TimestampLogicalType : public LogicalType {
 public:
  static std::shared_ptr<const LogicalType> Make(bool is_adjusted_to_utc,
                                                 LogicalType::TimeUnit::unit time_unit,
                                                 bool is_from_converted_type = false,
                                                 bool force_set_converted_type = false);
  bool is_adjusted_to_utc() const;
  LogicalType::TimeUnit::unit time_unit() const;

  /// \brief If true, will not set LogicalType in Thrift metadata
  bool is_from_converted_type() const;

  /// \brief If true, will set ConvertedType for micros and millis
  /// resolution in legacy ConvertedType Thrift metadata
  bool force_set_converted_type() const;

 private:
  TimestampLogicalType() = default;
};

I'd like to utilize the time_unit() method in particular. However, the manner in which you discover a column's metadata (ergo the column descriptor's logical type method) will return you a LogicalType object, regardless of what logical type the column actually is. To be precise, it returns to you a shared pointer to a const LogicalType object. However the LogicalType class does not have the method I need (naturally), so you need the TimestampLogicalType object in order to invoke time_unit(). Because LogicalType has a virtual destructor, I was thinking that I could use dynamic_cast<> to convert the LogicalType object to a TimestampLogicalType object. However that doesn't work.

So I dunno. When I think about the problem, I get the feeling that the answer is obvious, rudimentary/fundamental, and something that I should be able to see straight away. However after three or four days of playing around with it, I am still not seeing how to make this work. Any feedback? Am I just thinking about this in the wrong way?

I am using the Arrow/Parquet libraries, version 4.0.1. Building on a LAX box, x86_64, GCC/G++ 7.4.0.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

潇烟暮雨 2025-02-10 04:45:02

好吧,我弄清楚了。我不确定我最初出错了哪里,但是我今天早上重新探讨了dynamic_cast&gt;方法。出于简化的原因,我将每个步骤都分为单独的指令。这就是我想到的:


parquet::LogicalType *localTimestampBase = const_cast<parquet::LogicalType*>(localLogical.get());

parquet::TimestampLogicalType *localTimestamp = dynamic_cast<parquet::TimestampLogicalType*>( localTimestampBase );

std::cout << "   Logical Type TIMESTAMP is-timestamp = " << std::boolalpha << localLogical->is_timestamp() << "\n";
std::cout << "   Logical Type TIMESTAMP is-adjusted-to-utc = " << std::boolalpha << localTimestamp->is_adjusted_to_utc() << "\n";
std::cout << "   Logical Type TIMESTAMP time unit = " << time_unit_string( localTimestamp->time_unit() ) << "\n";

这是可行的:

   Logical Type TIMESTAMP is-timestamp = true
   Logical Type TIMESTAMP is-adjusted-to-utc = true
   Logical Type TIMESTAMP time unit = nanoseconds

希望这对某人有帮助。谢谢!

Alright I figured this out; I am not certain where I went wrong initially, but I revisited the dynamic_cast<> approach this morning. For simplification reasons, I broke out each step into its own, separate instruction. This is what I came up with:


parquet::LogicalType *localTimestampBase = const_cast<parquet::LogicalType*>(localLogical.get());

parquet::TimestampLogicalType *localTimestamp = dynamic_cast<parquet::TimestampLogicalType*>( localTimestampBase );

std::cout << "   Logical Type TIMESTAMP is-timestamp = " << std::boolalpha << localLogical->is_timestamp() << "\n";
std::cout << "   Logical Type TIMESTAMP is-adjusted-to-utc = " << std::boolalpha << localTimestamp->is_adjusted_to_utc() << "\n";
std::cout << "   Logical Type TIMESTAMP time unit = " << time_unit_string( localTimestamp->time_unit() ) << "\n";

And this works, thus:

   Logical Type TIMESTAMP is-timestamp = true
   Logical Type TIMESTAMP is-adjusted-to-utc = true
   Logical Type TIMESTAMP time unit = nanoseconds

Hope this helps someone. Thanks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文