pgsql扩展全在这里
发布日期:2021-06-29 18:40:20 浏览次数:2 分类:技术文章

本文共 6426 字,大约阅读时间需要 21 分钟。

文章目录

  • 我发现:\c test 切换数据库的时候,后端进程也跟着切换了!
    • 而且安装的扩展也只是针对某个数据库才起作用!
    • 比如你在test里面装了扩展,那postgres里面是没有的

我要看看能不能改动sql文件

  • 下面这个是原始的sql文件哦

我突发奇想再里面加一点东西

-- complain if script is sourced in psql, rather than via CREATE EXTENSION\echo Use "CREATE EXTENSION base36" to load this file. \quitCREATE FUNCTION base36_encode(digits int)RETURNS textLANGUAGE plpgsql IMMUTABLE STRICT  AS $$    DECLARE      chars char[];      ret varchar;      val int;    BEGIN      chars := ARRAY[                '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h',                'i','j','k','l','m','n','o','p','q','r','s','t', 'u','v','w','x','y','z'              ];      val := digits;      ret := '';    WHILE val != 0 LOOP      ret := chars[(val % 36)+1] || ret;      val := val / 36;    END LOOP;    RETURN(ret);    END;  $$;create scheme haha;
  • 我现在看看呢
  • drop extension base36;
  • 重新再安装,看有没有那个模式呢??

在这里插入图片描述

  • 他说我语法有错,看来的确要执行的啊!!
  • 也就是每当创建扩展的时候,SQL文件就被执行啊!

  • 应该是schema啊!!
  • 果然有这个模式啊!牛逼!!

  • 而且俺还没办法删掉他

pg的扩展有哪些,在哪里呢?

  • 看看你的电脑上有哪些扩展
    • 这些扩展未必安装了哦

  • 有多少个control文件就有多少个扩展啊!!!

Writing Postgres Extensions - the Basics

  • the code examples here on branch part_i

  • https://github.com/adjust/postgresql_extension_demo/tree/part_i

base36

  • You might already know the trick used by url shorteners.
  • Use some unique random characters such as http://goo.gl/EAZSKW to point to something else.
  • You have to remember what points to where, of course, so you need to store it in a database.
  • But instead of saving 6 characters using varchar(6) (and thus wasting 7 bytes)
  • why not use an integer with 4 bytes and
    • represent it as base36?

The Extension Skeleton

  • To be able to run the CREATE EXTENSION ,
    • your extension needs at least two files
  • control file in the format extension_name.control,
    • tell Pg some basics about your extension
  • a extension’s SQL script in the format extension–version.sql.
  • add them into our project directory.

  • base36.control
# base36 extensioncomment = 'base36 datatype'default_version = '0.0.1'relocatable = true
  • extension no functionality.
  • add some in an SQL script file:
  • base36–0.0.1.sql
-- complain if script is sourced in psql, rather than via CREATE EXTENSION\echo Use "CREATE EXTENSION base36" to load this file. \quitCREATE FUNCTION base36_encode(digits int)RETURNS textLANGUAGE plpgsql IMMUTABLE STRICT  AS $$    DECLARE      chars char[];      ret varchar;      val int;    BEGIN      chars := ARRAY[                '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h',                'i','j','k','l','m','n','o','p','q','r','s','t', 'u','v','w','x','y','z'              ];      val := digits;      ret := '';    WHILE val != 0 LOOP      ret := chars[(val % 36)+1] || ret;      val := val / 36;    END LOOP;    RETURN(ret);    END;  $$;
  • second line ensures the file won’t be loaded into the database directly,only via CREATE EXTENSION.

  • 这个pl/pgsql函数允许将任何整数编码到它的base36
  • 两文件复制到pg的SHAREDIR/extension中(可通过pg_config命令获取),就可通过CREATE EXTENSION使用这个扩展
  • 但我们不会麻烦用户去弄清楚这些文件放在哪里,以及如何手动复制它们,这是makefile该做的。
  • 现在项目中添加一个makefile。

在这里插入图片描述

  • 不过这样是不可以的,因为这里的sql里面是C语言写的
  • 后来我把它换成了用plpsql来写,好了!

在这里插入图片描述

Makefile

  • 9.1开始,每个PostgreSQL安装都为扩展提供了一个名为PGXS的构建基础设施,允许在已经安装的服务器上轻松构建扩展。
  • 构建扩展所需的大多环境变量都在pg_config中设置,可简单重用。
  • 下面这个Makefile就符合需求。
EXTENSION = base36        # 扩展名称DATA = base36--0.0.1.sql  # 要安装的脚本文件# postgres build stuffPG_CONFIG = pg_configPGXS := $(shell $(PG_CONFIG) --pgxs)include $(PGXS)

在这里插入图片描述

在这里插入图片描述

  • 现在可开始用扩展了
  • 在你的工程运行make install
  • 并在数据库中执行如下
test=# CREATE EXTENSION base36;CREATE EXTENSIONTime: 3,329 mstest=# SELECT base36_encode(123456789); base36_encode--------------- 21i3v9(1 row)Time: 0,558 ms

