【Spark源码分析】规则框架- `analysis`分析阶段使用的规则

analysis分析阶段使用的规则

规则批策略规则说明
SubstitutionfixedPointOptimizeUpdateFields该规则优化了 UpdateFields 表达式链,因此看起来更像优化规则。但是,在处理深嵌套模式时,UpdateFields 表达式树可能会非常复杂,导致分析无法进行。因此,我们需要在分析开始时尽早优化 UpdateFields
CTESubstitution分析 WITH 节点,并根据以下条件用 CTE 引用或 CTE 定义替代子计划:
1. 如果在传统模式下,或如果查询是 SQL 命令或 DML 语句,则用 CTE 定义(即内联 CTE)替换。
2. 否则,替换为 CTE 引用 CTERelationRefs。是否内联将在查询分析后由 InlineCTE 规则决定。
替换后未内联的所有 CTE 定义将归入主查询和子查询的一个 WithCTE 节点下。任何不包含 CTE 或已内联所有 CTE 的主查询或子查询显然都不会有任何 WithCTE 节点。如果有,WithCTE 节点将与最外层的 With 节点位于同一位置。
WithCTE 节点中的 CTE 定义将按照它们被解析的顺序排列。这意味着对于任何有效的 CTE 查询,CTE 定义都能保证按照它们的依赖关系以拓扑顺序排列(即,给定 CTE 定义 A 和 B,且 B 引用 A,则 A 保证出现在 B 之前)。否则,这一定是一个无效的用户查询,稍后关系解析规则将抛出分析异常。
BindParameters查找 ParameterizedQuery 中所有已命名的参数,并用用户指定参数中的字面量替换它们。
WindowsSubstitution用 WindowSpecDefinitions 代替子计划。 WindowSpecDefinition 是窗口函数的规范。
EliminateUnions如果只有一个子项,则从计划中删除 Union 算子
SubstituteUnresolvedOrdinals用 UnresolvedOrdinal 表达式替换 “order by ”或 “group by ”中的序号。
Disable HintsOnceDisableHints当设置了 spark.sql.optimizer.disableHints 时,删除所有提示。
这将在分析器开始时执行,以禁用提示功能。
HintsfixedPointResolveJoinStrategyHints允许的连接策略提示列表在 JoinStrategyHint.strategies 中定义,连接策略提示可以指定关系别名序列,例如 “MERGE(a, c)”、“BROADCAST(a)”。连接策略提示计划节点将被插入任何与指定名称相匹配的关系(没有不同的别名)、子查询或公共表表达式的顶部。
提示解析的工作方式是向下递归遍历查询计划,找到与指定关系别名之一匹配的关系或子查询。遍历不会超出任何视图引用、子查询别名。
该规则必须在普通表表达式之前执行。
ResolveCoalesceHintsCOALESCE Hint 提示接受名称 “COALESCE”、“REPARTITION ”和 “REPARTITION_BY_RANGE”。
Simple Sanity CheckOnceLookupFunctions检查 UnresolvedFunction 引用的函数标识符是否在函数注册表中定义。请注意,该规则不会尝试解析 UnresolvedFunction。它只是根据函数标识符执行简单的存在性检查,以快速识别未定义的函数,而不会触发关系解析,这在某些情况下可能会导致昂贵的分区/模式发现过程。为了避免重复查找外部函数,外部函数标识符将存储在本地哈希集 externalFunctionNameSet 中。
Keep Legacy OutputsOnceKeepLegacyOutputsspark.sql.legacy.keepCommandOutputSchema为true时,保留 SQL 命令传统输出的规则。ShowTables,ShowNamespaces,DescribeNamespace,ShowTableProperties。
ResolutionfixedPointResolveCatalogs解析table/view/function/namespace的名称部分目录。
ResolveUserSpecifiedColumns解析用户指定的列。当用户在 INSERT INTO 中指定列列表时,为 DSv1 提供了重新排列列顺序的特殊规则。DSv2 由 Analyzer.ResolveInsertInto 单独处理。ResolveInsertInto 单独处理。
ResolveInsertInto解析INSERT INTO语句
ResolveRelations用catalog中的具体关系替换未解决的关系(表和视图)。
ResolvePartitionSpec在分区相关命令中将UnresolvedPartitionSpec解析成ResolvedPartitionSpec
ResolveFieldNameAndPosition根据命令的大小写敏感性解析、规范化和重写字段名称的规则。
AddMetadataColumns当节点缺少已解析的属性时,为子关系的输出添加元数据列。
元数据列的引用是使用 LogicalPlan.metadataOutput 中的列来解析的,但在关系被替换之前,关系的输出不包括元数据列。除非此规则将元数据添加到关系的输出中,否则分析器会检测到没有产生这些列。
只有当节点已解析但缺少其子节点的输入时,该规则才会添加元数据列。这样可以确保除非使用了元数据列,否则不会将其添加到计划中。通过只检查已解析的节点,可确保 * 扩展已完成,这样元数据列就不会被 * 意外选中。此规则会向下解析操作符,以避免过早投影出元数据列。
DeduplicateRelationsLogicalPlan的关系去重
ResolveReferences解析查询计划中的列引用。基本上,它会自下而上地转换查询计划树,只有当一个计划节点的所有子节点都已解析,且子节点之间不存在冲突属性时,才会尝试解析该节点的引用(详见 hasConflictingAttrs)。
ResolveLateralColumnAliasReference该规则是解决横向列别名的第二阶段。
解析横向列别名,它引用了之前在 SELECT 列表中定义的别名。从计划角度看,它处理两种类型的操作符: 项目和聚合。- 在 “项目 ”中,将引用的横向别名下推到新创建的 “项目 ”中,解析引用这些别名的属性 - 在 “聚合 ”中,在上面插入 “项目 ”节点,并返回到 “项目 ”的解析。
ResolveExpressionsWithNamePlaceholders如果表达式中包含 NamePlaceholders,则解析表达式。NamePlaceholders代表的是占位符的
ResolveDeserializer用已解析为给定输入属性的反序列化表达式替换 UnresolvedDeserializer。
ResolveNewInstance如果正在构造的对象是一个内部类,则通过查找并添加外部作用域来解决 NewInstance 问题。
ResolveUpCast用 Cast 替换 UpCast 表达式,并在可能截断的情况下抛出异常。
ResolveGroupingAnalytics解析grouping函数
ResolvePivot解析Pivot,
ResolveUnpivot解析Unpivot,
ResolveOrdinalInOrderByAndGroupBy在SQL的许多方言中,在order/sort by和group by子句中使用的顺序位置是有效的。此规则用于将序号位置转换为选择列表中的相应表达式。Spark 2.0中引入了这种支持。如果排序引用或分组依据表达式不是整数而是可折叠表达式,请忽略它们。当spark.sql.orderByOrdinal/spark.sql.groupByOrdinal设置为false,也忽略位置号。
ExtractGenerator从Project操作符的Project列表中提取Generator,并在Project下创建Generator操作符。
在以下情况下,该规则会抛出 AnalysisException: 1. 生成器嵌套在表达式中,例如:SELECT explode(list) + 1 FROM tbl 2. 在项目列表中发现多个生成器,例如:SELECT explode(list), explode(list) FROM tbl 3. 在非 Project 或 Generate 的其他操作符中发现 Generator,例如 SELECT * FROM tbl SORT BY explode(list)
ResolveGenerate重写表。生成表达式,这些表达式需要以下一项或多项才能解析:输出的具体属性引用。 从SELECT子句(即从Project)重新定位到Generate子句中。 输出Attribute的名称是从封装GeneratorAliasMultiAlias表达式中提取的。
ResolveFunctions用具体的 LogicalPlans 代替 UnresolvedFunctionNames。
用具体的表达式替换 UnresolvedFunctions。
用具体表达式替换 UnresolvedGenerators。
用具体的 LogicalPlans 代替 UnresolvedTableValuedFunctions。
ResolveAliases用具体的别名代替 UnresolvedAliass。
ResolveSubquery该规则可解析和重写表达式内部的子查询。
注:CTE 在 CTESubstitution 中处理。
ResolveSubqueryColumnAliases用投影替换子查询中未解决的列别名。
ResolveWindowOrder检查和添加顺序到AggregateWindowFunction
ResolveWindowFrame检查并为所有窗口功能添加合适的窗口框架。
ResolveNaturalAndUsingJoin根据两侧的输出计算输出列,消除自然连接或使用连接,然后在普通连接上应用 Project 消除自然连接或使用连接。
ResolveOutputRelation根据逻辑计划中的数据解析输出表的列。该规则将
- 按名称写入时重新排列列顺序
- 在数据类型不匹配时插入转换
- 在列名不匹配时插入别名
- 检测与输出表不兼容的计划并抛出 AnalysisException
ExtractWindowExpressions从 Project 运算符的 projectList 和 Aggregate 运算符的 aggregateExpressions 中提取 WindowExpressions,并为每个不同的 WindowSpecDefinition 创建单独的 Window 运算符。
GlobalAggregates将包含聚合表达式的投影转化为聚合。
ResolveAggregateFunctions该规则可查找不在聚合运算符中的聚合表达式。例如,HAVING 子句或 ORDER BY 子句中的表达式。这些表达式会被下推到底层的聚合运算符,然后在原始运算符后被投影掉。
在从中查找聚合函数和分组表达式之前,我们需要确保所有表达式都已完全解析。
TimeWindowing使用扩展运算符将时间列映射到多个时间窗口。要知道一个时间列可以映射到多少个窗口并非易事,因此我们会高估窗口的数量,并过滤掉时间列不在时间窗口内的行。
SessionWindowing将时间列映射到会话窗口。
ResolveWindowTime解析 window_time 表达式,从作为窗口聚合运算符输出的窗口列中提取正确的窗口时间。窗口列的类型为 struct { start: TimestampType, end: TimestampType }。窗口的正确代表事件时间是 window.
ResolveDefaultColumns这是一条在 CREATE/ REPLACE TABLE 等语句中处理 DEFAULT 列的规则。
CREATE TABLE 和 ALTER TABLE 调用支持为以后的操作设置列默认值。随后的 INSERT、UPDATE 和 MERGE 命令可根据需要使用 DEFAULT 关键字引用该值。
ResolveInlineTables使用LocalRelation替换UnresolvedInlineTable
ResolveLambdaVariables解决高阶函数公开的 lambda 变量。
该规则分两步运行:
[1]. 将高阶函数公开的匿名变量绑定到 lambda 函数的参数上;这样就创建了命名和类型化的 lambda 变量。在这一步中,将检查参数名称是否重复,并检查参数的数量。
[2]. 解析 lambda 函数的函数表达式树中使用的 lambda 变量。请注意,我们允许使用当前 lambda 之外的变量,这些变量可以是定义在外层作用域中的 lambda 函数,也可以是由计划的子计划产生的属性。如果名称重复,则使用最内部作用域中定义的名称。
ResolveTimeZone用会话本地时区的副本替换不含时区 ID 的 TimeZoneAwareExpression。
ResolveRandomSeed设置随机数生成的种子。
ResolveBinaryArithmetic解析二进制算法
对于加法
1. 如果两边都是时间间隔,则保持不变;
2. 否则,如果一边是日期,另一边是时间间隔,则将其转为 DateAddInterval;
3. 否则,如果一边是时间间隔,则将其转为 TimeAdd;
4. 否则,如果一边是日期,则将其转为 DateAdd;
5. 否则保持不变。
减法
1. 如果两边都是时间间隔,则保持不变;
2. 否则,如果左边是日期,右边是区间,则将其转为(l, -r); 3. 否则,如果右边是区间,则将其转为(l, -r);
4. 否则,如果一边是时间戳,则将其转为 SubtractTimestamps;
5. 否则,如果右边是日期,则将其转为 DateDiff/SubtractDates;
6. 否则,如果左边是日期,则将其转为 DateSub;
7. 否则改为保持不变。
乘法
1. 如果一边是区间,则将其转换为 MultiplyInterval;
2. 否则保持不变。
对于除法
1. 如果左边是区间,则将其转为 DivideInterval;
2. 否则,保持不变。
ResolveUnion将 Union 的不同子代解析为一组共同的列。
RewriteDeleteFromTable重写 DELETE 操作的规则,使用对单行或行群组进行操作的计划。
如果表实现了 SupportsDeleteV2 和 SupportsRowLevelOperations,该规则仍将重写 DELETE 操作,但优化器会检查是否可以通过向连接器传递删除筛选器来处理该特定 DELETE 语句。如果可以,优化器将放弃重写的计划,并允许数据源使用过滤器删除。
typeCoercionRulesspark.sql.ansi.enabled设置为 true 的时候,采取 ANSI 的方式进行解析,这代表的是一组解析规则。
ResolveWithCTE使用相应 CTE 定义的解析输出属性更新 CTE 引用。
Remove TempResolvedColumnOnceRemoveTempResolvedColumn主解析批次中的 ResolveReferences 规则会在 UnresolvedHaving/ Filter/ Sort 中创建 TempResolvedColumn,用于保存临时解析的带有 agg.
如果托管 TempResolvedColumn 的表达式已完全解析,则规则 ResolveAggregationFunctions 将 - 如果 TempResolvedColumn 位于聚合函数或分组表达式中,则用 AttributeReference 替换 TempResolvedColumn。- 如果 TempResolvedColumn 不在聚合函数或分组表达式中,则将其标记为已尝试,希望其他规则能重新解决它。如果 hasTried 为真,ResolveReferences 将重新解析 TempResolvedColumn,如果解析失败,则保持不变。我们应该将其转回 UnresolvedAttribute,这样分析器稍后就能报告缺少列的错误。
如果托管 TempResolvedColumn 的表达式未被解析,TempResolvedColumn 将保持 hasTried 为 false。我们应该剥离 TempResolvedColumn,这样用户就能看到表达式未解析的原因,例如类型不匹配。
Post-Hoc ResolutionOnceResolveCommandsWithIfExists用于在未解析表或临时视图时处理命令的规则。这些命令支持 “ifExists ”标志,因此在未解析关系时不会失败。如果 “ifExists ”标志被设为 true,则该计划将被解析为 NoopCommand.
Remove Unresolved HintsOnceRemoveAllHints删除所有hits,用于删除用户提供的无效hits。必须在执行完所有其他hits规则后才能执行。
NondeterministicOncePullOutNondeterministic从非 Project 或过滤器的 LogicalPlan 中提取非确定表达式,将其放入内部 Project,最后将其投射到外部 Project。
UDFOnceHandleNullInputsForUDF通过添加额外的 If 表达式来进行空值检查,从而正确处理 UDF 的空基元输入。当用户使用基元参数定义 UDF 时,无法判断基元参数是否为空,因此我们假定基元输入为可传递的空,如果输入为空,则返回空。
ResolveEncodersInUDF通过明确给出属性来解决 UDF 的编码器问题。我们明确给出属性是为了处理输入值的数据类型与编码器内部模式不一致的情况,这可能会导致数据丢失。例如,如果实际数据类型是 Decimal(30,0),编码器不应将输入值转换为 Decimal(38,18)。
解析后的编码器将用于将内部行反序列化为 Scala 值。
UpdateNullabilityOnceUpdateAttributeNullability通过使用子输出属性(Attributes)中相应属性的无效性,更新已解析逻辑计划(LogicalPlan)中属性的无效性。之所以需要这一步骤,是因为用户可以在数据集 API 中使用已解析的 AttributeReference,而外连接可以改变 AttributeReference 的无效性。如果没有这条规则,可空列的可空字段实际上可能会被设置为不可空,从而导致非法优化(如 NULL 传播)和错误答案。

