PgSQL技术内幕 - case when表达式实现机制

news2024/9/24 7:22:35

PgSQL技术内幕 - case when表达式实现机制

CASE表达式如同 C语言中的if/else语句一样,为SQL添加了条件逻辑处理能力,可以根据不同条件返回不同结果。PgSQL支持两种语法:简单表达式和搜索表达式。

1、搜索表达式

语法如下:

CASE WHEN condition THEN result
     [WHEN ...]
     [ELSE result]
END

表达式计算过程:

1fa4cc6e303f417fb57ae6e61647e5f3.png

按照顺序依次计算WHEN子句的条件表达式:condition1,condition2...,当遇到结果为真的分支就返回相应的THEN结果;若不为真,则继续下一个WHEN条件计算;若所有WHEN都不为真,则返回ELSE默认值;当没有指定ELSE时,就返回NULL。

2、简单表达式

语法如下:

CASE expression
    WHEN value THEN result
    [WHEN ...]
    [ELSE result]
END

表达式计算过程:

7402926e89b3e2fbc9a83fc98307eb19.png

首先计算表达式testexpr的值,然后依次与WHEN中值:value1,value2...进行比较,遇到匹配的就返回THEN对应的结果;如果没有匹配则继续下一个WHEN值比较;若所有WHEN都不匹配则返回ELSE的默认值;如果没有指定ELSE则返回NULL。

3、搜索表达式实现机制

3.1 结构体

18e6c28e9e3eb7ff06493a1a2431c5c2.png

3.2 搜索表达式的实现机制

b7f818831d0913612bf46d616dc0f992.png

首先生成表达式计算步骤:ExecInitExprRec函数的T_CaseExpr分支。大致分为2大部分:

1)所有when的表达式caseExpr->args。首先通过ExecInitExprRec初始化when->expr的表达式计算步骤;然后添加EEOP_JUMP_IF_NOT_TRUE步骤,当when->expr表达式步骤计算为false时需要跳到下一个when,后面的state->steps[whenstep].d.jump.jumpdone = state->steps即为跳转位置;接着ExecInitExprRec初始化THEN的表达式(when->result)计算步骤;最后通过EEOP_JUMP跳到case的结束位置,它的结束位置需要计算完ELSE表达式后进行调整。

2)所有when表达式计算步骤生成后,需要对ELSE表达式进行初始化,即调用ExecInitExprRec对caseExpr->defresult生成计算步骤;最后调整EEOP_JUMP的跳转位置

3.3 简单表达式的实现机制

643907aa65f67e85a897bd6c6be51ba1.png

和搜索表达式不同,需要对CASE的表达式生成计算步骤,即caseExpr->arg的步骤;当该表达式结果类型为变长类型时,需要添加EEOP_MAKE_READONLY步骤进行结果值拷贝。

当没有ELSE时怎么办?

transformCaseExpr
  ...
  defresult = (Node *) c->defresult;
  if (defresult == NULL)
  {
    A_Const    *n = makeNode(A_Const);


    n->val.type = T_Null;
    n->location = -1;
    defresult = (Node *) n;
  }
  newc->defresult = (Expr *) transformExprRecurse(pstate, defresult);
  ...

也就是会添加一个const节点表示NULL,caseExpr->defresult总是有值。

参考

https://www.postgresql.org/docs/12/functions-conditional.html

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

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

相关文章

android studio下开发flutter

文章目录 1. 配置环境 https://flutter.cn/docs/get-started/install2. android studio下开发flutter 1. 配置环境 https://flutter.cn/docs/get-started/install 2. android studio下开发flutter 打开Android Studio -> File -> Settings -> Plugins 搜索Dart插件 …

java_error_in_pycharm.hprof文件是什么?能删除吗?

java_error_in_pycharm.hprof文件是什么?能删除吗? 🌵文章目录🌵 🌳引言🌳🌳hprof格式文件介绍🌳🌳java_error_in_pycharm.hprof文件什么情况下能删除🌳&…

简化版SpringMVC

简化版SpringMVC web.xml xml version"1.0" encoding"UTF-8"?> <web-app version"2.5" xmlns"http://java.sun.com/xml/ns/javaee" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation&quo…

科技王座“座次变更”:英伟达超越亚马逊在即,距离谷歌也不远

英伟达的市值即将超过亚马逊&#xff0c;为二十年来首次。 截至2月7日收盘&#xff0c;英伟达市值达到1.73万亿美元&#xff0c;逼近亚马逊1.77万亿美元的市值&#xff0c;距离谷歌1.82万亿美元的市值也不远。 对人工智能的热情推升英伟达的股价去年以来一路飙涨&#xff0c;受…

【开源】基于JAVA+Vue+SpringBoot的新能源电池回收系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户档案模块2.2 电池品类模块2.3 回收机构模块2.4 电池订单模块2.5 客服咨询模块 三、系统设计3.1 用例设计3.2 业务流程设计3.3 E-R 图设计 四、系统展示五、核心代码5.1 增改电池类型5.2 查询电池品类5.3 查询电池回…

nginx登录用户验证配置

我们的nginx端口一般都是对外开放的&#xff0c;所以有一定程度上有被别人扫描的风险&#xff0c;所以为了减少被扫描的风险&#xff0c;我们可以配置一个nginx的用户登录验证&#xff1b; 用户验证登录需要nginx的一个模块&#xff1a;ngx_http_auth_basic_module 我们使用…

