DuckDB:详细解读 TableRef 类

目录

TableRef 的设计及实现

设计思想

实现剖析

1)类的定义与结构

1.1 构造函数与析构函数

1.2 成员变量

1.3 关于SampleOption

1.4 关于query_location

2)多态与虚函数

2.1 ToString()

2.2 Equals()

2.3 Copy()

2.4 Serialize() 和 Deserialize()

3) 模板方法 Cast()

TableRef 的子类实现与应用场景

1. BaseTableRef

2. SubqueryRef

3. JoinRef

4. TableFunctionRef

5. EmptyTableRef

关于 TableFunctionRef

TableFunctionRef 的作用

表函数的定义与注册

表函数的执行

示例:表函数的使用

支持投影下推

小结

总结


在 DuckDB 的架构中,TableRef 是一个核心组件,用于表示查询中的表引用。它不仅是一个抽象基类,还通过多种子类实现支持了复杂多样的表引用场景。本文将从源码层面深入分析 TableRef 的设计思想及其子类的实现细节。

TableRef 的设计及实现

设计思想

TableRef 是一个抽象基类,用于表示查询中的表引用。它在解析 SQL 查询时被定义,并在后续的绑定和优化阶段中被进一步处理。TableRef 的设计思想主要体现在以下几个方面:

1)抽象性与扩展性

TableRef 是一个抽象类,定义了表引用的基本接口和行为。通过继承 TableRef,DuckDB 实现了多种具体的表引用类型,例如:

  • BaseTableRef:表示普通表引用。

  • SubqueryRef:表示子查询引用。

  • JoinRef:表示连接操作的表引用。

  • TableFunctionRef:表示通过表函数生成的表引用。

  • EmptyTableRef:空表引用

这种设计使得 DuckDB 能够灵活地处理各种复杂的查询场景。

2)模块化与解耦

TableRef 的设计将表引用逻辑与查询解析、执行计划生成等模块分离。这种解耦使得 DuckDB 的代码更加模块化,便于维护和扩展。

3)支持多种数据源

通过 TableRef 的子类实现,DuckDB 能够支持多种数据源,包括本地表、内存表、外部表以及通过表函数生成的虚拟表。

实现剖析

TableRef是个多态类,通过继承和多态机制支持多种表引用类型(如普通表、子查询、表函数等)。以下是对 TableRef 类及其设计思想的详细分析:

1)类的定义与结构

namespace duckdb {

//! Represents a generic expression that returns a table.
class TableRef {
public:
	static constexpr const TableReferenceType TYPE = TableReferenceType::INVALID;

public:
	explicit TableRef(TableReferenceType type) : type(type) {
	}
	virtual ~TableRef() {
	}

	TableReferenceType type;
	string alias;
	//! Sample options (if any)
	unique_ptr<SampleOptions> sample;
	//! The location in the query (if any)
	optional_idx query_location;
	//! External dependencies of this table function
	shared_ptr<ExternalDependency> external_dependency;
	//! Aliases for the column names
	vector<string> column_name_alias;

public:
	//! Convert the object to a string
	virtual string ToString() const = 0;
	string BaseToString(string result) const;
	string BaseToString(string result, const vector<string> &column_name_alias) const;
	void Print();

	virtual bool Equals(const TableRef &other) const;
	static bool Equals(const unique_ptr<TableRef> &left, const unique_ptr<TableRef> &right);

	virtual unique_ptr<TableRef> Copy() = 0;

	//! Copy the properties of this table ref to the target
	void CopyProperties(TableRef &target) const;

	virtual void Serialize(Serializer &serializer) const;
	static unique_ptr<TableRef> Deserialize(Deserializer &deserializer);

public:
	template <class TARGET>
	TARGET &Cast() {
		if (type != TARGET::TYPE && TARGET::TYPE != TableReferenceType::INVALID) {
			throw InternalException("Failed to cast constraint to type - constraint type mismatch");
		}
		return reinterpret_cast<TARGET &>(*this);
	}

	template <class TARGET>
	const TARGET &Cast() const {
		if (type != TARGET::TYPE && TARGET::TYPE != TableReferenceType::INVALID) {
			throw InternalException("Failed to cast constraint to type - constraint type mismatch");
		}
		return reinterpret_cast<const TARGET &>(*this);
	}
};
} // namespace duckdb
1.1 构造函数与析构函数
  • TableRef 的构造函数接受一个 TableReferenceType 参数,用于初始化 type 属性。TableReferenceType 是一个枚举类型,用于区分不同的表引用类型(如普通表、子查询、表函数等)。

  • 析构函数是虚函数,这表明 TableRef 是一个多态类,允许派生类覆盖析构函数。

1.2 成员变量
  • TableReferenceType type:表示表引用的类型

    代码中实际支持的表类型很多:
    enum class TableReferenceType : uint8_t {
    	INVALID = 0,         // invalid table reference type
    	BASE_TABLE = 1,      // base table reference
    	SUBQUERY = 2,        // output of a subquery
    	JOIN = 3,            // output of join
    	TABLE_FUNCTION = 5,  // table producing function
    	EXPRESSION_LIST = 6, // expression list
    	CTE = 7,             // Recursive CTE
    	EMPTY_FROM = 8,      // placeholder for empty FROM
    	PIVOT = 9,           // pivot statement
    	SHOW_REF = 10,       // SHOW statement
    	COLUMN_DATA = 11,    // column 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值