暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

【手写数据库核心揭秘系列】别名查询,相同数据表却成为不同的数据源表

开源无限 2025-04-15
126

💻 深耕数据库内核架构设计与开发十余年,曾主导多款高性能分布式数据库内核研发,攻克高并发、低延迟等核心技术难题。现倾力打造《从零手写数据库》系列教程,首次系统性公开数据库内核源码级实现细节!

🚀 从存储引擎、查询优化到分布式事务,手把手拆解核心模块;从语法解析树构建到执行计划生成,逐行代码还原设计精髓
🌟 无论你是数据库开发者、系统架构师,还是对底层技术充满好奇的极客,这里都有你想要的“硬核干货”!点击关注,与行业老兵共同探索数据库技术的星辰大海!

一、概述 


在SQL语法解析中,select子句和from子句中都支持别名语法,也就是属性列名称、数据表名称或者子查询等都可以进行重命名操作,

这就需要在一些处理流程上做相应的匹配,主要涉及以下改动点:

  1. 目标列与数据源表的对应关系;
  2. 查询结果与数据源表的对应关系;
  3. 查询结果显示时的标题。

二、目标列与数据源表的对应 


目标列需要与它命名域对应的数据源表关联起来,

比如SQL查询 “select a.id, b.id from student a, student b;”,

虽然两个数据源来自同一个实际的数据表student,但是两个目标列对应不同的数据源表,不同的数据源表在执行过程中查询的结果是不一样的。

因此在目标列结构中新增数据源的成员,在逻辑执行计划阶段与对应的数据源表关联起来。

typedef struct TargetElement
{

    Node                *tblRefInfo;
}TargetElement;

在处理添加目标列和检查目标列时,会在数据源表中检查目标列是否存在,此时目标列中记录对应的数据源表信息。

在下面两个函数中增加数据源表的关联动作。

int AddOneRelationAttributes(TableRefInfo *tblRefInfo, QueryStmt *queryStmt)

        te->tblRefInfo 
= (Node*)tblRefInfo;

int CheckOneAttribute(TargetElement *te, char *attrName, TableRefInfo *tblRefInfo)

            te->tblRefInfo 
= (Node*)tblRefInfo;

另外,目标列的别名信息为空时,将它赋值为数据源表中的属性列名称,使得结果显示时可以统一使用目标列的别名字段。

int CheckAttributes(TargetElement *te, QueryStmt *queryStmt)
        if(te->alias == NULL)
            te->alias 
= refNode->sub_name;

三、查询结果与数据源表的对应 


如上节的举例,一个实际的数据表会作为多个数据源表来查询,每个数据源表都会产生查询结果,因此查询结果集中的每个结果需要与数据源表进行关联,而不是与实际的数据表关联。

typedef struct ResultNode
{

    Node            *tblRefInfo;
}ResultNode;

因此在查询结果结构中新增数据源成员,来记录结果的来源表。

在扫描操作产生一条查询结果时,将数据源表信息也记录到结果节点当中。

Node* ExecSeqScan(Node *planNode)

result->tblRefInfo 
= seqScan->tblRefInfoNode;

相同的数据表,在不同数据源查询中的结果不同,所以在结果集上的运算需要按数据源来获取对应的值。

在投影操作时,根据目标列获取对应的数据源表的查询结果时,也根据目标列对应的数据源在结果集中查找。

ResultNode* GetResultNodeFromList(TargetElement *te, List *resultList)

        if(te->tblRefInfo == resNode->tblRefInfo)

四、查询结果标题显示 


在客户端显示查询结果时,结果的标题显示应该是目标列的别名,而不是数据表的属性列,如果没有指定别名时,才显示为属性列名称。

void ShowTableHead(List *targetList)

        snprintf(buf + bufOffset, PORT_BUFFER_SIZE - bufOffset, "|%-*s", te->attr->maxWidth, te->alias)
;

五、概述 


本节修改内容在目录exam_48下的 plan.c, excutor.c和portal.c文件中。

🌟 点赞收藏,分享给身边的技术伙伴,关注我们,持续获取数据库内核开发的硬核干货!一起从源码级实现到分布式架构,解锁数据库技术的每一个核心细节!🚀
【往期精彩推荐】

【手写数据库内核miniToadb】第81讲 数据字典的持久化存储

【手写数据库核心揭秘系列】第80讲 执行器基本操作符(扫描/投影/嵌套联接/选择)算法

【手写数据库核心揭秘系列】第79讲 迭代执行器的实现


文章转载自开源无限,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论