Older html conversion of original docs to html

superceded by the new sgml/docbook versions.
This commit is contained in:
Thomas G. Lockhart 1998-04-06 15:33:53 +00:00
parent cf1f24fbf0
commit 0bf8141172
22 changed files with 0 additions and 4701 deletions

View File

@ -1,539 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - ADMINISTERING POSTGRES</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="rules.html">[ Previous ]</A>
<A HREF="refs.html">[ Next ]</A>
</font>
<HR>
<H1>15. ADMINISTERING POSTGRES</H1>
<HR>
In this section, we will discuss aspects of POSTGRES
that are of interest to those who make extensive use of
POSTGRES, or who are the site administrator for a group
of POSTGRES users.
<H2>15.1. Frequent Tasks</H2>
Here we will briefly discuss some procedures that you
should be familiar with in managing any POSTGRES
installation.
<H3>15.1.1. Starting the Postmaster</H3>
If you did not install POSTGRES exactly as described in
the installation instructions, you may have to perform
some additional steps before starting the postmaster
process.
<UL>
<LI>Even if you were not the person who installed POSTGRES,
you should understand the installation
instructions. The installation instructions explain
some important issues with respect to where POSTGRES
places some important files, proper settings for
environment variables, etc. that may vary from one
version of POSTGRES to another.<p>
<LI>You must start the postmaster process with the userid
that owns the installed database files. In most
cases, if you have followed the installation
instructions, this will be the user "<B>postgres</B>". If
you do not start the postmaster with the right userid,
the backend servers that are started by the
postmaster will not be able to read the data.<p>
<LI>Make sure that <CODE>/usr/local/postgres95/bin</CODE> is in your
shell command path, because the postmaster will use
your <B>PATH</B> to locate POSTGRES commands.<p>
<LI>Remember to set the environment variable <B>PGDATA</B> to
the directory where the POSTGRES databases are
installed. (This variable is more fully explained
in the POSTGRES installation instructions.)<p>
<LI>If you do start the postmaster using non-standard
options, such as a different TCP port number, remember
to tell all users so that they can set their
<B>PGPORT</B> environment variable correctly.<p>
</UL>
<H3>15.1.2. Shutting Down the Postmaster</H3>
If you need to halt the postmaster process, you can use
the <B>UNIX</B> <B>kill(1)</B> command. Some people habitually use
the <B>-9</B> or <B>-KILL</B> option; this should never be necessary
and we do not recommend that you do this, as the postmaster
will be unable to free its various shared
resources, its child processes will be unable to exit
gracefully, etc.
<H3>15.1.3. Adding and Removing Users</H3>
The createuser and destroyuser commands enable and disable
access to POSTGRES by specific users on the host
system.
<H3>15.1.4. Periodic Upkeep</H3>
The vacuum command should be run on each database periodically.
This command processes deleted instances<A HREF="#9"><font size=-1>[9]</font></A>
and, more importantly, updates the system statistics
concerning the size of each class. If these statistics
are permitted to become out-of-date and inaccurate, the
POSTGRES query optimizer may make extremely poor decisions
with respect to query evaluation strategies.
Therefore, we recommend running vacuum every night or
so (perhaps in a script that is executed by the <B>UNIX</B>
<B>cron(1)</B> or <B>at(1)</B> commands).
Do frequent backups. That is, you should either back
up your database directories using the POSTGRES copy
command and/or the <B>UNIX</B> <B>dump(1)</B> or <B>tar(1)</B> commands.
You may think, "Why am I backing up my database? What
about crash recovery?" One side effect of the POSTGRES
"no overwrite" storage manager is that it is also a "no
log" storage manager. That is, the database log stores
only abort/commit data, and this is not enough information
to recover the database if the storage medium
(disk) or the database files are corrupted! In other
words, if a disk block goes bad or POSTGRES happens to
corrupt a database file, you cannot recover that file.
This can be disastrous if the file is one of the shared
catalogs, such as pg_database.
<H3>15.1.5. Tuning</H3>
Once your users start to load a significant amount of
data, you will typically run into performance problems.
POSTGRES is not the fastest DBMS in the world, but many
of the worst problems encountered by users are due to
their lack of experience with any DBMS. Some general
tips include:
<OL>
<LI> Define indices over attributes that are commonly
used for qualifications. For example, if you
often execute queries of the form
<pre> SELECT &#42; from EMP where salary &lt; 5000
</pre>
then a B-tree index on the salary attribute will
probably be useful. If scans involving equality
are more common, as in
<pre> SELECT &#42; from EMP where salary = 5000
</pre>
then you should consider defining a hash index
on salary. You can define both, though it will
use more disk space and may slow down updates a
bit. Scans using indices are much faster than
sequential scans of the entire class.<p>
<LI> Run the vacuum command a lot. This command
updates the statistics that the query optimizer
uses to make intelligent decisions; if the
statistics are inaccurate, the system will make
inordinately stupid decisions with respect to
the way it joins and scans classes.<p>
<LI> When specifying query qualfications (i.e., the
where part of the query), try to ensure that a
clause involving a constant can be turned into
one of the form range_variable operator constant, e.g.,
<pre> EMP.salary = 5000
</pre>
The POSTGRES query optimizer will only use an
index with a constant qualification of this
form. It doesn't hurt to write the clause as
<pre> 5000 = EMP.salary
</pre>
if the operator (in this case, =) has a commutator
operator defined so that POSTGRES can
rewrite the query into the desired form. However,
if such an operator does not exist, POSTGRES
will never consider the use of an index.<p>
<LI> When joining several classes together in one
query, try to write the join clauses in a
"chained" form, e.g.,
<pre> where A.a = B.b and B.b = C.c and ...
</pre>
Notice that relatively few clauses refer to a
given class and attribute; the clauses form a
linear sequence connecting the attributes, like
links in a chain. This is preferable to a query
written in a "star" form, such as
<pre> where A.a = B.b and A.a = C.c and ...
</pre>
Here, many clauses refer to the same class and
attribute (in this case, A.a). When presented
with a query of this form, the POSTGRES query
optimizer will tend to consider far more choices
than it should and may run out of memory.<p>
<LI> If you are really desperate to see what query
plans look like, you can run the postmaster with
the -d option and then run monitor with the -t
option. The format in which query plans will be
printed is hard to read but you should be able
to tell whether any index scans are being performed.<br>
</OL>
<H2>15.2. Infrequent Tasks</H2>
At some time or another, every POSTGRES site
administrator has to perform all of the following actions.
15.2.1. Cleaning Up After Crashes
The <B>postgres</B> server and the <B>postmaster</B> run as two
different processes. They may crash separately or
together. The housekeeping procedures required to fix
one kind of crash are different from those required to
fix the other.
The message you will usually see when the backend
server crashes is:
<pre> FATAL: no response from backend: detected in ...
</pre>
This generally means one of two things: there is a bug
in the POSTGRES server, or there is a bug in some user
code that has been dynamically loaded into POSTGRES.
You should be able to restart your application and
resume processing, but there are some considerations:
<OL>
<LI> POSTGRES usually dumps a core file (a snapshot
of process memory used for debugging) in the
database directory
<pre> /usr/local/postgres95/data/base/&lt;database&gt;/core
</pre>
on the server machine. If you don't want to try
to debug the problem or produce a stack trace to
report the bug to someone else, you can delete
this file (which is probably around 10MB).<p>
<LI> When one backend crashes in an uncontrolled way
(i.e., without calling its built-in cleanup
routines), the postmaster will detect this situation,
kill all running servers and reinitialize
the state shared among all backends (e.g., the
shared buffer pool and locks). If your server
crashed, you will get the "no response" message
shown above. If your server was killed because
someone else's server crashed, you will see the
following message:
<pre> I have been signalled by the postmaster.
Some backend process has died unexpectedly and possibly
corrupted shared memory. The current transaction was
aborted, and I am going to exit. Please resend the
last query. -- The postgres backend
</pre><br>
<LI> Sometimes shared state is not completely cleaned
up. Frontend applications may see errors of the
form:
<pre> WARN: cannot write block 34 of myclass [mydb] blind
</pre>
In this case, you should kill the postmaster and
restart it.<p>
<LI> When the system crashes while updating the system
catalogs (e.g., when you are creating a
class, defining an index, retrieving into a
class, etc.) the B-tree indices defined on the
catalogs are sometimes corrupted. The general
(and non-unique) symptom is that all queries
stop working. If you have tried all of the
above steps and nothing else seems to work, try
using the reindexdb command. If reindexdb succeeds
but things still don't work, you have
another problem; if it fails, the system catalogs
themselves were almost certainly corrupted
and you will have to go back to your backups.<p>
</OL>
The postmaster does not usually crash (it doesn't do
very much except start servers) but it does happen on
occasion. In addition, there are a few cases where it
encounters problems during the reinitialization of
shared resources. Specifically, there are race conditions
where the operating system lets the postmaster
free shared resources but then will not permit it to
reallocate the same amount of shared resources (even
when there is no contention).
You will typically have to run the ipcclean command if
system errors cause the postmaster to crash. If this
happens, you may find (using the UNIX ipcs(1) command)
that the "<B>postgres</B>" user has shared memory and/or
semaphores allocated even though no postmaster process
is running. In this case, you should run ipcclean as
the "<B>postgres</B>" user in order to deallocate these
resources. Be warned that all such resources owned by
the "<B>postgres</B>" user will be deallocated. If you have
multiple postmaster processes running on the same
machine, you should kill all of them before running
ipcclean (otherwise, they will crash on their own when
their shared resources are suddenly deallocated).
<H3>15.2.2. Moving Database Directories</H3>
By default, all POSTGRES databases are stored in
separate subdirectories under
<CODE>/usr/local/postgres95/data/base</CODE>.<A HREF="#10"><font size=-1>[10]</font></A> At some point, you
may find that you wish to move one or more databases to
another location (e.g., to a filesystem with more free
space).
If you wish to move all of your databases to the new
location, you can simply:
<UL>
<LI>Kill the postmaster.<p>
<LI>Copy the entire data directory to the new location
(making sure that the new files are owned by user
"<B>postgres</B>").
<pre> &#37; cp -rp /usr/local/postgres95/data /new/place/data
</pre><p>
<LI>Reset your PGDATA environment variable (as described
earlier in this manual and in the installation
instructions).
<pre> # using csh or tcsh...
&#37; setenv PGDATA /new/place/data
# using sh, ksh or bash...
&#37; PGDATA=/new/place/data; export PGDATA
</pre><p>
<LI>Restart the postmaster.
<pre> &#37; postmaster &amp;
</pre><p>
<LI>After you run some queries and are sure that the
newly-moved database works, you can remove the old
data directory.
<pre> &#37; rm -rf /usr/local/postgres95/data
</pre><p>
</UL>
To install a single database in an alternate directory
while leaving all other databases in place, do the following:
<UL>
<LI>Create the database (if it doesn't already exist)
using the createdb command. In the following steps
we will assume the database is named foo.<p>
<LI>Kill the postmaster.<p>
<LI>Copy the directory
<CODE>/usr/local/postgres95/data/base/foo</CODE> and its contents
to its ultimate destination. It should still be
owned by the "<B>postgres</B>" user.
<pre> &#37; cp -rp /usr/local/postgres95/data/base/foo /new/place/foo
</pre>
<LI>Remove the directory
<CODE>/usr/local/postgres95/data/base/foo</CODE>:
<pre> &#37; rm -rf /usr/local/postgres95/data/base/foo
</pre>
<LI>Make a symbolic link from
<CODE>/usr/local/postgres95/data/base</CODE> to the new directory:
<pre> &#37; ln -s /new/place/foo /usr/local/postgres95/data/base/foo
</pre>
<LI>Restart the postmaster.
</UL>
<p>
<H3>15.2.3. Updating Databases</H3>
POSTGRES is a research system. In general, POSTGRES
may not retain the same binary format for the storage
of databases from release to release. Therefore, when
you update your POSTGRES software, you will probably
have to modify your databases as well. This is a common
occurrence with commercial database systems as
well; unfortunately, unlike commercial systems, POSTGRES
does not come with user-friendly utilities to make
your life easier when these updates occur.
In general, you must do the following to update your
databases to a new software release:
<UL>
<LI>Extensions (such as user-defined types, functions,
aggregates, etc.) must be reloaded by re-executing
the <B>SQL CREATE</B> commands. See Appendix A for more
details.
<LI>Data must be dumped from the old classes into ASCII
files (using the <B>COPY</B> command), the new classes created
in the new database (using the <B>CREATE TABLE</B>
command), and the data reloaded from the ASCII files.
<LI>Rules and views must also be reloaded by
reexecuting the various CREATE commands.
</UL>
You should give any new release a "trial period"; in
particular, do not delete the old database until you
are satisfied that there are no compatibility problems
with the new software. For example, you do not want to
discover that a bug in a type's "input" (conversion
from ASCII) and "output" (conversion to ASCII) routines
prevents you from reloading your data after you have
destroyed your old databases! (This should be standard
procedure when updating any software package, but some
people try to economize on disk space without applying
enough foresight.)
<H2>15.3. Database Security</H2>
Most sites that use POSTGRES are educational or
research institutions and do not pay much attention to
security in their POSTGRES installations. If desired,
one can install POSTGRES with additional security
features. Naturally, such features come with additional
administrative overhead that must be dealt with.
<H3>15.3.1. Kerberos</H3>
POSTGRES can be configured to use the <B>MIT</B> <B>Kerberos</B> network
authentication system. This prevents outside
users from connecting to your databases over the network
without the correct authentication information.
<p>
<H2>15.4. Querying the System Catalogs</H2>
As an administrator (or sometimes as a plain user), you
want to find out what extensions have been added to a
given database. The queries listed below are "canned"
queries that you can run on any database to get simple
answers. Before executing any of the queries below, be
sure to execute the POSTGRES <B>vacuum</B> command. (The
queries will run much more quickly that way.) Also,
note that these queries are also listed in
<pre> /usr/local/postgres95/tutorial/syscat.sql
</pre>
so use cut-and-paste (or the <B>\i</B> command) instead of
doing a lot of typing.
This query prints the names of all database adminstrators
and the name of their database(s).
<pre> SELECT usename, datname
FROM pg_user, pg_database
WHERE usesysid = int2in(int4out(datdba))
ORDER BY usename, datname;
</pre>
This query lists all user-defined classes in the
database.
<pre> SELECT relname
FROM pg_class
WHERE relkind = 'r' -- not indices
and relname !~ '^pg_' -- not catalogs
and relname !~ '^Inv' -- not large objects
ORDER BY relname;
</pre>
This query lists all simple indices (i.e., those that
are not defined over a function of several attributes).
<pre> SELECT bc.relname AS class_name,
ic.relname AS index_name,
a.attname
FROM pg_class bc, -- base class
pg_class ic, -- index class
pg_index i,
pg_attribute a -- att in base
WHERE i.indrelid = bc.oid
and i.indexrelid = ic.oid
and i.indkey[0] = a.attnum
and a.attrelid = bc.oid
and i.indproc = '0'::oid -- no functional indices
ORDER BY class_name, index_name, attname;
</pre>
This query prints a report of the user-defined
attributes and their types for all user-defined classes
in the database.
<pre> SELECT c.relname, a.attname, t.typname
FROM pg_class c, pg_attribute a, pg_type t
WHERE c.relkind = 'r' -- no indices
and c.relname !~ '^pg_' -- no catalogs
and c.relname !~ '^Inv' -- no large objects
and a.attnum &gt; 0 -- no system att's
and a.attrelid = c.oid
and a.atttypid = t.oid
ORDER BY relname, attname;
</pre>
This query lists all user-defined base types (not
including array types).
<pre> SELECT u.usename, t.typname
FROM pg_type t, pg_user u
WHERE u.usesysid = int2in(int4out(t.typowner))
and t.typrelid = '0'::oid -- no complex types
and t.typelem = '0'::oid -- no arrays
and u.usename &lt;&gt; 'postgres'
ORDER BY usename, typname;
</pre>
This query lists all left-unary (post-fix) operators.
<pre> SELECT o.oprname AS left_unary,
right.typname AS operand,
result.typname AS return_type
FROM pg_operator o, pg_type right, pg_type result
WHERE o.oprkind = 'l' -- left unary
and o.oprright = right.oid
and o.oprresult = result.oid
ORDER BY operand;
</pre>
This query lists all right-unary (pre-fix) operators.
<pre> SELECT o.oprname AS right_unary,
left.typname AS operand,
result.typname AS return_type
FROM pg_operator o, pg_type left, pg_type result
WHERE o.oprkind = 'r' -- right unary
and o.oprleft = left.oid
and o.oprresult = result.oid
ORDER BY operand;
</pre>
This query lists all binary operators.
<pre> SELECT o.oprname AS binary_op,
left.typname AS left_opr,
right.typname AS right_opr,
result.typname AS return_type
FROM pg_operator o, pg_type left, pg_type right, pg_type result
WHERE o.oprkind = 'b' -- binary
and o.oprleft = left.oid
and o.oprright = right.oid
and o.oprresult = result.oid
ORDER BY left_opr, right_opr;
</pre>
This query returns the name, number of arguments
(parameters) and return type of all user-defined C
functions. The same query can be used to find all
built-in C functions if you change the "<B>C</B>" to "<B>internal</B>",
or all <B>SQL</B> functions if you change the "<B>C</B>" to
"<B>sql</B>".
<pre> SELECT p.proname, p.pronargs, t.typname
FROM pg_proc p, pg_language l, pg_type t
WHERE p.prolang = l.oid
and p.prorettype = t.oid
and l.lanname = 'c'
ORDER BY proname;
</pre>
This query lists all of the aggregate functions that
have been installed and the types to which they can be
applied. count is not included because it can take any
type as its argument.
<pre> SELECT a.aggname, t.typname
FROM pg_aggregate a, pg_type t
WHERE a.aggbasetype = t.oid
ORDER BY aggname, typname;
</pre>
This query lists all of the operator classes that can
be used with each access method as well as the operators
that can be used with the respective operator
classes.
<pre> SELECT am.amname, opc.opcname, opr.oprname
FROM pg_am am, pg_amop amop, pg_opclass opc, pg_operator opr
WHERE amop.amopid = am.oid
and amop.amopclaid = opc.oid
and amop.amopopr = opr.oid
ORDER BY amname, opcname, oprname;
</pre>
<p>
<HR>
<A NAME="9"><B>9.</B></A>
This may mean different things depending on the archive
mode with which each class has been created. However, the
current implementation of the vacuum command does not perform any compaction or clustering of data. Therefore, the
UNIX files which store each POSTGRES class never shrink and
the space "reclaimed" by vacuum is never actually reused.
<HR width=50 align=left>
<A NAME="10"><B>10.</B></A>
Data for certain classes may stored elsewhere if a
non-standard storage manager was specified when they were
created. Use of non-standard storage managers is an experimental feature that is not supported outside of Berkeley.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="rules.html">[ Previous ]</A>
<A HREF="refs.html">[ Next ]</A>
</font>

View File

