PostgreSQL源码分析——CREATE CAST

CREATE CAST源码分析

CREATE CAST用法

CREATE CAST —— 定义一个用户自定义的类型转换
用法如下:

CREATE CAST (source_type AS target_type)WITH FUNCTION function_name [ (argument_type [, ...]) ][ AS ASSIGNMENT | AS IMPLICIT ]CREATE CAST (source_type AS target_type)WITHOUT FUNCTION[ AS ASSIGNMENT | AS IMPLICIT ]CREATE CAST (source_type AS target_type)WITH INOUT[ AS ASSIGNMENT | AS IMPLICIT ]

如何使用以及用法请参考PostgreSQL文档中CREATE CAST一节。下面我们主要分析一下其源码,看一下是如何实现的。

源码分析

因为CREATE CAST属于Utility型语句,无需查询优化,其主流程如下:

exec_simple_query
--> pg_parse_query      // 语法解析
--> pg_analyze_and_rewrite   // 语义分析--> parse_analyze--> pg_rewrite_query
--> pg_plan_queries    // 生成执行计划
--> PortalStart
--> PortalRun          // 执行器执行--> PortalRunMulti--> PortalRunUtility--> ProcessUtility--> standard_ProcessUtility--> ProcessUtilitySlow--> CreateCast    // 进入CreateCast处理函数处理CREATE CAST语句
--> PortalDrop

主要的处理逻辑都在CreateCast函数中完成。后续会重点分析一下这个函数。

解析部分

我们首先分析一下其语法解析部分,这部分比较简单,核心是CreateCastStmt的定义,定义如下:

/* ----------------------*	CREATE CAST Statement* ----------------------*/
typedef struct CreateCastStmt
{NodeTag		type;TypeName   *sourcetype;TypeName   *targettype;ObjectWithArgs *func;CoercionContext context;bool		inout;
} CreateCastStmt;

CREATE CAST其在gram.y中定义的表示如下:

/***************************************************		CREATE CAST / DROP CAST**************************************************/
CreateCastStmt: CREATE CAST '(' Typename AS Typename ')'WITH FUNCTION function_with_argtypes cast_context{CreateCastStmt *n = makeNode(CreateCastStmt);n->sourcetype = $4;n->targettype = $6;n->func = $10;n->context = (CoercionContext) $11;n->inout = false;$$ = (Node *)n;}| CREATE CAST '(' Typename AS Typename ')'WITHOUT FUNCTION cast_context{CreateCastStmt *n = makeNode(CreateCastStmt);n->sourcetype = $4;n->targettype = $6;n->func = NULL;n->context = (CoercionContext) $10;n->inout = false;$$ = (Node *)n;}| CREATE CAST '(' Typename AS Typename ')'WITH INOUT cast_context{CreateCastStmt *n = makeNode(CreateCastStmt);n->sourcetype = $4;n->targettype = $6;n->func = NULL;n->context = (CoercionContext) $10;n->inout = true;$$ = (Node *)n;};cast_context:  AS IMPLICIT_P					{ $$ = COERCION_IMPLICIT; }| AS ASSIGNMENT							{ $$ = COERCION_ASSIGNMENT; }| /*EMPTY*/								{ $$ = COERCION_EXPLICIT; };DropCastStmt: DROP CAST opt_if_exists '(' Typename AS Typename ')' opt_drop_behavior{DropStmt *n = makeNode(DropStmt);n->removeType = OBJECT_CAST;n->objects = list_make1(list_make2($5, $7));n->behavior = $9;n->missing_ok = $3;n->concurrent = false;$$ = (Node *)n;};opt_if_exists: IF_P EXISTS						{ $$ = true; }| /*EMPTY*/								{ $$ = false; };

非常容易理解,下面我们重点分析一下CreateCast函数的实现。

执行部分

