pllua

Lua as a procedural language

Overview

PackageVersionCategoryLicenseLanguage
pllua2.0.12LANGMITC
IDExtensionBinLibLoadCreateTrustRelocSchema
3020plluaNoYesNoYesNoNopg_catalog
3021hstore_plluaNoYesNoYesNoYes-
3030plluauNoYesNoYesNoNopg_catalog
3031hstore_plluauNoYesNoYesNoYespg_catalog
Relatedplperl plpgsql plpython3u pg_tle plv8 pljava plperlu
Depended Byhstore_pllua

missing pg12-15 on el.aarch64

Version

TypeRepoVersionPG VerPackageDeps
EXTPGDG2.0.121817161514pllua-
RPMPGDG2.0.121817161514pllua_$v-
DEBPGDG2.0.121817161514postgresql-$v-pllua-
OS / PGPG18PG17PG16PG15PG14
el8.x86_64PGDG MISS
el8.aarch64PGDG MISSPGDG MISSPGDG MISS
el9.x86_64PGDG MISS
el9.aarch64PGDG MISSPGDG MISSPGDG MISS
el10.x86_64PGDG MISS
el10.aarch64PGDG MISS
d12.x86_64
d12.aarch64
PGDG 2.0.12
PGDG 2.0.12
PGDG 2.0.12
PGDG 2.0.12
PGDG 2.0.12
d13.x86_64
d13.aarch64
PGDG 2.0.12
PGDG 2.0.12
PGDG 2.0.12
PGDG 2.0.12
PGDG 2.0.12
u22.x86_64
u22.aarch64
u24.x86_64
u24.aarch64

Install

You can install pllua directly. First, make sure the PGDG repository is added and enabled:

pig repo add pgdg -u          # Add PGDG repo and update cache

Install the extension using pig or apt/yum/dnf:

pig install pllua;          # Install for current active PG version
pig ext install -y pllua -v 18  # PG 18
pig ext install -y pllua -v 17  # PG 17
pig ext install -y pllua -v 16  # PG 16
pig ext install -y pllua -v 15  # PG 15
pig ext install -y pllua -v 14  # PG 14
dnf install -y pllua_18       # PG 18
dnf install -y pllua_17       # PG 17
dnf install -y pllua_16       # PG 16
dnf install -y pllua_15       # PG 15
dnf install -y pllua_14       # PG 14
apt install -y postgresql-18-pllua   # PG 18
apt install -y postgresql-17-pllua   # PG 17
apt install -y postgresql-16-pllua   # PG 16
apt install -y postgresql-15-pllua   # PG 15
apt install -y postgresql-14-pllua   # PG 14

Create Extension:

CREATE EXTENSION pllua;

Usage

pllua: Lua as a procedural language

pllua enables writing PostgreSQL functions in Lua (5.3, 5.4, or LuaJIT 2.1).

CREATE EXTENSION pllua;

Create Functions

CREATE FUNCTION lua_max(a integer, b integer) RETURNS integer LANGUAGE pllua AS $$
  if a > b then return a else return b end
$$;

CREATE FUNCTION hello(name text) RETURNS text LANGUAGE pllua AS $$
  return "Hello, " .. name .. "!"
$$;

Data Type Handling

Arguments are automatically converted: integers/floats to Lua numbers, text/varchar to strings, booleans to Lua booleans, NULL to nil. Other types remain as datum objects.

Construct typed values with pgtype:

pgtype.numeric(1234)
pgtype.date('2017-12-01')
pgtype.array.integer(1, 2, 3, 4)
pgtype.numrange(1, 2)

Composite Types (Rows)

row.columnname     -- access by name
row[3]             -- access by attribute number
for colname, value, attnum in pairs(row) do ... end

Set-Returning Functions

CREATE FUNCTION generate_n(n integer) RETURNS SETOF integer LANGUAGE pllua AS $$
  for i = 1, n do
    coroutine.yield(i)
  end
$$;

SPI Database Access

-- Simple query
local rows = spi.execute("SELECT * FROM mytable WHERE id = $1", 42)

-- Row iterator
for row in spi.rows("SELECT * FROM mytable") do
  print(row.name)
end

-- Prepared statements
local stmt = spi.prepare("SELECT * FROM users WHERE id = $1", {'integer'})
local result = stmt:execute(42)
for row in stmt:rows(42) do ... end

Cursors

local cursor = spi.newcursor()
cursor:open("SELECT * FROM items")
local rows = cursor:fetch(10)
cursor:move(5)
cursor:close()

Trigger Functions

CREATE FUNCTION my_trigger() RETURNS trigger LANGUAGE pllua AS $$
  function(trigger, old, new)
    trigger.row = new
    return trigger.row
  end
$$;

Trigger fields: trigger.event (INSERT/UPDATE/DELETE), trigger.when (BEFORE/AFTER), trigger.level (ROW/STATEMENT), trigger.new, trigger.old, trigger.row.

Error Handling

spi.error('division_by_zero', 'Cannot divide by zero')
spi.notice('informational message')
spi.warning('warning message')

-- Subtransactions with pcall
local ok, err = pcall(function()
  spi.execute("INSERT INTO mytable VALUES ($1)", val)
end)

Logging

print("info message")
spi.debug("debug")
spi.notice("notice")
spi.warning("warning")
spi.error("error")

Last Modified 2026-03-12: add pg extension catalog (95749bf)