pljs

PL/JS 可信过程程序语言

概览

扩展包名版本分类许可证语言
pljs1.0.5LANGPostgreSQLC
ID扩展名BinLibLoadCreateTrustReloc模式
3011pljspg_catalog
相关扩展plv8 jsquery pllua pg_tle plpgsql pg_jsonschema plperl plpython3u

with submodules, hot fix with CONFIG_VERSION

版本

类型仓库版本PG 大版本包名依赖
EXTMIXED1.0.51817161514pljs-
RPMPIGSTY1.0.51817161514pljs_$v-
DEBPIGSTY1.0.51817161514postgresql-$v-pljs-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64
el8.aarch64
el9.x86_64
el9.aarch64
el10.x86_64
el10.aarch64
d12.x86_64
d12.aarch64
d13.x86_64
d13.aarch64
u22.x86_64
u22.aarch64
u24.x86_64
u24.aarch64

构建

您可以使用 pig build 命令构建 pljs 扩展的 RPM / DEB 包:

pig build pkg pljs         # 构建 RPM / DEB 包

安装

您可以直接安装 pljs 扩展包的预置二进制包,首先确保 PGDGPIGSTY 仓库已经添加并启用:

pig repo add pgsql -u          # 添加仓库并更新缓存

使用 pig 或者是 apt/yum/dnf 安装扩展:

pig install pljs;          # 当前活跃 PG 版本安装
pig ext install -y pljs -v 18  # PG 18
pig ext install -y pljs -v 17  # PG 17
pig ext install -y pljs -v 16  # PG 16
pig ext install -y pljs -v 15  # PG 15
pig ext install -y pljs -v 14  # PG 14
dnf install -y pljs_18       # PG 18
dnf install -y pljs_17       # PG 17
dnf install -y pljs_16       # PG 16
dnf install -y pljs_15       # PG 15
dnf install -y pljs_14       # PG 14
apt install -y postgresql-18-pljs   # PG 18
apt install -y postgresql-17-pljs   # PG 17
apt install -y postgresql-16-pljs   # PG 16
apt install -y postgresql-15-pljs   # PG 15
apt install -y postgresql-14-pljs   # PG 14

创建扩展

CREATE EXTENSION pljs;

用法

pljs: PL/JavaScript 可信过程语言

pljs 允许使用 QuickJS 引擎在 PostgreSQL 中编写 JavaScript 函数。

CREATE EXTENSION pljs;
DO $$ pljs.elog(NOTICE, "Hello, World!") $$ LANGUAGE pljs;

创建函数

CREATE FUNCTION pljs_add(a int, b int) RETURNS int AS $$
  return a + b;
$$ LANGUAGE pljs;

SELECT pljs_add(1, 2);  -- 3

数据库访问

CREATE FUNCTION get_users() RETURNS SETOF json AS $$
  var rows = pljs.execute('SELECT * FROM users');
  for (var i = 0; i < rows.length; i++) {
    pljs.return_next(JSON.stringify(rows[i]));
  }
$$ LANGUAGE pljs;

使用参数执行:

var rows = pljs.execute('SELECT * FROM tbl WHERE id = $1', [42]);
var affected = pljs.execute('DELETE FROM tbl WHERE price > $1', [1000]);

预备语句

var plan = pljs.prepare('SELECT * FROM tbl WHERE col = $1', ['int']);
var rows = plan.execute([1]);
plan.free();

游标

var plan = pljs.prepare('SELECT * FROM tbl WHERE col = $1', ['int']);
var cursor = plan.cursor([1]);
var row;
while (row = cursor.fetch()) {
    // 处理行
}
cursor.close();
plan.free();

子事务

try {
  pljs.subtransaction(function() {
    pljs.execute("INSERT INTO tbl VALUES(1)");
    pljs.execute("INSERT INTO tbl VALUES(1/0)"); // 出错 - 回滚
  });
} catch(e) {
  // 处理错误
}

日志记录

pljs.elog(DEBUG1, 'debug message');
pljs.elog(NOTICE, 'notice message');
pljs.elog(WARNING, 'warning message');
pljs.elog(ERROR, 'error message');

查找其他 PLJS 函数

CREATE FUNCTION callee(a int) RETURNS int AS $$ return a * a $$ LANGUAGE pljs;
CREATE FUNCTION caller(a int, t int) RETURNS int AS $$
  var func = pljs.find_function("callee");
  return func(a);
$$ LANGUAGE pljs;

窗口函数

CREATE FUNCTION my_window_func(val int) RETURNS int AS $$
  var winobj = pljs.get_window_object();
  var pos = winobj.get_current_position();
  var total = winobj.get_partition_row_count();
  return winobj.get_func_arg_in_current(0);
$$ LANGUAGE pljs WINDOW;

窗口对象方法:get_current_position()get_partition_row_count()set_mark_position(pos)rows_are_peers(pos1, pos2)get_func_arg_in_partition(argno, relpos, seektype, mark_pos)get_func_arg_in_frame(argno, relpos, seektype, mark_pos)get_func_arg_in_current(argno)get_partition_local()set_partition_local(obj)

实用函数

SELECT pljs_info();     -- 以 JSON 格式返回内存和栈使用情况
SELECT pljs_version();  -- 扩展版本

最后修改 2026-03-14: update extension metadata (953cbd0)