用户通过CREATE CAST语句自定义一个类型转换,数据库肯定有个地方将这个转换的信息存起来,这个地方就是pg_cast系统表。pg_cast系统表存在数据类型转换路径,包括内建和用户自定义的。

postgres@postgres=# \d pg_castTable "pg_catalog.pg_cast"Column    |  Type  | Collation | Nullable | Default 
-------------+--------+-----------+----------+---------oid         | oid    |           | not null | castsource  | oid    |           | not null |             -- 源数据类型的OIDcasttarget  | oid    |           | not null |             -- 目标数据类型的OIDcastfunc    | oid    |           | not null |             -- 执行该转换的函数的OID。如果该转换方法不需要一个函数则存储0。castcontext | "char" |           | not null |             -- 指示该转换能被调用的环境castmethod  | "char" |           | not null |             -- 指示转换如何被执行。
Indexes:"pg_cast_oid_index" UNIQUE, btree (oid)"pg_cast_source_target_index" UNIQUE, btree (castsource, casttarget)

CreateCast函数的主要内容就是将用户自定义的类型转换信息插入到pg_cast系统表中。

CreateCast
--> LookupFuncWithArgs  // 查到pg_proc系统表,看是否已存在--> LookupFuncNameInternal--> FuncnameGetCandidates
--> IsBinaryCoercible(Oid srctype, Oid targettype) //Check if srctype is binary-coercible to targettype.
--> CastCreate  // 将类型转换信息插入pg_cast系统表中

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

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

相关文章

防止更新或保存 Laravel 模型

