Chapter 38. The Rule System
Now you can fill the table
shoelace_arrive
with the data from the parts list:
SELECT
*
FROM shoelace_arrive;
arr_name | arr_quant
----------+-----------
sl3
|
10
sl6
|
20
sl8
|
20
(3 rows)
Take a quick look at the current data:
SELECT
*
FROM shoelace;
sl_name
| sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
----------+----------+----------+--------+---------+-----------
sl1
|
5 | black
|
80 | cm
|
80
sl2
|
6 | black
|
100 | cm
|
100
sl7
|
6 | brown
|
60 | cm
|
60
sl3
|
0 | black
|
35 | inch
|
88.9
sl4
|
8 | black
|
40 | inch
|
101.6
sl8
|
1 | brown
|
40 | inch
|
101.6
sl5
|
4 | brown
|
1 | m
|
100
sl6
|
0 | brown
|
0.9 | m
|
90
(8 rows)
Now move the arrived shoelaces in:
INSERT INTO shoelace_ok SELECT
*
FROM shoelace_arrive;
and check the results:
SELECT
*
FROM shoelace ORDER BY sl_name;
sl_name
| sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
----------+----------+----------+--------+---------+-----------
sl1
|
5 | black
|
80 | cm
|
80
sl2
|
6 | black
|
100 | cm
|
100
sl7
|
6 | brown
|
60 | cm
|
60
sl4
|
8 | black
|
40 | inch
|
101.6
sl3
|
10 | black
|
35 | inch
|
88.9
sl8
|
21 | brown
|
40 | inch
|
101.6
sl5
|
4 | brown
|
1 | m
|
100
sl6
|
20 | brown
|
0.9 | m
|
90
(8 rows)
SELECT
*
FROM shoelace_log;
sl_name | sl_avail | log_who| log_when
---------+----------+--------+----------------------------------
sl7
|
6 | Al
| Tue Oct 20 19:14:45 1998 MET DST
sl3
|
10 | Al
| Tue Oct 20 19:25:16 1998 MET DST
sl6
|
20 | Al
| Tue Oct 20 19:25:16 1998 MET DST
sl8
|
21 | Al
| Tue Oct 20 19:25:16 1998 MET DST
(4 rows)
1018
Adding an image to a pdf form - insert images into PDF in C#.net, ASP.NET, MVC, Ajax, WinForms, WPF
Sample C# code to add image, picture, logo or digital photo into PDF document page using PDF page editor control
pdf insert image; add image to pdf form
Adding an image to a pdf form - VB.NET PDF insert image library: insert images into PDF in vb.net, ASP.NET, MVC, Ajax, WinForms, WPF
Guide VB.NET Programmers How to Add Images in PDF Document
add photo to pdf in preview; adding a jpeg to a pdf
Chapter 38. The Rule System
It’s a long way from the one
INSERT ... SELECT
to these results. And the description of thequery-
tree transformation will be the last in this chapter. First, there is the parser’s output:
INSERT INTO shoelace_ok
SELECT shoelace_arrive.arr_name, shoelace_arrive.arr_quant
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok;
Now the first rule
shoelace_ok_ins
is applied and turns this into:
UPDATE shoelace
SET sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace
WHERE shoelace.sl_name = shoelace_arrive.arr_name;
and throws away the original
INSERT
on
shoelace_ok
.This rewritten query is passed to the rule
system again, andthe second applied rule
shoelace_upd
produces:
UPDATE shoelace_data
SET sl_name = shoelace.sl_name,
sl_avail = shoelace.sl_avail + shoelace_arrive.arr_quant,
sl_color = shoelace.sl_color,
sl_len = shoelace.sl_len,
sl_unit = shoelace.sl_unit
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace, shoelace old,
shoelace new, shoelace_data shoelace_data
WHERE shoelace.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = shoelace.sl_name;
Again it’s an
INSTEAD
rule and the previous query tree is trashed. Note that this query still uses
the view
shoelace
.But the rule system isn’t finished with this step, so it continues and applies the
_RETURN
rule on it, and we get:
UPDATE shoelace_data
SET sl_name = s.sl_name,
sl_avail = s.sl_avail + shoelace_arrive.arr_quant,
sl_color = s.sl_color,
sl_len = s.sl_len,
sl_unit = s.sl_unit
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace, shoelace old,
shoelace new, shoelace_data shoelace_data,
shoelace old, shoelace new,
shoelace_data s, unit u
WHERE s.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = s.sl_name;
Finally, the rule
log_shoelace
gets applied, producing the extra query tree:
INSERT INTO shoelace_log
SELECT s.sl_name,
s.sl_avail + shoelace_arrive.arr_quant,
current_user,
current_timestamp
1019
VB.NET PDF Page Insert Library: insert pages into PDF file in vb.
Support adding PDF page number. Offer PDF page break inserting function. DLLs for Adding Page into PDF Document in VB.NET Class. Add necessary references:
adding image to pdf file; how to add an image to a pdf in acrobat
VB.NET PDF Library SDK to view, edit, convert, process PDF file
PDF document to/from supported document and image forms. to define text or images on PDF document and Capable of adding PDF file navigation features to your VB
add photo to pdf; add image field to pdf form
Chapter 38. The Rule System
FROM shoelace_arrive shoelace_arrive, shoelace_ok shoelace_ok,
shoelace_ok old, shoelace_ok new,
shoelace shoelace, shoelace old,
shoelace new, shoelace_data shoelace_data,
shoelace old, shoelace new,
shoelace_data s, unit u,
shoelace_data old, shoelace_data new
shoelace_log shoelace_log
WHERE s.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = s.sl_name
AND (s.sl_avail + shoelace_arrive.arr_quant) <> s.sl_avail;
After that the rule system runs out of rules and returns the generated query trees.
So we end up with two final query trees that are equivalent to the SQL statements:
INSERT INTO shoelace_log
SELECT s.sl_name,
s.sl_avail + shoelace_arrive.arr_quant,
current_user,
current_timestamp
FROM shoelace_arrive shoelace_arrive, shoelace_data shoelace_data,
shoelace_data s
WHERE s.sl_name = shoelace_arrive.arr_name
AND shoelace_data.sl_name = s.sl_name
AND s.sl_avail + shoelace_arrive.arr_quant <> s.sl_avail;
UPDATE shoelace_data
SET sl_avail = shoelace_data.sl_avail + shoelace_arrive.arr_quant
FROM shoelace_arrive shoelace_arrive,
shoelace_data shoelace_data,
shoelace_data s
WHERE s.sl_name = shoelace_arrive.sl_name
AND shoelace_data.sl_name = s.sl_name;
The result is thatdatacomingfrom one relation inserted intoanother, changedinto updates on a third,
changed into updating a fourth plus logging that final update in a fifth gets reduced into two queries.
There isa little detailthat’s a bitugly. Lookingat thetwoqueries, itturns out thatthe
shoelace_data
relation appears twice in the range table where it coulddefinitelybe reduced to one. The planner does
not handle it and so the execution plan for the rule systems output of the
INSERT
will be
Nested Loop
->
Merge Join
->
Seq Scan
->
Sort
->
Seq Scan on s
->
Seq Scan
->
Sort
->
Seq Scan on shoelace_arrive
->
Seq Scan on shoelace_data
while omitting the extra range table entry would result in a
Merge Join
->
Seq Scan
->
Sort
->
Seq Scan on s
1020
C# PDF Page Insert Library: insert pages into PDF file in C#.net
By using reliable APIs, C# programmers are capable of adding and inserting (empty) PDF page or pages from various file formats, such as PDF, Tiff, Word, Excel
add an image to a pdf acrobat; add picture to pdf document
C# PDF insert text Library: insert text into PDF content in C#.net
Supports adding text to PDF in preview without adobe reader installed in ASP.NET. Powerful .NET PDF edit control allows modify existing scanned PDF text.
adding an image to a pdf file; add png to pdf preview
Chapter 38. The Rule System
->
Seq Scan
->
Sort
->
Seq Scan on shoelace_arrive
which produces exactly the same entries in the log table. Thus, the rule system caused one extra scan
on the table
shoelace_data
that is absolutely not necessary. And the same redundant scan is done
once more in the
UPDATE
.But it was a really hard job to make that all possible at all.
Now we make a final demonstrationof the PostgreSQL rule system and its power. Say you add some
shoelaces with extraordinary colors to your database:
INSERT INTO shoelace VALUES (’sl9’, 0, ’pink’, 35.0, ’inch’, 0.0);
INSERT INTO shoelace VALUES (’sl10’, 1000, ’magenta’, 40.0, ’inch’, 0.0);
We would like to make a view to check which
shoelace
entries do not fit any shoe in color. The
view for this is:
CREATE VIEW shoelace_mismatch AS
SELECT
*
FROM shoelace WHERE NOT EXISTS
(SELECT shoename FROM shoe WHERE slcolor = sl_color);
Its output is:
SELECT
*
FROM shoelace_mismatch;
sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
---------+----------+----------+--------+---------+-----------
sl9
|
0 | pink
|
35 | inch
|
88.9
sl10
|
1000 | magenta
|
40 | inch
|
101.6
Now we want to set it up so that mismatching shoelaces that are not in stock are deleted from the
database. To make it a little harder for PostgreSQL, we don’t delete it directly. Instead we create one
more view:
CREATE VIEW shoelace_can_delete AS
SELECT
*
FROM shoelace_mismatch WHERE sl_avail = 0;
and do it this way:
DELETE FROM shoelace WHERE EXISTS
(SELECT
*
FROM shoelace_can_delete
WHERE sl_name = shoelace.sl_name);
Voilà:
SELECT
*
FROM shoelace;
sl_name | sl_avail | sl_color | sl_len | sl_unit | sl_len_cm
---------+----------+----------+--------+---------+-----------
sl1
|
5 | black
|
80 | cm
|
80
sl2
|
6 | black
|
100 | cm
|
100
sl7
|
6 | brown
|
60 | cm
|
60
sl4
|
8 | black
|
40 | inch
|
101.6
sl3
|
10 | black
|
35 | inch
|
88.9
sl8
|
21 | brown
|
40 | inch
|
101.6
sl10
|
1000 | magenta
|
40 | inch
|
101.6
sl5
|
4 | brown
|
1 | m
|
100
1021
C# PDF Library SDK to view, edit, convert, process PDF file for C#
Capable of adding PDF file navigation features to your C# program. You may easily generate thumbnail image from PDF. C#.NET: PDF Form Field Edit.
adding an image to a pdf; acrobat add image to pdf
VB.NET Image: How to Draw Annotation on Doc Images with Image SDK
multi-page TIFF, Microsoft Office Word and PDF file programmer, you might need some other image annotating tutorials besides adding annotation using VB
add image to pdf; add jpg to pdf document
Chapter 38. The Rule System
sl6
|
20 | brown
|
0.9 | m
|
90
(9 rows)
A
DELETE
on a view, with a subquery qualification that in total uses 4 nesting/joined views, where
one of them itself has a subquery qualification containing a view and where calculated view columns
are used, gets rewritten into one single query tree that deletes the requested data from a real table.
There are probably onlya few situations out in the real world where sucha construct is necessary. But
it makes youfeel comfortable that it works.
38.5. Rules and Privileges
Due to rewriting of queries by the PostgreSQL rule system, other tables/views than those used in the
original query get accessed. When update rules are used, this can include write access to tables.
Rewrite rules don’t havea separate owner. The owner of a relation(table or view) is automatically the
owner of the rewrite rules that are defined for it. The PostgreSQL rule system changes the behavior
of the default access control system. Relations that are used due to rules get checked against the
privileges of the rule owner, not the user invoking the rule. This means that a user only needs the
required privileges for the tables/views that he names explicitly in his queries.
For example: A user has a list of phone numbers where some of them are private, the others are of
interest for the secretary of the office. He can construct the following:
CREATE TABLE phone_data (person text, phone text, private boolean);
CREATE VIEW phone_number AS
SELECT person, CASE WHEN NOT private THEN phone END AS phone
FROM phone_data;
GRANT SELECT ON phone_number TO secretary;
Nobody except him (and the database superusers) can access the
phone_data
table. But because of
the
GRANT
,the secretary canruna
SELECT
on the
phone_number
view. The rule system will rewrite
the
SELECT
from
phone_number
into a
SELECT
from
phone_data
.Since the user is the owner of
phone_number
and therefore the owner of the rule, the read access to
phone_data
is now checked
against his privileges and the query is permitted. The check for accessing
phone_number
is also
performed, but this is done against the invokinguser, so nobody but the user and the secretary canuse
it.
The privileges arecheckedrule by rule. Sothe secretary is for now theonly one whocansee the public
phone numbers. But the secretarycan setup another view andgrant access to that to the public. Then,
anyone can see the
phone_number
data through the secretary’s view. What the secretary cannot do
is to create a view that directly accesses
phone_data
.(Actually he can, but it will not work since
every access will be denied during the permission checks.) And as soon as the user will notice, that
the secretary opened his
phone_number
view, he can revoke his access. Immediately, any access to
the secretary’s view would fail.
One might think that this rule-by-rule checking is a security hole, but in fact it isn’t. But if it did not
work this way, the secretary could set up a table with the same columns as
phone_number
and copy
the data to there once per day. Then it’s his own data and he can grantaccess to everyone he wants. A
GRANT
command means, “I trust you”. If someone you trust does the thing above, it’s time to think it
over and then use
REVOKE
.
1022
C# PDF Password Library: add, remove, edit PDF file password in C#
Following are examples for adding password to a plain PDF passwordSetting.IsAnnot = true; // Allow to fill form. IsAssemble = true; // Add password to PDF file
how to add image to pdf in preview; how to add image to pdf
VB.NET PDF File & Page Process Library SDK for vb.net, ASP.NET
merge and splitting PDF pages and Files, adding a page is the programmatic representation of a PDF document. of newly created blank pages or image-only pages
add photo to pdf for; how to add a picture to a pdf document
Chapter 38. The Rule System
Note that while views can be used to hide the contents of certain columns using the technique shown
above, theycannotbeusedtoreliablyconcealthedatainunseen rows unlessthe
security_barrier
flag has been set. For example, the following view is insecure:
CREATE VIEW phone_number AS
SELECT person, phone FROM phone_data WHERE phone NOT LIKE ’412%’;
This view might seem secure, since the rule system will rewrite any
SELECT
from
phone_number
into a
SELECT
from
phone_data
and add the qualification that only entries where
phone
does not
begin with 412 are wanted. But if the user can create his or her own functions, it is not difficult
to convince the planner to execute the user-defined function prior to the
NOT LIKE
expression. For
example:
CREATE FUNCTION tricky(text, text) RETURNS bool AS $$
BEGIN
RAISE NOTICE ’% => %’, $1, $2;
RETURN true;
END
$$ LANGUAGE plpgsql COST 0.0000000000000000000001;
SELECT
*
FROM phone_number WHERE tricky(person, phone);
Every person and phone number in the
phone_data
table will be printed as a
NOTICE
,because
the planner will choose to execute the inexpensive
tricky
function before the more expensive
NOT
LIKE
.Even if the user is prevented from defining new functions, built-in functions can be used in
similar attacks. (For example, most casting functions include their input values in the error messages
they produce.)
Similar considerations apply to update rules. In the examples of the previous section, the owner of the
tables in the example database could grant the privileges
SELECT
,
INSERT
,
UPDATE
,and
DELETE
on
the
shoelace
view to someone else, but only
SELECT
on
shoelace_log
.The rule action to write
log entries will still be executed successfully, and that other user could see the log entries. But he
cannot create fake entries, nor could he manipulate or remove existing ones. In this case, there is no
possibility of subverting the rules by convincing the planner to alter the order of operations, because
the only rule which references
shoelace_log
is an unqualified
INSERT
.This might not be true in
more complex scenarios.
When it is necessary for a view to provide row-level security, the
security_barrier
attribute
should be applied to the view. This prevents maliciously-chosen functions and operators from being
invoked on rows until after the view has done its work. For example, if the view shown above had
been createdlike this, it would be secure:
CREATE VIEW phone_number WITH (security_barrier) AS
SELECT person, phone FROM phone_data WHERE phone NOT LIKE ’412%’;
Views created with the
security_barrier
may perform far worse than views created without this
option. In general, there is no way to avoid this: the fastest possible plan must be rejected if it may
compromise security. For this reason, this option is not enabled by default.
The query planner has more flexibility when dealing with functions that have no side effects. Such
functions are referred to as
LEAKPROOF
,and include many simple, commonly used operators, such
as many equality operators. The query planner can safely allow such functions to be evaluated at any
point in the query execution process, since invoking them on rows invisible to the user will not leak
any information about the unseen rows. In contrast, a function that might throw an error depending
on the values received as arguments (such as one that throws an error in the event of overflow or
1023
Chapter 38. The Rule System
division by zero) are not leak-proof, and could provide significant information about the unseen rows
if applied before the security view’s row filters.
Itis importanttounderstandthatevena viewcreatedwith the
security_barrier
option is intended
to be secure only in the limited sense that the contents of the invisible tuples will not be passed to
possibly-insecure functions. The user may well have other means of making inferences about the
unseen data; for example, they can see the query plan using
EXPLAIN
,or measure the run time of
queries against the view. A malicious attacker might be able to infer something about the amount of
unseendata, or even gain some information about the data distribution or most common values (since
these things may affect the runtime of the plan; or even, since they are also reflected in the optimizer
statistics, the choice of plan). If these types of "covert channel" attacks are of concern, it is probably
unwise to grant any access to the data at all.
38.6. Rules and Command Status
The PostgreSQL server returns a command status string, such as
INSERT 149592 1
,for each com-
mand it receives. This is simple enough when there are no rules involved, but what happens when the
query is rewritten by rules?
Rules affect the commandstatus as follows:
If there is nounconditional
INSTEAD
rule for the query, thenthe originallygivenquerywill be exe-
cuted, and its command status will be returnedas usual. (Butnote that if there wereanyconditional
INSTEAD
rules, the negation of their qualifications will have been added to the original query. This
might reduce the number of rows it processes, and if so the reported status will be affected.)
If thereis anyunconditional
INSTEAD
rule for thequery, thenthe original querywill notbeexecuted
at all. In this case, the server will return the command status for the last query that was inserted
by an
INSTEAD
rule (conditional or unconditional) and is of the same command type (
INSERT
,
UPDATE
,or
DELETE
)as the original query. If no query meeting those requirements is added by any
rule, then the returned command status shows the original query type and zeroes for the row-count
and OID fields.
The programmer can ensure that any desired
INSTEAD
rule is the one that sets the command status in
the second case, by giving it the alphabetically last rule name among the active rules, so that it gets
applied last.
38.7. Rules Versus Triggers
Manythings that can be done using triggers can alsobe implemented using the PostgreSQL rule sys-
tem. One of the things that cannot be implemented by rules are some kinds of constraints, especially
foreign keys. It is possible to place a qualified rule that rewrites a command to
NOTHING
if the value
of a column does notappear in another table. But then the data is silently thrown awayand that’s nota
good idea. If checks for valid values are required, and in the case of an invalid value an error message
should be generated, it must be done by a trigger.
In this chapter, we focused on using rules to update views. All of the update rule examples in this
chapter can also be implemented using
INSTEAD OF
triggers on the views. Writing such triggers is
often easier than writing rules, particularly if complex logic is required to perform the update.
1024
Chapter 38. The Rule System
For the things that can be implemented by both, which is best depends on the usage of the database.
Atrigger is fired once for each affected row. A rule modifies the query or generates an additional
query. Soif many rows are affected in one statement, a rule issuingone extra command is likely to be
faster than a trigger that is called for every single row and must re-determine what to do many times.
However, the trigger approach is conceptually far simpler than the rule approach, and is easier for
novices to get right.
Here we show an example of how the choice of rules versus triggers plays out in one situation. There
are two tables:
CREATE TABLE computer (
hostname
text,
-- indexed
manufacturer
text
-- indexed
);
CREATE TABLE software (
software
text,
-- indexed
hostname
text
-- indexed
);
Bothtables have manythousands of rows andtheindexes on
hostname
areunique. The rule or trigger
should implement a constraint that deletes rows from
software
that reference a deleted computer.
The trigger would use this command:
DELETE FROM software WHERE hostname = $1;
Since the trigger is calledfor each individual row deletedfrom
computer
,itcan prepare and save the
plan for this command and pass the
hostname
value in the parameter. The rule would be written as:
CREATE RULE computer_del AS ON DELETE TO computer
DO DELETE FROM software WHERE hostname = OLD.hostname;
Now we look at different types of deletes. In the case of a:
DELETE FROM computer WHERE hostname = ’mypc.local.net’;
the table
computer
is scanned byindex (fast), andthe command issuedby the trigger would alsouse
an index scan (also fast). The extra command from the rule would be:
DELETE FROM software WHERE computer.hostname = ’mypc.local.net’
AND software.hostname = computer.hostname;
Since there are appropriate indexes setup, the planner will create a plan of
Nestloop
->
Index Scan using comp_hostidx on computer
->
Index Scan using soft_hostidx on software
So there wouldbe not thatmuch difference in speed between the trigger and the rule implementation.
With the next delete we want to get rid of all the 2000 computers where the
hostname
starts with
old
.There are two possible commands to do that. One is:
DELETE FROM computer WHERE hostname >= ’old’
AND hostname <
’ole’
The command added by the rule will be:
1025
Chapter 38. The Rule System
DELETE FROM software WHERE computer.hostname >= ’old’ AND computer.hostname < ’ole’
AND software.hostname = computer.hostname;
with the plan
Hash Join
->
Seq Scan on software
->
Hash
->
Index Scan using comp_hostidx on computer
The other possible command is:
DELETE FROM computer WHERE hostname ~ ’^old’;
which results in the following executing plan for the command added by the rule:
Nestloop
->
Index Scan using comp_hostidx on computer
->
Index Scan using soft_hostidx on software
This shows, that the planner does not realize that the qualification for
hostname
in
computer
could
also be used for an index scan on
software
when there are multiple qualification expressions com-
bined with
AND
,which is what it does in the regular-expression version of the command. The trigger
will get invoked once for eachof the 2000 oldcomputers thathave tobe deleted, andthat willresult in
one index scan over
computer
and 2000 index scans over
software
.The rule implementation will
do it with two commands that use indexes. And it depends on the overall size of the table
software
whether the rule will still be faster in the sequential scan situation. 2000 command executions from
the trigger over the SPI manager take some time, even if alltheindex blocks will soon be inthe cache.
The last command we look at is:
DELETE FROM computer WHERE manufacturer = ’bim’;
Again this could resultinmanyrows to be deletedfrom
computer
.Sothe trigger will againrun many
commands through the executor. The command generated by the rule will be:
DELETE FROM software WHERE computer.manufacturer = ’bim’
AND software.hostname = computer.hostname;
The plan for that command will again be the nested loop over two index scans, only using a different
index on
computer
:
Nestloop
->
Index Scan using comp_manufidx on computer
->
Index Scan using soft_hostidx on software
Inanyof these cases, the extra commands from the rule system will be more or less independentfrom
the number of affected rows ina command.
The summary is, rules willonly be significantly slower than triggers if their actions resultin large and
badly qualified joins, a situation where the planner fails.
1026
Chapter 39. Procedural Languages
PostgreSQL allows user-definedfunctions tobe written in other languages besides SQL and C. These
other languages are generically called procedural languages (PLs). For a function written in a proce-
dural language, the database server has no built-in knowledge about how to interpret the function’s
source text. Instead, the task is passed to a special handler that knows the details of the language.
The handler could either do all the work of parsing, syntax analysis, execution, etc. itself, or it could
serve as “glue” between PostgreSQL and an existing implementation of a programming language.
The handler itself is a C language function compiled into a shared object and loaded on demand, just
like any other C function.
There are currently four procedural languages available in the standard PostgreSQL distribution:
PL/pgSQL (Chapter 40), PL/Tcl (Chapter 41), PL/Perl (Chapter 42), and PL/Python (Chapter 43).
There are additional procedural languages available that are not included inthe core distribution. Ap-
pendix H has information about finding them. In addition other languages can be defined by users;
the basics of developing a new procedural language are covered in Chapter 52.
39.1. Installing Procedural Languages
Aprocedural language must be “installed” into each database where it is to be used. But procedu-
ral languages installed in the database
template1
are automatically available in all subsequently
created databases, since their entries in
template1
will be copied by
CREATE DATABASE
.So the
database administrator can decide which languages are available in which databases and can make
some languages available bydefault if he chooses.
For the languages supplied with the standard distribution, it is only necessary to execute
CREATE
EXTENSION language_name
to installthe language intothe currentdatabase. Alternatively, the pro-
gram createlang can be used to do this from the shell command line. For example, to install the
language PL/Perl into the database
template1
,use:
createlang plperl template1
The manual procedure described below is only recommended for installing languages that have not
been packaged as extensions.
Manual Procedural Language Installation
Aprocedural language is installed in a database in five steps, which must be carried out bya database
superuser. In most cases the required SQL commands should be packaged as the installation script of
an “extension”, so that
CREATE EXTENSION
can be used to execute them.
1. The shared object for the language handler must be compiled and installed into an appropriate
library directory. This works in the same way as building and installing modules with regular
user-defined C functions does; see Section 35.9.6. Often, the language handler will depend on
an external library that provides the actual programming language engine; if so, that must be
installed as well.
2. The handler must be declared with the command
CREATE FUNCTION
handler_function_name
()
RETURNS language_handler
AS ’
path-to-shared-object
LANGUAGE C;
1027
Documents you may be interested
Documents you may be interested