有关这种情况的具体查询,请参见 SPARK-13484 和 SPARK-13801。
SubqueryOnceUpdateOuterReferences引用外部查询块的子查询中的聚合表达式会被推送到外部查询块进行评估。下面的规则更新了此类外部引用,如 AttributeReference 引用父查询块/外部查询块中的属性。
CleanupfixedPointCleanupAliases清除计划中不必要的别名。基本上,我们只需要在 Project(项目列表)或 Aggregate(聚合表达式)或 Window(窗口表达式)中将别名作为顶层表达式。请注意,如果一个表达式有其他不在其子表达式中的表达式参数,如 RuntimeReplaceable,则本规则中的别名转换对这些参数不起作用。
HandleSpecialCommandOnceHandleSpecialCommand用于处理分析完成后需要通知的特殊命令的规则。该规则应在所有其他分析规则运行后运行。
Remove watermark for batch queryOnceEliminateEventTimeWatermark忽略批量查询中的事件时间水印,该功能仅在结构化数据流中支持。TODO:将此规则添加到分析器规则列表中。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/887945.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt详解QUiLoader 动态加载UI文件

文章目录 详解 QUiLoader 模块的使用1. QUiLoader 简介1.1 应用场景 2. 准备工作2.1 添加模块依赖2.2 引入头文件 3. 使用 QUiLoader 加载界面3.1 示例代码form.uimain.cpp 4. 常用方法详解4.1 load函数原型作用参数返回值示例代码 4.2 createWidget函数原型作用参数返回值示例…