@ -1,237 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - ADVANCED POSTGRES SQL FEATURES</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="query.html">[ Previous ]</A>
<A HREF="extend.html">[ Next ]</A>
</font>
<HR>
<H1>5. ADVANCED POSTGRES <B>SQL</B> FEATURES</H1>
<HR>
Having covered the basics of using POSTGRES <B>SQL</B> to
access your data, we will now discuss those features of
POSTGRES that distinguish it from conventional data
managers. These features include inheritance, time
travel and non-atomic data values (array- and
set-valued attributes).
Examples in this section can also be found in
<CODE>advance.sql</CODE> in the tutorial directory. (Refer to the
introduction of the <A HREF="query.html">previous chapter</A> for how to use
it.)
<H2><A NAME="inheritance">5.1. Inheritance</A></H2>
Let's create two classes. The capitals class contains
state capitals which are also cities. Naturally, the
capitals class should inherit from cities.
<pre> CREATE TABLE cities (
name text,
population float,
altitude int -- (in ft)
);
CREATE TABLE capitals (
state char2
) INHERITS (cities);
</pre>
In this case, an instance of capitals <B>inherits</B> all
attributes (name, population, and altitude) from its
parent, cities. The type of the attribute name is
<B>text</B>, a built-in POSTGRES type for variable length
ASCII strings. The type of the attribute population is
<B>float4</B>, a built-in POSTGRES type for double precision
floating point numbres. State capitals have an extra
attribute, state, that shows their state. In POSTGRES,
a class can inherit from zero or more other classes,<A HREF="#4"><font size=-1>[4]</font></A>
and a query can reference either all instances of a
class or all instances of a class plus all of its
descendants. For example, the following query finds
all the cities that are situated at an attitude of 500
'ft or higher:
<pre> SELECT name, altitude
FROM cities
WHERE altitude &gt; 500;
+----------+----------+
|name | altitude |
+----------+----------+
|Las Vegas | 2174 |
+----------+----------+
|Mariposa | 1953 |
+----------+----------+
</pre>
On the other hand, to find the names of all cities,
including state capitals, that are located at an altitude
over 500 'ft, the query is:
<pre> SELECT c.name, c.altitude
FROM cities&#42; c
WHERE c.altitude &gt; 500;
</pre>
which returns:
<pre> +----------+----------+
|name | altitude |
+----------+----------+
|Las Vegas | 2174 |
+----------+----------+
|Mariposa | 1953 |
+----------+----------+
|Madison | 845 |
+----------+----------+
</pre>
Here the &#42; after cities indicates that the query should
be run over cities and all classes below cities in the
inheritance hierarchy. Many of the commands that we
have already discussed -- select, update and delete --
support this &#42; notation, as do others, like alter command.
<H2><A NAME="time-travel">5.2. Time Travel</A></H2>
POSTGRES supports the notion of time travel. This feature
allows a user to run historical queries. For
example, to find the current population of Mariposa
city, one would query:
<pre> SELECT &#42; FROM cities WHERE name = 'Mariposa';
+---------+------------+----------+
|name | population | altitude |
+---------+------------+----------+
|Mariposa | 1320 | 1953 |
+---------+------------+----------+
</pre>
POSTGRES will automatically find the version of Mariposa's
record valid at the current time.
One can also give a time range. For example to see the
past and present populations of Mariposa, one would
query:
<pre> SELECT name, population
FROM cities['epoch', 'now']
WHERE name = 'Mariposa';
</pre>
where "epoch" indicates the beginning of the system
clock.<A HREF="#5"><font size=-1>[5]</font></A> If you have executed all of the examples so
far, then the above query returns:
<pre> +---------+------------+
|name | population |
+---------+------------+
|Mariposa | 1200 |
+---------+------------+
|Mariposa | 1320 |
+---------+------------+
</pre>
The default beginning of a time range is the earliest
time representable by the system and the default end is
the current time; thus, the above time range can be
abbreviated as ``[,].''
<H2><A NAME="non-atomic-values">5.3. Non-Atomic Values</A></H2>
One of the tenets of the relational model is that the
attributes of a relation are atomic. POSTGRES does not
have this restriction; attributes can themselves contain
sub-values that can be accessed from the query
language. For example, you can create attributes that
are arrays of base types.
<H3><A NAME="arrays">5.3.1. Arrays</A></H3>
POSTGRES allows attributes of an instance to be defined
as fixed-length or variable-length multi-dimensional
arrays. Arrays of any base type or user-defined type
can be created. To illustrate their use, we first create a
class with arrays of base types.
<pre> &#42; CREATE TABLE SAL_EMP (
name text,
pay_by_quarter int4[],
schedule char16[][]
);
</pre>
The above query will create a class named SAL_EMP with
a <B>text</B> string (name), a one-dimensional array of <B>int4</B>
(pay_by_quarter), which represents the employee's
salary by quarter and a two-dimensional array of <B>char16</B>
(schedule), which represents the employee's weekly
schedule. Now we do some <B>INSERTS</B>s; note that when
appending to an array, we enclose the values within
braces and separate them by commas. If you know <B>C</B>,
this is not unlike the syntax for initializing structures.
<pre> INSERT INTO SAL_EMP
VALUES ('Bill',
'{10000, 10000, 10000, 10000}',
'{{"meeting", "lunch"}, {}}');
INSERT INTO SAL_EMP
VALUES ('Carol',
'{20000, 25000, 25000, 25000}',
'{{"talk", "consult"}, {"meeting"}}');
</pre>
By default, POSTGRES uses the "one-based" numbering
convention for arrays -- that is, an array of n elements starts with array[1] and ends with array[n].
Now, we can run some queries on SAL_EMP. First, we
show how to access a single element of an array at a
time. This query retrieves the names of the employees
whose pay changed in the second quarter:
<pre> &#42; SELECT name
FROM SAL_EMP
WHERE SAL_EMP.pay_by_quarter[1] &lt;&gt;
SAL_EMP.pay_by_quarter[2];
+------+
|name |
+------+
|Carol |
+------+
</pre>
This query retrieves the third quarter pay of all
employees:
<pre> &#42; SELECT SAL_EMP.pay_by_quarter[3] FROM SAL_EMP;
+---------------+
|pay_by_quarter |
+---------------+
|10000 |
+---------------+
|25000 |
+---------------+
</pre>
We can also access arbitrary slices of an array, or
subarrays. This query retrieves the first item on
Bill's schedule for the first two days of the week.
<pre> &#42; SELECT SAL_EMP.schedule[1:2][1:1]
FROM SAL_EMP
WHERE SAL_EMP.name = 'Bill';
+-------------------+
|schedule |
+-------------------+
|{{"meeting"},{""}} |
+-------------------+
</pre>
<p>
<HR>
<A NAME="4"><B>4.</B></A> i.e., the inheritance hierarchy is a directed acyclic
graph.<br>
<A NAME="5"><B>5.</B></A> On UNIX systems, this is always midnight, January 1,
1970 GMT.<br>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="query.html">[ Previous ]</A>
<A HREF="extend.html">[ Next ]</A>
</font>

View File

@ -1,200 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - Appendix A:</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="refs.html">[ Previous ]</A>
[ Next ]
</font>
<HR>
<H1>Appendix A: Linking Dynamically-Loaded Functions</H1>
<HR>
After you have created and registered a user-defined
function, your work is essentially done. POSTGRES,
however, must load the object code (e.g., a .o file, or
a shared library) that implements your function. As
previously mentioned, POSTGRES loads your code at
runtime, as required. In order to allow your code to be
dynamically loaded, you may have to compile and
linkedit it in a special way. This section briefly
describes how to perform the compilation and
linkediting required before you can load your user-defined
functions into a running POSTGRES server. Note that
this process has changed as of Version 4.2.<A HREF="#11">11</A> You
should expect to read (and reread, and re-reread) the
manual pages for the C compiler, cc(1), and the link
editor, ld(1), if you have specific questions. In
addition, the regression test suites in the directory
/usr/local/postgres95/src/regress contain several
working examples of this process. If you copy what these
tests do, you should not have any problems.
The following terminology will be used below:
<DL>
<DT>Dynamic loading
<DD>is what POSTGRES does to an object file. The
object file is copied into the running POSTGRES
server and the functions and variables within the
file are made available to the functions within
the POSTGRES process. POSTGRES does this using
the dynamic loading mechanism provided by the
operating system.
<DT>Loading and link editing
<DD>is what you do to an object file in order to produce
another kind of object file (e.g., an executable
program or a shared library). You perform
this using the link editing program, ld(1).
</DL>
<p>
The following general restrictions and notes also apply
to the discussion below.
<UL>
<LI>Paths given to the create function command must be
absolute paths (i.e., start with "/") that refer to
directories visible on the machine on which the
POSTGRES server is running.<A HREF="#12">12</A>
<LI>The POSTGRES user must be able to traverse the path
given to the create function command and be able to
read the object file. This is because the POSTGRES
server runs as the POSTGRES user, not as the user
who starts up the frontend process. (Making the
file or a higher-level directory unreadable and/or
unexecutable by the "postgres" user is an extremely
common mistake.)
<LI>Symbol names defined within object files must not
conflict with each other or with symbols defined in
POSTGRES.
<LI>The GNU C compiler usually does not provide the special
options that are required to use the operating
system's dynamic loader interface. In such cases,
the C compiler that comes with the operating system
must be used.
</UL>
<p>
<B>ULTRIX</B><br>
It is very easy to build dynamically-loaded object
files under ULTRIX. ULTRIX does not have any sharedlibrary
mechanism and hence does not place any restrictions on
the dynamic loader interface. On the other
hand, we had to (re)write a non-portable dynamic loader
ourselves and could not use true shared libraries.
Under ULTRIX, the only restriction is that you must
produce each object file with the option -G 0. (Notice
that that's the numeral ``0'' and not the letter
``O''). For example,
<pre> # simple ULTRIX example
&#37; cc -G 0 -c foo.c
</pre>
produces an object file called foo.o that can then be
dynamically loaded into POSTGRES. No additional loading or link-editing must be performed.
<p>
<B>DEC OSF/1</B><br>
Under DEC OSF/1, you can take any simple object file
and produce a shared object file by running the ld command over it with the correct options. The commands to
do this look like:
<pre> # simple DEC OSF/1 example
&#37; cc -c foo.c
&#37; ld -shared -expect_unresolved '&#42;' -o foo.so foo.o
</pre>
The resulting shared object file can then be loaded
into POSTGRES. When specifying the object file name to
the create function command, one must give it the name
of the shared object file (ending in .so) rather than
the simple object file.<A HREF="#13">13</A> If the file you specify is
not a shared object, the backend will hang!
<p>
<B>SunOS 4.x, Solaris 2.x and HP-UX</B><br>
Under both SunOS 4.x, Solaris 2.x and HP-UX, the simple
object file must be created by compiling the source
file with special compiler flags and a shared library
must be produced.
The necessary steps with HP-UX are as follows. The +z
flag to the HP-UX C compiler produces so-called
"Position Independent Code" (PIC) and the +u flag
removes
some alignment restrictions that the PA-RISC architecture
normally enforces. The object file must be turned
into a shared library using the HP-UX link editor with
the -b option. This sounds complicated but is actually
very simple, since the commands to do it are just:
<pre> # simple HP-UX example
&#37; cc +z +u -c foo.c
&#37; ld -b -o foo.sl foo.o
</pre>
As with the .so files mentioned in the last subsection,
the create function command must be told which file is
the correct file to load (i.e., you must give it the
location of the shared library, or .sl file).
Under SunOS 4.x, the commands look like:
<pre> # simple SunOS 4.x example
&#37; cc -PIC -c foo.c
&#37; ld -dc -dp -Bdynamic -o foo.so foo.o
</pre>
and the equivalent lines under Solaris 2.x are:
<pre> # simple Solaris 2.x example
&#37; cc -K PIC -c foo.c
or
&#37; gcc -fPIC -c foo.c
&#37; ld -G -Bdynamic -o foo.so foo.o
</pre>
When linking shared libraries, you may have to specify
some additional shared libraries (typically system
libraries, such as the C and math libraries) on your ld
command line.
<HR>
<A NAME="11"><B>11.</B></A> The old POSTGRES dynamic
loading mechanism required
in-depth knowledge in terms of executable format, placement
and alignment of executable instructions within memory, etc.
on the part of the person writing the dynamic loader. Such
loaders tended to be slow and buggy. As of Version 4.2, the
POSTGRES dynamic loading mechanism has been rewritten to use
the dynamic loading mechanism provided by the operating
system. This approach is generally faster, more reliable and
more portable than our previous dynamic loading mechanism.
The reason for this is that nearly all modern versions of
UNIX use a dynamic loading mechanism to implement shared
libraries and must therefore provide a fast and reliable
mechanism. On the other hand, the object file must be
postprocessed a bit before it can be loaded into POSTGRES. We
hope that the large increase in speed and reliability will
make up for the slight decrease in convenience.
<hr width=50 align=left>
<A NAME="12"><B>12.</B></A> Relative paths do in fact work,
but are relative to
the directory where the database resides (which is generally
invisible to the frontend application). Obviously, it makes
no sense to make the path relative to the directory in which
the user started the frontend application, since the server
could be running on a completely different machine!<br>
<hr width=50 align=left>
<A NAME="13"><B>13.</B></A> Actually, POSTGRES does not care
what you name the
file as long as it is a shared object file. If you prefer
to name your shared object files with the extension .o, this
is fine with POSTGRES so long as you make sure that the correct
file name is given to the create function command. In
other words, you must simply be consistent. However, from a
pragmatic point of view, we discourage this practice because
you will undoubtedly confuse yourself with regards to which
files have been made into shared object files and which have
not. For example, it's very hard to write Makefiles to do
the link-editing automatically if both the object file and
the shared object file end in .o!<br>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="refs.html">[ Previous ]</A>
[ Next ]
</font>
</BODY>
</HTML>

View File

@ -1,76 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - ARCHITECTURE</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="intro.html">[ Previous ]</A>
<A HREF="start.html">[ Next ]</A>
</font>
<HR>
<H1>2. POSTGRES ARCHITECTURE CONCEPTS</H1>
<HR>
Before we continue, you should understand the basic
POSTGRES system architecture. Understanding how the
parts of POSTGRES interact will make the next chapter
somewhat clearer.
In database jargon, POSTGRES uses a simple "process
per-user" client/server model. A POSTGRES session
consists of the following cooperating UNIX processes (programs):
<UL>
<LI>A supervisory daemon process (the <B>postmaster</B>),
<LI>the user's frontend application (e.g., the <B>psql</B> program), and
<LI>the one or more backend database servers (the <B>postgres</B> process itself).
</UL>
A single <B>postmaster</B> manages a given collection of
databases on a single host. Such a collection of
databases is called an installation or site. Frontend
applications that wish to access a given database
within an installation make calls to the library.
The library sends user requests over the network to the
<B>postmaster</B> (Figure 1(a)), which in turn starts a new
backend server process (Figure 1(b))
<IMG SRC="figure01.gif" ALIGN=right ALT="Figure 1- How a connection is established"><br>
and connects the
frontend process to the new server (Figure 1(c)). From
that point on, the frontend process and the backend
server communicate without intervention by the
<B>postmaster</B>. Hence, the <B>postmaster</B> is always running, waiting
for requests, whereas frontend and backend processes
come and go. The <B>LIBPQ</B> library allows a single
frontend to make multiple connections to backend processes.
However, the frontend application is still a
single-threaded process. Multithreaded frontend/backend
connections are not currently supported in <B>LIBPQ</B>.
One implication of this architecture is that the
<B>postmaster</B> and the backend always run on the same
machine (the database server), while the frontend
application may run anywhere. You should keep this
in mind,
because the files that can be accessed on a client
machine may not be accessible (or may only be accessed
using a different filename) on the database server
machine.
You should also be aware that the <B>postmaster</B> and
postgres servers run with the user-id of the POSTGRES
"superuser." Note that the POSTGRES superuser does not
have to be a special user (e.g., a user named
"postgres"). Furthermore, the POSTGRES superuser
should
definitely not be the UNIX superuser, "root"! In any
case, all files relating to a database should belong to
this POSTGRES superuser.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="intro.html">[ Previous ]</A>
<A HREF="start.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,32 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 - Copyright</TITLE>
</HEAD>
<BODY>
<H1 align=center>The <B>POSTGRES95</B> - Copyright</H1>
<HR>
<B>POSTGRES95</B> is copyright (C) 1994-5 by the Regents of the
University of California. Permission to use, copy, modify,
and distribute this software and its documentation for any
purpose, without fee, and without a written agreement is
hereby granted, provided that the above copyright notice and
this paragraph and the following two paragraphs appear in
all copies.<p>
<b> IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE
LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL,
INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST
PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND
ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA
HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
THE UNIVERSITY OF CALIFORNIA SPECIFICALLY
DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED
HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
</b>
</BODY>
</HTML>

View File

@ -1,199 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - EXTENDING SQL: AN OVERVIEW</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="advanced.html">[ Previous ]</A>
<A HREF="xfunc.html">[ Next ]</A>
</font>
<HR>
<H1>6. EXTENDING SQL: AN OVERVIEW</H1>
<HR>
In the sections that follow, we will discuss how you
can extend the POSTGRES <B>SQL</B> query language by adding:
<UL>
<LI>functions
<LI>types
<LI>operators
<LI>aggregates
</UL>
<p>
<H2><A NAME="how-extensibility-works">6.1. How Extensibility Works</A></H2>
POSTGRES is extensible because its operation is
catalog-driven. If you are familiar with standard
relational systems, you know that they store information
about databases, tables, columns, etc., in what are
commonly known as system catalogs. (Some systems call
this the data dictionary). The catalogs appear to the
user as classes, like any other, but the DBMS stores
its internal bookkeeping in them. One key difference
between POSTGRES and standard relational systems is
that POSTGRES stores much more information in its
catalogs -- not only information about tables and columns,
but also information about its types, functions, access
methods, and so on. These classes can be modified by
the user, and since POSTGRES bases its internal operation
on these classes, this means that POSTGRES can be
extended by users. By comparison, conventional
database systems can only be extended by changing hardcoded
procedures within the DBMS or by loading modules
specially-written by the DBMS vendor.
POSTGRES is also unlike most other data managers in
that the server can incorporate user-written code into
itself through dynamic loading. That is, the user can
specify an object code file (e.g., a compiled .o file
or shared library) that implements a new type or function
and POSTGRES will load it as required. Code written
in <B>SQL</B> are even more trivial to add to the server.
This ability to modify its operation "on the fly" makes
POSTGRES uniquely suited for rapid prototyping of new
applications and storage structures.
<H2><A NAME="the-postgres-type-system">6.2. The POSTGRES Type System</A></H2>
The POSTGRES type system can be broken down in several
ways.
Types are divided into base types and composite types.
Base types are those, like <CODE>int4</CODE>, that are implemented
in a language such as <B>C</B>. They generally correspond to
what are often known as "abstract data types"; POSTGRES
can only operate on such types through methods provided
by the user and only understands the behavior of such
types to the extent that the user describes them.
Composite types are created whenever the user creates a
class. EMP is an example of a composite type.
POSTGRES stores these types in only one way (within the
file that stores all instances of the class) but the
user can "look inside" at the attributes of these types
from the query language and optimize their retrieval by
(for example) defining indices on the attributes.
POSTGRES base types are further divided into built-in
types and user-defined types. Built-in types (like
<CODE>int4</CODE>) are those that are compiled into the system.
User-defined types are those created by the user in the
manner to be described below.
<H2><A NAME="about-the-postgres-system-catalogs">6.3. About the POSTGRES System Catalogs</A></H2>
Having introduced the basic extensibility concepts, we
can now take a look at how the catalogs are actually
laid out. You can skip this section for now, but some
later sections will be incomprehensible without the
information given here, so mark this page for later
reference.
All system catalogs have names that begin with <CODE>pg_</CODE>.
The following classes contain information that may be
useful to the end user. (There are many other system
catalogs, but there should rarely be a reason to query
them directly.)
<p>
<center>
<table border=1>
<tr>
<th>catalog name</th><th> description </th>
</tr>
<tr>
<td><CODE>pg_database</CODE> </td><td> databases </td>
</tr>
<tr>
<td><CODE>pg_class</CODE> </td><td> classes </td>
</tr>
<tr>
<td><CODE>pg_attribute</CODE> </td><td> class attributes </td>
</tr>
<tr>
<td><CODE>pg_index</CODE> </td><td> secondary indices </td>
</tr>
<tr>
</tr>
<tr>
<td><CODE>pg_proc</CODE> </td><td> procedures (both C and SQL) </td>
</tr>
<tr>
<td><CODE>pg_type</CODE> </td><td> types (both base and complex) </td>
</tr>
<tr>
<td><CODE>pg_operator</CODE> </td><td> operators </td>
</tr>
<tr>
<td><CODE>pg_aggregate</CODE> </td><td> aggregates and aggregate functions </td>
</tr>
<tr>
</tr>
<tr>
</tr>
<tr>
<td><CODE>pg_am</CODE> </td><td> access methods </td>
</tr>
<tr>
<td><CODE>pg_amop</CODE> </td><td> access method operators </td>
</tr>
<tr>
<td><CODE>pg_amproc</CODE> </td><td> access method support functions </td>
</tr>
<tr>
<td><CODE>pg_opclass</CODE> </td><td> access method operator classes </td>
</tr>
</table>
</center>
<p>
<IMG SRC="figure03.gif"
ALT="Figure 3. The major POSTGRES system catalogs">
The Reference Manual gives a more detailed explanation
of these catalogs and their attributes. However, Figure 3
shows the major entities and their relationships
in the system catalogs. (Attributes that do not refer
to other entities are not shown unless they are part of
a primary key.)
This diagram is more or less incomprehensible until you
actually start looking at the contents of the catalogs
and see how they relate to each other. For now, the
main things to take away from this diagram are as follows:
<OL>
<LI> In several of the sections that follow, we will
present various join queries on the system
catalogs that display information we need to extend
the system. Looking at this diagram should make
some of these join queries (which are often
three- or four-way joins) more understandable,
because you will be able to see that the
attributes used in the queries form foreign keys
in other classes.
<LI> Many different features (classes, attributes,
functions, types, access methods, etc.) are
tightly integrated in this schema. A simple
create command may modify many of these catalogs.
<LI> Types and procedures <A HREF="#6"><font size=-1>[6]</font></A>
are central to the schema.
Nearly every catalog contains some reference to
instances in one or both of these classes. For
example, POSTGRES frequently uses type
signatures (e.g., of functions and operators) to
identify unique instances of other catalogs.
<LI> There are many attributes and relationships that
have obvious meanings, but there are many
(particularly those that have to do with access
methods) that do not. The relationships between
<CODE>pg_am, pg_amop, pg_amproc, pg_operator</CODE> and
<CODE>pg_opclass</CODE> are particularly hard to understand
and will be described in depth (in the section
on interfacing types and operators to indices)
after we have discussed basic extensions.
</OL>
<p>
<HR>
<A NAME="6"><B>6.</B></A> We use the words <I>procedure</I> and <I>function</I> more or less
interchangably.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="advanced.html">[ Previous ]</A>
<A HREF="xfunc.html">[ Next ]</A>
</font>
</BODY>
</HTML>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