编写测试

  • 向项目中加些回归测试,

    • 测试可在完成make install之后
    • 通过make install check调
  • 可将测试脚本文件放sql/下

  • 对每个测试文件,expected/中也有一个对应包含预期输出的文件,该文件有与测试脚本相同的名称,.out

  • make install check执行每个测试,

    • 并将结果输出与匹配的预期文件比较。
  • 任何差异都将写入文件regression.diffs

  • sql/base36_test.sql

CREATE EXTENSION base36;SELECT base36_encode(0);SELECT base36_encode(1);SELECT base36_encode(10);SELECT base36_encode(35);SELECT base36_encode(36);SELECT base36_encode(123456789);

  • 还需告诉Makefile关于测试的信息(第3行):
EXTENSION = base36     DATA = base36--0.0.1.sql  REGRESS = base36_test     # 我们的测试脚本文件(没有后缀名)# postgres build stuffPG_CONFIG = pg_configPGXS := $(shell $(PG_CONFIG) --pgxs)include $(PGXS)

优化速度,写一些C代码

  • 有趣的是用c实现
  • 让我们获得第一个1M base36数字。
test=# SELECT i, base36_encode(i) FROM generate_series(1,1e6::int) i;Time: 11289,610 ms
  • base36.c
#include "postgres.h"#include "fmgr.h"#include "utils/builtins.h"PG_MODULE_MAGIC;PG_FUNCTION_INFO_V1(base36_encode);Datumbase36_encode(PG_FUNCTION_ARGS){
int32 arg = PG_GETARG_INT32(0); char base36[36] = "0123456789abcdefghijklmnopqrstuvwxyz"; /* max 6 char + '\0' */ char *buffer = palloc(7 * sizeof(char)); unsigned int offset = sizeof(buffer); buffer[--offset] = '\0'; do {
buffer[--offset] = base36[arg % 36]; } while (arg /= 36); PG_RETURN_TEXT_P(cstring_to_text(&buffer[offset]));}
  • #include "postgres.h"包括与Postgres接口所需的大部分基本内容。 须含在声明Postgres函数的每个C文件中。
  • #include "fmgr.h"以使用PG_GETARG_XXX和PG_RETURN_XXX宏。
  • #include "utils/builtins.h"在Postgres的内置数据类型上定义了一些操作(稍后使用cstring_to_text)
  • PG_MODULE_MAGIC 是8.2中包含头文件fmgr.h后,
    • 模块源文件中的一个(且仅一个)中需要的魔法块。
  • PG_FUNCTION_INFO_V1(base36_encode);
    • 将该函数作为版本1调用约定引入Postges,
    • 只有在希望用到函数->Postgres接口时才需要。
  • Dtum是每个Postgres函数的返回类型,可是任何数据类型。
    • 可把它想象成类似于void *
  • base36_encode(PG_FUNCTION_ARGS) 我们的函数名
  • PG_FUNCTION_ARGS可接受任何数字和任何类型的参数。
  • int32 arg = PG_GETARG_INT32(0);
    • 获取第一个参数,编号从0开始。
    • 须用fmgr.h中定义的PG GETARG XXX宏来获取实际的参数值。
  • har *buffer = palloc(7 * sizeof(char));
    • 为了在分配内存时防止内存泄漏,总使用palloc和pfree,而不是C库函数malloc和free。
    • palloc分配的内存将在每个事务结束时自动释放。
    • 你也可以使用palloc0来确保字节清零。
  • PG_RETURN_TEXT_P(cstring_to_text(&buffer[offset]));
    • 要将一个值返回给Postgres,
    • 须使用一个PG_RETURN_XXX宏。
    • cstring_to_text将cstring转换为Postgres文本类型。
    • 完成c语言代码部分之后,需要修改SQL函数。

本大王好奇:为啥malloc之后不free呢!因为他自己查询结束后会自动释放的!

  • 文件名:base36-0.0.1.sql
-- complain if script is sourced in psql, rather than via CREATE EXTENSION\echo Use "CREATE EXTENSION base36" to load this file. \quitCREATE FUNCTION base36_encode(integer) RETURNS textAS '$libdir/base36'LANGUAGE C IMMUTABLE STRICT;

  • 为能够用该函数,还要改Makefile(第4行)
EXTENSION = base36        # 扩展名称DATA = base36--0.0.1.sql  # 要安装的脚本文件REGRESS = base36_test     # 测试脚本文件 (没有后缀名)MODULES = base36          # 要构建的c模块文件# postgres build stuffPG_CONFIG = pg_configPGXS := $(shell $(PG_CONFIG) --pgxs)include $(PGXS)

  • make install && make install check进行测试。
  • 打开数据库控制台证明速度要快(30倍)
test=# SELECT i, base36_encode(i) FROM generate_series(1,1e6::int) i;Time: 361,054 ms

https://www.cnblogs.com/taceywong/p/11269408.html

值得借鉴的链接

转载地址:https://cyj666.blog.csdn.net/article/details/104609177 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:pgstrom如何工作
下一篇:sql创建函数

发表评论

最新留言

很好
[***.229.124.182]2024年04月29日 12时56分54秒