【Git 工具】用 IntelliJ IDEA 玩转 Git 分支与版本管理

文章目录 一、使用 IDEA 配置和操作 Git1.1 查看 Idea 中的 Git 配置1.2 克隆 Github 项目到本地 二、版本管理2.1 提交并推送修改2.2 拉取远程仓库2.3 查看历史2.4 版本回退 三、分支管理3.1 新建分支3.2 切换分支3.2 合并分支3.4 Cherry-Pick 参考资料 一、使用 IDEA 配置和操…

shell编程(4)脚本与用户交互以及if条件判断

声明: 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&#…

架构-微服务-服务调用Dubbo

文章目录 前言一、Dubbo介绍1. 什么是Dubbo 二、实现1. 提供统一业务api2. 提供服务提供者3. 提供服务消费者 前言 服务调用方案--Dubbo‌ 基于 Java 的高性能 RPC分布式服务框架,致力于提供高性能和透明化的 RPC远程服务调用方案,以及SOA服务治理方案。…

【Python网络爬虫笔记】2-HTTP协议中网络爬虫需要的请求头和响应头内容

1 HTTP 协议整理 HTTP(Hyper Text Transfer Protocol)即超文本传输协议,是用于从万维网(WWW)服务器传输超文本到本地浏览器的传送协议,直白点儿,就是浏览器和服务器之间的数据交互就是通过 HTT…