View File

@ -1,201 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - Introduction</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
[ Previous ]
<A HREF="architec.html">[ Next ]</A>
</font>
<HR>
<H1>1. INTRODUCTION</H1>
<HR>
This document is the user manual for the
<A HREF="http://s2k-ftp.cs.berkeley.edu:8000/postgres95/"><B>POSTGRES95</B></A>
database management system developed at the University
of California at Berkeley. <B>POSTGRES95</B> is based on
<A HREF="http://s2k-ftp.CS.Berkeley.EDU:8000/postgres/postgres.html">
<B>POSTGRES release 4.2</B></A>. The POSTGRES project,
led by Professor Michael Stonebraker, has been sponsored by the
Defense Advanced Research Projects Agency (DARPA), the
Army Research Office (ARO), the National Science
Foundation (NSF), and ESL, Inc.
<H2>1.1. What is POSTGRES?</H2>
Traditional relational database management systems
(DBMSs) support a data model consisting of a collection
of named relations, containing attributes of a specific
type. In current commercial systems, possible types
include floating point numbers, integers, character
strings, money, and dates. It is commonly recognized
that this model is inadequate for future data
processing applications.
The relational model successfully replaced previous
models in part because of its "Spartan simplicity".
However, as mentioned, this simplicity often makes the
implementation of certain applications very difficult
to implement. POSTGRES offers substantial additional
power by incorporating the following four additional
basic constructs in such a way that users can easily
extend the system:
<p>
<PRE> classes
inheritance
types
functions
</PRE><p>
In addition, POSTGRES supports a powerful production
rule system.
<H2><A NAME="a-short-history-of-the-postgres-project">1.2. A Short History of the POSTGRES Project</A></H2>
Implementation of the POSTGRES DBMS began in 1986. The
initial concepts for the system were presented in
<A HREF="refs.html#STON86">[STON86]</A> and the definition of the initial data model
appeared in <A HREF="refs.html#ROW87">[ROWE87]</A>. The design of the rule system at
that time was described in <A HREF="refs.html#STON87a">[STON87a]</A>. The rationale
and architecture of the storage manager were detailed
in <A HREF="refs.html#STON87b">[STON87b]</A>.
POSTGRES has undergone several major releases since
then. The first "demoware" system became operational
in 1987 and was shown at the 1988 <B>ACM-SIGMOD</B>
Conference. We released Version 1, described in <A HREF="refs.html#STON90a">[STON90a]</A>,
to a few external users in June 1989. In response to a
critique of the first rule system <A HREF="refs.html#STON89">[STON89]</A>, the rule
system was redesigned <A HREF="refs.html#STON90">[STON90b]</A> and Version 2 was
released in June 1990 with the new rule system.
Version 3 appeared in 1991 and added support for multiple
storage managers, an improved query executor, and a
rewritten rewrite rule system. For the most part,
releases since then have focused on portability and
reliability.
POSTGRES has been used to implement many different
research and production applications. These include: a
financial data analysis system, a jet engine
performance monitoring package, an asteroid tracking
database, a medical information database, and several
geographic information systems. POSTGRES has also been
used as an educational tool at several universities.
Finally, <A HREF="http://www.illustra.com/">Illustra Information Technologies</A> picked up
the code and commercialized it.
POSTGRES became the primary data manager for the
<A HREF="http://www.sdsc.edu/0/Parts_Collabs/S2K/s2k_home.html">Sequoia 2000</A> scientific computing project in late 1992.
Furthermore, the size of the external user community
nearly doubled during 1993. It became increasingly
obvious that maintenance of the prototype code and
support was taking up large amounts of time that should
have been devoted to database research. In an effort
to reduce this support burden, the project officially
ended with <B>Version 4.2</B>.
<H2><A NAME="what-is-postgres95">1.3. What is <B>POSTGRES95</B>?</A></H2>
<B>POSTGRES95</B> is a derivative of the last official release
of POSTGRES (version 4.2). The code is now completely
ANSI C and the code size has been trimmed by 25&#37;. There
are a lot of internal changes that improve performance
and code maintainability. <B>POSTGRES95</B> runs about 30-50&#37;
faster on the Wisconsin Benchmark compared to v4.2.
Apart from bug fixes, these are the major enhancements:
<UL>
<LI>The query language <B>POSTQUEL</B> has been replaced with
<B>SQL</B> (implemented in the server). We do not support
subqueries (which can be imitated with user defined
<B>SQL</B> functions) at the moment. Aggregates have been
re-implemented. We also added support for <B>GROUP BY</B>.
The <B>libpq</B> interface is still available for <B>C</B>
programs.
<LI>In addition to the monitor program, we provide a new
program (<B>psql</B>) which supports <B>GNU</B> <B>readline</B>.
<LI>We added a new front-end library, <B>libpgtcl</B>, that
supports <B>Tcl</B>-based clients. A sample shell,
pgtclsh, provides new Tcl commands to interface <B>tcl</B>
programs with the <B>POSTGRES95</B> backend.
<LI>The large object interface has been overhauled. We
kept Inversion large objects as the only mechanism
for storing large objects. (This is not to be
confused with the Inversion file system which has been
removed.)
<LI>The instance-level rule system has been removed.
<LI>Rules are still available as rewrite rules.
<LI>A short tutorial introducing regular <B>SQL</B> features as
well as those of ours is distributed with the source
code.
<LI><B>GNU</B> make (instead of <B>BSD</B> make) is used for the
build. Also, <B>POSTGRES95</B> can be compiled with an
unpatched <B>gcc</B> (data alignment of doubles has been
fixed).
</UL>
<p>
<H2><A NAME="about-this-release">1.4. About This Release</A></H2>
<B>POSTGRES95</B> is available free of charge. This manual
describes version 1.0 of <B>POSTGRES95</B>. The authors have
compiled and tested <B>POSTGRES95</B> on the following
platforms:
<p>
<center>
<table border=4>
<tr>
<th>Architecture</th>
<th>Processor</th>
<th>Operating System</th>
</tr>
<tr>
<td>DECstation 3000</td>
<td>Alpha AXP</td>
<td>OSF/1 2.1, 3.0, 3.2</td>
</tr>
<tr>
<td>DECstation 5000</td>
<td>MIPS</td>
<td>ULTRIX 4.4</td>
</tr>
<tr>
<td>Sun4</td>
<td>SPARC</td>
<td>SunOS 4.1.3, 4.1.3_U1; Solaris 2.4</td>
</tr>
<tr>
<td>H-P 9000/700 and 800</td>
<td>PA-RISC</td>
<td>HP-UX 9.00, 9.01, 9.03</td>
</tr>
<tr>
<td>Intel</td>
<td>X86</td>
<td>Linux 1.2.8, ELF</td>
</table>
</center>
<p>
<H2><A NAME="outline-of-this-manual">1.5. Outline of This Manual</A></H2>
From now on, We will use POSTGRES to mean <B>POSTGRES95</B>.
The first part of this manual goes over some basic sys-
tem concepts and procedures for starting the POSTGRES
system. We then turn to a tutorial overview of the
POSTGRES data model and SQL query language, introducing
a few of its advanced features. Next, we explain the
POSTGRES approach to extensibility and describe how
users can extend POSTGRES by adding user-defined types,
operators, aggregates, and both query language and pro-
gramming language functions. After an extremely brief
overview of the POSTGRES rule system, the manual
concludes with a detailed appendix that discusses some of
the more involved and operating system-specific
procedures involved in extending the system.
<HR>
<B>UNIX</B> is a trademark of X/Open, Ltd. Sun4, SPARC, SunOS
and Solaris are trademarks of Sun Microsystems, Inc. DEC,
DECstation, Alpha AXP and ULTRIX are trademarks of Digital
Equipment Corp. PA-RISC and HP-UX are trademarks of
Hewlett-Packard Co. OSF/1 is a trademark of the Open
Software Foundation.<p>
We assume proficiency with UNIX and C programming.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
[ Previous ]
<A HREF="architec.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,815 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - LIBPQ</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xindex.html">[ Previous ]</A>
<A HREF="lobj.html">[ Next ]</A>
</font>
<HR>
<H1>12. <B>LIBPQ</B></H1>
<HR>
<B>LIBPQ</B> is the application programming interface to POSTGRES.
<B>LIBPQ</B> is a set of library routines which allows
client programs to pass queries to the POSTGRES backend
server and to receive the results of these queries.
This version of the documentation describes the <B>C</B>
interface library. Three short programs are included
at the end of this section to show how to write programs that use <B>LIBPQ</B>.
There are several examples of <B>LIBPQ</B> applications in the
following directories:
<pre> ../src/test/regress
../src/test/examples
../src/bin/psql
</pre>
Frontend programs which use <B>LIBPQ</B> must include the
header file <CODE>libpq-fe.h</CODE> and must link with the <B>libpq</B>
library.
<H2><A NAME="control-and-initialization">12.1. Control and Initialization</A></H2>
The following environment variables can be used to set
up default environment values to avoid hard-coding
database names into an application program:
<UL>
<LI><B>PGHOST</B> sets the default server name.
<LI><B>PGOPTIONS</B> sets additional runtime options for the POSTGRES backend.
<LI><B>PGPORT</B> sets the default port for communicating with the POSTGRES backend.
<LI><B>PGTTY</B> sets the file or tty on which debugging messages from the backend server are displayed.
<LI><B>PGDATABASE</B> sets the default POSTGRES database name.
<LI><B>PGREALM</B> sets the Kerberos realm to use with POSTGRES, if it is different from the local realm. If
<LI><B>PGREALM</B> is set, POSTGRES applications will attempt
authentication with servers for this realm and use
separate ticket files to avoid conflicts with local
ticket files. This environment variable is only
used if Kerberos authentication is enabled.
</UL>
<H2><A NAME="database-connection-functions">12.2. Database Connection Functions</A></H2>
The following routines deal with making a connection to
a backend from a <B>C</B> program.
<DL>
<DT><B>PQsetdb</B>
<DD>Makes a new connection to a backend.
<pre> PGconn &#42;PQsetdb(char &#42;pghost,
char &#42;pgport,
char &#42;pgoptions,
char &#42;pgtty,
char &#42;dbName);
</pre>
<DD>If any argument is NULL, then the corresponding
environment variable is checked. If the environment variable is also not set, then hardwired
defaults are used.
<DD>PQsetdb always returns a valid PGconn pointer.
<DD>The PQstatus (see below) command should be called
to ensure that a connection was properly made
before queries are sent via the connection. <B>LIBPQ</B>
programmers should be careful to maintain the
<DD>PGconn abstraction. Use the accessor functions
below to get at the contents of PGconn. Avoid
directly referencing the fields of the PGconn
structure as they are subject to change in the
future.<br>
<DT><B>PQdb</B>
<DD>Returns the database name of the connection.
<pre> char &#42;PQdb(PGconn &#42;conn)
</pre><br>
<DT><B>PQhost</B>
<DD>Returns the host name of the connection.
<pre> char &#42;PQhost(PGconn &#42;conn)
</pre><br>
<DT><B>PQoptions</B>
<DD>Returns the pgoptions used in the connection.
<pre> char &#42;PQoptions(PGconn &#42;conn)
</pre><br>
<DT><B>PQport</B>
<DD>Returns the pgport of the connection.
<pre> char &#42;PQport(PGconn &#42;conn)
</pre><br>
<DT><B>PQtty</B>
<DD>Returns the pgtty of the connection.
<pre> char &#42;PQtty(PGconn &#42;conn)
</pre><br>
<DT><B>PQstatus</B>
<DD>Returns the status of the connection.
<DD>The status can be CONNECTION_OK or CONNECTION_BAD.
<pre> ConnStatusType &#42;PQstatus(PGconn &#42;conn)
</pre><br>
<DT><B>PQerrorMessage</B>
<DD>Returns the error message associated with the connection
<pre> char &#42;PQerrorMessage(PGconn&#42; conn);
</pre><br>
<DT><B>PQfinish</B>
<DD>Close the connection to the backend. Also frees
memory used by the PGconn structure. The PGconn
pointer should not be used after PQfinish has been
called.
<pre> void PQfinish(PGconn &#42;conn)
</pre><br>
<DT><B>PQreset</B>
<DD>Reset the communication port with the backend.
This function will close the IPC socket connection
to the backend and attempt to reestablish a new
connection to the same backend.
<pre> void PQreset(PGconn &#42;conn)
</pre><br>
<DT><B>PQtrace</B>
<DD>Enables tracing of messages passed between the
frontend and the backend. The messages are echoed
to the debug_port file stream.
<pre> void PQtrace(PGconn &#42;conn,
FILE&#42; debug_port);
</pre><br>
<DT><B>PQuntrace</B>
<DD>Disables tracing of messages passed between the
frontend and the backend.
<pre> void PQuntrace(PGconn &#42;conn);
</pre><br>
</DL>
<H2><A NAME="query-execution-functions">12.3. Query Execution Functions</A></H2>
<DL>
<DT><B>PQexec</B>
<DD>Submit a query to POSTGRES. Returns a PGresult
pointer if the query was successful or a NULL otherwise. If a NULL is returned, PQerrorMessage can
be used to get more information about the error.
<pre> PGresult &#42;PQexec(PGconn &#42;conn,
char &#42;query);
</pre>
<DD>The <B>PGresult</B> structure encapsulates the query
result returned by the backend. <B>LIBPQ</B> programmers
should be careful to maintain the PGresult
abstraction. Use the accessor functions described
below to retrieve the results of the query. Avoid
directly referencing the fields of the PGresult
structure as they are subject to change in the
future.<br>
<DT><B>PQresultStatus</B>
<DD>Returns the result status of the query. PQresultStatus can return one of the following values:
<pre> PGRES_EMPTY_QUERY,
PGRES_COMMAND_OK, /&#42; the query was a command &#42;/
PGRES_TUPLES_OK, /&#42; the query successfully returned tuples &#42;/
PGRES_COPY_OUT,
PGRES_COPY_IN,
PGRES_BAD_RESPONSE, /&#42; an unexpected response was received &#42;/
PGRES_NONFATAL_ERROR,
PGRES_FATAL_ERROR
</pre>
<DD>If the result status is PGRES_TUPLES_OK, then the
following routines can be used to retrieve the
tuples returned by the query.<br>
<DT><B>PQntuples</B> returns the number of tuples (instances)
in the query result.
<pre> int PQntuples(PGresult &#42;res);
</pre><br>
<DT><B>PQnfields</B>
<DD>Returns the number of fields
(attributes) in the query result.
<pre> int PQnfields(PGresult &#42;res);
</pre><br>
<DT><B>PQfname</B>
<DD>Returns the field (attribute) name associated with the given field index. Field indices
start at 0.
<pre> char &#42;PQfname(PGresult &#42;res,
int field_index);
</pre><br>
<DT><B>PQfnumber</B>
<DD>Returns the field (attribute) index
associated with the given field name.
<pre> int PQfnumber(PGresult &#42;res,
char&#42; field_name);
</pre><br>
<DT><B>PQftype</B>
<DD>Returns the field type associated with the
given field index. The integer returned is an
internal coding of the type. Field indices start
at 0.
<pre> Oid PQftype(PGresult &#42;res,
int field_num);
</pre><br>
<DT><B>PQfsize</B>
<DD>Returns the size in bytes of the field
associated with the given field index. If the size
returned is -1, the field is a variable length
field. Field indices start at 0.
<pre> int2 PQfsize(PGresult &#42;res,
int field_index);
</pre><br>
<DT><B>PQgetvalue</B>
<DD>Returns the field (attribute) value.
For most queries, the value returned by PQgetvalue
is a null-terminated ASCII string representation
of the attribute value. If the query was a result
of a <B>BINARY</B> cursor, then the value returned by
PQgetvalue is the binary representation of the
type in the internal format of the backend server.
It is the programmer's responsibility to cast and
convert the data to the correct C type. The value
returned by PQgetvalue points to storage that is
part of the PGresult structure. One must explicitly
copy the value into other storage if it is to
be used past the lifetime of the PGresult structure itself.
<pre> char&#42; PQgetvalue(PGresult &#42;res,
int tup_num,
int field_num);
</pre><br>
<DT><B>PQgetlength</B>
<DD>Returns the length of a field
(attribute) in bytes. If the field is a struct
varlena, the length returned here does not include
the size field of the varlena, i.e., it is 4 bytes
less.
<pre> int PQgetlength(PGresult &#42;res,
int tup_num,
int field_num);
</pre><br>
<DT><B>PQcmdStatus</B>
Returns the command status associated with the
last query command.
<pre>
char &#42;PQcmdStatus(PGresult &#42;res);
</pre><br>
<DT><B>PQoidStatus</B>
Returns a string with the object id of the tuple
inserted if the last query is an INSERT command.
Otherwise, returns an empty string.
<pre> char&#42; PQoidStatus(PGresult &#42;res);
</pre><br>
<DT><B>PQprintTuples</B>
Prints out all the tuples and, optionally, the
attribute names to the specified output stream.
The programs psql and monitor both use PQprintTuples for output.
<pre> void PQprintTuples(
PGresult&#42; res,
FILE&#42; fout, /&#42; output stream &#42;/
int printAttName,/&#42; print attribute names or not&#42;/
int terseOutput, /&#42; delimiter bars or not?&#42;/
int width /&#42; width of column, variable width if 0&#42;/
);
</pre><br>
<DT><B>PQclear</B>
Frees the storage associated with the PGresult.
Every query result should be properly freed when
it is no longer used. Failure to do this will
result in memory leaks in the frontend application.
<pre> void PQclear(PQresult &#42;res);
</pre><br>
</DL>
<H2><A NAME="fast-path">12.4. Fast Path</A></H2>
POSTGRES provides a fast path interface to send function calls to the backend. This is a trapdoor into
system internals and can be a potential security hole.
Most users will not need this feature.
<pre> PGresult&#42; PQfn(PGconn&#42; conn,
int fnid,
int &#42;result_buf,
int &#42;result_len,
int result_is_int,
PQArgBlock &#42;args,
int nargs);
</pre><br>
The fnid argument is the object identifier of the function to be executed. result_buf is the buffer in which
to load the return value. The caller must have allocated sufficient space to store the return value. The
result length will be returned in the storage pointed
to by result_len. If the result is to be an integer
value, than result_is_int should be set to 1; otherwise
it should be set to 0. args and nargs specify the
arguments to the function.
<pre> typedef struct {
int len;
int isint;
union {
int &#42;ptr;
int integer;
} u;
} PQArgBlock;
</pre>
PQfn always returns a valid PGresult&#42;. The resultStatus should be checked before the result is used. The
caller is responsible for freeing the PGresult with
PQclear when it is not longer needed.
<H2><A NAME="asynchronous-notification">12.5. Asynchronous Notification</A></H2>
POSTGRES supports asynchronous notification via the
LISTEN and NOTIFY commands. A backend registers its
interest in a particular relation with the LISTEN command. All backends listening on a particular relation
will be notified asynchronously when a NOTIFY of that
relation name is executed by another backend. No
additional information is passed from the notifier to
the listener. Thus, typically, any actual data that
needs to be communicated is transferred through the
relation.
<B>LIBPQ</B> applications are notified whenever a connected
backend has received an asynchronous notification.
However, the communication from the backend to the
frontend is not asynchronous. Notification comes
piggy-backed on other query results. Thus, an application must submit queries, even empty ones, in order to
receive notice of backend notification. In effect, the
<B>LIBPQ</B> application must poll the backend to see if there
is any pending notification information. After the
execution of a query, a frontend may call PQNotifies to
see if any notification data is available from the
backend.
<DL>
<DT><B>PQNotifies</B>
<DD>returns the notification from a list of unhandled
notifications from the backend. Returns NULL if
there are no pending notifications from the backend. PQNotifies behaves like the popping of a
stack. Once a notification is returned from PQnotifies, it is considered handled and will be
removed from the list of notifications.
<pre> PGnotify&#42; PQNotifies(PGconn &#42;conn);
</pre><br>
</DL>
The second sample program gives an example of the use
of asynchronous notification.
<H2><A NAME="functions-associated-with-the-copy-command">12.6. Functions Associated with the COPY Command</A></H2>
The copy command in POSTGRES has options to read from
or write to the network connection used by <B>LIBPQ</B>.
Therefore, functions are necessary to access this network connection directly so applications may take full
advantage of this capability.
<DL>
<DT><B>PQgetline</B>
<DD>Reads a newline-terminated line of characters
(transmitted by the backend server) into a buffer
string of size length. Like fgets(3), this routine copies up to length-1 characters into string.
It is like gets(3), however, in that it converts
the terminating newline into a null character.
PQgetline returns EOF at EOF, 0 if the entire line
has been read, and 1 if the buffer is full but the
terminating newline has not yet been read.
Notice that the application must check to see if a
new line consists of the single character ".",
which indicates that the backend server has finished sending the results of the copy command.
Therefore, if the application ever expects to
receive lines that are more than length-1 characters long, the application must be sure to check
the return value of PQgetline very carefully.
The code in
<pre> ../src/bin/psql/psql.c
</pre>
contains routines that correctly handle the copy
protocol.
<pre> int PQgetline(PGconn &#42;conn,
char &#42;string,
int length)
</pre><br>
<DT><B>PQputline</B>
<DD>Sends a null-terminated string to the backend
server.
The application must explicitly send the single
character "." to indicate to the backend that it
has finished sending its data.
<pre> void PQputline(PGconn &#42;conn,
char &#42;string);
</pre><br>
<DT><B>PQendcopy</B>
<DD>Syncs with the backend. This function waits until
the backend has finished the copy. It should
either be issued when the last string has been
sent to the backend using PQputline or when the
last string has been received from the backend
using PGgetline. It must be issued or the backend
may get "out of sync" with the frontend. Upon
return from this function, the backend is ready to
receive the next query.
The return value is 0 on successful completion,
nonzero otherwise.
<pre> int PQendcopy(PGconn &#42;conn);
</pre><br>
As an example:
<pre> PQexec(conn, "create table foo (a int4, b char16, d float8)");
PQexec(conn, "copy foo from stdin");
PQputline(conn, "3&lt;TAB&gt;hello world&lt;TAB&gt;4.5\n");
PQputline(conn,"4&lt;TAB&gt;goodbye world&lt;TAB&gt;7.11\n");
...
PQputline(conn,".\n");
PQendcopy(conn);
</pre><br>
</DL>
<H2><A NAME="tracing-functions">12.7. <B>LIBPQ</B> Tracing Functions</A></H2>
<DL>
<DT><B>PQtrace</B>
<DD>Enable tracing of the frontend/backend communication to a debugging file stream.
<pre> void PQtrace(PGconn &#42;conn
FILE &#42;debug_port)
</pre><br>
<DT><B>PQuntrace</B>
<DD>Disable tracing started by PQtrace
<pre> void PQuntrace(PGconn &#42;conn)
</pre><br>
</DL>
<H2><A NAME="authentication-functions">12.8. User Authentication Functions</A></H2>
If the user has generated the appropriate authentication credentials (e.g., obtaining <B>Kerberos</B> tickets),
the frontend/backend authentication process is handled
by <B>PQexec</B> without any further intervention. The following routines may be called by <B>LIBPQ</B> programs to tailor the behavior of the authentication process.
<DL>
<DT><B>fe_getauthname</B>
<DD>Returns a pointer to static space containing whatever name the user has authenticated. Use of this
routine in place of calls to getenv(3) or getpwuid(3) by applications is highly recommended, as
it is entirely possible that the authenticated
user name is not the same as value of the <B>USER</B>
environment variable or the user's entry in
<CODE>/etc/passwd</CODE>.
<pre> char &#42;fe_getauthname(char&#42; errorMessage)
</pre><br>
<DT><B>fe_setauthsvc</B>
<DD>Specifies that <B>LIBPQ</B> should use authentication
service name rather than its compiled-in default.
<DD>This value is typically taken from a command-line
switch.
<pre> void fe_setauthsvc(char &#42;name,
char&#42; errorMessage)
</pre>
<DD>Any error messages from the authentication
attempts are returned in the errorMessage argument.
</DL>
<H2><A NAME="bugs">12.9. BUGS</A></H2>
The query buffer is 8192 bytes long, and queries over
that length will be silently truncated.
<H2><A NAME="sample-programs">12.10. Sample Programs</H2>
<p>
<H3><A NAME="sample-program-1">12.10.1. Sample Program 1</A></H3>
<pre>
/&#42;
&#42; testlibpq.c
&#42; Test the C version of LIBPQ, the POSTGRES frontend library.
&#42;
&#42;
&#42;/
#include &lt;stdio.h&gt;
#include "libpq-fe.h"
<p>
void
exit_nicely(PGconn&#42; conn)
{
PQfinish(conn);
exit(1);
}
<p>
main()
{
char &#42;pghost, &#42;pgport, &#42;pgoptions, &#42;pgtty;
char&#42; dbName;
int nFields;
int i,j;
<p>
/&#42; FILE &#42;debug; &#42;/
<p>
PGconn&#42; conn;
PGresult&#42; res;
<p>
/&#42; begin, by setting the parameters for a backend connection
if the parameters are null, then the system will try to use
reasonable defaults by looking up environment variables
or, failing that, using hardwired constants &#42;/
pghost = NULL; /&#42; host name of the backend server &#42;/
pgport = NULL; /&#42; port of the backend server &#42;/
pgoptions = NULL; /&#42; special options to start up the backend server &#42;/
pgtty = NULL; /&#42; debugging tty for the backend server &#42;/
dbName = "template1";
<p>
/&#42; make a connection to the database &#42;/
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
<p>
/&#42; check to see that the backend connection was successfully made &#42;/
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr,"Connection to database '&#37;s' failed.0, dbName);
fprintf(stderr,"&#37;s",PQerrorMessage(conn));
exit_nicely(conn);
}
<p>
/&#42; debug = fopen("/tmp/trace.out","w"); &#42;/
/&#42; PQtrace(conn, debug); &#42;/
<p>
/&#42; start a transaction block &#42;/
res = PQexec(conn,"BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr,"BEGIN command failed0);
PQclear(res);
exit_nicely(conn);
}
/&#42; should PQclear PGresult whenever it is no longer needed to avoid
memory leaks &#42;/
PQclear(res);
<p>
/&#42; fetch instances from the pg_database, the system catalog of databases&#42;/
res = PQexec(conn,"DECLARE myportal CURSOR FOR select &#42; from pg_database");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr,"DECLARE CURSOR command failed0);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
<p>
res = PQexec(conn,"FETCH ALL in myportal");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr,"FETCH ALL command didn't return tuples properly0);
PQclear(res);
exit_nicely(conn);
}
<p>
/&#42; first, print out the attribute names &#42;/
nFields = PQnfields(res);
for (i=0; i &lt; nFields; i++) {
printf("&#37;-15s",PQfname(res,i));
}
printf("0);
<p>
/&#42; next, print out the instances &#42;/
for (i=0; i &lt; PQntuples(res); i++) {
for (j=0 ; j &lt; nFields; j++) {
printf("&#37;-15s", PQgetvalue(res,i,j));
}
printf("0);
}
<p>
PQclear(res);
<p>
/&#42; close the portal &#42;/
res = PQexec(conn, "CLOSE myportal");
PQclear(res);
<p>
/&#42; end the transaction &#42;/
res = PQexec(conn, "END");
PQclear(res);
<p>
/&#42; close the connection to the database and cleanup &#42;/
PQfinish(conn);
/&#42; fclose(debug); &#42;/
}
</pre>
<p>
<H3><A NAME="sample-program-2">12.10.2. Sample Program 2</A></H3>
<pre>
/&#42;
&#42; testlibpq2.c
&#42; Test of the asynchronous notification interface
&#42;
populate a database with the following:
<p>
CREATE TABLE TBL1 (i int4);
<p>
CREATE TABLE TBL2 (i int4);
<p>
CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2];
<p>
&#42; Then start up this program
&#42; After the program has begun, do
<p>
INSERT INTO TBL1 values (10);
<p>
&#42;
&#42;
&#42;/
#include &lt;stdio.h&gt;
#include "libpq-fe.h"
<p>
void exit_nicely(PGconn&#42; conn)
{
PQfinish(conn);
exit(1);
}
<p>
main()
{
char &#42;pghost, &#42;pgport, &#42;pgoptions, &#42;pgtty;
char&#42; dbName;
int nFields;
int i,j;
<p>
PGconn&#42; conn;
PGresult&#42; res;
PGnotify&#42; notify;
<p>
/&#42; begin, by setting the parameters for a backend connection
if the parameters are null, then the system will try to use
reasonable defaults by looking up environment variables
or, failing that, using hardwired constants &#42;/
pghost = NULL; /&#42; host name of the backend server &#42;/
pgport = NULL; /&#42; port of the backend server &#42;/
pgoptions = NULL; /&#42; special options to start up the backend server &#42;/
pgtty = NULL; /&#42; debugging tty for the backend server &#42;/
dbName = getenv("USER"); /&#42; change this to the name of your test database&#42;/
<p>
/&#42; make a connection to the database &#42;/
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
/&#42; check to see that the backend connection was successfully made &#42;/
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr,"Connection to database '&#37;s' failed.0, dbName);
fprintf(stderr,"&#37;s",PQerrorMessage(conn));
exit_nicely(conn);
}
<p>
res = PQexec(conn, "LISTEN TBL2");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr,"LISTEN command failed0);
PQclear(res);
exit_nicely(conn);
}
/&#42; should PQclear PGresult whenever it is no longer needed to avoid
memory leaks &#42;/
PQclear(res);
<p>
while (1) {
/&#42; async notification only come back as a result of a query&#42;/
/&#42; we can send empty queries &#42;/
res = PQexec(conn, " ");
/&#42; printf("res-&gt;status = &#37;s0, pgresStatus[PQresultStatus(res)]); &#42;/
/&#42; check for asynchronous returns &#42;/
notify = PQnotifies(conn);
if (notify) {
fprintf(stderr,
"ASYNC NOTIFY of '&#37;s' from backend pid '&#37;d' received0,
notify-&gt;relname, notify-&gt;be_pid);
free(notify);
break;
}
PQclear(res);
}
<p>
/&#42; close the connection to the database and cleanup &#42;/
PQfinish(conn);
<p>
}
</pre>
<p>
<H3><A NAME="sample-program-3">12.10.3. Sample Program 3</A></H3>
<pre>
/&#42;
&#42; testlibpq3.c
&#42; Test the C version of LIBPQ, the POSTGRES frontend library.
&#42; tests the binary cursor interface
&#42;
&#42;
&#42;
populate a database by doing the following:
<p>
CREATE TABLE test1 (i int4, d float4, p polygon);
<p>
INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon);
<p>
INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon);
<p>
the expected output is:
<p>
tuple 0: got
i = (4 bytes) 1,
d = (4 bytes) 3.567000,
p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000)
tuple 1: got
i = (4 bytes) 2,
d = (4 bytes) 89.050003,
p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000)
<p>
&#42;
&#42;/
#include &lt;stdio.h&gt;
#include "libpq-fe.h"
#include "utils/geo-decls.h" /&#42; for the POLYGON type &#42;/
<p>
void exit_nicely(PGconn&#42; conn)
{
PQfinish(conn);
exit(1);
}
<p>
main()
{
char &#42;pghost, &#42;pgport, &#42;pgoptions, &#42;pgtty;
char&#42; dbName;
int nFields;
int i,j;
int i_fnum, d_fnum, p_fnum;
<p>
PGconn&#42; conn;
PGresult&#42; res;
<p>
/&#42; begin, by setting the parameters for a backend connection
if the parameters are null, then the system will try to use
reasonable defaults by looking up environment variables
or, failing that, using hardwired constants &#42;/
pghost = NULL; /&#42; host name of the backend server &#42;/
pgport = NULL; /&#42; port of the backend server &#42;/
pgoptions = NULL; /&#42; special options to start up the backend server &#42;/
pgtty = NULL; /&#42; debugging tty for the backend server &#42;/
<p>
dbName = getenv("USER"); /&#42; change this to the name of your test database&#42;/
<p>
/&#42; make a connection to the database &#42;/
conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName);
<p>
/&#42; check to see that the backend connection was successfully made &#42;/
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr,"Connection to database '&#37;s' failed.0, dbName);
fprintf(stderr,"&#37;s",PQerrorMessage(conn));
exit_nicely(conn);
}
<p>
/&#42; start a transaction block &#42;/
res = PQexec(conn,"BEGIN");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr,"BEGIN command failed0);
PQclear(res);
exit_nicely(conn);
}
/&#42; should PQclear PGresult whenever it is no longer needed to avoid
memory leaks &#42;/
PQclear(res);
<p>
/&#42; fetch instances from the pg_database, the system catalog of databases&#42;/
res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select &#42; from test1");
if (PQresultStatus(res) != PGRES_COMMAND_OK) {
fprintf(stderr,"DECLARE CURSOR command failed0);
PQclear(res);
exit_nicely(conn);
}
PQclear(res);
<p>
res = PQexec(conn,"FETCH ALL in mycursor");
if (PQresultStatus(res) != PGRES_TUPLES_OK) {
fprintf(stderr,"FETCH ALL command didn't return tuples properly0);
PQclear(res);
exit_nicely(conn);
}
<p>
i_fnum = PQfnumber(res,"i");
d_fnum = PQfnumber(res,"d");
p_fnum = PQfnumber(res,"p");
<p>
for (i=0;i&lt;3;i++) {
printf("type[&#37;d] = &#37;d, size[&#37;d] = &#37;d0,
i, PQftype(res,i),
i, PQfsize(res,i));
}
for (i=0; i &lt; PQntuples(res); i++) {
int &#42;ival;
float &#42;dval;
int plen;
POLYGON&#42; pval;
/&#42; we hard-wire this to the 3 fields we know about &#42;/
ival = (int&#42;)PQgetvalue(res,i,i_fnum);
dval = (float&#42;)PQgetvalue(res,i,d_fnum);
plen = PQgetlength(res,i,p_fnum);
<p>
/&#42; plen doesn't include the length field so need to increment by VARHDSZ&#42;/
pval = (POLYGON&#42;) malloc(plen + VARHDRSZ);
pval-&gt;size = plen;
memmove((char&#42;)&amp;pval-&gt;npts, PQgetvalue(res,i,p_fnum), plen);
printf("tuple &#37;d: got0, i);
printf(" i = (&#37;d bytes) &#37;d,0,
PQgetlength(res,i,i_fnum), &#42;ival);
printf(" d = (&#37;d bytes) &#37;f,0,
PQgetlength(res,i,d_fnum), &#42;dval);
printf(" p = (&#37;d bytes) &#37;d points boundbox = (hi=&#37;f/&#37;f, lo = &#37;f,&#37;f)0,
PQgetlength(res,i,d_fnum),
pval-&gt;npts,
pval-&gt;boundbox.xh,
pval-&gt;boundbox.yh,
pval-&gt;boundbox.xl,
pval-&gt;boundbox.yl);
}
<p>
PQclear(res);
<p>
/&#42; close the portal &#42;/
res = PQexec(conn, "CLOSE mycursor");
PQclear(res);
<p>
/&#42; end the transaction &#42;/
res = PQexec(conn, "END");
PQclear(res);
<p>
/&#42; close the connection to the database and cleanup &#42;/
PQfinish(conn);
<p>
}
</pre>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xindex.html">[ Previous ]</A>
<A HREF="lobj.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,429 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - LARGE OBJECTS</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="libpq.html">[ Previous ]</A>
<A HREF="rules.html">[ Next ]</A>
</font>
<HR>
<H1>13. LARGE OBJECTS</H1>
<HR>
In POSTGRES, data values are stored in tuples and
individual tuples cannot span data pages. Since the size of
a data page is 8192 bytes, the upper limit on the size
of a data value is relatively low. To support the storage
of larger atomic values, POSTGRES provides a large
object interface. This interface provides file
oriented access to user data that has been declared to
be a large type.
This section describes the implementation and the
programmatic and query language interfaces to POSTGRES
large object data.
<H2><A NAME="historical-note">13.1. Historical Note</A></H2>
Originally, <B>POSTGRES 4.2</B> supports three standard
implementations of large objects: as files external
to POSTGRES, as <B>UNIX</B> files managed by POSTGRES, and as data
stored within the POSTGRES database. It causes
considerable confusion among users. As a result, we only
support large objects as data stored within the POSTGRES
database in <B>POSTGRES95</B>. Even though is is slower to
access, it provides stricter data integrity and time
travel. For historical reasons, they are called
Inversion large objects. (We will use Inversion and large
objects interchangeably to mean the same thing in this
section.)
<H2><A NAME="inversion-large-objects">13.2. Inversion Large Objects</A></H2>
The Inversion large object implementation breaks large
objects up into "chunks" and stores the chunks in
tuples in the database. A B-tree index guarantees fast
searches for the correct chunk number when doing random
access reads and writes.
<H2><A NAME="large-object-interfaces">13.3. Large Object Interfaces</A></H2>
The facilities POSTGRES provides to access large
objects, both in the backend as part of user-defined
functions or the front end as part of an application
using the interface, are described below. (For users
familiar with <B>POSTGRES 4.2</B>, <B>POSTGRES95</B> has a new set of
functions providing a more coherent interface. The
interface is the same for dynamically-loaded C
functions as well as for .
The POSTGRES large object interface is modeled after
the <B>UNIX</B> file system interface, with analogues of
<B>open(2), read(2), write(2), lseek(2)</B>, etc. User
functions call these routines to retrieve only the data of
interest from a large object. For example, if a large
object type called mugshot existed that stored
photographs of faces, then a function called beard could
be declared on mugshot data. Beard could look at the
lower third of a photograph, and determine the color of
the beard that appeared there, if any. The entire
large object value need not be buffered, or even
examined, by the beard function.
Large objects may be accessed from dynamically-loaded <B>C</B>
functions or database client programs that link the
library. POSTGRES provides a set of routines that
support opening, reading, writing, closing, and seeking on
large objects.
<p>
<H3><A NAME="creating-large-objects">13.3.1. Creating a Large Object</A></H3>
The routine
<pre> Oid lo_creat(PGconn &#42;conn, int mode)
</pre>
creates a new large object. The mode is a bitmask
describing several different attributes of the new
object. The symbolic constants listed here are defined
in
<pre> /usr/local/postgres95/src/backend/libpq/libpq-fs.h
</pre>
The access type (read, write, or both) is controlled by
OR ing together the bits <B>INV_READ</B> and <B>INV_WRITE</B>. If
the large object should be archived -- that is, if
historical versions of it should be moved periodically to
a special archive relation -- then the <B>INV_ARCHIVE</B> bit
should be set. The low-order sixteen bits of mask are
the storage manager number on which the large object
should reside. For sites other than Berkeley, these
bits should always be zero.
The commands below create an (Inversion) large object:
<pre> inv_oid = lo_creat(INV_READ|INV_WRITE|INV_ARCHIVE);
</pre>
<H3><A NAME="importing-a-large-object">13.3.2. Importing a Large Object</A></H3>
To import a <B>UNIX</B> file as
a large object, call
<pre> Oid
lo_import(PGconn &#42;conn, text &#42;filename)
</pre>
The filename argument specifies the <B>UNIX</B> pathname of
the file to be imported as a large object.
<p>
<H3><A NAME="exporting-a-large-object">13.3.3. Exporting a Large Object</A></H3>
To export a large object
into <B>UNIX</B> file, call
<pre> int
lo_export(PGconn &#42;conn, Oid lobjId, text &#42;filename)
</pre>
The lobjId argument specifies the Oid of the large
object to export and the filename argument specifies
the <B>UNIX</B> pathname of the file.
<p>
<H3><A NAME="opening-an-existing-large-object">13.3.4. Opening an Existing Large Object</A></H3>
To open an existing large object, call
<pre> int
lo_open(PGconn &#42;conn, Oid lobjId, int mode, ...)
</pre>
The lobjId argument specifies the Oid of the large
object to open. The mode bits control whether the
object is opened for reading INV_READ), writing or
both.
A large object cannot be opened before it is created.
lo_open returns a large object descriptor for later use
in lo_read, lo_write, lo_lseek, lo_tell, and lo_close.
<p>
<H3><A NAME="writing-data-to-a-large-object">13.3.5. Writing Data to a Large Object</A></H3>
The routine
<pre> int
lo_write(PGconn &#42;conn, int fd, char &#42;buf, int len)
</pre>
writes len bytes from buf to large object fd. The fd
argument must have been returned by a previous lo_open.
The number of bytes actually written is returned. In
the event of an error, the return value is negative.
<p>
<H3><A NAME="seeking-on-a-large-object">13.3.6. Seeking on a Large Object</A></H3>
To change the current read or write location on a large
object, call
<pre> int
lo_lseek(PGconn &#42;conn, int fd, int offset, int whence)
</pre>
This routine moves the current location pointer for the
large object described by fd to the new location specified
by offset. The valid values for .i whence are
SEEK_SET SEEK_CUR and SEEK_END.
<p>
<H3><A NAME="closing-a-large-object-descriptor">13.3.7. Closing a Large Object Descriptor</A></H3>
A large object may be closed by calling
<pre> int
lo_close(PGconn &#42;conn, int fd)
</pre>
where fd is a large object descriptor returned by
lo_open. On success, <B>lo_close</B> returns zero. On error,
the return value is negative.
<H2><A NAME="built-in-registered-functions">13.4. Built in registered functions</A></H2>
There are two built-in registered functions, <B>lo_import</B>
and <B>lo_export</B> which are convenient for use in <B>SQL</B>
queries.
Here is an example of there use
<pre> CREATE TABLE image (
name text,
raster oid
);
INSERT INTO image (name, raster)
VALUES ('beautiful image', lo_import('/etc/motd'));
SELECT lo_export(image.raster, "/tmp/motd") from image
WHERE name = 'beautiful image';
</pre>
<H2><A NAME="accessing-large-objects-from-libpq">13.5. Accessing Large Objects from LIBPQ</A></H2>
Below is a sample program which shows how the large object
interface
in LIBPQ can be used. Parts of the program are
commented out but are left in the source for the readers
benefit. This program can be found in
<pre> ../src/test/examples
</pre>
Frontend applications which use the large object interface
in LIBPQ should include the header file
libpq/libpq-fs.h and link with the libpq library.
<H2><A NAME="sample-program">13.6. Sample Program</A></H2>
<pre> /&#42;--------------------------------------------------------------
&#42;
&#42; testlo.c--
&#42; test using large objects with libpq
&#42;
&#42; Copyright (c) 1994, Regents of the University of California
&#42;
&#42;
&#42; IDENTIFICATION
&#42; /usr/local/devel/pglite/cvs/src/doc/manual.me,v 1.16 1995/09/01 23:55:00 jolly Exp
&#42;
&#42;--------------------------------------------------------------
&#42;/
#include &lt;stdio.h&gt;
#include "libpq-fe.h"
#include "libpq/libpq-fs.h"
<p>
#define BUFSIZE 1024
<p>
/&#42;
&#42; importFile &#42; import file "in_filename" into database as large object "lobjOid"
&#42;
&#42;/
Oid importFile(PGconn &#42;conn, char &#42;filename)
{
Oid lobjId;
int lobj_fd;
char buf[BUFSIZE];
int nbytes, tmp;
int fd;
<p>
/&#42;
&#42; open the file to be read in
&#42;/
fd = open(filename, O_RDONLY, 0666);
if (fd &lt; 0) { /&#42; error &#42;/
fprintf(stderr, "can't open unix file
}
<p>
/&#42;
&#42; create the large object
&#42;/
lobjId = lo_creat(conn, INV_READ|INV_WRITE);
if (lobjId == 0) {
fprintf(stderr, "can't create large object");
}
<p>
lobj_fd = lo_open(conn, lobjId, INV_WRITE);
/&#42;
&#42; read in from the Unix file and write to the inversion file
&#42;/
while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0) {
tmp = lo_write(conn, lobj_fd, buf, nbytes);
if (tmp &lt; nbytes) {
fprintf(stderr, "error while reading
}
}
<p>
(void) close(fd);
(void) lo_close(conn, lobj_fd);
<p>
return lobjId;
}
<p>
void pickout(PGconn &#42;conn, Oid lobjId, int start, int len)
{
int lobj_fd;
char&#42; buf;
int nbytes;
int nread;
<p>
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd &lt; 0) {
fprintf(stderr,"can't open large object &#37;d",
lobjId);
}
<p>
lo_lseek(conn, lobj_fd, start, SEEK_SET);
buf = malloc(len+1);
<p>
nread = 0;
while (len - nread &gt; 0) {
nbytes = lo_read(conn, lobj_fd, buf, len - nread);
buf[nbytes] = ' ';
fprintf(stderr,"&gt;&gt;&gt; &#37;s", buf);
nread += nbytes;
}
fprintf(stderr,"0);
lo_close(conn, lobj_fd);
}
<p>
void overwrite(PGconn &#42;conn, Oid lobjId, int start, int len)
{
int lobj_fd;
char&#42; buf;
int nbytes;
int nwritten;
int i;
<p>
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd &lt; 0) {
fprintf(stderr,"can't open large object &#37;d",
lobjId);
}
<p>
lo_lseek(conn, lobj_fd, start, SEEK_SET);
buf = malloc(len+1);
<p>
for (i=0;i&lt;len;i++)
buf[i] = 'X';
buf[i] = ' ';
<p>
nwritten = 0;
while (len - nwritten &gt; 0) {
nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
nwritten += nbytes;
}
fprintf(stderr,"0);
lo_close(conn, lobj_fd);
}
<p>
/&#42;
&#42; exportFile &#42; export large object "lobjOid" to file "out_filename"
&#42;
&#42;/
void exportFile(PGconn &#42;conn, Oid lobjId, char &#42;filename)
{
int lobj_fd;
char buf[BUFSIZE];
int nbytes, tmp;
int fd;
<p>
/&#42;
&#42; create an inversion "object"
&#42;/
lobj_fd = lo_open(conn, lobjId, INV_READ);
if (lobj_fd &lt; 0) {
fprintf(stderr,"can't open large object &#37;d",
lobjId);
}
<p>
/&#42;
&#42; open the file to be written to
&#42;/
fd = open(filename, O_CREAT|O_WRONLY, 0666);
if (fd &lt; 0) { /&#42; error &#42;/
fprintf(stderr, "can't open unix file
filename);
}
<p>
/&#42;
&#42; read in from the Unix file and write to the inversion file
&#42;/
while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0) {
tmp = write(fd, buf, nbytes);
if (tmp &lt; nbytes) {
fprintf(stderr,"error while writing
filename);
}
}
<p>
(void) lo_close(conn, lobj_fd);
(void) close(fd);
<p>
return;
}
<p>
void
exit_nicely(PGconn&#42; conn)
{
PQfinish(conn);
exit(1);
}
<p>
int
main(int argc, char &#42;&#42;argv)
{
char &#42;in_filename, &#42;out_filename;
char &#42;database;
Oid lobjOid;
PGconn &#42;conn;
PGresult &#42;res;
<p>
if (argc != 4) {
fprintf(stderr, "Usage: &#37;s database_name in_filename out_filename0,
argv[0]);
exit(1);
}
<p>
database = argv[1];
in_filename = argv[2];
out_filename = argv[3];
<p>
/&#42;
&#42; set up the connection
&#42;/
conn = PQsetdb(NULL, NULL, NULL, NULL, database);
<p>
/&#42; check to see that the backend connection was successfully made &#42;/
if (PQstatus(conn) == CONNECTION_BAD) {
fprintf(stderr,"Connection to database '&#37;s' failed.0, database);
fprintf(stderr,"&#37;s",PQerrorMessage(conn));
exit_nicely(conn);
}
<p>
res = PQexec(conn, "begin");
PQclear(res);
printf("importing file
/&#42; lobjOid = importFile(conn, in_filename); &#42;/
lobjOid = lo_import(conn, in_filename);
/&#42;
printf("as large object &#37;d.0, lobjOid);
<p>
printf("picking out bytes 1000-2000 of the large object0);
pickout(conn, lobjOid, 1000, 1000);
<p>
printf("overwriting bytes 1000-2000 of the large object with X's0);
overwrite(conn, lobjOid, 1000, 1000);
&#42;/
<p>
printf("exporting large object to file
/&#42; exportFile(conn, lobjOid, out_filename); &#42;/
lo_export(conn, lobjOid,out_filename);
<p>
res = PQexec(conn, "end");
PQclear(res);
PQfinish(conn);
exit(0);
}
</pre>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="libpq.html">[ Previous ]</A>
<A HREF="rules.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,154 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual</TITLE>
</HEAD>
<BODY>
<H1 align=center>
The <B>
<A HREF="http://s2k-ftp.cs.berkeley.edu:8000/postgres95/">
POSTGRES95</A></B> User Manual</H1>
<p align=CENTER>
Version 1.0 (September 5, 1995)<br><br>
<A HREF="http://s2k-ftp.cs.berkeley.edu:8000/personal/andrew">Andrew Yu</A>
and
<A HREF="http://http.cs.berkeley.edu/~jolly/">Jolly Chen</A><br>
(with the POSTGRES Group)<br>
Computer Science Div., Dept. of EECS<br>
University of California at Berkeley<br>
</p>
<!--#exec cgi="/cgi-bin/wais-pg95.pl"-->
<H1 align=center>Table of Contents</H1>
<DL>
<DT><A HREF="intro.html">1. INTRODUCTION</A>
<DL>
<DT><A HREF="intro.html#a-short-history-of-the-postgres-project">1.1. A Short History of POSTGRES</A>
<DT><A HREF="intro.html#what-is-postgres95">1.2. What is POSTGRES95?</A>
<DT><A HREF="intro.html#about-this-release">1.4. About This Release</A>
<DT><A HREF="intro.html#outline-of-this-manual">1.5. Outline of This Manual</A>
</DL>
<DT><A HREF="architec.html">2. ARCHITECTURE CONCEPTS</A>
<DT><A HREF="start.html">3. GETTING STARTED</A>
<DL>
<DT><A HREF="start.html#setting-up-your-environment">3.1. Setting Up Your Enviroment</A>
<DT><A HREF="start.html#starting-the-postmaster">3.2. Starting The Postmaster</A>
<DT><A HREF="start.html#adding-and-deleting-users">3.3. Adding And Deleting Users</A>
<DT><A HREF="start.html#starting-applications">3.4. Starting Applications</A>
<DT><A HREF="start.html#managing-a-database">3.5. Managing A Database</A>
<DL>
<DT><A HREF="start.html#creating-a-database">3.5.1. Creating A Database</A>
<DT><A HREF="start.html#accesssing-a-database">3.5.2. Accessing A Database</A>
<DT><A HREF="start.html#destroying-a-database">3.5.3. Destroying A Database</A>
</DL>
</DL>
<DT><A HREF="query.html">4. QUERY LANGUAGE</A>
<DL>
<DT><A HREF="query.html#concepts">4.1. Concepts</A>
<DT><A HREF="query.html#creating-a-new-class">4.2. Creating a New Class</A>
<DT><A HREF="query.html#populating-a-class-with-instances">4.3. Populating a Class with Instances</A>
<DT><A HREF="query.html#querying-a-class">4.4. Querying a Class</A>
<DT><A HREF="query.html#redirecting-select-queries">4.5. Redirecting SELECT Queries</A>
</DL>
<DT><A HREF="advanced.html">5. ADVANCED POSTGRES SQL FEATURES</A>
<DL>
<DT><A HREF="advanced.html#inheritance">5.1. Inheritance</A>
<DT><A HREF="advanced.html#time-travel">5.2. Time Travel</A>
<DT><A HREF="advanced.html#non-atomic-values">5.3. Non-Atomic Values</A>
<DL>
<DT><A HREF="advanced.html#arrays">5.3.1. Arrays</A>
</DL>
</DL>
<DT><A HREF="extend.html">6. EXTENDING SQL: AN OVERVIEW</A>
<DL>
<DT><A HREF="extend.html#how-extensibility-works">6.1. How Extensibility Works</A>
<DT><A HREF="extend.html#the-postgres-type-system">6.2. The POSTGRES Type System</A>
<DT><A HREF="extend.html#about-the-postgres-system-catalogs">6.3. About the POSTGRES System Catalogs</A>
</DL>
<DT><A HREF="xfunc.html">7. EXTENDING SQL: FUNCTIONS</A>
<DL>
<DT><A HREF="xfunc.html#query-language-sql-functions">7.1. Query Language (SQL) Functions</A>
<DL>
<DT><A HREF="xfunc.html#sql-functions-on-base-types">7.1.1. SQL Functions on Base Types</A>
</DL>
<DT><A HREF="xfunc.html#programming-language-functions">7.2. Programming Language Functions</A>
<DL>
<DT><A HREF="xfunc.html#programming-language-functions-on-base-types">7.2.1. Programming Language Functions on Base Types</A>
<DT><A HREF="xfunc.html#programming-language-functions-on-composite-types">7.2.2. Programming Language Functions on Composite Types</A>
<DT><A HREF="xfunc.html#caveats">7.2.3. Caveats</A>
</DL>
</DL>
<DT><A HREF="xtypes.html">8. EXTENDING SQL: TYPES</A>
<DL>
<DT><A HREF="xtypes.html#user-defined-types">8.1. User-Defined Types</A>
<DL>
<DT><A HREF="xtypes.html#functions-needed-for-a-user-defined-type">8.1.1. Functions Needed for a User-Defined Type</A>
<DT><A HREF="xtypes.html#large-objects">8.1.2. Large Objects</A>
</DL>
</DL>
<DT><A HREF="xoper.html">9. EXTENDING SQL: OPERATORS</A>
<DL>
</DL>
<DT><A HREF="xaggr.html">10. EXTENDING SQL: AGGREGATES</A>
<DL>
</DL>
<DT><A HREF="xindex.html">11. INTERFACING EXTENSIONS TO INDICES</A>
<DL>
</DL>
<DT><A HREF="libpq.html">12. LIBPQ</A>
<DL>
<DT><A HREF="libpq.html#control-and-initialization">12.1. Control and Initialization</A>
<DT><A HREF="libpq.html#database-connection-functions">12.2. Database Connection Functions</A>
<DT><A HREF="libpq.html#query-execution-functions">12.3. Query Execution Functions</A>
<DT><A HREF="libpq.html#fast-path">12.4. Fast Path</A>
<DT><A HREF="libpq.html#asynchronous-notification">12.5. Asynchronous Notification</A>
<DT><A HREF="libpq.html#functions-associated-with-the-copy-command">12.6. Functions Associated with the COPY Command</A>
<DT><A HREF="libpq.html#tracing-functions">12.7. LIBPQ Tracing Functions</A></A>
<DT><A HREF="libpq.html#authentication-functions">12.8. User Authentication Functions</A>
<DT><A HREF="libpq.html#bugs">12.9. BUGS</A>
<DT><A HREF="libpq.html#sample-programs">12.10. Sample Programs</A>
<DL>
<DT><A HREF="libpq.html#sample-program-1">12.10.1. Sample Program 1</A>
<DT><A HREF="libpq.html#sample-program-2">12.10.2. Sample Program 2</A>
<DT><A HREF="libpq.html#sample-program-3">12.10.3. Sample Program 3</A>
</DL>
</DL>
<DT><A HREF="lobj.html">13. LARGE OBJECTS</A>
<DL>
<DT><A HREF="lobj.html#historical-note">13.1. Historical Note</A>
<DT><A HREF="lobj.html#inversion-large-objects">13.2. Inversion Large Objects</A>
<DT><A HREF="lobj.html#large-object-interfaces">13.3. Large Object Interfaces</A>
<DL>
<DT><A HREF="lobj.html#creating-large-objects">13.3.1. Creating a Large Object</A>
<DT><A HREF="lobj.html#importing-a-large-object">13.3.2. Importing a Large Object</A>
<DT><A HREF="lobj.html#exporting-a-large-object">13.3.3. Exporting a Large Object</A>
<DT><A HREF="lobj.html#opening-an-existing-large-object">13.3.4. Opening an Existing Large Object</A>
<DT><A HREF="lobj.html#writing-data-to-a-large-object">13.3.5. Writing Data to a Large Object</A>
<DT><A HREF="lobj.html#seeking-on-a-large-object">13.3.6. Seeking on a Large Object</A>
<DT><A HREF="lobj.html#closing-a-large-object-descriptor">13.3.7. Closing a Large Object Descriptor</A>
</DL>
<DT><A HREF="lobj.html#built-in-registered-functions">13.4. Built in registered functions</A>
<DT><A HREF="lobj.html#accessing-large-objects-from-libpq">13.5. Accessing Large Objects from LIBPQ</A>
<DT><A HREF="lobj.html#sample-program">13.6. Sample Program</A>
</DL>
<DT><A HREF="rules.html">14. THE POSTGRES RULE SYSTEM</A>
<DT><A HREF="admin.html">15. ADMINISTERING POSTGRES</A>
<DT><A HREF="refs.html">16. REFERENCES</A>
<p>
<DT><A HREF="appenda.html">Appendix A: Linking Dynamically-Loaded Functions</A>
</DL>
<HR>
<A HREF="http://eol.ists.ca/cgi-bin/HyperNews/get/dunlop/pg95-user.html">HyperNews Forum</A> - About this Manual.
<HR>
<p align=center><B>POSTGRES95</B> is <A HREF="copy.html">copyright</A> &copy; 1994-5 by the Regents of the
University of California.<br><br>
Converted to HTML by <a href="http://www.eol.ists.ca/~dunlop/dunlop.html">J. Douglas Dunlop</a>
<a href="mailto:dunlop@eol.ists.ca">&lt;dunlop@eol.ists.ca&gt;</a><br>
The file
<A HREF="http://www.eol.ists.ca/~dunlop/postgres95-manual/pg95user.tgz">
pg95user.tgz</a> contains the complete manual for download.</p>
</BODY>
</HTML>

View File

@ -1,259 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - THE QUERY LANGUAGE</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="start.html">[ Previous ]</A>
<A HREF="advanced.html">[ Next ]</A>
</font>
<HR>
<H1>4. THE QUERY LANGUAGE</H1>
<HR>
The POSTGRES query language is a variant of <B>SQL-3</B>. It
has many extensions such as an extensible type system,
inheritance, functions and production rules. Those are
features carried over from the original POSTGRES query
language, POSTQUEL. This section provides an overview
of how to use POSTGRES <B>SQL</B> to perform simple operations.
This manual is only intended to give you an idea of our
flavor of <B>SQL</B> and is in no way a complete tutorial on
<B>SQL</B>. Numerous books have been written on <B>SQL</B>. For
instance, consult <A HREF="refs.html#MELT93">[MELT93]</A> or
<A HREF="refs.html#DATE93">[DATE93]</A>. You should also
be aware that some features are not part of the <B>ANSI</B>
standard.
In the examples that follow, we assume that you have
created the mydb database as described in the previous
subsection and have started <B>psql</B>.
Examples in this manual can also be found in
<CODE>/usr/local/postgres95/src/tutorial</CODE>. Refer to the
<CODE>README</CODE> file in that directory for how to use them. To
start the tutorial, do the following:
<pre> &#37; cd /usr/local/postgres95/src/tutorial
&#37; psql -s mydb
Welcome to the POSTGRES95 interactive sql monitor:
type \? for help on slash commands
type \q to quit
type \g or terminate with semicolon to execute query
You are currently connected to the database: jolly
mydb=&gt; \i basics.sql
</pre>
The <B>\i</B> command read in queries from the specified
files. The <B>-s</B> option puts you in single step mode which
pauses before sending a query to the backend. Queries
in this section are in the file <CODE>basics.sql</CODE>.
<H2><A NAME="concepts">4.1. Concepts</A></H2>
The fundamental notion in POSTGRES is that of a class,
which is a named collection of object instances. Each
instance has the same collection of named attributes,
and each attribute is of a specific type. Furthermore,
each instance has a permanent <B>object identifier (OID)</B>
that is unique throughout the installation. Because
<B>SQL</B> syntax refers to tables, we will <B>use the terms
table< and class interchangeably</B>. Likewise, a <B>row is an
instance</B> and <B>columns are attributes</B>.
As previously discussed, classes are grouped into
databases, and a collection of databases managed by a
single <B>postmaster</B> process constitutes an installation
or site.
<H2><A NAME="creating-a-new-class">4.2. Creating a New Class</A></H2>
You can create a new class by specifying the class
name, along with all attribute names and their types:
<pre> CREATE TABLE weather (
city varchar(80),
temp_lo int, -- low temperature
temp_hi int, -- high temperature
prcp real, -- precipitation
date date
);
</pre>
Note that keywords are case-insensitive but identifiers
are case-sensitive. POSTGRES <B>SQL</B> supports the usual
<B>SQL</B> types <B>int, float, real, smallint, char(N),
varchar(N), date,</B> and <B>time</B>. As we will
see later, POSTGRES can be customized with an
arbitrary number of
user-defined data types. Consequently, type names are
not keywords.
So far, the POSTGRES create command looks exactly like
the command used to create a table in a traditional
relational system. However, we will presently see that
classes have properties that are extensions of the
relational model.
<H2><A NAME="populating-a-class-with-instances">4.3. Populating a Class with Instances</A></H2>
The <B>insert</B> statement is used to populate a class with
instances:
<pre> INSERT INTO weather
VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')
</pre>
You can also use the <B>copy</B> command to perform load large
amounts of data from flat (<B>ASCII</B>) files.
<H2><A NAME="querying-a-class">4.4. Querying a Class</A></H2>
The weather class can be queried with normal relational
selection and projection queries. A <B>SQL</B> <B>select</B>
statement is used to do this. The statement is divided into
a target list (the part that lists the attributes to be
returned) and a qualification (the part that specifies
any restrictions). For example, to retrieve all the
rows of weather, type:
<pre> SELECT &#42; FROM WEATHER;
</pre>
and the output should be:
<pre>
+--------------+---------+---------+------+------------+
|city | temp_lo | temp_hi | prcp | date |
+--------------+---------+---------+------+------------+
|San Francisco | 46 | 50 | 0.25 | 11-27-1994 |
+--------------+---------+---------+------+------------+
|San Francisco | 43 | 57 | 0 | 11-29-1994 |
+--------------+---------+---------+------+------------+
|Hayward | 37 | 54 | | 11-29-1994 |
+--------------+---------+---------+------+------------+
</pre>
You may specify any aribitrary expressions in the target list. For example, you can do:
<pre> &#42; SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
</pre>
Arbitrary Boolean operators ( <B>and</B>, or and <B>not</B>) are
allowed in the qualification of any query. For example,
<pre> SELECT &#42;
FROM weather
WHERE city = 'San Francisco'
and prcp &gt; 0.0;
+--------------+---------+---------+------+------------+
|city | temp_lo | temp_hi | prcp | date |
+--------------+---------+---------+------+------------+
|San Francisco | 46 | 50 | 0.25 | 11-27-1994 |
+--------------+---------+---------+------+------------+
</pre>
As a final note, you can specify that the results of a
select can be returned in a <B>sorted order</B> or with <B>duplicate instances removed</B>.
<pre> SELECT DISTINCT city
FROM weather
ORDER BY city;
</pre>
<H2><A NAME="redirecting-select-queries">4.5. Redirecting SELECT Queries</A></H2>
Any select query can be redirected to a new class
<pre> SELECT &#42; INTO temp from weather;
</pre>
This creates an implicit create command, creating a new
class temp with the attribute names and types specified
in the target list of the <B>SELECT INTO</B> command. We can
then, of course, perform any operations on the resulting
class that we can perform on other classes.
<H2><A NAME="joins-between-classes">4.6. Joins Between Classes</A></H2>
Thus far, our queries have only accessed one class at a
time. Queries can access multiple classes at once, or
access the same class in such a way that multiple
instances of the class are being processed at the same
time. A query that accesses multiple instances of the
same or different classes at one time is called a join
query.
As an example, say we wish to find all the records that
are in the temperature range of other records. In
effect, we need to compare the temp_lo and temp_hi
attributes of each EMP instance to the temp_lo and
temp_hi attributes of all other EMP instances.<A HREF="#2">2</A> We can
do this with the following query:
<pre> SELECT W1.city, W1.temp_lo, W1.temp_hi,
W2.city, W2.temp_lo, W2.temp_hi
FROM weather W1, weather W2
WHERE W1.temp_lo &lt; W2.temp_lo
and W1.temp_hi &gt; W2.temp_hi;
+--------------+---------+---------+---------------+---------+---------+
|city | temp_lo | temp_hi | city | temp_lo | temp_hi |
+--------------+---------+---------+---------------+---------+---------+
|San Francisco | 43 | 57 | San Francisco | 46 | 50 |
+--------------+---------+---------+---------------+---------+---------+
|San Francisco | 37 | 54 | San Francisco | 46 | 50 |
+--------------+---------+---------+---------------+---------+---------+
</pre>
In this case, both W1 and W2 are surrogates for an
instance of the class weather, and both range over all
instances of the class. (In the terminology of most
database systems, W1 and W2 are known as "range variables.")
A query can contain an arbitrary number of
class names and surrogates.<A HREF="#3">3</A>
<H2><A NAME="updates">4.7. Updates</A></H2>
You can update existing instances using the update command.
Suppose you discover the temperature readings are
all off by 2 degrees as of Nov 28, you may update the
data as follow:
<pre> &#42; UPDATE weather
SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
WHERE date &gt; '11/28/1994;
</pre>
<H2><A NAME="deletions">4.8. Deletions</A></H2>
Deletions are performed using the <B>delete</B> command:
<pre> &#42; DELETE FROM weather WHERE city = 'Hayward';
</pre>
All weather recording belongs to Hayward is removed.
One should be wary of queries of the form
<pre> DELETE FROM classname;
</pre>
Without a qualification, the delete command will simply
delete all instances of the given class, leaving it
empty. The system will not request confirmation before
doing this.
<H2><A NAME="using-aggregate-functions">4.9. Using Aggregate Functions</A></H2>
Like most other query languages, POSTGRES supports
aggregate functions. However, the current
implementation of POSTGRES aggregate functions is very limited.
Specifically, while there are aggregates to compute
such functions as the <B>count, sum, average, maximum</B> and
<B>minimum</B> over a set of instances, aggregates can only
appear in the target list of a query and not in the
qualification ( where clause) As an example,
<pre> SELECT max(temp_lo)
FROM weather;
</pre>
Aggregates may also have <B>GROUP BY</B> clauses:
<pre>
SELECT city, max(temp_lo)
FROM weather
GROUP BY city;
</pre>
<HR>
<A NAME="2"><B>2.</B></A> This is only a conceptual model. The actual join may
be performed in a more efficient manner, but this is invisible to the user.<br>
<A NAME="3"><B>3.</B></A> The semantics of such a join are
that the qualification
is a truth expression defined for the Cartesian product of
the classes indicated in the query. For those instances in
the Cartesian product for which the qualification is true,
POSTGRES computes and returns the values specified in the
target list. POSTGRES <B>SQL</B> does not assign any meaning to
duplicate values in such expressions. This means that POSTGRES
sometimes recomputes the same target list several times
this frequently happens when Boolean expressions are connected
with an or. To remove such duplicates, you must use
the select distinct statement.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="start.html">[ Previous ]</A>
<A HREF="advanced.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,55 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - REFERENCES</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="rules.html">[ Previous ]</A>
<A HREF="appenda.html">[ Next ]</A>
</font>
<HR>
<H1>16. REFERENCES</H1>
<HR>
<DL COMPACT>
<DT><A NAME="DATE93"><B>[DATE93]</B></A><DD>Date, C. J. and Darwen, Hugh, A Guide to The
SQL Standard, 3rd Edition, Reading, MA, June
1993.
<DT><A NAME="MELT93"><B>[MELT93]</B></A><DD>Melton, J. Understanding the New SQL, 1994.
<DT><A NAME="ONG90"><B>[ONG90]</B></A><DD>Ong, L. and Goh, J., ``A Unified Framework
for Version Modeling Using Production Rules
in a Database System," Electronics Research
Laboratory, University of California, ERL
Technical Memorandum M90/33, Berkeley, CA,
April 1990.
<DT><A NAME="ROWE87"><B>[ROWE87]</B></A><DD>Rowe, L. and Stonebraker, M., ``The POSTGRES
Data Model,'' Proc. 1987 VLDB Conference,
Brighton, England, Sept. 1987.
<DT><A NAME="STON86"><B>[STON86]</B></A><DD>Stonebraker, M. and Rowe, L., ``The Design
of POSTGRES,'' Proc. 1986 ACM-SIGMOD Conference on Management of Data, Washington, DC,
May 1986.
<DT><A NAME="STON87a"><B>[STON87a]</B></A><DD>Stonebraker, M., Hanson, E. and Hong, C.-H.,
``The Design of the POSTGRES Rules System,''
Proc. 1987 IEEE Conference on Data Engineering, Los Angeles, CA, Feb. 1987.
<DT><A NAME="STON87b"><B>[STON87b]</B></A><DD>Stonebraker, M., ``The POSTGRES Storage System,'' Proc. 1987 VLDB Conference, Brighton,
England, Sept. 1987.
<DT><A NAME="STON89"><B>[STON89]</B></A><DD>Stonebraker, M., Hearst, M., and Potamianos,
S., ``A Commentary on the POSTGRES Rules
System,'' SIGMOD Record 18(3), Sept. 1989.
<DT><A NAME="STON90a"><B>[STON90a]</B></A><DD>Stonebraker, M., Rowe, L. A., and Hirohama,
M., ``The Implementation of POSTGRES,'' IEEE
Transactions on Knowledge and Data Engineering 2(1), March 1990.
<DT><A NAME="STON90b"><B>[STON90b]</B></A><DD>Stonebraker, M. et al., ``On Rules, Procedures, Caching and Views in Database Systems,'' Proc. 1990 ACM-SIGMOD Conference on
Management of Data, Atlantic City, N.J.,
June 1990.
</DL>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="rules.html">[ Previous ]</A>
<A HREF="appenda.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,43 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - THE POSTGRES RULE SYSTEM</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="lobj.html">[ Previous ]</A>
<A HREF="admin.html">[ Next ]</A>
</font>
<HR>
<H1>14. THE POSTGRES RULE SYSTEM
</H1><HR>
Production rule systems are conceptually simple, but
there are many subtle points involved in actually using
them. Consequently, we will not attempt to explain the
actual syntax and operation of the POSTGRES rule system
here. Instead, you should read <A HREF="refs.html#STON90b">[STON90b]</A> to understand
some of these points and the theoretical foundations of
the POSTGRES rule system before trying to use rules.
The discussion in this section is intended to provide
an overview of the POSTGRES rule system and point the
user at helpful references and examples.
The "query rewrite" rule system modifies queries to
take rules into consideration, and then passes the modified
query to the query optimizer for execution. It
is very powerful, and can be used for many things such
as query language procedures, views, and versions. The
power of this rule system is discussed in
<A HREF="refs.html#ONG90">[ONG90]</A> as
well as <A HREF="refs.html#STON90b">[STON90b]</A>.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="lobj.html">[ Previous ]</A>
<A HREF="admin.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,231 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - GETTING STARTED</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="architec.html">[ Previous ]</A>
<A HREF="query.html">[ Next ]</A>
</font>
<HR>
<H1>3. GETTING STARTED WITH POSTGRES</H1>
<HR>
This section discusses how to start POSTGRES and set up
your own environment so that you can use frontend
applications. We assume POSTGRES has already been
successfully installed. (Refer to the installation notes
for how to install POSTGRES.)
<p>
Some of the steps listed in this section will apply to
all POSTGRES users, and some will apply primarily to
the site database administrator. This site administrator
is the person who installed the software, created
the database directories and started the <B>postmaster</B>
process. This person does not have to be the UNIX
superuser, "root," or the computer system administrator.
In this section, items for end users are labelled
"User" and items intended for the site administrator
are labelled "Admin."
Throughout this manual, any examples that begin with
the character ``&#37;'' are commands that should be typed
at the UNIX shell prompt. Examples that begin with the
character ``&#42;'' are commands in the POSTGRES query
language, POSTGRES <B>SQL</B>.
<H2><A NAME="setting-up-your-environment">3.1. Admin/User: Setting Up Your Environment</A></H2>
<IMG SRC="figure02.gif" ALT="Figure 2. POSTGRES file layout.">
Figure 2. shows how the POSTGRES distribution is laid
out when installed in the default way. For simplicity,
we will assume that POSTGRES has been installed in the
directory /usr/local/postgres95. Therefore, wherever
you see the directory /usr/local/postgres95 you should
substitute the name of the directory where POSTGRES is
actually installed.
All POSTGRES commands are installed in the directory
/usr/local/postgres95/bin. Therefore, you should add
this directory to your shell command path. If you use
a variant of the Berkeley C shell, such as csh or tcsh,
you would add
<pre> &#37; set path = ( /usr/local/postgres95/bin &#36;path )
</pre>
in the .login file in your home directory. If you use
a variant of the Bourne shell, such as sh, ksh, or
bash, then you would add
<pre>
&#37; PATH=/usr/local/postgres95/bin:&#36;PATH
&#37; export PATH
</pre>
to the .profile file in your home directory.
From now on, we will assume that you have added the
POSTGRES bin directory to your path. In addition, we
will make frequent reference to "setting a shell
variable" or "setting an environment variable" throughout
this document. If you did not fully understand the
last paragraph on modifying your search path, you
should consult the UNIX manual pages that describe your
shell before going any further.
<H2><A NAME="starting-the-postmaster">3.2. Admin: Starting the <B>Postmaster</A></B></H2>
It should be clear from the preceding discussion that
nothing can happen to a database unless the <B>postmaster</B>
process is running. As the site administrator, there
are a number of things you should remember before
starting the <B>postmaster</B>. These are discussed in the
section of this manual titled, "Administering POSTGRES."
However, if POSTGRES has been installed by following
the installation instructions exactly as written, the
following simple command is all you should
need to start the <B>postmaster</B>:
<pre> &#37; postmaster &amp;
</pre>
The <B>postmaster</B> occasionally prints out messages which
are often helpful during troubleshooting. If you wish
to view debugging messages from the <B>postmaster</B>, you can
start it with the -d option and redirect the output to
the log file:
<pre> &#37; postmaster -d &gt;&amp; pm.log &amp;
</pre>
If you do not wish to see these messages, you can type
<pre> &#37; postmaster -S
</pre>
and the <B>postmaster</B> will be "S"ilent. Notice that there
is no ampersand ("&amp;") at the end of the last example.
<H2><A NAME="adding-and-deleting-users">3.3. Admin: Adding and Deleting Users</A></H2>
The createuser command enables specific users to access
POSTGRES. The destroyuser command removes users and
prevents them from accessing POSTGRES. Note that these
commands only affect users with respect to POSTGRES;
they have no effect administration of users that the
operating system manages.
<H2><A NAME="starting-applications">3.4. User: Starting Applications</A></H2>
Assuming that your site administrator has properly
started the <B>postmaster</B> process and authorized you to
use the database, you (as a user) may begin to start up
applications. As previously mentioned, you should add
/usr/local/postgres95/bin to your shell search path.
In most cases, this is all you should have to do in
terms of preparation.<A HREF="#1">1</A>
If you get the following error message from a POSTGRES
command (such as <B>psql</B> or createdb):
<pre> connectDB() failed: Is the postmaster running at 'localhost' on port '4322'?
</pre>
it is usually because (1) the <B>postmaster</B> is not running, or (2) you are attempting to connect to the wrong
server host.
If you get the following error message:
<pre> FATAL 1:Feb 17 23:19:55:process userid (2360) !=
database owner (268)
</pre>
it means that the site administrator started the <B>postmaster</B> as the wrong user. Tell him to restart it as
the POSTGRES superuser.
<H2><A NAME="managing-a-database">3.5. User: Managing a Database</A></H2>
Now that POSTGRES is up and running we can create some
databases to experiment with. Here, we describe the
basic commands for managing a database.
<H3><A NAME="creating-a-database">3.5.1. Creating a Database</A></H3>
Let's say you want to create a database named mydb.
You can do this with the following command:
<pre> &#37; createdb mydb
</pre>
POSTGRES allows you to create any number of databases
at a given site and you automatically become the
database administrator of the database you just created. Database names must have an alphabetic first
character and are limited to 16 characters in length.
Not every user has authorization to become a database
administrator. If POSTGRES refuses to create databases
for you, then the site administrator needs to grant you
permission to create databases. Consult your site
administrator if this occurs.
<H3><A NAME="accessing-a-database">3.5.2. Accessing a Database</A></H3>
Once you have constructed a database, you can access it
by:
<UL>
<LI>running the POSTGRES terminal monitor programs (
monitor or <B>psql</B>) which allows you to interactively
enter, edit, and execute <B>SQL</B> commands.
<LI>writing a C program using the LIBPQ subroutine
library. This allows you to submit <B>SQL</B> commands
from C and get answers and status messages back to
your program. This interface is discussed further
in section ??.
</UL>
You might want to start up <B>psql</B>, to try out the examples in this manual. It can be activated for the mydb
database by typing the command:
<pre> &#37; psql mydb
</pre>
You will be greeted with the following message:
<pre> Welcome to the POSTGRES95 interactive sql monitor:
type \? for help on slash commands
type \q to quit
type \g or terminate with semicolon to execute query
You are currently connected to the database: mydb
mydb=&gt;
</pre> This prompt indicates that the terminal monitor is listening to you and that you can type <B>SQL</B> queries into a
workspace maintained by the terminal monitor.
The <B>psql</B> program responds to escape codes that begin
with the backslash character, "\". For example, you
can get help on the syntax of various POSTGRES <B>SQL</B> commands by typing:
<pre> mydb=&gt; \h
</pre>
Once you have finished entering your queries into the
workspace, you can pass the contents of the workspace
to the POSTGRES server by typing:
<pre> mydb=&gt; \g
</pre>
This tells the server to process the query. If you
terminate your query with a semicolon, the \g is not
necessary. <B>psql</B> will automatically process semicolon terminated queries.
To read queries from a file, say myFile, instead of
entering them interactively, type:
<pre> mydb=&gt; \i fileName
</pre>
To get out of <B>psql</B> and return to UNIX, type
<pre> mydb=&gt; \q
</pre>
and <B>psql</B> will quit and return you to your command
shell. (For more escape codes, type \h at the monitor
prompt.)
White space (i.e., spaces, tabs and newlines) may be
used freely in <B>SQL</B> queries. Comments are denoted by
<b>--</b>. Everything after the dashes up to the end of the
line is ignored.
<H3><A NAME="detroying-a-database">3.5.3. Destroying a Database</A></H3>
If you are the database administrator for the database
mydb, you can destroy it using the following UNIX command:
<pre> &#37; destroydb mydb
</pre>
This action physically removes all of the UNIX files
associated with the database and cannot be undone, so
this should only be done with a great deal of fore-thought.
<p>
<HR>
<A NAME="1"><B>1.</B></A> If your site administrator has not set things up in the
default way, you may have some more work to do. For example, if the database server machine is a remote machine, you
will need to set the <B>PGHOST</B> environment variable to the name
of the database server machine. The environment variable
<B>PGPORT</B> may also have to be set. The bottom line is this: if
you try to start an application program and it complains
that it cannot connect to the <B>postmaster</B>, you should immediately consult your site administrator to make sure that your
environment is properly set up.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="architec.html">[ Previous ]</A>
<A HREF="query.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,109 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - EXTENDING SQL: AGGREGATES</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xoper.html">[ Previous ]</A>
<A HREF="xindex.html">[ Next ]</A>
</font>
<HR>
<H1>10. EXTENDING SQL: AGGREGATES</H1>
<HR>
Aggregates in POSTGRES are expressed in terms of state
transition functions. That is, an aggregate can be
defined in terms of state that is modified whenever an
instance is processed. Some state functions look at a
particular value in the instance when computing the new
state (<B>sfunc1</B> in the create aggregate syntax) while
others only keep track of their own internal state
(<B>sfunc2</B>).
If we define an aggregate that uses only <B>sfunc1</B>, we
define an aggregate that computes a running function of
the attribute values from each instance. "Sum" is an
example of this kind of aggregate. "Sum" starts at
zero and always adds the current instance's value to
its running total. We will use the <B>int4pl</B> that is
built into POSTGRES to perform this addition.
<pre> CREATE AGGREGATE complex_sum (
sfunc1 = complex_add,
basetype = complex,
stype1 = complex,
initcond1 = '(0,0)'
);
SELECT complex_sum(a) FROM test_complex;
+------------+
|complex_sum |
+------------+
|(34,53.9) |
+------------+
</pre>
If we define only <B>sfunc2</B>, we are specifying an aggregate
that computes a running function that is independent of
the attribute values from each instance.
"Count" is the most common example of this kind of
aggregate. "Count" starts at zero and adds one to its
running total for each instance, ignoring the instance
value. Here, we use the built-in <B>int4inc</B> routine to do
the work for us. This routine increments (adds one to)
its argument.
<pre> CREATE AGGREGATE my_count (sfunc2 = int4inc, -- add one
basetype = int4, stype2 = int4,
initcond2 = '0')
SELECT my_count(&#42;) as emp_count from EMP;
+----------+
|emp_count |
+----------+
|5 |
+----------+
</pre>
"Average" is an example of an aggregate that requires
both a function to compute the running sum and a function
to compute the running count. When all of the
instances have been processed, the final answer for the
aggregate is the running sum divided by the running
count. We use the <B>int4pl</B> and <B>int4inc</B> routines we used
before as well as the POSTGRES integer division
routine, <B>int4div</B>, to compute the division of the sum by
the count.
<pre> CREATE AGGREGATE my_average (sfunc1 = int4pl, -- sum
basetype = int4,
stype1 = int4,
sfunc2 = int4inc, -- count
stype2 = int4,
finalfunc = int4div, -- division
initcond1 = '0',
initcond2 = '0')
SELECT my_average(salary) as emp_average FROM EMP;
+------------+
|emp_average |
+------------+
|1640 |
+------------+
</pre>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xoper.html">[ Previous ]</A>
<A HREF="xindex.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,474 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - EXTENDING SQL: FUNCTIONS</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="extend.html">[ Previous ]</A>
<A HREF="xtypes.html">[ Next ]</A>
</font>
<HR>
<H1>7. EXTENDING <B>SQL</B>: FUNCTIONS</H1>
<HR>
As it turns out, part of defining a new type is the
definition of functions that describe its behavior.
Consequently, while it is possible to define a new
function without defining a new type, the reverse is
not true. We therefore describe how to add new functions
to POSTGRES before describing how to add new
types.
POSTGRES <B>SQL</B> provides two types of functions: query
language functions (functions written in <B>SQL</B> and
programming language functions (functions written in a
compiled programming language such as <B>C</B>.) Either kind
of function can take a base type, a composite type or
some combination as arguments (parameters). In addition,
both kinds of functions can return a base type or
a composite type. It's easier to define <B>SQL</B> functions,
so we'll start with those.
Examples in this section can also be found in <CODE>funcs.sql</CODE>
and <CODE>C-code/funcs.c</CODE>.
<p>
<H2><A NAME="query-language-sql-functions">7.1. Query Language (<B>SQL</B>) Functions</A></H2>
<H3><A NAME="sql-functions-on-base-types">7.1.1. <B>SQL</B> Functions on Base Types</A></H3>
The simplest possible <B>SQL</B> function has no arguments and
simply returns a base type, such as <B>int4</B>:
<pre> CREATE FUNCTION one() RETURNS int4
AS 'SELECT 1 as RESULT' LANGUAGE 'sql';
SELECT one() AS answer;
+-------+
|answer |
+-------+
|1 |
+-------+
</pre>
Notice that we defined a target list for the function
(with the name RESULT), but the target list of the
query that invoked the function overrode the function's
target list. Hence, the result is labelled answer
instead of one.
<p>
It's almost as easy to define <B>SQL</B> functions that take
base types as arguments. In the example below, notice
how we refer to the arguments within the function as &#36;1
and &#36;2.
<pre> CREATE FUNCTION add_em(int4, int4) RETURNS int4
AS 'SELECT &#36;1 + &#36;2;' LANGUAGE 'sql';
SELECT add_em(1, 2) AS answer;
+-------+
|answer |
+-------+
|3 |
+-------+
</pre>
<H3>7.1.2. <B>SQL</B> Functions on Composite Types</H3>
When specifying functions with arguments of composite
types (such as EMP), we must not only specify which
argument we want (as we did above with &#36;1 and &#36;2) but
also the attributes of that argument. For example,
take the function double_salary that computes what your
salary would be if it were doubled.
<pre> CREATE FUNCTION double_salary(EMP) RETURNS int4
AS 'SELECT &#36;1.salary &#42; 2 AS salary;' LANGUAGE 'sql';
SELECT name, double_salary(EMP) AS dream
FROM EMP
WHERE EMP.dept = 'toy';
+-----+-------+
|name | dream |
+-----+-------+
|Sam | 2400 |
+-----+-------+
</pre>
Notice the use of the syntax &#36;1.salary.
Before launching into the subject of functions that
return composite types, we must first introduce the
function notation for projecting attributes. The simple way
to explain this is that we can usually use the
notation attribute(class) and class.attribute interchangably.
<pre> --
-- this is the same as:
-- SELECT EMP.name AS youngster FROM EMP WHERE EMP.age &lt; 30
--
SELECT name(EMP) AS youngster
FROM EMP
WHERE age(EMP) &lt; 30;
+----------+
|youngster |
+----------+
|Sam |
+----------+
</pre>
As we shall see, however, this is not always the case.
This function notation is important when we want to use
a function that returns a single instance. We do this
by assembling the entire instance within the function,
attribute by attribute. This is an example of a function
that returns a single EMP instance:
<pre> CREATE FUNCTION new_emp() RETURNS EMP
AS 'SELECT \'None\'::text AS name,
1000 AS salary,
25 AS age,
\'none\'::char16 AS dept;'
LANGUAGE 'sql';
</pre>
In this case we have specified each of the attributes
with a constant value, but any computation or expression
could have been substituted for these constants.
Defining a function like this can be tricky. Some of
the more important caveats are as follows:
<UL>
<LI>The target list order must be exactly the same as
that in which the attributes appear in the <B>CREATE
TABLE</B> statement (or when you execute a .&#42; query).
<LI>You must be careful to typecast the expressions
(using ::) very carefully or you will see the following error:
<pre> WARN::function declared to return type EMP does not retrieve (EMP.&#42;)
</pre>
<LI>When calling a function that returns an instance, we
cannot retrieve the entire instance. We must either
project an attribute out of the instance or pass the
entire instance into another function.
<pre> SELECT name(new_emp()) AS nobody;
+-------+
|nobody |
+-------+
|None |
+-------+
</pre>
<LI>The reason why, in general, we must use the function
syntax for projecting attributes of function return
values is that the parser just doesn't understand
the other (dot) syntax for projection when combined
with function calls.
<pre> SELECT new_emp().name AS nobody;
WARN:parser: syntax error at or near "."
</pre>
</UL>
Any collection of commands in the <B>SQL</B> query language
can be packaged together and defined as a function.
The commands can include updates (i.e., <B>insert</B>, <B>update</B>
and <B>delete</B>) as well as <B>select</B> queries. However, the
final command must be a <B>select</B> that returns whatever is
specified as the function's returntype.
<pre>
CREATE FUNCTION clean_EMP () RETURNS int4
AS 'DELETE FROM EMP WHERE EMP.salary &lt;= 0;
SELECT 1 AS ignore_this'
LANGUAGE 'sql';
SELECT clean_EMP();
+--+
|x |
+--+
|1 |
+--+
</pre>
<p>
<H2><A NAME="programming-language-functions">7.2. Programming Language Functions</A></H2>
<H3><A NAME="programming-language-functions-on-base-types">7.2.1. Programming Language Functions on Base Types</A></H3>
Internally, POSTGRES regards a base type as a "blob of
memory." The user-defined functions that you define
over a type in turn define the way that POSTGRES can
operate on it. That is, POSTGRES will only store and
retrieve the data from disk and use your user-defined
functions to input, process, and output the data.
Base types can have one of three internal formats:
<UL>
<LI>pass by value, fixed-length
<LI>pass by reference, fixed-length
<LI>pass by reference, variable-length
</UL>
By-value types can only be 1, 2 or 4 bytes in length
(even if your computer supports by-value types of other
sizes). POSTGRES itself only passes integer types by
value. You should be careful to define your types such
that they will be the same size (in bytes) on all
architectures. For example, the <B>long</B> type is dangerous
because it is 4 bytes on some machines and 8 bytes on
others, whereas <B>int</B> type is 4 bytes on most <B>UNIX</B>
machines (though not on most personal computers). A
reasonable implementation of the <B>int4</B> type on <B>UNIX</B>
machines might be:
<pre> /&#42; 4-byte integer, passed by value &#42;/
typedef int int4;
</pre>
On the other hand, fixed-length types of any size may
be passed by-reference. For example, here is a sample
implementation of the POSTGRES char16 type:
<pre> /&#42; 16-byte structure, passed by reference &#42;/
typedef struct {
char data[16];
} char16;
</pre>
Only pointers to such types can be used when passing
them in and out of POSTGRES functions.
Finally, all variable-length types must also be passed
by reference. All variable-length types must begin
with a length field of exactly 4 bytes, and all data to
be stored within that type must be located in the memory
immediately following that length field. The
length field is the total length of the structure
(i.e., it includes the size of the length field
itself). We can define the text type as follows:
<pre> typedef struct {
int4 length;
char data[1];
} text;
</pre>
Obviously, the data field is not long enough to hold
all possible strings -- it's impossible to declare such
a structure in <B>C</B>. When manipulating variable-length
types, we must be careful to allocate the correct
amount of memory and initialize the length field. For
example, if we wanted to store 40 bytes in a text
structure, we might use a code fragment like this:
<pre> #include "postgres.h"
#include "utils/palloc.h"
...
char buffer[40]; /&#42; our source data &#42;/
...
text &#42;destination = (text &#42;) palloc(VARHDRSZ + 40);
destination-&gt;length = VARHDRSZ + 40;
memmove(destination-&gt;data, buffer, 40);
...
</pre>
Now that we've gone over all of the possible structures
for base types, we can show some examples of real functions.
Suppose <CODE>funcs.c</CODE> look like:
<pre> #include &lt;string.h&gt;
#include "postgres.h" /&#42; for char16, etc. &#42;/
#include "utils/palloc.h" /&#42; for palloc &#42;/
int
add_one(int arg)
{
return(arg + 1);
}
char16 &#42;
concat16(char16 &#42;arg1, char16 &#42;arg2)
{
char16 &#42;new_c16 = (char16 &#42;) palloc(sizeof(char16));
memset((void &#42;) new_c16, 0, sizeof(char16));
(void) strncpy(new_c16, arg1, 16);
return (char16 &#42;)(strncat(new_c16, arg2, 16));
}
<p>
text &#42;
copytext(text &#42;t)
{
/&#42;
&#42; VARSIZE is the total size of the struct in bytes.
&#42;/
text &#42;new_t = (text &#42;) palloc(VARSIZE(t));
<p>
memset(new_t, 0, VARSIZE(t));
<p>
VARSIZE(new_t) = VARSIZE(t);
/&#42;
&#42; VARDATA is a pointer to the data region of the struct.
&#42;/
memcpy((void &#42;) VARDATA(new_t), /&#42; destination &#42;/
(void &#42;) VARDATA(t), /&#42; source &#42;/
VARSIZE(t)-VARHDRSZ); /&#42; how many bytes &#42;/
<p>
return(new_t);
}
</pre>
On <B>OSF/1</B> we would type:
<pre> CREATE FUNCTION add_one(int4) RETURNS int4
AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
CREATE FUNCTION concat16(char16, char16) RETURNS char16
AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
CREATE FUNCTION copytext(text) RETURNS text
AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
</pre>
On other systems, we might have to make the filename
end in .sl (to indicate that it's a shared library).
<p>
<H3><A NAME="programming-language-functions-on-composite-types">7.2.2. Programming Language Functions on Composite Types</A></H3>
Composite types do not have a fixed layout like C
structures. Instances of a composite type may contain
null fields. In addition, composite types that are
part of an inheritance hierarchy may have different
fields than other members of the same inheritance hierarchy.
Therefore, POSTGRES provides a procedural
interface for accessing fields of composite types from
C.
As POSTGRES processes a set of instances, each instance
will be passed into your function as an opaque structure of type <B>TUPLE</B>.
Suppose we want to write a function to answer the query
<pre> &#42; SELECT name, c_overpaid(EMP, 1500) AS overpaid
FROM EMP
WHERE name = 'Bill' or name = 'Sam';
</pre>
In the query above, we can define c_overpaid as:
<pre> #include "postgres.h" /&#42; for char16, etc. &#42;/
#include "libpq-fe.h" /&#42; for TUPLE &#42;/
<p>
bool
c_overpaid(TUPLE t,/&#42; the current instance of EMP &#42;/
int4 limit)
{
bool isnull = false;
int4 salary;
<p>
salary = (int4) GetAttributeByName(t, "salary", &amp;isnull);
<p>
if (isnull)
return (false);
return(salary &gt; limit);
}
</pre>
<B>GetAttributeByName</B> is the POSTGRES system function that
returns attributes out of the current instance. It has
three arguments: the argument of type TUPLE passed into
the function, the name of the desired attribute, and a
return parameter that describes whether the attribute
is null. <B>GetAttributeByName</B> will align data properly
so you can cast its return value to the desired type.
For example, if you have an attribute name which is of
the type char16, the <B>GetAttributeByName</B> call would look
like:
<pre> char &#42;str;
...
str = (char &#42;) GetAttributeByName(t, "name", &amp;isnull)
</pre>
The following query lets POSTGRES know about the
c_overpaid function:
<pre> &#42; CREATE FUNCTION c_overpaid(EMP, int4) RETURNS bool
AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
</pre>
While there are ways to construct new instances or modify
existing instances from within a C function, these
are far too complex to discuss in this manual.
<p>
<H3><A NAME="caveats">7.2.3. Caveats</A></H3>
We now turn to the more difficult task of writing
programming language functions. Be warned: this section
of the manual will not make you a programmer. You must
have a good understanding of <B>C</B> (including the use of
pointers and the malloc memory manager) before trying
to write <B>C</B> functions for use with POSTGRES.
While it may be possible to load functions written in
languages other than <B>C</B> into POSTGRES, this is often
difficult (when it is possible at all) because other
languages, such as <B>FORTRAN</B> and <B>Pascal</B> often do not follow
the same "calling convention" as <B>C</B>. That is, other
languages do not pass argument and return values
between functions in the same way. For this reason, we
will assume that your programming language functions
are written in <B>C</B>.
The basic rules for building <B>C</B> functions are as follows:
<OL>
<LI> Most of the header (include) files for POSTGRES
should already be installed in
/usr/local/postgres95/include (see Figure 2).
You should always include
<pre> -I/usr/local/postgres95/include
</pre>
on your cc command lines. Sometimes, you may
find that you require header files that are in
the server source itself (i.e., you need a file
we neglected to install in include). In those
cases you may need to add one or more of
<pre>
-I/usr/local/postgres95/src/backend
-I/usr/local/postgres95/src/backend/include
-I/usr/local/postgres95/src/backend/port/&lt;PORTNAME&gt;
-I/usr/local/postgres95/src/backend/obj
</pre>
(where &lt;PORTNAME&gt; is the name of the port, e.g.,
alpha or sparc).
<LI> When allocating memory, use the POSTGRES
routines palloc and pfree instead of the
corresponding <B>C</B> library routines malloc and free.
The memory allocated by palloc will be freed
automatically at the end of each transaction,
preventing memory leaks.
<LI> Always zero the bytes of your structures using
memset or bzero. Several routines (such as the
hash access method, hash join and the sort algorithm)
compute functions of the raw bits contained in
your structure. Even if you initialize all fields
of your structure, there may be
several bytes of alignment padding (holes in the
structure) that may contain garbage values.
<LI> Most of the internal POSTGRES types are declared
in postgres.h, so it's usually a good idea to
include that file as well.
<LI> Compiling and loading your object code so that
it can be dynamically loaded into POSTGRES
always requires special flags. See Appendix A
for a detailed explanation of how to do it for
your particular operating system.
</OL>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="extend.html">[ Previous ]</A>
<A HREF="xtypes.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,430 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - THE QUERY LANGUAGE</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xaggr.html">[ Previous ]</A>
<A HREF="libpq.html">[ Next ]</A>
</font>
<HR>
<H1>11. INTERFACING EXTENSIONS TO INDICES</H1>
<HR>
The procedures described thus far let you define a new
type, new functions and new operators. However, we
cannot yet define a secondary index (such as a <B>B-tree</B>,
<B>R-tree</B> or hash access method) over a new type or its
operators.<p>
<A HREF="extend.html#about-the-postgres-system-catalogs">Look back at Figure 3</A>.
The right half shows the catalogs
that we must modify in order to tell POSTGRES how
to use a user-defined type and/or user-defined operators
with an index (i.e., <CODE>pg_am, pg_amop, pg_amproc</CODE> and
<CODE>pg_opclass</CODE>). Unfortunately, there is no simple command
to do this. We will demonstrate how to modify these
catalogs through a running example: a new operator
class for the <B>B-tree</B> access method that sorts integers
in ascending absolute value order.<p>
The <CODE>pg_am</CODE> class contains one instance for every user
defined access method. Support for the heap access
method is built into POSTGRES, but every other access
method is described here. The schema is
<p>
<center>
<table border=1>
<tr>
<td>amname </td><td> name of the access method </td>
</tr>
<td>amowner </td><td> object id of the owner's instance in pg_user </td>
</tr>
<tr>
<td>amkind </td><td> not used at present, but set to 'o' as a place holder </td>
</tr>
<tr>
<td>amstrategies </td><td> number of strategies for this access method (see below) </td>
</tr>
<tr>
<td>amsupport </td><td> number of support routines for this access method (see below) </td>
</tr>
<tr>
<td>amgettuple<br>
aminsert<br>
...</td>
<td>procedure identifiers for interface routines to the access
method. For example, regproc ids for opening, closing, and
getting instances from the access method appear here. </td>
</tr>
</table>
</center>
<p>
The <B>object ID</B> of the instance in <CODE>pg_am</CODE> is used as a
foreign key in lots of other classes. You don't need
to add a new instance to this class; all you're interested in
is the <B>object ID</B> of the access method instance
you want to extend:
<pre> SELECT oid FROM pg_am WHERE amname = 'btree'
+----+
|oid |
+----+
|403 |
+----+
</pre>
The <CODE>amstrategies</CODE> attribute exists to standardize
comparisons across data types. For example, <B>B-tree</B>s
impose a strict ordering on keys, lesser to greater.
Since POSTGRES allows the user to define operators,
POSTGRES cannot look at the name of an operator (eg, &gt;
or &lt;) and tell what kind of comparison it is. In fact,
some access methods don't impose any ordering at all.
For example, <B>R-tree</B>s express a rectangle-containment
relationship, whereas a hashed data structure expresses
only bitwise similarity based on the value of a hash
function. POSTGRES needs some consistent way of taking
a qualification in your query, looking at the operator
and then deciding if a usable index exists. This
implies that POSTGRES needs to know, for example, that
the &lt;= and &gt; operators partition a <B>B-tree</B>. POSTGRES
uses strategies to express these relationships between
operators and the way they can be used to scan indices.<p>
Defining a new set of strategies is beyond the scope of
this discussion, but we'll explain how <B>B-tree</B> strategies
work because you'll need to know that to add a new
operator class. In the <CODE>pg_am</CODE> class, the amstrategies
attribute is the number of strategies defined for this
access method. For <B>B-tree</B>s, this number is 5. These
strategies correspond to
<p>
<center>
<table border=1>
<tr>
<td>less than </td><td> 1 </td>
</tr>
<tr>
<td>less than or equal </td><td> 2 </td>
</tr>
<tr>
<td>equal </td><td> 3 </td>
</tr>
<tr>
<td>greater than or equal </td><td> 4 </td>
</tr>
<tr>
<td>greater than </td><td> 5 </td>
</tr>
</table>
</center>
<p>
The idea is that you'll need to add procedures corresponding
to the comparisons above to the <CODE>pg_amop</CODE> relation
(see below). The access method code can use these
strategy numbers, regardless of data type, to figure
out how to partition the <B>B-tree</B>, compute selectivity,
and so on. Don't worry about the details of adding
procedures yet; just understand that there must be a
set of these procedures for <CODE>int2, int4, oid,</CODE> and every
other data type on which a <B>B-tree</B> can operate.
<p>
Sometimes, strategies aren't enough information for the
system to figure out how to use an index. Some access
methods require other support routines in order to
work. For example, the <B>B-tree</B> access method must be
able to compare two keys and determine whether one is
greater than, equal to, or less than the other.
Similarly, the <B>R-tree</B> access method must be able to compute
intersections, unions, and sizes of rectangles. These
operations do not correspond to user qualifications in
SQL queries; they are administrative routines used by
the access methods, internally.<p>
In order to manage diverse support routines
consistently across all POSTGRES access methods, <CODE>pg_am</CODE>
includes an attribute called <CODE>amsupport</CODE>. This attribute
records the number of support routines used by an
access method. For <B>B-tree</B>s, this number is one -- the
routine to take two keys and return -1, 0, or +1,
depending on whether the first key is less than, equal
to, or greater than the second.<A HREF="#8"><font size=-1>[8]</font></A><p>
The <CODE>amstrategies</CODE> entry in pg_am is just the number of
strategies defined for the access method in question.
The procedures for less than, less equal, and so on
don't appear in <CODE>pg_am</CODE>. Similarly, <CODE>amsupport</CODE> is just
the number of support routines required by the access
method. The actual routines are listed elsewhere.<p>
The next class of interest is pg_opclass. This class
exists only to associate a name with an oid. In
pg_amop, every <B>B-tree</B> operator class has a set of
procedures, one through five, above. Some existing
opclasses are <CODE>int2_ops, int4_ops, and oid_ops</CODE>. You
need to add an instance with your opclass name (for
example, <CODE>complex_abs_ops</CODE>) to <CODE>pg_opclass</CODE>. The <CODE>oid</CODE> of
this instance is a foreign key in other classes.
<pre> INSERT INTO pg_opclass (opcname) VALUES ('complex_abs_ops');
SELECT oid, opcname
FROM pg_opclass
WHERE opcname = 'complex_abs_ops';
+------+--------------+
|oid | opcname |
+------+--------------+
|17314 | int4_abs_ops |
+------+--------------+
</pre>
Note that the oid for your <CODE>pg_opclass</CODE> instance will be
different! You should substitute your value for 17314
wherever it appears in this discussion.<p>
So now we have an access method and an operator class.
We still need a set of operators; the procedure for
defining operators was discussed earlier in this manual.
For the complex_abs_ops operator class on Btrees,
the operators we require are:
<pre> absolute value less-than
absolute value less-than-or-equal
absolute value equal
absolute value greater-than-or-equal
absolute value greater-than
</pre>
Suppose the code that implements the functions defined
is stored in the file
<pre>
/usr/local/postgres95/src/tutorial/complex.c
</pre>
Part of the code look like this: (note that we will
only show the equality operator for the rest of the
examples. The other four operators are very similar.
Refer to <CODE>complex.c</CODE> or <CODE>complex.sql</CODE> for the details.)
<pre> #define Mag(c) ((c)-&gt;x&#42;(c)-&gt;x + (c)-&gt;y&#42;(c)-&gt;y)
bool
complex_abs_eq(Complex &#42;a, Complex &#42;b)
{
double amag = Mag(a), bmag = Mag(b);
return (amag==bmag);
}
</pre>
There are a couple of important things that are happening below.<p>
First, note that operators for less-than, less-than-or
equal, equal, greater-than-or-equal, and greater-than
for <CODE>int4</CODE> are being defined. All of these operators are
already defined for <CODE>int4</CODE> under the names &lt;, &lt;=, =, &gt;=,
and &gt;. The new operators behave differently, of
course. In order to guarantee that POSTGRES uses these
new operators rather than the old ones, they need to be
named differently from the old ones. This is a key
point: you can overload operators in POSTGRES, but only
if the operator isn't already defined for the argument
types. That is, if you have &lt; defined for (int4,
int4), you can't define it again. POSTGRES does not
check this when you define your operator, so be careful.
To avoid this problem, odd names will be used for
the operators. If you get this wrong, the access methods
are likely to crash when you try to do scans.<p>
The other important point is that all the operator
functions return Boolean values. The access methods
rely on this fact. (On the other hand, the support
function returns whatever the particular access method
expects -- in this case, a signed integer.)
The final routine in the file is the "support routine"
mentioned when we discussed the amsupport attribute of
the <CODE>pg_am</CODE> class. We will use this later on. For now,
ignore it.
<pre> CREATE FUNCTION complex_abs_eq(complex, complex)
RETURNS bool
AS '/usr/local/postgres95/tutorial/obj/complex.so'
LANGUAGE 'c';
</pre>
Now define the operators that use them. As noted, the
operator names must be unique among all operators that
take two <CODE>int4</CODE> operands. In order to see if the
operator names listed below are taken, we can do a query on
<CODE>pg_operator</CODE>:
<pre> /&#42;
&#42; this query uses the regular expression operator (~)
&#42; to find three-character operator names that end in
&#42; the character &amp;
&#42;/
SELECT &#42;
FROM pg_operator
WHERE oprname ~ '^..&amp;&#36;'::text;
</pre>
to see if your name is taken for the types you want.
The important things here are the procedure (which are
the <B>C</B> functions defined above) and the restriction and
join selectivity functions. You should just use the
ones used below--note that there are different such
functions for the less-than, equal, and greater-than
cases. These must be supplied, or the access method
will crash when it tries to use the operator. You
should copy the names for restrict and join, but use
the procedure names you defined in the last step.
<pre> CREATE OPERATOR = (
leftarg = complex, rightarg = complex, procedure = complex_abs_eq,
restrict = eqsel, join = eqjoinsel
)
</pre>
Notice that five operators corresponding to less, less
equal, equal, greater, and greater equal are defined.<p>
We're just about finished. the last thing we need to do
is to update the <CODE>pg_amop</CODE> relation. To do this, we need
the following attributes:
<p>
<center>
<table border=1>
<td>amopid </td><td> the <CODE>oid</CODE> of the <CODE>pg_am</CODE> instance for B-tree
(== 403, see above) </td>
<tr>
</tr>
<td>amopclaid </td><td> the <CODE>oid</CODE> of the
<CODE>pg_opclass</CODE> instance for <CODE>int4_abs_ops</CODE> (==
whatever you got instead of <CODE>17314</CODE>, see above)</td>
<tr>
</tr>
<td>amopopr </td><td> the <CODE>oid</CODE>s of the operators for the opclass (which we'll
get in just a minute) </td>
<tr>
</tr>
<td>amopselect, amopnpages </td><td> cost functions.</td>
</tr>
</table>
</center>
<p>
The cost functions are used by the query optimizer to
decide whether or not to use a given index in a scan.
Fortunately, these already exist. The two functions
we'll use are <CODE>btreesel</CODE>, which estimates the selectivity
of the <B>B-tree</B>, and <CODE>btreenpage</CODE>, which estimates the
number of pages a search will touch in the tree.<p>
So we need the <CODE>oid</CODE>s of the operators we just defined.
We'll look up the names of all the operators that take
two <CODE>int4</CODE>s, and pick ours out:
<pre> SELECT o.oid AS opoid, o.oprname
INTO TABLE complex_ops_tmp
FROM pg_operator o, pg_type t
WHERE o.oprleft = t.oid and o.oprright = t.oid
and t.typname = 'complex';
which returns:
+------+---------+
|oid | oprname |
+------+---------+
|17321 | &lt; |
+------+---------+
|17322 | &lt;= |
+------+---------+
|17323 | = |
+------+---------+
|17324 | &gt;= |
+------+---------+
|17325 | &gt; |
+------+---------+
</pre>
(Again, some of your <CODE>oid</CODE> numbers will almost certainly
be different.) The operators we are interested in are
those with <CODE>oid</CODE>s 17321 through 17325. The values you
get will probably be different, and you should
substitute them for the values below. We can look at the
operator names and pick out the ones we just added.<p>
Now we're ready to update <CODE>pg_amop</CODE> with our new operator
class. The most important thing in this entire
discussion is that the operators are ordered, from less equal
through greater equal, in <CODE>pg_amop</CODE>. We add the
instances we need:
<pre> INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
amopselect, amopnpages)
SELECT am.oid, opcl.oid, c.opoid, 3,
'btreesel'::regproc, 'btreenpage'::regproc
FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
WHERE amname = 'btree' and opcname = 'complex_abs_ops'
and c.oprname = '=';
</pre>
Note the order: "less than" is 1, "less than or equal"
is 2, "equal" is 3, "greater than or equal" is 4, and
"greater than" is 5.<p>
The last step (finally!) is registration of the
"support routine" previously described in our discussion of
<CODE>pg_am</CODE>. The <CODE>oid</CODE> of this support routine is stored in
the <CODE>pg_amproc</CODE> class, keyed by the access method <CODE>oid</CODE> and
the operator class <CODE>oid</CODE>. First, we need to register the
function in POSTGRES (recall that we put the <B>C</B> code
that implements this routine in the bottom of the file
in which we implemented the operator routines):
<pre> CREATE FUNCTION int4_abs_cmp(int4, int4)
RETURNS int4
AS '/usr/local/postgres95/tutorial/obj/complex.so'
LANGUAGE 'c';
SELECT oid, proname FROM pg_proc WHERE prname = 'int4_abs_cmp';
+------+--------------+
|oid | proname |
+------+--------------+
|17328 | int4_abs_cmp |
+------+--------------+
</pre>
(Again, your <CODE>oid</CODE> number will probably be different and
you should substitute the value you see for the value
below.) Recalling that the <B>B-tree</B> instance's oid is
403 and that of <CODE>int4_abs_ops</CODE> is 17314, we can add the
new instance as follows:
<pre> INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
VALUES ('403'::oid, -- btree oid
'17314'::oid, -- pg_opclass tuple
'17328'::oid, -- new pg_proc oid
'1'::int2);
</pre>
<p>
<HR>
<A NAME="8"><B>[8]</B></A> Strictly speaking, this routine can return a negative
number (&lt; 0), 0, or a non-zero positive number (&gt; 0).
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xaggr.html">[ Previous ]</A>
<A HREF="libpq.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,70 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - THE QUERY LANGUAGE</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xtypes.html">[ Previous ]</A>
<A HREF="xaggr.html">[ Next ]</A>
</font>
<HR>
<H1>9. EXTENDING SQL: OPERATORS</H1>
<HR>
POSTGRES supports left unary, right unary and binary
operators. Operators can be overloaded, or re-used
with different numbers and types of arguments. If
there is an ambiguous situation and the system cannot
determine the correct operator to use, it will return
an error and you may have to typecast the left and/or
right operands to help it understand which operator you
meant to use.
To create an operator for adding two complex numbers
can be done as follows. First we need to create a
function to add the new types. Then, we can create the
operator with the function.
<pre>
CREATE FUNCTION complex_add(complex, complex)
RETURNS complex
AS '&#36;PWD/obj/complex.so'
LANGUAGE 'c';
CREATE OPERATOR + (
leftarg = complex,
rightarg = complex,
procedure = complex_add,
commutator = +
);
</pre>
We've shown how to create a binary operator here. To
create unary operators, just omit one of leftarg (for
left unary) or rightarg (for right unary).
If we give the system enough type information, it can
automatically figure out which operators to use.
<pre>
SELECT (a + b) AS c FROM test_complex;
+----------------+
|c |
+----------------+
|(5.2,6.05) |
+----------------+
|(133.42,144.95) |
+----------------+
</pre>
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xtypes.html">[ Previous ]</A>
<A HREF="xaggr.html">[ Next ]</A>
</font>
</BODY>
</HTML>

View File

@ -1,148 +0,0 @@
<HTML>
<HEAD>
<TITLE>The POSTGRES95 User Manual - EXTENDING SQL: TYPES</TITLE>
</HEAD>
<BODY>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xfunc.html">[ Previous ]</A>
<A HREF="xoper.html">[ Next ]</A>
</font>
<HR>
<H1>8. EXTENDING SQL: TYPES</H1>
<HR>
As previously mentioned, there are two kinds of types
in POSTGRES: base types (defined in a programming language)
and composite types (instances).
Examples in this section up to interfacing indices can
be found in <CODE>complex.sql</CODE> and <CODE>complex.c</CODE>. Composite examples
are in <CODE>funcs.sql</CODE>.
<p>
<H2><A NAME="user-defined-types">8.1. User-Defined Types</A></H2>
<p>
<H3><A NAME="functions-needed-for-a-user-defined-type">8.1.1. Functions Needed for a User-Defined Type</A></H3>
A user-defined type must always have input and output
functions. These functions determine how the type
appears in strings (for input by the user and output to
the user) and how the type is organized in memory. The
input function takes a null-delimited character string
as its input and returns the internal (in memory)
representation of the type. The output function takes the
internal representation of the type and returns a null
delimited character string.
Suppose we want to define a complex type which represents
complex numbers. Naturally, we choose to represent a
complex in memory as the following <B>C</B> structure:
<pre> typedef struct Complex {
double x;
double y;
} Complex;
</pre>
and a string of the form (x,y) as the external string
representation.
These functions are usually not hard to write, especially
the output function. However, there are a number of points
to remember.
<OL>
<LI> When defining your external (string) representation,
remember that you must eventually write a
complete and robust parser for that representation
as your input function!
<pre> Complex &#42;
complex_in(char &#42;str)
{
double x, y;
Complex &#42;result;
if (sscanf(str, " ( &#37;lf , &#37;lf )", &amp;x, &amp;y) != 2) {
elog(WARN, "complex_in: error in parsing
return NULL;
}
result = (Complex &#42;)palloc(sizeof(Complex));
result-&gt;x = x;
result-&gt;y = y;
return (result);
}
</pre>
The output function can simply be:
<pre> char &#42;
complex_out(Complex &#42;complex)
{
char &#42;result;
<p>
if (complex == NULL)
return(NULL);
<p>
result = (char &#42;) palloc(60);
sprintf(result, "(&#37;g,&#37;g)", complex-&gt;x, complex-&gt;y);
return(result);
}
</pre>
<LI> You should try to make the input and output
functions inverses of each other. If you do
not, you will have severe problems when you need
to dump your data into a file and then read it
back in (say, into someone else's database on
another computer). This is a particularly common
problem when floating-point numbers are
involved.
</OL>
To define the <B>complex</B> type, we need to create the two
user-defined functions complex_in and complex_out
before creating the type:
<pre> CREATE FUNCTION complex_in(opaque)
RETURNS complex
AS '/usr/local/postgres95/tutorial/obj/complex.so'
LANGUAGE 'c';
CREATE FUNCTION complex_out(opaque)
RETURNS opaque
AS '/usr/local/postgres95/tutorial/obj/complex.so'
LANGUAGE 'c';
CREATE TYPE complex (
internallength = 16,
input = complex_in,
output = complex_out
);
</pre>
As discussed earlier, POSTGRES fully supports arrays of
base types. Additionally, POSTGRES supports arrays of
user-defined types as well. When you define a type,
POSTGRES automatically provides support for arrays of
that type. For historical reasons, the array type has
the same name as the user-defined type with the
underscore character _ prepended.
Composite types do not need any function defined on
them, since the system already understands what they
look like inside.
<p>
<H3><A NAME="large-objects">8.1.2. Large Objects</A></H3>
The types discussed to this point are all "small"
objects -- that is, they are smaller than 8KB<A HREF="#7"><font size=-1>[7]</font></A> in size.
If you require a larger type for something like a document
retrieval system or for storing bitmaps, you will
need to use the POSTGRES large object interface.
<p>
<HR>
<A NAME="8"><B>[7]</B></A> 8 &#42; 1024 == 8192 bytes. In fact, the type must be considerably smaller than 8192 bytes, since the POSTGRES tuple
and page overhead must also fit into this 8KB limitation.
The actual value that fits depends on the machine architecture.
<HR>
<font size=-1>
<A HREF="pg95user.html">[ TOC ]</A>
<A HREF="xfunc.html">[ Previous ]</A>
<A HREF="xoper.html">[ Next ]</A>
</font>
</BODY>
</HTML>