高唐企业网站建设,wordpress支持多少会员,网站建设的计划,mysql 网站登录密码PgSQL技术内幕 - ereport ERROR跳转机制 使用客户端执行SQL的时候经常遇到报ERROR错误#xff0c;然后SQL语句就退出了。当然#xff0c;事务也会回滚掉。本文我们看下它是如何做到退出SQL语句并回滚事务的。 1、以insert一个numeric类型值为例 表一个字段为numeric(10,2)类型… PgSQL技术内幕 - ereport ERROR跳转机制 使用客户端执行SQL的时候经常遇到报ERROR错误然后SQL语句就退出了。当然事务也会回滚掉。本文我们看下它是如何做到退出SQL语句并回滚事务的。 1、以insert一个numeric类型值为例 表一个字段为numeric(10,2)类型表示存储10位数字精确到小数点后两位。当插入的值超过10位时就会报错numeric field overflow 首先观察报错的位置 由ereport输出打印日志。从函数ereport_domain函数的调用逻辑如下图所示可以看到通过siglongjmp函数进行跳转。 2、PG_TRY/PG_CATCH/PG_RE_THROW/PG_END_TRY 从上面可知PG中通过PG_RE_THROW完成跳转捕获ereport(ERROR)的API为 PG_TRY();
{... code that might throw ereport(ERROR) ...
}
PG_CATCH();
{... error recovery code ...
}
PG_END_TRY(); 该宏定义 sigsetjmp会保存目前堆栈环境然后将目前的地址作为一个记号。程序其他地方调用siglongjmp时会直接跳到这个记号位置然后还原堆栈继续程序的执行。 3、整体逻辑 从PostgresMain接收命令ReadCommand到调用exec_simple_query执行SQL然后standard_ExectorRun执行器开始执行再到ExecModifyTable执行insert操作。首先从子节点获取slot然后执行ExecInsert执行插入操作。红色箭头为插入操作函数调用方向。 从子节点获取slot时会调用apply_typmod函数校验numeric类型值是否会溢出。一旦溢出则报ereport ERROR。 蓝色箭头为跳转方向。从apply_typmod函数跳转到standard_ExecutorRun的PG_TRY位置然后通过PG_CATCH处理一些清理操作再由PG_RE_THROW跳转到exec_simple_query的PG_TRY位置同理一直跳转到PostgresMain的sigsetjmp位置。 由此完成插入过程中报错退出动作也就是说当ereport报ERROR时并不是继续当前函数的退出逻辑而是跳转到PostgresMain的sigsetjmp位置接着执行继续一些清理操作包括调用AbortCurrentTransaction回滚事务。 从上图中可以看到回滚事务后会接着再次进入for循环调用ReadCommand读取新命令执行当然若没有命令到来则进入等待。