【前端开发】小程序无感登录验证

概述 封装的网络请求库,主要用于处理 API 请求并支持自动处理 token 过期 和 token 刷新,适用于需要身份验证的应用场景,特别是在移动端中。 主要功能 自动附加 Token 在每个请求中自动附加 Authorization 头部,使用存储的 acces…

关于Spring基础了解

Spring简介 Spring框架是一个开源的Java应用框架,旨在简化企业级应用程序的开发。它提供了一系列强大的工具和服务,帮助开发者构建高质量的Java应用程序。Spring框架的核心理念是使开发过程更加模块化、可测试和可维护。 主要特性 依赖注入&#xff08…

解析 SpringBoot 新冠密接者跟踪系统:灵活的权限管理机制

第2章 程序开发技术 2.1 Mysql数据库 为了更容易理解Mysql数据库,接下来就对其具备的主要特征进行描述。 (1)首选Mysql数据库也是为了节省开发资金,因为网络上对Mysql的源码都已进行了公开展示,开发者根据程序开发需要…

TYUT设计模式大题

对比简单工厂,工厂方法,抽象工厂模式 比较安全组合模式和透明组合模式 安全组合模式容器节点有管理子部件的方法,而叶子节点没有,防止在用户在叶子节点上调用不适当的方法,保证了的安全性,防止叶子节点暴露…