例如,创建模型后,我不希望任何人能够再次更新该记录。相反,它应该被全新的记录覆盖并存档。 这是一个简单的特征,您可以在模型上使用它来禁用更新: trait PreventsUpdating {public static function bootPreventsUpd…

java多线程面试总结

创建线程的方式有哪些? 1.继承Thread类,重写run方法。2.实现Runnable接口,实现run方法。3.实现Callable接口,实现call方法,结合FutureTask。(可以获取线程的返回值)4.线程池创建线程。 线程的…

OpenGL绘制Bezier曲面

Bezier的定义 贝塞尔曲面是贝塞尔曲线在二维上的扩展。它由一组控制点定义,通过这些控制点生成光滑的曲面。贝塞尔曲面通常用两个参数 u u u和 v v v来表示,这两个参数的取值范围都在 [0, 1] 之间。 数学表示 P ( u , v ) = ∑ i = 0 n ∑ j = 0 m p i j ⋅ B i , n ( u ) ⋅…

redis-基础篇(1)

黑马redis-基础篇笔记 1. 初识redis REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库。Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存、分布式、可选持久性的…

Mybatis中BaseEntity作用

新建各种对象的时候,一般来说,有几个属性是所有对象共有的,比如说id,is_del,is_enable这些,然后设置一个基础对象,以后新建所有对象的时候都继承它,就省的每次都要写这些共有的属性了

Flask request 中获取访问的ip

在Flask中,可以通过request对象的remote_addr属性获取访问者的IP地址。以下是一个简单的示例代码: from flask import Flask, requestapp Flask(__name__)app.route(/) def index():ip_address request.remote_addrreturn f"Your IP address is …

HCIA-速查-ENSP模拟器2步清空配置

需求:清空模拟器配置 清空当前图中配置 步骤1:reset saved-configuration 后输入y确认 步骤2:reboot后输入n否认再输入y确认 验证已经清空配置

文件防篡改监控工具 - WGCLOUD全面介绍

WGCLOUD是一款优秀的运维监控软件,免费、轻量、高效,部署容易,上手简单,对新手非常友好 WGCLOUD部署完成后,点击菜单【文件防篡改】,可以看到如下页面 我们点击【添加】按钮,输入监控文件的信息…

Java面向对象的三大特性之一——继承

目录 一、继承概念 二、为什么要继承 三、继承语法(关键字extends) 四、父类成员访问 1、子类中访问父类的成员变量 (1)子类和父类不存在同名的成员变量 (2)子类和父类中存在同名的成员变量 2、子类中访…

React+TS 从零开始教程(1)

源码链接:https://pan.quark.cn/s/c6fbc31dcb02 创建项目 直接通过以下命令,我们来创建一个reactts的项目。 npx create-react-app myapp --template typescript这样就创建好了,然后我们导入vscode. npx是npm里面的一个库,可以让你自动使用…

ARM-V9 RME(Realm Management Extension)系统架构之系统启动

本节描述了初始化RME系统的要求。 目录 一、复位需求 二、RME禁用 一、复位需求 RME系统重置(即复位)是指重置整个系统的全局功能状态的任何系统事件。 RME系统重置包括处理单元(PEs)、处理单元集群(PE-clusters)、系统核心逻辑和辅助逻辑、所有系统…

构造函数、实例、原型对象三者之间的关系

在 JavaScript 中,构造函数、实例和原型对象之间有着密切的关系。下面是对它们之间关系的详细解析和代码示例: 构造函数:构造函数是一个特殊的函数,用于创建对象的模板。它定义了对象的属性和方法。构造函数通常以大写字母开头&a…

2-11 基于matlab的BP-Adaboost的强分类器分类预测

基于matlab的BP-Adaboost的强分类器分类预测,Adaboost是一种迭代分类算法,其在同一训练集采用不同方法训练不同分类器(弱分类器),并根据弱分类器的误差分配不同权重,然后将这些弱分类器组合成一个更强的最终…

云专线组网方案的特性和实施要素

云专线组网方案是指企业通过专用的网络连接,将其内部网络与云服务商的数据中心直接相连,从而实现高速、安全、稳定的云资源访问。云专线通常提供比公共互联网更优的网络性能,包括更低的延迟、更高的带宽和更强的安全性。以下是云专线组网方案…

物联网设备安装相关知识整理

拓扑图 对于ADAM-4150先接设备的整体的供电。 ADAM-4150就涉及到几个电子元器件的连接,一个是485-232的转换器,一个是将RS-232转换为USB的转接口,因为现在的计算机很多都去掉了RS-232接口而使用USB接口。 4150右侧有个拨码,分别两…

UniApp 开发微信小程序教程(一):准备工作和环境搭建,项目结构和配置

文章目录 一、准备工作和环境搭建1. 安装 HBuilderX步骤: 2. 注册微信开发者账号步骤: 3. 创建 UniApp 项目步骤: 二、项目结构和配置1. UniApp 项目结构2. 配置微信小程序修改 manifest.json修改 pages.json 3. 添加首页文件index.vue 示例&…

排序之快速排序

快速排序之所以叫快速排序,肯定要配得上它的名字。我们就来看看它是如何这么快的。 快速排序的原理 快速排序是霍尔创建的,是通过以第一个或者最后一个数值作为比较值key,形成一个它的左边比它都小,右边比它都大的情况&#xff0…

redHat9 安装 iptables 过程记录

1. redHat9安装 iptables: 方法1:对于使用 yum 的旧版 Red Hat 9: yum install iptables-services 方法2:对于使用 dnf 的新版 Red Hat 9 或 CentOS: dnf install iptables ps: 可能会报错,诸如 connect f…

家用电器信息管理系统

摘 要 随着互联网的快速发展,传统家电行业受到冲击,逐渐向智能家居市场转型。因此,智能家居无疑是一个有着巨大市场需求和新兴发展空间的新兴产业,也是人们追求安全、便捷、舒适的生活方式的必然趋势。互联网推动了我国传统家居产…

从复用性角度阐述中台建设

目录 复用性中台定义深思中台建设产品线形态何时演变中台能力落地中台 业务中台架构总结 技术学习永不止步,最近也是看了很多关于架构设计相关的专栏,慢慢总结出来一部分知识,代入自己的思考与理解,以及结合并反思自己之前公司的架…