MySQL 时间索引的选择

背景 MySQL 在使用过程中经常会对时间加索引&#xff0c;方便进行时间范围的查询&#xff0c;常见的时间类型有 data、datetime、long、timestamp 等&#xff0c;在此分析下这几种时间类型的索引大小&#xff0c;以找到比较合适的时间类型。 时间类型对比 常用的索引类型是 …

SolidWorks学习笔记——入门知识2

目录 建出第一个模型 1、建立草图 2、选取中心线 3、草图绘制 4、拉伸 特征的显示与隐藏 改变特征名称 5、外观 6、渲染 建出第一个模型 1、建立草图 图1 建立草图 按需要选择基准面。 2、选取中心线 图2 选取中心线 3、草图绘制 以对称图形举例&#xff0c;先画出…

市场复盘总结 20240207

仅用于记录当天的市场情况&#xff0c;用于统计交易策略的适用情况&#xff0c;以便程序回测 短线核心&#xff1a;不参与任何级别的调整&#xff0c;采用龙空龙模式 一支股票 10%的时候可以操作&#xff0c; 90%的时间适合空仓等待 二进三&#xff1a; 进级率中 75% 最常用…

优化 IT 支出和消除浪费的 8 种主要方法

不懈追求最佳 IT 支出对于任何组织的长期可持续发展和成功都至关重要。在这个技术快速进步的时代&#xff0c;您必须做出明智的决策&#xff0c;消除浪费&#xff0c;同时最大限度地提高技术投资的价值。 从进行 IT 成本分析到采用敏捷预算和技术标准化&#xff0c;这些策略对…

算法学习——LeetCode力扣链表篇2

算法学习——LeetCode力扣链表篇2 24. 两两交换链表中的节点 24. 两两交换链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 描述 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&…

C语言特殊指针

1 野指针 概念&#xff1a;指向一块未知区域的指针&#xff0c;被称为野指针。野指针是危险的。 危害&#xff1a; 引用野指针&#xff0c;相当于访问了非法的内存&#xff0c;常常会导致段错误&#xff08;segmentation fault&#xff09;引用野指针&#xff0c;可能会破坏系…

CRNN介绍:用于识别图中文本的深度学习模型

CRNN&#xff1a;用于识别图中文本的深度学习模型 CRNN介绍&#xff1a;用于识别图中文本的深度学习模型CRNN的结构组成部分工作原理 CRNN结构分析卷积层&#xff08;Convolutional Layers&#xff09;递归层&#xff08;Recurrent Layers&#xff09;转录层&#xff08;Transc…

day7(2024/2/8)

mainui.h(第二个界面) #ifndef MAINUI_H #define MAINUI_H#include <QWidget>namespace Ui { class MainUi; }class MainUi : public QWidget {Q_OBJECTpublic:explicit MainUi(QWidget *parent nullptr);~MainUi();public slots:void main_ui();private:Ui::MainUi *u…

【Godot4.2】文件系统自定义控件 - FileSystemTree

FileSystemTree B站【Godot4.2】文件系统自定义节点 - FileSystemTree 概述 在Godot设计编辑器插件或应用程序时&#xff0c;可能需要涉及文件系统的显示&#xff0c;比如文件夹或文件的树形列表。 我们可以用Godot的Tree控件快速书写相应的功能&#xff0c;但是为了复用到…

如何内网映射到外网访问?

内网映射到外网访问是一种常见的网络技术&#xff0c;它允许内部网络的资源通过公网进行访问。在某些情况下&#xff0c;我们可能想要访问内部服务器或设备&#xff0c;但由于网络环境的限制&#xff0c;无法直接通过公网访问。此时&#xff0c;内网映射就成为一种解决方案。 天…

Unity BuffSystem buff系统

Unity BuffSystem buff系统 一、介绍二、buff系统架构三、架构讲解四、框架使用buff数据Json数据以及工具ShowTypeBuffTypeMountTypeBuffOverlapBuffShutDownTypeBuffCalculateType时间和层数这里也不过多说明了如何给生物添加buff 五、总结 一、介绍 现在基本做游戏都会需要些…

开源项目的三年,我的项目经历了哪些变化?

0.前言 自己一个项目写了三年&#xff0c;到底写了什么东西了&#xff0c;这个项目经历了哪些变化呢&#xff1f;其中的心路历程如何&#xff1f; 兄弟们&#xff0c;要是感觉我的项目有价值&#xff0c;去b站给俺点点关注呐。我更新的更快。点击下面的了解就可以跳转去b站。…

电路设计(14)——奥运纪念日显示装置的proteus仿真

1.设计要求 北京奥运于2008年8月8日开幕&#xff0c;假设倒计时还剩69天&#xff0c;请你&#xff0c;制作一个电子作品&#xff0c;用以显示上述意思 采用三个数码管&#xff0c;其中一个数码管反复显示2008 8.8&#xff1b;该数码管下方并排放置另两个数码管&#xff0c;这二…

PyTorch 2.2 中文官方教程(十一)

使用 PyTorch C 前端 原文&#xff1a;pytorch.org/tutorials/advanced/cpp_frontend.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 PyTorch C 前端是 PyTorch 机器学习框架的纯 C 接口。虽然 PyTorch 的主要接口自然是 Python&#xff0c;但这个 Python API 坐…