SpringBoot集成Kafka和avro和Schema注册表

Schema注册表 为了提升kafka的性能,减少网络传输和存储的数据大小,可以把数据的schema部分单独存储到外部的schema注册表中,整体架构如下图所示: 1)把所有数据需要用到的 schema 保存在注册表里,然后在记…

Nodemailer使用教程:在Node.js中发送电子邮件

目录 1. 简介 2. 安装 3. 基本配置 3.1 创建传输器 3.2 配置说明 4. 发送邮件 4.1 基本发送示例 4.2 发送验证码示例 5. 常见问题解决 5.1 "Greeting never received" 错误 5.2 安全建议 SMTP与邮件加密协议详解 1. SMTP简介 1.1 基本特点 2. 加密协…

Cause: java.sql.SQLException: No value specified for parameter 4

问题 执行更新sql时报错,异常栈如下 org.springframework.jdbc.BadSqlGrammarException: ### Error updating database. Cause: java.sql.SQLException: No value specified for parameter 4 ### The error may exist in com/my/mapper/MyMapper.java (best gue…

Wireshark 4.4.2:安全更新、错误修复、更新协议支持

流行的网络协议分析器Wireshark已更新至4.4.2版本。它可用于网络故障排除、分析、开发和教育。 已修复以下漏洞: wnpa-sec-2024-14 FiveCo RAP 解剖器无限循环。wnpa-sec-2024-15 ECMP 解析器崩溃。 更新的协议支持: ARTNET、ASN.1 PER、BACapp、B…

