Decarbonising Buildings: Making a net-zero built environment a reality
PostgreSQL and PL/Java
1. PostgreSQL and PL/Java
Server-Side Functions in Java
Peter Eisentraut
petere@postgresql.org
2. Agenda
• Functions in PostgreSQL
• Enter PL/Java
• Features of PL/Java
• Support and Compatibility
• Outlook and Wrap-Up
2
3. Defining a Function
Example of an SQL function:
CREATE FUNCTION add(int, int) RETURNS int
LANGUAGE SQL
AS 'SELECT $1 + $2;';
SELECT add(4, 5);
add
-----
9
3
4. Defining a Function
Example of a C function:
PG_FUNCTION_INFO_V1(funcname);
Datum add(PG_FUNCTION_ARGS)
{
int32 a = PG_GETARG_INT32(0);
int32 b = PG_GETARG_INT32(1);
PG_RETURN_INT32(a + b);
}
4
5. Defining a Function
Example of a C function, continued:
gcc -fPIC -c file.c
gcc -shared -o file.so file.o
CREATE FUNCTION add(int, int) RETURNS int
LANGUAGE C
AS 'file.so', 'add';
5
6. Features of Functions
• Overloading
• Processing sets/tables
• Caching options
(deterministic/nondeterministic)
• Execution privileges
6
7. Advantages of Server-Side
Functions
• Encapsulation
• Faster database access
• Plan caching, inlining
• Data validation through triggers
• Side effects through triggers
7
8. Functions as Building Blocks
• Operators
• Data types
• Aggregate functions
• Index access methods
• Type casts
• Character set conversions
8
9. Procedural Languages
• Choice of SQL vs. C quite limited
• Solution: pluggable language handlers
• Available languages:
Tcl, PL/pgSQL, Perl, Ruby, Python, Shell,
R, Java, PHP
9
10. Procedural Language Example:
PL/pgSQL
CREATE FUNCTION logfunc(logtxt text)
RETURNS timestamp
AS '
DECLARE
curtime timestamp;
BEGIN
curtime := ''now'';
INSERT INTO logtable VALUES (logtxt, curtime);
RETURN curtime;
END;
' LANGUAGE plpgsql;
10
11. Procedural Language Example:
PL/Perl
CREATE OR REPLACE FUNCTION valid_id()
RETURNS trigger
AS '
if (($_TD->{new}{i} >= 100) || ($_TD->{new}{i} <= 0)) {
return "SKIP"; # skip INSERT/UPDATE command
} elsif ($_TD->{new}{v} ne "immortal") {
$_TD->{new}{v} .= "(modified by trigger)";
return "MODIFY"; # modify row and run INSERT/UPDATE
} else {
return; # execute INSERT/UPDATE command
}
' LANGUAGE plperl;
11
12. Enter PL/Java
• Developed by Thomas Hallgren
• Stored procedures written in the Java
language
• Java the most popular (client) language for
PostgreSQL
12
13. Standardization
SQL standard: ISO/IEC 9075-13:2003
SQL Routines and Types for the Java
Programming Language ("SQL/JRT")
(210 pages)
driven by Oracle and IBM
13
14. Timeline of PL/Java
• Nov. 2000: first attempt with Kaffe 1.0.6
• Dec. 2003: PL/Java project launched
• Jan. 2004: first alpha release
• Jan. 2005: release 1.0.0 (for PG 7.4)
• Apr. 2005: release 1.1.0 (for PG 8.0)
• currently “stable”
14
15. Concept
• Write a Java class
• Designate static method as entry point
• Pack into JAR
• Load JAR into database
• Adjust classpath
• Create function in PostgreSQL
15
16. Simple Example: Code
package com.example;
public class Foo
{
static int add(int a, int b)
{
return a + b;
}
}
16
17. Simple Example: Deployment
javac com/example/Foo.java
jar cf foo.jar com/example/Foo.class
SELECT
sqlj.install_jar('file:/home/peter/tmp/foo.jar',
'foo', false);
SELECT sqlj.set_classpath('public', 'foo:bar:etc');
CREATE FUNCTION add(int, int) RETURNS int
LANGUAGE java
AS 'com.example.Foo.add';
17
18. Deployment Descriptor
Optional way to integrate install/uninstall SQL
statements into the JAR file:
SQLActions[] = {
"BEGIN INSTALL
CREATE FUNCTION add(int, int) RETURNS int
LANGUAGE java
AS 'com.example.Foo.add';
END INSTALL",
"BEGIN REMOVE
DROP FUNCTION add(int, int);
END REMOVE"
}
18
20. Parameter Type Mapping
Parameter types are mapped automatically:
PostgreSQL Java
boolean boolean
shortint short
int int
bigint long
real float
double precision double
varchar, text java.lang.String
bytea byte[]
date java.sql.Date
time java.sql.Time
timestamp java.sql.Timestamp
other java.lang.String
20
21. Composite Types
CREATE TYPE compositeTest AS (
base integer,
incbase integer,
ctime timestamp
);
CREATE FUNCTION useCompositeTest (compositeTest)
RETURNS varchar
AS 'foo.fee.Fum.useCompositeTest'
LANGUAGE java;
21
22. Composite Types
Represented as java.sql.ResultSet with one
row.
public static String useCompositeTest(ResultSet
compositeTest) throws SQLException
{
int base = compositeTest.getInt(1);
int incbase = compositeTest.getInt(2);
Timestamp ctime = compositeTest.getTimestamp(3);
return "Base = "" + base +
"", incbase = "" + incbase +
"", ctime = "" + ctime + """;
}
22
23. Returning Sets
CREATE FUNCTION getNames() RETURNS SETOF varchar
AS 'Bar.getNames'
LANGUAGE java;
import java.util.Iterator;
public class Bar {
public static Iterator getNames() {
ArrayList names = new ArrayList();
names.add("Lisa");
names.add("Bob");
names.add("Bill");
return names.iterator();
}
}
23
25. Triggers
static void moddatetime(TriggerData td) throws SQLException
{
if(td.isFiredForStatement())
throw new TriggerException(td, "can't process STATEMENT events");
if(td.isFiredAfter())
throw new TriggerException(td, "must be fired before event");
if(!td.isFiredByUpdate())
throw new TriggerException(td, "can only process UPDATE events");
ResultSet _new = td.getNew();
String[] args = td.getArguments();
if (args.length != 1)
throw new TriggerException(td, "one argument was expected");
_new.updateTimestamp(args[0], new Timestamp(System.currentTimeMillis()));
}
25
26. Other Features
• Exception handling
• Logging
• DatabaseMetaData
• Multithreading
• IN/OUT parameters (PostgreSQL 8.1)
• Security
26
30. Supported Platforms
• Linux (most architectures)
• Cygwin
• Windows (PostgreSQL 8.1/recent)
• More reports welcome!
30
31. Compatibility
• vs. Oracle:
• data type system not as good
• trigger procedures not compatible (wrappers
possible)
• vs. DB/2, Firebird, ...:
• unknown
31
32. The Future
• Dynamic type system (SQL:2003)
• Work on SQL conformance and
compatibility
• More work on J4SQL
• Cooperation with PL/J project
32
33. Conclusion
• PL/Java is stable today.
• It is being used.
• It is almost feature complete.
• Get it now!
http://gborg.postgresql.org/project/pljava/projdisplay.php
33