【一维DP】【三种解法】力扣983. 最低票价

在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行。在接下来的一年里,你要旅行的日子将以一个名为 days 的数组给出。每一项是一个从 1 到 365 的整数。 火车票有 三种不同的销售方式 : 一张 为期一天 的通行证售价为 costs[0] …

C语言中数据类型对应的打印格式

提示:文章 文章目录 前言一、背景二、C语言中数据类型对应的打印格式三、3.1 总结 前言 前期疑问: 本文目标: 一、背景 最近 二、C语言中数据类型对应的打印格式 int 对应 %d long 对应 %ld char 对应 %c float 对应 %f long long 对应 %…

《Django 5 By Example》阅读笔记:p339-p358

《Django 5 By Example》学习第12天,p339-p358总结,总计20页。 一、技术总结 1.项目(购物网站) django-admin startproject myshop 虽然这里只是示例,但我觉得这种命名为 myxxx 的习惯非常不好,因为在实际应用中,是…

Vue 项目开发常用知识点

一、基础语法与指令 1. 插值表达式 插值表达式是 Vue 中最基础的数据绑定方式,使用双大括号{{ }}将数据包裹起来,例如{{ message }},它会将 Vue 实例中的message属性的值渲染到页面相应位置。这种方式可以方便地在页面中展示动态数据&#x…

【Web开发基础学习——corsheaders 应用的理解】

Web开发基础学习系列文章目录 第一章 基础知识学习之corsheaders 应用的理解 文章目录 Web开发基础学习系列文章目录前言一、使用1.1 安装1.2 配置 二、功能总结 前言 corsheaders 是一个 Django 第三方应用,用于处理跨域资源共享 (CORS)。CORS 是一种机制&#x…

【简单好抄保姆级教学】javascript调用本地exe程序(谷歌,edge,百度,主流浏览器都可以使用....)

javascript调用本地exe程序 详细操作步骤结果 详细操作步骤 在本地创建一个txt文件依次输入 1.指明所使用注册表编程器版本 Windows Registry Editor Version 5.00这是脚本的第一行,指明了所使用的注册表编辑器版本。这是必需的,以确保脚本能够被正确解…

Milvus 2.5:全文检索上线,标量过滤提速,易用性再突破!

01. 概览 我们很高兴为大家带来 Milvus 2.5 最新版本的介绍。 在 Milvus 2.5 里,最重要的一个更新是我们带来了“全新”的全文检索能力,之所以说“全新”主要是基于以下两点: 第一,对于全文检索基于的 BM25 算法,我们采…